From 72b42c7eb8dd3fff33fe9dfcec53acb919984f66 Mon Sep 17 00:00:00 2001
From: cv <34649812+cpvalente@users.noreply.github.com>
Date: Thu, 6 May 2021 14:02:56 +0200
Subject: [PATCH] feat: apply delays
---
client/src/app/api/eventsApi.js | 11 ++-
.../components/buttons/ApplyIconBtn.jsx | 16 +++++
.../src/features/editors/list/DelayBlock.jsx | 6 ++
.../src/features/editors/list/EventList.jsx | 3 +
.../editors/list/EventListWrapper.jsx | 45 +++++++++++-
server/controllers/eventsController.js | 71 +++++++++++++++++--
server/routes/eventsRouter.js | 3 +
7 files changed, 145 insertions(+), 10 deletions(-)
create mode 100644 client/src/common/components/buttons/ApplyIconBtn.jsx
diff --git a/client/src/app/api/eventsApi.js b/client/src/app/api/eventsApi.js
index c258cc2b9..ec19409be 100644
--- a/client/src/app/api/eventsApi.js
+++ b/client/src/app/api/eventsApi.js
@@ -31,9 +31,14 @@ export const requestPatch = async (data) => {
};
export const requestReorder = async (data) => {
- const reorder = 'reorder';
- console.log('debug got reorder with payload', data);
- const res = await axios.patch(eventsURL + '/' + reorder, data);
+ const action = 'reorder';
+ const res = await axios.patch(eventsURL + '/' + action, data);
+ return res;
+};
+
+export const requestApplyDelay = async (eventId) => {
+ const action = 'applydelay';
+ const res = await axios.patch(eventsURL + '/' + action + '/' + eventId);
return res;
};
diff --git a/client/src/common/components/buttons/ApplyIconBtn.jsx b/client/src/common/components/buttons/ApplyIconBtn.jsx
new file mode 100644
index 000000000..67a4e2f3a
--- /dev/null
+++ b/client/src/common/components/buttons/ApplyIconBtn.jsx
@@ -0,0 +1,16 @@
+import { IconButton } from '@chakra-ui/button';
+import { FiChevronsDown } from 'react-icons/fi';
+
+export default function ApplyIconBtn(props) {
+ const { clickhandler, ...rest } = props;
+ return (
+ }
+ colorScheme='orange'
+ onClick={clickhandler}
+ _focus={{ boxShadow: 'none' }}
+ {...rest}
+ />
+ );
+}
diff --git a/client/src/features/editors/list/DelayBlock.jsx b/client/src/features/editors/list/DelayBlock.jsx
index 960703c6f..4ee8e1ac3 100644
--- a/client/src/features/editors/list/DelayBlock.jsx
+++ b/client/src/features/editors/list/DelayBlock.jsx
@@ -5,6 +5,7 @@ import TimeInput from '../../../common/input/TimeInput';
import style from './Block.module.css';
import ActionButtons from './ActionButtons';
import DeleteIconBtn from '../../../common/components/buttons/DeleteIconBtn';
+import ApplyIconBtn from '../../../common/components/buttons/ApplyIconBtn';
export default function DelayBlock(props) {
const { data, eventsHandler, index } = props;
@@ -22,6 +23,10 @@ export default function DelayBlock(props) {
eventsHandler('delete', data.id);
};
+ const applyDelayHandler = () => {
+ eventsHandler('applyDelay', { id: data.id, duration: data.duration });
+ };
+
let delayValue =
data.duration != null ? millisToMinutes(data.duration) : undefined;
return (
@@ -37,6 +42,7 @@ export default function DelayBlock(props) {
diff --git a/client/src/features/editors/list/EventList.jsx b/client/src/features/editors/list/EventList.jsx
index 50176d63f..d5d5e2e99 100644
--- a/client/src/features/editors/list/EventList.jsx
+++ b/client/src/features/editors/list/EventList.jsx
@@ -95,6 +95,9 @@ export default function EventList(props) {
// drop outside of area
if (!result.destination) return;
+ // no change
+ if (result.destination === result.source.index) return;
+
// Call API
eventsHandler('reorder', {
index: result.draggableId,
diff --git a/client/src/features/editors/list/EventListWrapper.jsx b/client/src/features/editors/list/EventListWrapper.jsx
index c75872bc1..af1f6f5ec 100644
--- a/client/src/features/editors/list/EventListWrapper.jsx
+++ b/client/src/features/editors/list/EventListWrapper.jsx
@@ -8,6 +8,7 @@ import {
requestPut,
requestDelete,
requestReorder,
+ requestApplyDelay,
} from '../../../app/api/eventsApi.js';
import EventList from './EventList';
import EventListMenu from '../../menu/EventListMenu.jsx';
@@ -156,7 +157,14 @@ export default function EventListWrapper() {
},
});
- const reorderEvent = useMutation(requestReorder, {
+ const applyDelay = useMutation(requestApplyDelay, {
+ // Mutation finished, failed or successful
+ onSettled: () => {
+ queryClient.invalidateQueries(eventsNamespace);
+ },
+ });
+
+ const reorderEvent = useMutation(requestReorder, {
// we optimistically update here
onMutate: async (data) => {
// cancel ongoing queries
@@ -241,6 +249,41 @@ export default function EventListWrapper() {
} catch (error) {
showErrorToast('Error reordering event', error.message);
}
+ break;
+ case 'applyDelay':
+ let t = Date.now();
+
+ // if delay <= 0 delete delay and next block
+ if (payload.duration <= 0) {
+ try {
+ // look for block after
+ let afterId = false;
+ let blockAfter = null;
+ for (const d of data) {
+ if (d.id === payload.id) afterId = true;
+ if (afterId && d.type === 'block') {
+ blockAfter = d.id;
+ break;
+ }
+ }
+
+ // delete delay
+ await deleteEvent.mutateAsync(payload.id);
+ // delete block after, if any
+ if (blockAfter) await deleteEvent.mutateAsync(blockAfter);
+ } catch (error) {
+ showErrorToast('Error applying delay', error.message);
+ }
+ } else {
+ console.log('debug applydelay', payload.id);
+ try {
+ await applyDelay.mutateAsync(payload.id);
+ } catch (error) {
+ showErrorToast('Error applying delay', error.message);
+ }
+ }
+ console.log('debug m apply', Date.now() - t);
+
break;
default:
showErrorToast('Unrecognised request', action);
diff --git a/server/controllers/eventsController.js b/server/controllers/eventsController.js
index ef933eac4..e9ab335c3 100644
--- a/server/controllers/eventsController.js
+++ b/server/controllers/eventsController.js
@@ -165,15 +165,11 @@ exports.eventsReorder = async (req, res) => {
// TODO: Validate event
if (!req.body) {
res.status(400).send(`No object found in request`);
- console.log(`No object found in request`);
-
return;
}
const { index, from, to } = req.body;
- console.log(req.body);
-
// get events
let events = db.get('events').value();
let idx = events.findIndex((e) => e.id === index, from);
@@ -181,7 +177,6 @@ exports.eventsReorder = async (req, res) => {
// Check if item is at given index
if (idx !== from) {
res.status(400).send(`Id not found at index`);
- console.log(`Id not found at index`, idx, from);
return;
}
@@ -206,6 +201,71 @@ exports.eventsReorder = async (req, res) => {
}
};
+// Create controller for PATCH request to '/events/applydelay/:eventId'
+// Returns -
+exports.eventsApplyDelay = async (req, res) => {
+ // no valid params
+ if (!req.params.eventId) {
+ res.status(400).send(`No id found in request`);
+ return;
+ }
+
+ try {
+ // get events
+ let events = db.get('events').value();
+
+ // AUX
+ let delayIndex = null;
+ let blockIndex = null;
+ let delayValue = 0;
+
+ for (const [index, e] of events.entries()) {
+ if (delayIndex == null) {
+ // look for delay
+ if (e.id === req.params.eventId && e.type === 'delay') {
+ delayValue = e.duration;
+ delayIndex = index;
+ }
+ }
+
+ // apply delay value to all items until block or end
+ else {
+ if (e.type === 'event') {
+ // update times
+ e.timeStart += delayValue;
+ e.timeEnd += delayValue;
+
+ // increment revision
+ e.revision += 1;
+ } else if (e.type === 'block') {
+ // save id and stop
+ blockIndex = index;
+ break;
+ }
+ }
+ }
+
+ // delete delay
+ events.splice(delayIndex, 1);
+
+ // delete block
+ // index would have moved down since we deleted delay
+ if (blockIndex) events.splice(blockIndex - 1, 1);
+
+ // update events
+ db.set('events', events).write();
+
+ // update timer
+ _updateTimers();
+
+ res.sendStatus(201);
+ } catch (error) {
+ console.log('debug:', error);
+
+ res.status(400).send(error);
+ }
+};
+
// Create controller for DELETE request to '/events/:eventId'
// Returns -
exports.eventsDelete = async (req, res) => {
@@ -213,7 +273,6 @@ exports.eventsDelete = async (req, res) => {
if (!req.params.eventId) {
res.status(400).send(`No id found in request`);
return;
- console.log('debug: No id found in request');
}
try {
diff --git a/server/routes/eventsRouter.js b/server/routes/eventsRouter.js
index 2f4515afa..a156906cf 100644
--- a/server/routes/eventsRouter.js
+++ b/server/routes/eventsRouter.js
@@ -22,6 +22,9 @@ router.patch('/', eventsController.eventsPatch);
// create route between controller and '/events/reorder' endpoint
router.patch('/reorder/', eventsController.eventsReorder);
+// create route between controller and '/events/applydelay/:eventId' endpoint
+router.patch('/applydelay/:eventId', eventsController.eventsApplyDelay);
+
// create route between controller and '/events/:eventId' endpoint
router.delete('/:eventId', eventsController.eventsDelete);