add http subscription to integration modal

This commit is contained in:
arc-alex
2023-11-04 20:37:22 +01:00
parent 477fbbe666
commit 1e930851ca
5 changed files with 229 additions and 1 deletions
@@ -6,6 +6,7 @@ export const RUNDOWN_TABLE_KEY = 'rundown';
export const RUNDOWN_TABLE = [RUNDOWN_TABLE_KEY];
export const APP_INFO = ['appinfo'];
export const OSC_SETTINGS = ['oscSettings'];
export const HTTP_SETTINGS = ['httpSettings'];
export const APP_SETTINGS = ['appSettings'];
export const VIEW_SETTINGS = ['viewSettings'];
export const RUNTIME = ['runtimeStore'];
+21 -1
View File
@@ -93,6 +93,18 @@ export async function getOSC(): Promise<OSCSettings> {
return res.data;
}
/**
* @description HTTP request to retrieve http settings
* @return {Promise}
*/
export async function getHTTP(): Promise<HTTPSettings> {
console.log('getHTTP')
const res = await axios.get(`${ontimeURL}/http`);
console.log(res)
return res.data;
}
/**
* @description HTTP request to mutate osc settings
* @return {Promise}
@@ -105,10 +117,18 @@ export async function postOSC(data: OSCSettings) {
* @description HTTP request to mutate osc subscriptions
* @return {Promise}
*/
export async function postOscSubscriptions(data: OscSubscription) {
export async function postOscSubscriptions(data: Subscription) {
return axios.post(`${ontimeURL}/osc-subscriptions`, data);
}
/**
* @description HTTP request to mutate osc subscriptions
* @return {Promise}
*/
export async function postHttpSubscriptions(data: Subscription) {
return axios.post(`${ontimeURL}/http-subscriptions`, data);
}
/**
* @description HTTP request to download db in CSV format
*/
@@ -0,0 +1,34 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import { HTTPSettings } from 'ontime-types';
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
import { HTTP_SETTINGS } from '../api/apiConstants';
import { logAxiosError } from '../api/apiUtils';
import { getHTTP, postHttpSubscriptions } from '../api/ontimeApi';
import { httpPlaceholder } from '../models/Http';
import { ontimeQueryClient } from '../queryClient';
export default function useHttpSettings() {
const { data, status, isFetching, isError, refetch } = useQuery({
queryKey: HTTP_SETTINGS,
queryFn: getHTTP,
placeholderData: httpPlaceholder,
retry: 5,
retryDelay: (attempt: number) => attempt * 2500,
refetchInterval: queryRefetchIntervalSlow,
networkMode: 'always',
});
// we need to jump through some hoops because of the type op port
return { data: data! as unknown as HTTPSettings, status, isFetching, isError, refetch };
}
export function usePostHttpSubscriptions() {
const { isLoading, mutateAsync } = useMutation({
mutationFn: postHttpSubscriptions,
onError: (error) => logAxiosError('Error saving HTTP settings', error),
onSettled: () => ontimeQueryClient.invalidateQueries({ queryKey: HTTP_SETTINGS }),
});
return { isLoading, mutateAsync };
}
@@ -0,0 +1,167 @@
import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import type { Subscription } from 'ontime-types';
import { TimerLifeCycle } from 'ontime-types';
import useHttpSettings, { usePostHttpSubscriptions } from '../../../common/hooks-query/useHttpSettings';
import { useEmitLog } from '../../../common/stores/logger';
import ModalLoader from '../modal-loader/ModalLoader';
import OntimeModalFooter from '../OntimeModalFooter';
import SubscriptionRow from './SubscriptionRow';
import styles from '../Modal.module.scss';
type OntimeCycle = keyof typeof TimerLifeCycle;
const sectionText: { [key in TimerLifeCycle]: { title: string; subtitle: string } } = {
onLoad: {
title: 'On Load',
subtitle: 'Triggers when a timer is loaded',
},
onStart: {
title: 'On Start',
subtitle: 'Triggers when a timer starts',
},
onPause: {
title: 'On Pause',
subtitle: 'Triggers when a running timer is paused',
},
onStop: {
title: 'On Stop',
subtitle: 'Triggers when a running timer is stopped',
},
onUpdate: {
title: 'On Every Second',
subtitle: 'Triggers when a running timer is updated (at least once a second, can be more)',
},
onFinish: {
title: 'On Finish',
subtitle: 'Triggers when a running reaches 0',
},
};
export default function HttpIntegration() {
const { data, isFetching } = useHttpSettings();
const { mutateAsync } = usePostHttpSubscriptions();
const { emitError } = useEmitLog();
const {
control,
handleSubmit,
register,
reset,
formState: { isSubmitting, isDirty, isValid },
} = useForm<Subscription>({
defaultValues: data.subscriptions,
values: data.subscriptions,
resetOptions: {
keepDirtyValues: true,
},
});
const [showSection, setShowSection] = useState<OntimeCycle>(TimerLifeCycle.onLoad);
useEffect(() => {
if (data) {
reset(data.subscriptions);
}
}, [data, reset]);
const resetForm = () => {
reset(data.subscriptions);
};
const onSubmit = async (values: Subscription) => {
try {
const subscriptions = {
onLoad: values.onLoad ?? [],
onStart: values.onStart ?? [],
onPause: values.onPause ?? [],
onStop: values.onStop ?? [],
onUpdate: values.onUpdate ?? [],
onFinish: values.onFinish ?? [],
};
await mutateAsync(subscriptions);
} catch (error) {
emitError(`Error setting HTML: ${error}`);
}
};
if (isFetching) {
return <ModalLoader />;
}
const placeholder = 'http://x.x.x.x:xxxx/api/path'
return (
<form onSubmit={handleSubmit(onSubmit)} className={styles.sectionContainer} id='http-subscriptions'>
<SubscriptionRow
cycle={TimerLifeCycle.onLoad}
title={sectionText.onLoad.title}
subtitle={sectionText.onLoad.subtitle}
visible={showSection === TimerLifeCycle.onLoad}
setShowSection={setShowSection}
register={register}
control={control}
placeholder={placeholder}
/>
<SubscriptionRow
cycle={TimerLifeCycle.onStart}
title={sectionText.onStart.title}
subtitle={sectionText.onStart.subtitle}
visible={showSection === TimerLifeCycle.onStart}
setShowSection={setShowSection}
register={register}
control={control}
placeholder={placeholder}
/>
<SubscriptionRow
cycle={TimerLifeCycle.onPause}
title={sectionText.onPause.title}
subtitle={sectionText.onPause.subtitle}
visible={showSection === TimerLifeCycle.onPause}
setShowSection={setShowSection}
register={register}
control={control}
placeholder={placeholder}
/>
<SubscriptionRow
cycle={TimerLifeCycle.onStop}
title={sectionText.onStop.title}
subtitle={sectionText.onStop.subtitle}
visible={showSection === TimerLifeCycle.onStop}
setShowSection={setShowSection}
register={register}
control={control}
placeholder={placeholder}
/>
<SubscriptionRow
cycle={TimerLifeCycle.onUpdate}
title={sectionText.onUpdate.title}
subtitle={sectionText.onUpdate.subtitle}
visible={showSection === TimerLifeCycle.onUpdate}
setShowSection={setShowSection}
register={register}
control={control}
placeholder={placeholder}
/>
<SubscriptionRow
cycle={TimerLifeCycle.onFinish}
title={sectionText.onFinish.title}
subtitle={sectionText.onFinish.subtitle}
visible={showSection === TimerLifeCycle.onFinish}
setShowSection={setShowSection}
register={register}
control={control}
placeholder={placeholder}
/>
<OntimeModalFooter
formId='http-subscriptions'
handleRevert={resetForm}
isDirty={isDirty}
isValid={isValid}
isSubmitting={isSubmitting}
/>
</form>
);
}
@@ -5,6 +5,8 @@ import ModalWrapper from '../ModalWrapper';
import OscIntegration from './OscIntegration';
import OscSettings from './OscSettings';
import HttpIntegration from './HttpIntegration';
import styles from '../Modal.module.scss';
interface IntegrationModalProps {
@@ -30,6 +32,7 @@ export default function IntegrationModal(props: IntegrationModalProps) {
<TabList>
<Tab>OSC</Tab>
<Tab>OSC Integration</Tab>
<Tab>HTML Integration</Tab>
</TabList>
<TabPanels>
<TabPanel>
@@ -38,6 +41,9 @@ export default function IntegrationModal(props: IntegrationModalProps) {
<TabPanel>
<OscIntegration />
</TabPanel>
<TabPanel>
<HttpIntegration />
</TabPanel>
</TabPanels>
</Tabs>
</ModalBody>