mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-01 04:19:12 +00:00
add freeze feature to rundown (#1106)
* add frozen flag to runtime store * add middleware for when frozen * prevent rundown editing when frozen * add endpoint to router to set frozen state * add frozen property to rundown placeholder in client
This commit is contained in:
@@ -48,6 +48,7 @@ export const runtimeStorePlaceholder: RuntimeStore = {
|
|||||||
duration: 0,
|
duration: 0,
|
||||||
playback: SimplePlayback.Stop,
|
playback: SimplePlayback.Stop,
|
||||||
},
|
},
|
||||||
|
frozen: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const deepCompare = <T>(a: T, b: T) => isEqual(a, b);
|
const deepCompare = <T>(a: T, b: T) => isEqual(a, b);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
deleteEvent,
|
deleteEvent,
|
||||||
editEvent,
|
editEvent,
|
||||||
reorderEvent,
|
reorderEvent,
|
||||||
|
setFrozenState,
|
||||||
swapEvents,
|
swapEvents,
|
||||||
} from '../../services/rundown-service/RundownService.js';
|
} from '../../services/rundown-service/RundownService.js';
|
||||||
import {
|
import {
|
||||||
@@ -114,6 +115,17 @@ export async function rundownBatchPut(req: Request, res: Response<MessageRespons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function rundownFrozenPost(req: Request, res: Response<MessageResponse | ErrorResponse>) {
|
||||||
|
try {
|
||||||
|
const { frozen } = req.body;
|
||||||
|
setFrozenState(frozen);
|
||||||
|
res.status(200).send({ message: 'Rundown frozen state updated.' });
|
||||||
|
} catch (error) {
|
||||||
|
const message = getErrorMessage(error);
|
||||||
|
res.status(400).send({ message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function rundownReorder(req: Request, res: Response<OntimeRundownEntry | ErrorResponse>) {
|
export async function rundownReorder(req: Request, res: Response<OntimeRundownEntry | ErrorResponse>) {
|
||||||
if (failEmptyObjects(req.body, res)) {
|
if (failEmptyObjects(req.body, res)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { eventStore } from '../../stores/EventStore.js';
|
||||||
|
|
||||||
|
export const preventIfFrozen = function (req, res, next) {
|
||||||
|
if (eventStore.get('frozen')) {
|
||||||
|
res.status(403).send({ message: 'Rundown is frozen' });
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
rundownApplyDelay,
|
rundownApplyDelay,
|
||||||
rundownBatchPut,
|
rundownBatchPut,
|
||||||
rundownDelete,
|
rundownDelete,
|
||||||
|
rundownFrozenPost,
|
||||||
rundownGetById,
|
rundownGetById,
|
||||||
rundownGetNormalised,
|
rundownGetNormalised,
|
||||||
rundownGetPaginated,
|
rundownGetPaginated,
|
||||||
@@ -17,12 +18,14 @@ import {
|
|||||||
paramsMustHaveEventId,
|
paramsMustHaveEventId,
|
||||||
rundownArrayOfIds,
|
rundownArrayOfIds,
|
||||||
rundownBatchPutValidator,
|
rundownBatchPutValidator,
|
||||||
|
rundownFrozenPostValidator,
|
||||||
rundownGetPaginatedQueryParams,
|
rundownGetPaginatedQueryParams,
|
||||||
rundownPostValidator,
|
rundownPostValidator,
|
||||||
rundownPutValidator,
|
rundownPutValidator,
|
||||||
rundownReorderValidator,
|
rundownReorderValidator,
|
||||||
rundownSwapValidator,
|
rundownSwapValidator,
|
||||||
} from './rundown.validation.js';
|
} from './rundown.validation.js';
|
||||||
|
import { preventIfFrozen } from './rundown.middleware.js';
|
||||||
|
|
||||||
export const router = express.Router();
|
export const router = express.Router();
|
||||||
|
|
||||||
@@ -31,13 +34,14 @@ router.get('/normalised', rundownGetNormalised);
|
|||||||
router.get('/:eventId', paramsMustHaveEventId, rundownGetById); // not used in Ontime frontend
|
router.get('/:eventId', paramsMustHaveEventId, rundownGetById); // not used in Ontime frontend
|
||||||
|
|
||||||
router.post('/', rundownPostValidator, rundownPost);
|
router.post('/', rundownPostValidator, rundownPost);
|
||||||
|
router.post('/frozen', rundownFrozenPostValidator, rundownFrozenPost);
|
||||||
|
|
||||||
router.put('/', rundownPutValidator, rundownPut);
|
router.put('/', rundownPutValidator, rundownPut);
|
||||||
router.put('/batch', rundownBatchPutValidator, rundownBatchPut);
|
router.put('/batch', rundownBatchPutValidator, rundownBatchPut);
|
||||||
|
|
||||||
router.patch('/reorder/', rundownReorderValidator, rundownReorder);
|
router.patch('/reorder/', rundownReorderValidator, preventIfFrozen, rundownReorder);
|
||||||
router.patch('/swap', rundownSwapValidator, rundownSwap);
|
router.patch('/swap', rundownSwapValidator, preventIfFrozen, rundownSwap);
|
||||||
router.patch('/applydelay/:eventId', paramsMustHaveEventId, rundownApplyDelay);
|
router.patch('/applydelay/:eventId', paramsMustHaveEventId, rundownApplyDelay);
|
||||||
|
|
||||||
router.delete('/', rundownArrayOfIds, deletesEventById);
|
router.delete('/', rundownArrayOfIds, preventIfFrozen, deletesEventById);
|
||||||
router.delete('/all', rundownDelete);
|
router.delete('/all', preventIfFrozen, rundownDelete);
|
||||||
|
|||||||
@@ -21,6 +21,15 @@ export const rundownPutValidator = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const rundownFrozenPostValidator = [
|
||||||
|
body('frozen').isBoolean().exists(),
|
||||||
|
(req: Request, res: Response, next: NextFunction) => {
|
||||||
|
const errors = validationResult(req);
|
||||||
|
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
export const rundownBatchPutValidator = [
|
export const rundownBatchPutValidator = [
|
||||||
body('data').isObject().exists(),
|
body('data').isObject().exists(),
|
||||||
body('ids').isArray().exists(),
|
body('ids').isArray().exists(),
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ export const startServer = async (
|
|||||||
playback: SimplePlayback.Stop,
|
playback: SimplePlayback.Stop,
|
||||||
direction: SimpleDirection.CountDown,
|
direction: SimpleDirection.CountDown,
|
||||||
},
|
},
|
||||||
|
frozen: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// initialise logging service, escalateErrorFn is only exists in electron
|
// initialise logging service, escalateErrorFn is only exists in electron
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { runtimeService } from '../runtime-service/RuntimeService.js';
|
|||||||
|
|
||||||
import * as cache from './rundownCache.js';
|
import * as cache from './rundownCache.js';
|
||||||
import { getPlayableEvents } from './rundownUtils.js';
|
import { getPlayableEvents } from './rundownUtils.js';
|
||||||
|
import { eventStore } from '../../stores/EventStore.js';
|
||||||
|
|
||||||
type PatchWithId = (Partial<OntimeEvent> | Partial<OntimeBlock> | Partial<OntimeDelay>) & { id: string };
|
type PatchWithId = (Partial<OntimeEvent> | Partial<OntimeBlock> | Partial<OntimeDelay>) & { id: string };
|
||||||
|
|
||||||
@@ -262,3 +263,7 @@ export async function initRundown(rundown: Readonly<OntimeRundown>, customFields
|
|||||||
// notify timer of change
|
// notify timer of change
|
||||||
notifyChanges({ timer: true });
|
notifyChanges({ timer: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setFrozenState(state: boolean) {
|
||||||
|
eventStore.set('frozen', state);
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,4 +22,7 @@ export type RuntimeStore = {
|
|||||||
|
|
||||||
// extra timers
|
// extra timers
|
||||||
auxtimer1: SimpleTimerState;
|
auxtimer1: SimpleTimerState;
|
||||||
|
|
||||||
|
// flags
|
||||||
|
frozen: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user