mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-27 09:59:08 +00:00
fix: osc modal (#352)
* refactor: parse time input * fix: form dirty flag on dynamic elements
This commit is contained in:
@@ -34,7 +34,7 @@ const sectionText: { [key in TimerLifeCycle]: { title: string; subtitle: string
|
|||||||
subtitle: 'Triggers when a running timer is stopped',
|
subtitle: 'Triggers when a running timer is stopped',
|
||||||
},
|
},
|
||||||
onUpdate: {
|
onUpdate: {
|
||||||
title: 'On Update',
|
title: 'On Every Second',
|
||||||
subtitle: 'Triggers when timers are updated (at least once a second, can be more)',
|
subtitle: 'Triggers when timers are updated (at least once a second, can be more)',
|
||||||
},
|
},
|
||||||
onFinish: {
|
onFinish: {
|
||||||
@@ -50,37 +50,50 @@ export default function OscIntegration() {
|
|||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
register,
|
register,
|
||||||
|
reset,
|
||||||
formState: { isSubmitting, isDirty, isValid },
|
formState: { isSubmitting, isDirty, isValid },
|
||||||
} = useForm<PlaceholderSettings>({
|
} = useForm<PlaceholderSettings>({
|
||||||
defaultValues: data,
|
defaultValues: data,
|
||||||
values: data,
|
values: data,
|
||||||
});
|
});
|
||||||
|
|
||||||
const resetForm = () => data?.subscriptions || oscPlaceholderSettings.subscriptions;
|
const [subscriptionState, setSubscription] = useState<OscSubscription>(
|
||||||
const [subscriptionState, setSubscription] = useState<OscSubscription>(() => resetForm());
|
data?.subscriptions || oscPlaceholderSettings.subscriptions,
|
||||||
|
);
|
||||||
|
const [hasManualChange, setHasManualChange] = useState(false);
|
||||||
|
|
||||||
const [showSection, setShowSection] = useState<OntimeCycle>(TimerLifeCycle.onLoad);
|
const [showSection, setShowSection] = useState<OntimeCycle>(TimerLifeCycle.onLoad);
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
const originalData = data || oscPlaceholderSettings;
|
||||||
|
setSubscription(originalData.subscriptions);
|
||||||
|
// @ts-expect-error -- we know the data here is safe
|
||||||
|
reset(originalData);
|
||||||
|
};
|
||||||
|
|
||||||
const deleteSubscriptionEntry = (cycle: OntimeCycle, id: string) => {
|
const deleteSubscriptionEntry = (cycle: OntimeCycle, id: string) => {
|
||||||
setSubscription((prev) => {
|
setSubscription((prev) => {
|
||||||
const newData = { ...prev };
|
const newData = { ...prev };
|
||||||
newData[cycle] = [...prev[cycle].filter((el) => el.id !== id)];
|
newData[cycle] = [...prev[cycle].filter((el) => el.id !== id)];
|
||||||
return newData;
|
return newData;
|
||||||
});
|
});
|
||||||
|
setHasManualChange(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addNewSubscriptionEntry = async (cycle: OntimeCycle) => {
|
const addNewSubscriptionEntry = async (cycle: OntimeCycle) => {
|
||||||
setSubscription((prev) => {
|
setSubscription((prev) => {
|
||||||
const newData = { ...prev };
|
const newData = structuredClone(prev);
|
||||||
newData[cycle] = [...prev[cycle], { id: generateId(), message: '', enabled: false }];
|
newData[cycle] = [...prev[cycle], { id: generateId(), message: '', enabled: false }];
|
||||||
return newData;
|
return newData;
|
||||||
});
|
});
|
||||||
|
setHasManualChange(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async (values: OSCSettings | PlaceholderSettings) => {
|
const onSubmit = async (values: OSCSettings | PlaceholderSettings) => {
|
||||||
try {
|
try {
|
||||||
// @ts-expect-error -- we know of the type mismatch, not pertinent here
|
// @ts-expect-error -- we know of the type mismatch, not pertinent here
|
||||||
await mutateAsync(values);
|
await mutateAsync(values);
|
||||||
|
setHasManualChange(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
emitError(`Error setting OSC: ${error}`);
|
emitError(`Error setting OSC: ${error}`);
|
||||||
}
|
}
|
||||||
@@ -114,7 +127,7 @@ export default function OscIntegration() {
|
|||||||
<OntimeModalFooter
|
<OntimeModalFooter
|
||||||
formId='oscSubscriptions'
|
formId='oscSubscriptions'
|
||||||
handleRevert={resetForm}
|
handleRevert={resetForm}
|
||||||
isDirty={isDirty}
|
isDirty={isDirty || hasManualChange}
|
||||||
isValid={isValid}
|
isValid={isValid}
|
||||||
isSubmitting={isSubmitting}
|
isSubmitting={isSubmitting}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import { UseFormRegister } from 'react-hook-form';
|
||||||
import { Button, IconButton, Input, Switch } from '@chakra-ui/react';
|
import { Button, IconButton, Input, Switch } from '@chakra-ui/react';
|
||||||
import { FiChevronUp } from '@react-icons/all-files/fi/FiChevronUp';
|
import { FiChevronUp } from '@react-icons/all-files/fi/FiChevronUp';
|
||||||
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
|
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
|
||||||
import { OscSubscriptionOptions, TimerLifeCycle } from 'ontime-types';
|
import { OscSubscriptionOptions, TimerLifeCycle } from 'ontime-types';
|
||||||
|
|
||||||
import style from '../../../common/components/collapse-bar/CollapseBar.module.scss';
|
import collapseStyles from '../../../common/components/collapse-bar/CollapseBar.module.scss';
|
||||||
import styles from '../Modal.module.scss';
|
import styles from '../Modal.module.scss';
|
||||||
|
|
||||||
interface OscSubscriptionRowProps {
|
interface OscSubscriptionRowProps {
|
||||||
@@ -15,7 +16,7 @@ interface OscSubscriptionRowProps {
|
|||||||
subscriptionOptions: OscSubscriptionOptions[];
|
subscriptionOptions: OscSubscriptionOptions[];
|
||||||
handleDelete: (cycle: TimerLifeCycle, id: string) => void;
|
handleDelete: (cycle: TimerLifeCycle, id: string) => void;
|
||||||
handleAddNew: (cycle: TimerLifeCycle) => void;
|
handleAddNew: (cycle: TimerLifeCycle) => void;
|
||||||
register: object;
|
register: UseFormRegister<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function OscSubscriptionRow(props: OscSubscriptionRowProps) {
|
export default function OscSubscriptionRow(props: OscSubscriptionRowProps) {
|
||||||
@@ -33,7 +34,7 @@ export default function OscSubscriptionRow(props: OscSubscriptionRowProps) {
|
|||||||
<span className={`${styles.sectionTitle} ${styles.main}`}>{title}</span>
|
<span className={`${styles.sectionTitle} ${styles.main}`}>{title}</span>
|
||||||
{visible && <span className={styles.sectionSubtitle}>{subtitle}</span>}
|
{visible && <span className={styles.sectionSubtitle}>{subtitle}</span>}
|
||||||
</div>
|
</div>
|
||||||
<FiChevronUp className={visible ? style.moreCollapsed : style.moreExpanded} />
|
<FiChevronUp className={visible ? collapseStyles.moreCollapsed : collapseStyles.moreExpanded} />
|
||||||
</div>
|
</div>
|
||||||
{visible && (
|
{visible && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
Reference in New Issue
Block a user