mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-10 00:29:41 +00:00
Fix ontime aux actions (#1684)
* switch to base ui * ensure all action types is part of the valitation * update test * atempt to do it in the base-ui way * fix fixing * allow undefide visible on set timer message * fix set time not showing * correct time data for aux set automation --------- Co-authored-by: Carlos Valente <carlosvalente@pm.me>
This commit is contained in:
committed by
GitHub
parent
8d68a4554d
commit
4d359445a7
@@ -34,6 +34,11 @@
|
|||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: 2px solid $blue-500;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
&.fluid {
|
&.fluid {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ interface SelectProps<T> extends Omit<BaseSelect.Root.Props<T>, 'items'> {
|
|||||||
options: {
|
options: {
|
||||||
value: T;
|
value: T;
|
||||||
label: string;
|
label: string;
|
||||||
|
disabled?: boolean;
|
||||||
}[];
|
}[];
|
||||||
fluid?: boolean;
|
fluid?: boolean;
|
||||||
}
|
}
|
||||||
@@ -28,8 +29,8 @@ export default function Select<T>({ options, fluid, ...selectRootProps }: Select
|
|||||||
<BaseSelect.Positioner side='bottom' align='start'>
|
<BaseSelect.Positioner side='bottom' align='start'>
|
||||||
<BaseSelect.ScrollUpArrow className={styles.scrollArrow} />
|
<BaseSelect.ScrollUpArrow className={styles.scrollArrow} />
|
||||||
<BaseSelect.Popup className={styles.popup}>
|
<BaseSelect.Popup className={styles.popup}>
|
||||||
{options.map(({ label, value }) => (
|
{options.map(({ disabled, label, value }) => (
|
||||||
<BaseSelect.Item key={String(value)} className={styles.item} value={value}>
|
<BaseSelect.Item key={String(value)} className={styles.item} value={value} disabled={disabled}>
|
||||||
<BaseSelect.ItemIndicator className={styles.itemIndicator}>
|
<BaseSelect.ItemIndicator className={styles.itemIndicator}>
|
||||||
<IoCheckmark className={styles.itemIndicatorIcon} />
|
<IoCheckmark className={styles.itemIndicatorIcon} />
|
||||||
</BaseSelect.ItemIndicator>
|
</BaseSelect.ItemIndicator>
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export default function AutomationForm(props: AutomationFormProps) {
|
|||||||
setError,
|
setError,
|
||||||
setFocus,
|
setFocus,
|
||||||
setValue,
|
setValue,
|
||||||
|
watch,
|
||||||
formState: { errors, isSubmitting, isDirty, isValid },
|
formState: { errors, isSubmitting, isDirty, isValid },
|
||||||
} = useForm<AutomationDTO>({
|
} = useForm<AutomationDTO>({
|
||||||
mode: 'onChange',
|
mode: 'onChange',
|
||||||
@@ -106,8 +107,7 @@ export default function AutomationForm(props: AutomationFormProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleAddnewOntimeAction = () => {
|
const handleAddnewOntimeAction = () => {
|
||||||
// @ts-expect-error -- we dont want to choose an action
|
appendOutput({ type: 'ontime', action: 'aux1-start' });
|
||||||
appendOutput({ type: 'ontime', action: undefined });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTestOSCOutput = async (index: number) => {
|
const handleTestOSCOutput = async (index: number) => {
|
||||||
@@ -428,6 +428,7 @@ export default function AutomationForm(props: AutomationFormProps) {
|
|||||||
register={register}
|
register={register}
|
||||||
rowErrors={rowErrors}
|
rowErrors={rowErrors}
|
||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
|
watch={watch}
|
||||||
>
|
>
|
||||||
<span> </span>
|
<span> </span>
|
||||||
<Panel.InlineElements relation='inner'>
|
<Panel.InlineElements relation='inner'>
|
||||||
|
|||||||
+64
-43
@@ -1,10 +1,9 @@
|
|||||||
import { PropsWithChildren, useState } from 'react';
|
import { PropsWithChildren, useState } from 'react';
|
||||||
import { UseFormRegister, UseFormSetValue } from 'react-hook-form';
|
import { UseFormRegister, UseFormSetValue, UseFormWatch } from 'react-hook-form';
|
||||||
import { Select } from '@chakra-ui/react';
|
import { AutomationDTO, OntimeAction, OntimeActionKey, SecondarySource } from 'ontime-types';
|
||||||
import { AutomationDTO, OntimeAction } from 'ontime-types';
|
|
||||||
|
|
||||||
import Input from '../../../../common/components/input/input/Input';
|
import Input from '../../../../common/components/input/input/Input';
|
||||||
import { cx } from '../../../../common/utils/styleUtils';
|
import Select from '../../../../common/components/select/Select';
|
||||||
import * as Panel from '../../panel-utils/PanelUtils';
|
import * as Panel from '../../panel-utils/PanelUtils';
|
||||||
|
|
||||||
import style from './AutomationForm.module.scss';
|
import style from './AutomationForm.module.scss';
|
||||||
@@ -20,53 +19,58 @@ interface OntimeActionFormProps {
|
|||||||
secondarySource?: { message?: string };
|
secondarySource?: { message?: string };
|
||||||
};
|
};
|
||||||
value: OntimeAction['action'];
|
value: OntimeAction['action'];
|
||||||
|
watch: UseFormWatch<AutomationDTO>;
|
||||||
setValue: UseFormSetValue<AutomationDTO>;
|
setValue: UseFormSetValue<AutomationDTO>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function OntimeActionForm(props: PropsWithChildren<OntimeActionFormProps>) {
|
export default function OntimeActionForm(props: PropsWithChildren<OntimeActionFormProps>) {
|
||||||
const { index, register, setValue, rowErrors, value, children } = props;
|
const { index, register, setValue, rowErrors, value, children, watch } = props;
|
||||||
const [selectedAction, setSelectedAction] = useState<OntimeAction['action']>(value || 'aux-start');
|
const [selectedAction, setSelectedAction] = useState<string>(value);
|
||||||
|
|
||||||
const updateSelectedAction = (value: string) => {
|
const handleSetAction = (value: OntimeActionKey) => {
|
||||||
setSelectedAction(value as OntimeAction['action']);
|
setValue(`outputs.${index}.action`, value, { shouldDirty: true });
|
||||||
setValue(`outputs.${index}.action`, value as OntimeAction['action']);
|
setSelectedAction(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx([style.actionSection, selectedAction && style[selectedAction]])}>
|
<div className={style.actionSection}>
|
||||||
<input type='hidden' {...register(`outputs.${index}.action`)} value={selectedAction} />
|
|
||||||
<label>
|
<label>
|
||||||
Action
|
Action
|
||||||
<Select
|
<Select
|
||||||
variant='ontime'
|
onValueChange={(value) => {
|
||||||
size='sm'
|
handleSetAction(value as OntimeActionKey);
|
||||||
value={selectedAction}
|
}}
|
||||||
onChange={(event) => updateSelectedAction(event.target.value)}
|
value={watch(`outputs.${index}.action`)}
|
||||||
>
|
options={[
|
||||||
<option value='aux-start'>Aux 1: start</option>
|
{ value: 'aux1-pause', label: 'Aux 1: pause' },
|
||||||
<option value='aux-pause'>Aux 1: pause</option>
|
{ value: 'aux2-pause', label: 'Aux 2: pause' },
|
||||||
<option value='aux-stop'>Aux 1: stop</option>
|
{ value: 'aux3-pause', label: 'Aux 3: pause' },
|
||||||
<option value='aux-set'>Aux 2: set</option>
|
|
||||||
<option value='aux-start'>Aux 2: start</option>
|
{ value: 'aux1-start', label: 'Aux 1: start' },
|
||||||
<option value='aux-pause'>Aux 2: pause</option>
|
{ value: 'aux2-start', label: 'Aux 2: start' },
|
||||||
<option value='aux-stop'>Aux 2: stop</option>
|
{ value: 'aux3-start', label: 'Aux 3: start' },
|
||||||
<option value='aux-set'>Aux 2: set</option>
|
|
||||||
<option value='aux-start'>Aux 3: start</option>
|
{ value: 'aux1-stop', label: 'Aux 1: stop' },
|
||||||
<option value='aux-pause'>Aux 3: pause</option>
|
{ value: 'aux2-stop', label: 'Aux 2: stop' },
|
||||||
<option value='aux-stop'>Aux 3: stop</option>
|
{ value: 'aux3-stop', label: 'Aux 3: stop' },
|
||||||
<option value='aux-set'>Aux 3: set</option>
|
|
||||||
<option value='message-set'>Timer: timer message</option>
|
{ value: 'aux1-set', label: 'Aux 1: set' },
|
||||||
<option value='message-secondary'>Timer: timer secondary</option>
|
{ value: 'aux2-set', label: 'Aux 2: set' },
|
||||||
</Select>
|
{ value: 'aux3-set', label: 'Aux 3: set' },
|
||||||
|
|
||||||
|
{ value: 'message-set', label: 'Primary Message: set' },
|
||||||
|
{ value: 'message-secondary', label: 'Secondary Message: source' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<Panel.Error>{rowErrors?.action?.message}</Panel.Error>
|
<Panel.Error>{rowErrors?.action?.message}</Panel.Error>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
{selectedAction === 'aux1-set' && (
|
{selectedAction.startsWith('aux') && selectedAction.endsWith('set') && (
|
||||||
<label>
|
<label>
|
||||||
New time
|
New time
|
||||||
<Input
|
<Input
|
||||||
{...register(`outputs.${index}.time`, {
|
{...register(`outputs.${index}.time`, {
|
||||||
required: { value: true, message: 'Required field' },
|
required: { value: true, message: 'Required field' }, //TODO:(automation set aux) not sure what way around to have the string and where to have the ms value
|
||||||
})}
|
})}
|
||||||
fluid
|
fluid
|
||||||
placeholder='eg: 10m5s'
|
placeholder='eg: 10m5s'
|
||||||
@@ -84,11 +88,19 @@ export default function OntimeActionForm(props: PropsWithChildren<OntimeActionFo
|
|||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
Visibility
|
Visibility
|
||||||
<Select variant='ontime' size='sm' {...register(`outputs.${index}.visible`)}>
|
<Select
|
||||||
<option value=''>Untouched</option>
|
onValueChange={(value) => {
|
||||||
<option value='true'>Show</option>
|
// we need to translate the undefined value to 'untouched'
|
||||||
<option value='false'>Hide</option>
|
const translatedValue = value === 'untouched' ? undefined : (value as boolean | undefined);
|
||||||
</Select>
|
setValue(`outputs.${index}.visible`, translatedValue, { shouldDirty: true });
|
||||||
|
}}
|
||||||
|
value={watch(`outputs.${index}.visible`) === undefined ? 'untouched' : watch(`outputs.${index}.visible`)}
|
||||||
|
options={[
|
||||||
|
{ value: 'untouched', label: 'Untouched' },
|
||||||
|
{ value: true, label: 'Show' },
|
||||||
|
{ value: false, label: 'Hide' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<Panel.Error>{rowErrors?.visible?.message}</Panel.Error>
|
<Panel.Error>{rowErrors?.visible?.message}</Panel.Error>
|
||||||
</label>
|
</label>
|
||||||
</>
|
</>
|
||||||
@@ -97,11 +109,20 @@ export default function OntimeActionForm(props: PropsWithChildren<OntimeActionFo
|
|||||||
{selectedAction === 'message-secondary' && (
|
{selectedAction === 'message-secondary' && (
|
||||||
<label>
|
<label>
|
||||||
Timer secondary source
|
Timer secondary source
|
||||||
<Select variant='ontime' size='sm' {...register(`outputs.${index}.secondarySource`)}>
|
<Select
|
||||||
<option value='aux'>Auxiliary timer</option>
|
onValueChange={(value) => {
|
||||||
<option value='external'>External</option>
|
setValue(`outputs.${index}.secondarySource`, value as SecondarySource, { shouldDirty: true });
|
||||||
<option value='null'>None</option>
|
}}
|
||||||
</Select>
|
value={watch(`outputs.${index}.secondarySource`)}
|
||||||
|
options={[
|
||||||
|
{ value: null, label: 'Select secondary source', disabled: true },
|
||||||
|
{ value: 'aux1', label: 'Auxiliary timer 1' },
|
||||||
|
{ value: 'aux2', label: 'Auxiliary timer 2' },
|
||||||
|
{ value: 'aux3', label: 'Auxiliary timer 3' },
|
||||||
|
{ value: 'external', label: 'External' },
|
||||||
|
{ value: 'null', label: 'None' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<Panel.Error>{rowErrors?.secondarySource?.message}</Panel.Error>
|
<Panel.Error>{rowErrors?.secondarySource?.message}</Panel.Error>
|
||||||
</label>
|
</label>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -46,17 +46,17 @@ describe('parseOutput', () => {
|
|||||||
it('parses a valid payload', () => {
|
it('parses a valid payload', () => {
|
||||||
const auxStart = {
|
const auxStart = {
|
||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: 'aux-start',
|
action: 'aux1-start',
|
||||||
};
|
};
|
||||||
expect(parseOutput(auxStart)).toStrictEqual(auxStart);
|
expect(parseOutput(auxStart)).toStrictEqual(auxStart);
|
||||||
const auxStop = {
|
const auxStop = {
|
||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: 'aux-stop',
|
action: 'aux3-stop',
|
||||||
};
|
};
|
||||||
expect(parseOutput(auxStop)).toStrictEqual(auxStop);
|
expect(parseOutput(auxStop)).toStrictEqual(auxStop);
|
||||||
const auxPause = {
|
const auxPause = {
|
||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: 'aux-pause',
|
action: 'aux2-pause',
|
||||||
};
|
};
|
||||||
expect(parseOutput(auxPause)).toStrictEqual(auxPause);
|
expect(parseOutput(auxPause)).toStrictEqual(auxPause);
|
||||||
});
|
});
|
||||||
@@ -65,12 +65,12 @@ describe('parseOutput', () => {
|
|||||||
expect(
|
expect(
|
||||||
parseOutput({
|
parseOutput({
|
||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: 'aux-start',
|
action: 'aux1-start',
|
||||||
time: 10,
|
time: 10,
|
||||||
}),
|
}),
|
||||||
).toStrictEqual({
|
).toStrictEqual({
|
||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: 'aux-start',
|
action: 'aux1-start',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ describe('parseOutput', () => {
|
|||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: 'message-set',
|
action: 'message-set',
|
||||||
text: 'test',
|
text: 'test',
|
||||||
visible: 'true',
|
visible: true,
|
||||||
}),
|
}),
|
||||||
).toMatchObject({
|
).toMatchObject({
|
||||||
text: 'test',
|
text: 'test',
|
||||||
@@ -99,7 +99,7 @@ describe('parseOutput', () => {
|
|||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: 'message-set',
|
action: 'message-set',
|
||||||
text: '',
|
text: '',
|
||||||
visible: 'false',
|
visible: false,
|
||||||
}),
|
}),
|
||||||
).toMatchObject({
|
).toMatchObject({
|
||||||
text: undefined,
|
text: undefined,
|
||||||
@@ -110,7 +110,6 @@ describe('parseOutput', () => {
|
|||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: 'message-set',
|
action: 'message-set',
|
||||||
text: '',
|
text: '',
|
||||||
visible: '',
|
|
||||||
}),
|
}),
|
||||||
).toMatchObject({
|
).toMatchObject({
|
||||||
text: undefined,
|
text: undefined,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { EntryId, FilterRule, isOntimeEvent, MaybeNumber, OntimeAction, Rundown } from 'ontime-types';
|
import { EntryId, FilterRule, isOntimeEvent, MaybeNumber, OntimeAction, ontimeActionKeyValues, Rundown } from 'ontime-types';
|
||||||
import { millisToString, removeLeadingZero, splitWhitespace, getPropertyFromPath } from 'ontime-utils';
|
import { millisToString, removeLeadingZero, splitWhitespace, getPropertyFromPath } from 'ontime-utils';
|
||||||
import type { OscArgOrArrayInput, OscArgInput } from 'osc-min';
|
import type { OscArgOrArrayInput, OscArgInput } from 'osc-min';
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ export function isFilterRule(value: string): value is FilterRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isOntimeActionAction(value: string): value is OntimeAction['action'] {
|
export function isOntimeActionAction(value: string): value is OntimeAction['action'] {
|
||||||
return ['aux-start', 'aux-stop', 'aux-pause', 'aux-set', 'message-set', 'message-secondary'].includes(value);
|
return ontimeActionKeyValues.includes(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toOscValue(argString: string): OscArgInput {
|
function toOscValue(argString: string): OscArgInput {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
SecondarySource,
|
SecondarySource,
|
||||||
timerLifecycleValues,
|
timerLifecycleValues,
|
||||||
} from 'ontime-types';
|
} from 'ontime-types';
|
||||||
import { parseUserTime } from 'ontime-utils';
|
|
||||||
|
|
||||||
import { body, oneOf, param } from 'express-validator';
|
import { body, oneOf, param } from 'express-validator';
|
||||||
|
|
||||||
@@ -200,20 +199,24 @@ function parseOntimeAction(maybeOntimeAction: object): OntimeAction {
|
|||||||
return {
|
return {
|
||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: maybeOntimeAction.action,
|
action: maybeOntimeAction.action,
|
||||||
time: parseUserTime(maybeOntimeAction.time),
|
time: maybeOntimeAction.time, //TODO:(automation set aux) not sure what way around to have the string and where to have the ms value
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maybeOntimeAction.action === 'message-set') {
|
if (maybeOntimeAction.action === 'message-set') {
|
||||||
assert.hasKeys(maybeOntimeAction, ['text', 'visible']);
|
assert.hasKeys(maybeOntimeAction, ['text']);
|
||||||
assert.isString(maybeOntimeAction.text);
|
assert.isString(maybeOntimeAction.text);
|
||||||
assert.isString(maybeOntimeAction.visible);
|
let visible: boolean | undefined = undefined;
|
||||||
|
if ('visible' in maybeOntimeAction) {
|
||||||
|
assert.isBoolean(maybeOntimeAction.visible);
|
||||||
|
visible = maybeOntimeAction.visible;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'ontime',
|
type: 'ontime',
|
||||||
action: 'message-set',
|
action: 'message-set',
|
||||||
text: indeterminateText(maybeOntimeAction.text),
|
text: indeterminateText(maybeOntimeAction.text),
|
||||||
visible: indeterminateBooleanString(maybeOntimeAction.visible),
|
visible,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,16 +246,6 @@ function indeterminateText(value: string): string | undefined {
|
|||||||
return value === '' ? undefined : value;
|
return value === '' ? undefined : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to parse boolean values in transit
|
|
||||||
* "true" -> true
|
|
||||||
* "false" -> false
|
|
||||||
* "" | "null" -> undefined
|
|
||||||
*/
|
|
||||||
function indeterminateBooleanString(value: string): boolean | undefined {
|
|
||||||
return value === '' ? undefined : value === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to validate the secondary source
|
* Helper function to validate the secondary source
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { LogOrigin, OntimeAction } from 'ontime-types';
|
|||||||
import { logger } from '../../../classes/Logger.js';
|
import { logger } from '../../../classes/Logger.js';
|
||||||
import { auxTimerService } from '../../../services/aux-timer-service/AuxTimerService.js';
|
import { auxTimerService } from '../../../services/aux-timer-service/AuxTimerService.js';
|
||||||
import * as messageService from '../../../services/message-service/message.service.js';
|
import * as messageService from '../../../services/message-service/message.service.js';
|
||||||
|
import { parseUserTime } from 'ontime-utils';
|
||||||
|
|
||||||
export function toOntimeAction(action: OntimeAction) {
|
export function toOntimeAction(action: OntimeAction) {
|
||||||
const actionType = action.action;
|
const actionType = action.action;
|
||||||
@@ -15,7 +16,8 @@ export function toOntimeAction(action: OntimeAction) {
|
|||||||
case 'aux1-pause':
|
case 'aux1-pause':
|
||||||
return auxTimerService.pause(1);
|
return auxTimerService.pause(1);
|
||||||
case 'aux1-set': {
|
case 'aux1-set': {
|
||||||
return auxTimerService.setTime(action.time, 1);
|
const time = parseUserTime(action.time);
|
||||||
|
return auxTimerService.setTime(time, 1);
|
||||||
}
|
}
|
||||||
case 'aux2-start':
|
case 'aux2-start':
|
||||||
return auxTimerService.start(2);
|
return auxTimerService.start(2);
|
||||||
@@ -24,7 +26,8 @@ export function toOntimeAction(action: OntimeAction) {
|
|||||||
case 'aux2-pause':
|
case 'aux2-pause':
|
||||||
return auxTimerService.pause(2);
|
return auxTimerService.pause(2);
|
||||||
case 'aux2-set': {
|
case 'aux2-set': {
|
||||||
return auxTimerService.setTime(action.time, 2);
|
const time = parseUserTime(action.time);
|
||||||
|
return auxTimerService.setTime(time, 2);
|
||||||
}
|
}
|
||||||
case 'aux3-start':
|
case 'aux3-start':
|
||||||
return auxTimerService.start(3);
|
return auxTimerService.start(3);
|
||||||
@@ -33,7 +36,8 @@ export function toOntimeAction(action: OntimeAction) {
|
|||||||
case 'aux3-pause':
|
case 'aux3-pause':
|
||||||
return auxTimerService.pause(3);
|
return auxTimerService.pause(3);
|
||||||
case 'aux3-set': {
|
case 'aux3-set': {
|
||||||
return auxTimerService.setTime(action.time, 3);
|
const time = parseUserTime(action.time);
|
||||||
|
return auxTimerService.setTime(time, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message actions
|
// Message actions
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
import { is } from './is.js';
|
import { is } from './is.js';
|
||||||
|
|
||||||
|
export function isBoolean(value: unknown): asserts value is boolean {
|
||||||
|
if (!is.boolean(value)) {
|
||||||
|
throw new Error(`Unexpected payload type: ${String(value)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function isString(value: unknown): asserts value is string {
|
export function isString(value: unknown): asserts value is string {
|
||||||
if (!is.string(value)) {
|
if (!is.string(value)) {
|
||||||
throw new Error(`Unexpected payload type: ${String(value)}`);
|
throw new Error(`Unexpected payload type: ${String(value)}`);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export const is = {
|
export const is = {
|
||||||
|
boolean: (value: unknown): value is boolean => typeof value === 'boolean',
|
||||||
string: (value: unknown): value is string => typeof value === 'string',
|
string: (value: unknown): value is string => typeof value === 'string',
|
||||||
number: (value: unknown): value is number => typeof value === 'number',
|
number: (value: unknown): value is number => typeof value === 'number',
|
||||||
defined: <T>(value: T | undefined): value is T => value !== undefined,
|
defined: <T>(value: T | undefined): value is T => value !== undefined,
|
||||||
|
|||||||
@@ -54,33 +54,52 @@ export type HTTPOutput = {
|
|||||||
url: string;
|
url: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ontimeAuxTriggerAction = [
|
||||||
|
'aux1-start',
|
||||||
|
'aux1-stop',
|
||||||
|
'aux1-pause',
|
||||||
|
'aux2-start',
|
||||||
|
'aux2-stop',
|
||||||
|
'aux2-pause',
|
||||||
|
'aux3-start',
|
||||||
|
'aux3-stop',
|
||||||
|
'aux3-pause',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
const ontimeAuxSetAction = ['aux1-set', 'aux2-set', 'aux3-set'] as const;
|
||||||
|
|
||||||
|
type OntimeAuxTriggerAction = (typeof ontimeAuxTriggerAction)[number];
|
||||||
|
type OntimeAuxSetAction = (typeof ontimeAuxSetAction)[number];
|
||||||
|
type OntimeMessageSet = 'message-set';
|
||||||
|
type OntimeMessageSecondary = 'message-secondary';
|
||||||
|
|
||||||
|
export type OntimeActionKey = OntimeAuxTriggerAction | OntimeAuxSetAction | OntimeMessageSet | OntimeMessageSecondary;
|
||||||
|
|
||||||
|
export const ontimeActionKeyValues = [
|
||||||
|
...ontimeAuxTriggerAction,
|
||||||
|
...ontimeAuxSetAction,
|
||||||
|
'message-set',
|
||||||
|
'message-secondary',
|
||||||
|
];
|
||||||
|
|
||||||
export type OntimeAction =
|
export type OntimeAction =
|
||||||
| {
|
| {
|
||||||
type: 'ontime';
|
type: 'ontime';
|
||||||
action:
|
action: OntimeAuxTriggerAction;
|
||||||
| 'aux1-start'
|
|
||||||
| 'aux1-stop'
|
|
||||||
| 'aux1-pause'
|
|
||||||
| 'aux2-start'
|
|
||||||
| 'aux2-stop'
|
|
||||||
| 'aux2-pause'
|
|
||||||
| 'aux3-start'
|
|
||||||
| 'aux3-stop'
|
|
||||||
| 'aux3-pause';
|
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'ontime';
|
type: 'ontime';
|
||||||
action: 'aux1-set' | 'aux2-set' | 'aux3-set';
|
action: OntimeAuxSetAction;
|
||||||
time: number;
|
time: string; //TODO:(automation set aux) not sure what way around to have the string and where to have the ms value
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'ontime';
|
type: 'ontime';
|
||||||
action: 'message-set';
|
action: OntimeMessageSet;
|
||||||
text?: string;
|
text?: string;
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'ontime';
|
type: 'ontime';
|
||||||
action: 'message-secondary';
|
action: OntimeMessageSecondary;
|
||||||
secondarySource: SecondarySource;
|
secondarySource: SecondarySource;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ export { TimerType } from './definitions/TimerType.type.js';
|
|||||||
export type { OntimeReport, OntimeEventReport } from './definitions/core/Report.type.js';
|
export type { OntimeReport, OntimeEventReport } from './definitions/core/Report.type.js';
|
||||||
|
|
||||||
// ---> Automations
|
// ---> Automations
|
||||||
|
export { ontimeActionKeyValues } from './definitions/core/Automation.type.js';
|
||||||
export type {
|
export type {
|
||||||
|
OntimeActionKey,
|
||||||
Automation,
|
Automation,
|
||||||
AutomationDTO,
|
AutomationDTO,
|
||||||
AutomationFilter,
|
AutomationFilter,
|
||||||
|
|||||||
Reference in New Issue
Block a user