fix: osc modal (#352)

* refactor: parse time input

* fix: form dirty flag on dynamic elements
This commit is contained in:
Carlos Valente
2023-04-21 20:06:40 +02:00
committed by GitHub
parent 9c4c84905e
commit db9cb61164
2 changed files with 22 additions and 8 deletions
@@ -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 && (
<> <>