mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-22 15:39:11 +00:00
refactor: freeze is view option
This commit is contained in:
@@ -2,14 +2,23 @@ import axios from 'axios';
|
|||||||
import type { ViewSettings } from 'ontime-types';
|
import type { ViewSettings } from 'ontime-types';
|
||||||
|
|
||||||
import { apiEntryUrl } from './constants';
|
import { apiEntryUrl } from './constants';
|
||||||
const viewSettingsPath = apiEntryUrl + '/view-settings';
|
|
||||||
|
|
||||||
export async function getViewSettings() {
|
const viewSettingsPath = `${apiEntryUrl}/view-settings`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP request to fetch view settings
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getViewSettings(): Promise<ViewSettings> {
|
||||||
const res = await axios.get(viewSettingsPath);
|
const res = await axios.get(viewSettingsPath);
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postViewSettings(data: ViewSettings) {
|
/**
|
||||||
|
* HTTP request to update view settings
|
||||||
|
* needs to update entire objects, not just a patch
|
||||||
|
*/
|
||||||
|
export async function postViewSettings(data: ViewSettings): Promise<ViewSettings> {
|
||||||
const res = await axios.post(viewSettingsPath, data);
|
const res = await axios.post(viewSettingsPath, data);
|
||||||
return res.data as ViewSettings;
|
return res.data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ function ViewParamsEditor({ viewOptions }: EditFormDrawerProps) {
|
|||||||
|
|
||||||
const newParamsObject = Object.fromEntries(new FormData(formEvent.currentTarget));
|
const newParamsObject = Object.fromEntries(new FormData(formEvent.currentTarget));
|
||||||
const newSearchParams = getURLSearchParamsFromObj(newParamsObject, viewOptions);
|
const newSearchParams = getURLSearchParamsFromObj(newParamsObject, viewOptions);
|
||||||
|
|
||||||
console.log('New search params:', newParamsObject, newSearchParams.toString());
|
|
||||||
setSearchParams(newSearchParams);
|
setSearchParams(newSearchParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ import { ViewSettings } from 'ontime-types';
|
|||||||
|
|
||||||
export const viewsSettingsPlaceholder: ViewSettings = {
|
export const viewsSettingsPlaceholder: ViewSettings = {
|
||||||
dangerColor: '#ED3333',
|
dangerColor: '#ED3333',
|
||||||
endMessage: '',
|
|
||||||
freezeEnd: false,
|
|
||||||
normalColor: '#ffffffcc',
|
normalColor: '#ffffffcc',
|
||||||
overrideStyles: false,
|
overrideStyles: false,
|
||||||
warningColor: '#FFAB33',
|
warningColor: '#FFAB33',
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { maybeAxiosError } from '../../../../common/api/utils';
|
|||||||
import Button from '../../../../common/components/buttons/Button';
|
import Button from '../../../../common/components/buttons/Button';
|
||||||
import Info from '../../../../common/components/info/Info';
|
import Info from '../../../../common/components/info/Info';
|
||||||
import { SwatchPickerRHF } from '../../../../common/components/input/colour-input/SwatchPicker';
|
import { SwatchPickerRHF } from '../../../../common/components/input/colour-input/SwatchPicker';
|
||||||
import Input from '../../../../common/components/input/input/Input';
|
|
||||||
import ExternalLink from '../../../../common/components/link/external-link/ExternalLink';
|
import ExternalLink from '../../../../common/components/link/external-link/ExternalLink';
|
||||||
import Switch from '../../../../common/components/switch/Switch';
|
import Switch from '../../../../common/components/switch/Switch';
|
||||||
import useViewSettings from '../../../../common/hooks-query/useViewSettings';
|
import useViewSettings from '../../../../common/hooks-query/useViewSettings';
|
||||||
@@ -26,7 +25,6 @@ export default function ViewSettings() {
|
|||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
setError,
|
setError,
|
||||||
register,
|
|
||||||
reset,
|
reset,
|
||||||
setValue,
|
setValue,
|
||||||
watch,
|
watch,
|
||||||
@@ -122,31 +120,6 @@ export default function ViewSettings() {
|
|||||||
<SwatchPickerRHF name='dangerColor' control={control} />
|
<SwatchPickerRHF name='dangerColor' control={control} />
|
||||||
</Panel.ListItem>
|
</Panel.ListItem>
|
||||||
</Panel.ListGroup>
|
</Panel.ListGroup>
|
||||||
<Panel.ListGroup>
|
|
||||||
<Panel.ListItem>
|
|
||||||
<Panel.Field
|
|
||||||
title='Freeze timer on end'
|
|
||||||
description='When a timer hits 00:00:00, it freezes instead of going negative. It invalidates the End Message.'
|
|
||||||
/>
|
|
||||||
<Switch
|
|
||||||
size='large'
|
|
||||||
checked={watch('freezeEnd')}
|
|
||||||
onCheckedChange={(value: boolean) => setValue('freezeEnd', value, { shouldDirty: true })}
|
|
||||||
/>
|
|
||||||
</Panel.ListItem>
|
|
||||||
<Panel.ListItem>
|
|
||||||
<Panel.Field
|
|
||||||
title='End message'
|
|
||||||
description='Message for negative timers; applies only if the timer isn`t frozen on End. If no message is provided, it continues into negative time'
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
maxLength={150}
|
|
||||||
style={{ width: '275px' }}
|
|
||||||
placeholder='Shown when timer reaches end'
|
|
||||||
{...register('endMessage')}
|
|
||||||
/>
|
|
||||||
</Panel.ListItem>
|
|
||||||
</Panel.ListGroup>
|
|
||||||
</Panel.Section>
|
</Panel.Section>
|
||||||
</Panel.Card>
|
</Panel.Card>
|
||||||
</Panel.Section>
|
</Panel.Section>
|
||||||
|
|||||||
@@ -126,28 +126,6 @@ export default function QuickStart({ isOpen, onClose }: QuickStartProps) {
|
|||||||
/>
|
/>
|
||||||
</Panel.ListItem>
|
</Panel.ListItem>
|
||||||
</Panel.ListGroup>
|
</Panel.ListGroup>
|
||||||
|
|
||||||
<Panel.ListGroup>
|
|
||||||
<Panel.ListItem>
|
|
||||||
<Panel.Field
|
|
||||||
title='Freeze timer on end'
|
|
||||||
description='When a timer hits 00:00:00, it freezes instead of going negative. It invalidates the End Message.'
|
|
||||||
/>
|
|
||||||
<Switch
|
|
||||||
size='large'
|
|
||||||
name='viewSettings.freezeEnd'
|
|
||||||
checked={watch('viewSettings.freezeEnd')}
|
|
||||||
onCheckedChange={(checked) => setValue('viewSettings.freezeEnd', checked)}
|
|
||||||
/>
|
|
||||||
</Panel.ListItem>
|
|
||||||
<Panel.ListItem>
|
|
||||||
<Panel.Field
|
|
||||||
title='End message'
|
|
||||||
description='Message for negative timers; applies only if the timer isn`t frozen on End. If no message is provided, it continues into negative time'
|
|
||||||
/>
|
|
||||||
<Input maxLength={150} fluid placeholder='eg: Time is up!' {...register('viewSettings.endMessage')} />
|
|
||||||
</Panel.ListItem>
|
|
||||||
</Panel.ListGroup>
|
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
footerElements={
|
footerElements={
|
||||||
|
|||||||
@@ -8,8 +8,4 @@ export const quickStartDefaults: QuickStartData = {
|
|||||||
timeFormat: '24',
|
timeFormat: '24',
|
||||||
language: 'en',
|
language: 'en',
|
||||||
},
|
},
|
||||||
viewSettings: {
|
|
||||||
freezeEnd: false,
|
|
||||||
endMessage: '',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export default function TimerPreview() {
|
|||||||
if (showTimerMessage) return 'Message';
|
if (showTimerMessage) return 'Message';
|
||||||
if (timerType === TimerType.None) return timerPlaceholder;
|
if (timerType === TimerType.None) return timerPlaceholder;
|
||||||
if (phase === TimerPhase.Pending) return 'Standby to start';
|
if (phase === TimerPhase.Pending) return 'Standby to start';
|
||||||
if (phase === TimerPhase.Overtime && data.endMessage) return 'Custom end message';
|
if (phase === TimerPhase.Overtime) return 'Timer Overtime';
|
||||||
if (timerType === TimerType.Clock) return 'Clock';
|
if (timerType === TimerType.Clock) return 'Clock';
|
||||||
if (countToEnd) return 'Count to End';
|
if (countToEnd) return 'Count to End';
|
||||||
return 'Timer';
|
return 'Timer';
|
||||||
|
|||||||
@@ -30,10 +30,6 @@ export const validateQuickProject = [
|
|||||||
body('settings.timeFormat').optional().isIn(['12', '24']),
|
body('settings.timeFormat').optional().isIn(['12', '24']),
|
||||||
body('settings.language').optional().isString().trim(),
|
body('settings.language').optional().isString().trim(),
|
||||||
|
|
||||||
// ViewSettings fields
|
|
||||||
body('viewSettings.freezeEnd').optional().isBoolean(),
|
|
||||||
body('viewSettings.endMessage').optional().isString().trim(),
|
|
||||||
|
|
||||||
requestValidationFunction,
|
requestValidationFunction,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ export function parseViewSettings(data: Partial<DatabaseModel>, emitError?: Erro
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
dangerColor: data.viewSettings.dangerColor ?? dbModel.viewSettings.dangerColor,
|
dangerColor: data.viewSettings.dangerColor ?? dbModel.viewSettings.dangerColor,
|
||||||
endMessage: data.viewSettings.endMessage ?? dbModel.viewSettings.endMessage,
|
|
||||||
freezeEnd: data.viewSettings.freezeEnd ?? dbModel.viewSettings.freezeEnd,
|
|
||||||
normalColor: data.viewSettings.normalColor ?? dbModel.viewSettings.normalColor,
|
normalColor: data.viewSettings.normalColor ?? dbModel.viewSettings.normalColor,
|
||||||
overrideStyles: data.viewSettings.overrideStyles ?? dbModel.viewSettings.overrideStyles,
|
overrideStyles: data.viewSettings.overrideStyles ?? dbModel.viewSettings.overrideStyles,
|
||||||
warningColor: data.viewSettings.warningColor ?? dbModel.viewSettings.warningColor,
|
warningColor: data.viewSettings.warningColor ?? dbModel.viewSettings.warningColor,
|
||||||
|
|||||||
@@ -18,17 +18,17 @@ router.post('/', validateViewSettings, async (req: Request, res: Response<ViewSe
|
|||||||
try {
|
try {
|
||||||
const newData = {
|
const newData = {
|
||||||
dangerColor: req.body.dangerColor,
|
dangerColor: req.body.dangerColor,
|
||||||
endMessage: req.body.endMessage,
|
|
||||||
freezeEnd: req.body.freezeEnd,
|
|
||||||
normalColor: req.body.normalColor,
|
normalColor: req.body.normalColor,
|
||||||
overrideStyles: req.body.overrideStyles,
|
overrideStyles: req.body.overrideStyles,
|
||||||
warningColor: req.body.warningColor,
|
warningColor: req.body.warningColor,
|
||||||
} as ViewSettings;
|
} as ViewSettings;
|
||||||
await getDataProvider().setViewSettings(newData);
|
await getDataProvider().setViewSettings(newData);
|
||||||
res.status(200).send(newData);
|
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
sendRefetch(RefetchKey.ViewSettings);
|
sendRefetch(RefetchKey.ViewSettings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
res.status(200).send(newData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = getErrorMessage(error);
|
const message = getErrorMessage(error);
|
||||||
res.status(400).send({ message });
|
res.status(400).send({ message });
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import { requestValidationFunction } from '../validation-utils/validationFunctio
|
|||||||
*/
|
*/
|
||||||
export const validateViewSettings = [
|
export const validateViewSettings = [
|
||||||
body('dangerColor').isString().trim().withMessage('dangerColor value must be string'),
|
body('dangerColor').isString().trim().withMessage('dangerColor value must be string'),
|
||||||
body('endMessage').isString().trim().withMessage('endMessage value must be string'),
|
|
||||||
body('freezeEnd').isBoolean().withMessage('freezeEnd value must be boolean'),
|
|
||||||
body('normalColor').isString().trim().withMessage('normalColor value must be string'),
|
body('normalColor').isString().trim().withMessage('normalColor value must be string'),
|
||||||
body('overrideStyles').isBoolean().withMessage('overrideStyles value must be boolean'),
|
body('overrideStyles').isBoolean().withMessage('overrideStyles value must be boolean'),
|
||||||
body('warningColor').isString().trim().withMessage('warningColor value must be string'),
|
body('warningColor').isString().trim().withMessage('warningColor value must be string'),
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ export const dbModel: DatabaseModel = {
|
|||||||
normalColor: '#ffffffcc',
|
normalColor: '#ffffffcc',
|
||||||
warningColor: '#FFAB33',
|
warningColor: '#FFAB33',
|
||||||
dangerColor: '#ED3333',
|
dangerColor: '#ED3333',
|
||||||
freezeEnd: false,
|
|
||||||
endMessage: '',
|
|
||||||
},
|
},
|
||||||
urlPresets: [],
|
urlPresets: [],
|
||||||
customFields: {},
|
customFields: {},
|
||||||
|
|||||||
@@ -519,8 +519,6 @@ export const demoDb: DatabaseModel = {
|
|||||||
},
|
},
|
||||||
viewSettings: {
|
viewSettings: {
|
||||||
dangerColor: '#ED3333',
|
dangerColor: '#ED3333',
|
||||||
endMessage: '',
|
|
||||||
freezeEnd: false,
|
|
||||||
normalColor: '#ffffffcc',
|
normalColor: '#ffffffcc',
|
||||||
overrideStyles: false,
|
overrideStyles: false,
|
||||||
warningColor: '#FFAB33',
|
warningColor: '#FFAB33',
|
||||||
|
|||||||
@@ -468,8 +468,6 @@
|
|||||||
},
|
},
|
||||||
"viewSettings": {
|
"viewSettings": {
|
||||||
"dangerColor": "#ED3333",
|
"dangerColor": "#ED3333",
|
||||||
"endMessage": "",
|
|
||||||
"freezeEnd": false,
|
|
||||||
"normalColor": "#ffffffcc",
|
"normalColor": "#ffffffcc",
|
||||||
"overrideStyles": false,
|
"overrideStyles": false,
|
||||||
"warningColor": "#FFAB33"
|
"warningColor": "#FFAB33"
|
||||||
|
|||||||
Vendored
-2
@@ -485,8 +485,6 @@
|
|||||||
},
|
},
|
||||||
"viewSettings": {
|
"viewSettings": {
|
||||||
"dangerColor": "#ED3333",
|
"dangerColor": "#ED3333",
|
||||||
"endMessage": "",
|
|
||||||
"freezeEnd": false,
|
|
||||||
"normalColor": "#ffffffcc",
|
"normalColor": "#ffffffcc",
|
||||||
"overrideStyles": false,
|
"overrideStyles": false,
|
||||||
"warningColor": "#FFAB33"
|
"warningColor": "#FFAB33"
|
||||||
|
|||||||
@@ -3,5 +3,4 @@ import { type DatabaseModel } from '../../definitions/DataModel.type.js';
|
|||||||
export interface QuickStartData {
|
export interface QuickStartData {
|
||||||
project: Pick<DatabaseModel['project'], 'title'>;
|
project: Pick<DatabaseModel['project'], 'title'>;
|
||||||
settings: Pick<DatabaseModel['settings'], 'timeFormat' | 'language'>;
|
settings: Pick<DatabaseModel['settings'], 'timeFormat' | 'language'>;
|
||||||
viewSettings: Pick<DatabaseModel['viewSettings'], 'freezeEnd' | 'endMessage'>;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
export type ViewSettings = {
|
export type ViewSettings = {
|
||||||
dangerColor: string;
|
dangerColor: string;
|
||||||
endMessage: string;
|
|
||||||
freezeEnd: boolean;
|
|
||||||
normalColor: string;
|
normalColor: string;
|
||||||
overrideStyles: boolean;
|
overrideStyles: boolean;
|
||||||
warningColor: string;
|
warningColor: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user