feat: apply delays

This commit is contained in:
cv
2021-05-06 14:02:56 +02:00
parent 50e2fd5695
commit 72b42c7eb8
7 changed files with 145 additions and 10 deletions
+8 -3
View File
@@ -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;
};
@@ -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 (
<IconButton
size={props.size || 'xs'}
icon={<FiChevronsDown />}
colorScheme='orange'
onClick={clickhandler}
_focus={{ boxShadow: 'none' }}
{...rest}
/>
);
}
@@ -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) {
</span>
<TimeInput value={delayValue} submitHandler={submitHandler} />
<div className={style.actionOverlay}>
<ApplyIconBtn clickhandler={applyDelayHandler} />
<DeleteIconBtn clickhandler={deleteHandler} />
<ActionButtons showAdd addHandler={addHandler} />
</div>
@@ -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,
@@ -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);
+65 -6
View File
@@ -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 {
+3
View File
@@ -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);