mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-20 06:29:07 +00:00
Feature: quick start (#369)
* feat: quick start modal * refactor: end message is part of view settings * refactor: small tweaks and type improvements
This commit is contained in:
@@ -12,7 +12,7 @@ export class DataProvider {
|
||||
return data;
|
||||
}
|
||||
|
||||
static async setEventData(newData: EventData) {
|
||||
static async setEventData(newData: Partial<EventData>) {
|
||||
data.eventData = { ...data.eventData, ...newData };
|
||||
await this.persist();
|
||||
return data.eventData;
|
||||
|
||||
@@ -8,7 +8,6 @@ describe('safeMerge', () => {
|
||||
publicUrl: 'existing public URL',
|
||||
backstageUrl: 'existing backstageUrl',
|
||||
backstageInfo: 'existing backstageInfo',
|
||||
endMessage: 'existing endMessage',
|
||||
},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
@@ -20,6 +19,7 @@ describe('safeMerge', () => {
|
||||
},
|
||||
viewSettings: {
|
||||
overrideStyles: false,
|
||||
endMessage: 'existing endMessage',
|
||||
},
|
||||
aliases: [],
|
||||
userFields: {
|
||||
@@ -75,7 +75,6 @@ describe('safeMerge', () => {
|
||||
publicInfo: 'new public info',
|
||||
backstageUrl: 'existing backstageUrl',
|
||||
backstageInfo: 'existing backstageInfo',
|
||||
endMessage: 'existing endMessage',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -145,7 +144,6 @@ describe('safeMerge', () => {
|
||||
publicInfo: '',
|
||||
backstageUrl: '',
|
||||
backstageInfo: '',
|
||||
endMessage: '',
|
||||
},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
@@ -157,6 +155,7 @@ describe('safeMerge', () => {
|
||||
},
|
||||
viewSettings: {
|
||||
overrideStyles: false,
|
||||
endMessage: '',
|
||||
},
|
||||
aliases: [],
|
||||
userFields: {
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
import { removeUndefined } from '../utils/parserUtils.js';
|
||||
import { failEmptyObjects } from '../utils/routerUtils.js';
|
||||
import { DataProvider } from '../classes/data-provider/DataProvider.ts';
|
||||
import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
||||
|
||||
// Create controller for GET request to 'event'
|
||||
export const getEvent = async (req, res) => {
|
||||
export const getEventData = async (req, res) => {
|
||||
res.json(DataProvider.getEventData());
|
||||
};
|
||||
|
||||
// Create controller for POST request to 'event'
|
||||
export const postEvent = async (req, res) => {
|
||||
export const postEventData = async (req, res) => {
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { body, validationResult } from 'express-validator';
|
||||
|
||||
export const eventSanitizer = [
|
||||
export const eventDataSanitizer = [
|
||||
body('title').optional().isString().trim(),
|
||||
body('publicUrl').optional().isString().trim(),
|
||||
body('publicInfo').optional().isString().trim(),
|
||||
+27
-4
@@ -1,7 +1,8 @@
|
||||
import fs from 'fs';
|
||||
import type { EventData } from 'ontime-types';
|
||||
import { networkInterfaces } from 'os';
|
||||
import { generateId } from 'ontime-utils';
|
||||
import { fileHandler } from '../utils/parser.ts';
|
||||
import { fileHandler } from '../utils/parser.js';
|
||||
import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
||||
import { failEmptyObjects, failIsNotArray } from '../utils/routerUtils.js';
|
||||
import { mergeObject } from '../utils/parserUtils.js';
|
||||
@@ -10,6 +11,7 @@ import { eventStore } from '../stores/EventStore.js';
|
||||
import { resolveDbPath } from '../setup.js';
|
||||
import { oscIntegration } from '../services/integration-service/OscIntegration.js';
|
||||
import { logger } from '../classes/Logger.js';
|
||||
import { deleteAllEvents } from '../services/RundownService.js';
|
||||
|
||||
// Create controller for GET request to '/ontime/poll'
|
||||
// Returns data for current state
|
||||
@@ -56,9 +58,9 @@ const uploadAndParse = async (file, req, res, options) => {
|
||||
try {
|
||||
const result = await fileHandler(file);
|
||||
|
||||
if (result?.error) {
|
||||
if ('error' in result && result.error) {
|
||||
res.status(400).send({ message: result.message });
|
||||
} else if (result.message === 'success') {
|
||||
} else if ('data' in result && result.message === 'success') {
|
||||
PlaybackService.stop();
|
||||
// explicitly write objects
|
||||
if (typeof result !== 'undefined') {
|
||||
@@ -241,7 +243,10 @@ export const postViewSettings = async (req, res) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const newData = { overrideStyles: req.body.overrideStyles };
|
||||
const newData = {
|
||||
overrideStyles: req.body.overrideStyles,
|
||||
endMessage: req.body?.endMessage || '',
|
||||
};
|
||||
await DataProvider.setViewSettings(newData);
|
||||
res.status(200).send(newData);
|
||||
} catch (error) {
|
||||
@@ -288,3 +293,21 @@ export const dbUpload = async (req, res) => {
|
||||
const file = req.file.path;
|
||||
await uploadAndParse(file, req, res, options);
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/new'
|
||||
export const postNew = async (req, res) => {
|
||||
try {
|
||||
const newEventData: Omit<EventData, 'endMessage'> = {
|
||||
title: req.body?.title ?? '',
|
||||
publicUrl: req.body?.publicUrl ?? '',
|
||||
publicInfo: req.body?.publicInfo ?? '',
|
||||
backstageUrl: req.body?.backstageUrl ?? '',
|
||||
backstageInfo: req.body?.backstageInfo ?? '',
|
||||
};
|
||||
const newData = await DataProvider.setEventData(newEventData);
|
||||
await deleteAllEvents();
|
||||
res.status(201).send(newData);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
};
|
||||
@@ -6,6 +6,7 @@ import { validateOscSubscription } from '../utils/parserFunctions.js';
|
||||
*/
|
||||
export const viewValidator = [
|
||||
check('overrideStyles').isBoolean().withMessage('overrideStyles value must be boolean'),
|
||||
check('endMessage').isString().trim().withMessage('endMessage value must be string'),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
|
||||
@@ -8,7 +8,6 @@ export const dbModel: DatabaseModel = {
|
||||
publicInfo: '',
|
||||
backstageUrl: '',
|
||||
backstageInfo: '',
|
||||
endMessage: '',
|
||||
},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
@@ -20,6 +19,7 @@ export const dbModel: DatabaseModel = {
|
||||
},
|
||||
viewSettings: {
|
||||
overrideStyles: false,
|
||||
endMessage: '',
|
||||
},
|
||||
aliases: [],
|
||||
userFields: {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import express from 'express';
|
||||
// import event controller
|
||||
import { getEventData, postEventData } from '../controllers/eventDataController.ts';
|
||||
import { eventDataSanitizer } from '../controllers/eventDataController.validate.ts';
|
||||
|
||||
export const router = express.Router();
|
||||
|
||||
// import event controller
|
||||
import { getEvent, postEvent } from '../controllers/eventDataController.js';
|
||||
import { eventSanitizer } from '../controllers/eventDataController.validate.js';
|
||||
|
||||
// create route between controller and 'GET /event' endpoint
|
||||
router.get('/', getEvent);
|
||||
router.get('/', getEventData);
|
||||
|
||||
// create route between controller and 'POST /event' endpoint
|
||||
router.post('/', eventSanitizer, postEvent);
|
||||
router.post('/', eventDataSanitizer, postEventData);
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
getViewSettings,
|
||||
poll,
|
||||
postAliases,
|
||||
postNew,
|
||||
postOSC,
|
||||
postSettings,
|
||||
postUserFields,
|
||||
@@ -24,6 +25,7 @@ import {
|
||||
validateUserFields,
|
||||
viewValidator,
|
||||
} from '../controllers/ontimeController.validate.js';
|
||||
import { eventDataSanitizer } from '../controllers/eventDataController.validate.js';
|
||||
|
||||
export const router = express.Router();
|
||||
|
||||
@@ -68,3 +70,6 @@ router.get('/osc', getOSC);
|
||||
|
||||
// create route between controller and '/ontime/osc' endpoint
|
||||
router.post('/osc', validateOSC, postOSC);
|
||||
|
||||
// create route between controller and '/ontime/new' endpoint
|
||||
router.post('/new', eventDataSanitizer, postNew);
|
||||
|
||||
@@ -352,7 +352,7 @@ type ResponseError = { error: true; message: string };
|
||||
* @param {string} file - reference to file
|
||||
* @return {object} - parse result message
|
||||
*/
|
||||
export const fileHandler = async (file) => {
|
||||
export const fileHandler = async (file): ResponseOK | ResponseError => {
|
||||
let res: Partial<ResponseOK | ResponseError> = {};
|
||||
|
||||
// check which file type are we dealing with
|
||||
|
||||
@@ -87,7 +87,6 @@ export const parseEventData = (data, enforce): EventData => {
|
||||
publicInfo: e.publicInfo || dbModel.eventData.publicInfo,
|
||||
backstageUrl: e.backstageUrl || dbModel.eventData.backstageUrl,
|
||||
backstageInfo: e.backstageInfo || dbModel.eventData.backstageInfo,
|
||||
endMessage: e.endMessage || dbModel.eventData.endMessage,
|
||||
};
|
||||
} else if (enforce) {
|
||||
newEventData = { ...dbModel.eventData };
|
||||
@@ -145,6 +144,7 @@ export const parseViewSettings = (data, enforce): ViewSettings => {
|
||||
|
||||
const viewSettings = {
|
||||
overrideStyles: v.overrideStyles ?? dbModel.viewSettings.overrideStyles,
|
||||
endMessage: v.endMessage ?? dbModel.viewSettings.endMessage,
|
||||
};
|
||||
|
||||
// write to db
|
||||
|
||||
Reference in New Issue
Block a user