mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-11 00:59:35 +00:00
1a08b39b8b
* feat: update auto cue numbering * feat: renumber from ui * refactor: patchEntries is not used * chore: format * fix: correct cue at top of group * fix: handle precision * refactor dialog * bump limit for performance time test * extract type * add class name to lable * fix rebase * refator: extract renumering logic * chore: comments for getIntegerAndFraction function * chore: add the for renumber mutation * fix: fraction match precision * refactor: small cleanup * refactor: use more narrow validator --------- Co-authored-by: alex-Arc <omnivox@LAPTOP-RC5SNBVV.localdomain>
132 lines
3.8 KiB
TypeScript
132 lines
3.8 KiB
TypeScript
import { RenumberCues } from 'ontime-types';
|
|
import { useForm } from 'react-hook-form';
|
|
import { create } from 'zustand';
|
|
|
|
import { maybeAxiosError } from '../../../common/api/utils';
|
|
import Button from '../../../common/components/buttons/Button';
|
|
import Dialog from '../../../common/components/dialog/Dialog';
|
|
import Input from '../../../common/components/input/input/Input';
|
|
import { useEntryActionsContext } from '../../../common/context/EntryActionsContext';
|
|
import useRundown from '../../../common/hooks-query/useRundown';
|
|
import { orderEntries } from '../rundown.utils';
|
|
import { useEventSelection } from '../useEventSelection';
|
|
|
|
import style from './RenumberCuesDialog.module.scss';
|
|
|
|
type RenumberCueData = Pick<RenumberCues, 'increment' | 'prefix' | 'start'>;
|
|
|
|
export default function RenumberCuesDialog() {
|
|
'use memo';
|
|
const { data } = useRundown();
|
|
const { flatOrder } = data;
|
|
const { onClose, isOpen } = useRenumberCuesDialogStore();
|
|
const { renumberCues } = useEntryActionsContext();
|
|
const selectedEvents = useEventSelection((state) => state.selectedEvents);
|
|
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
setError,
|
|
clearErrors,
|
|
formState: { errors, isSubmitting },
|
|
} = useForm<RenumberCueData>();
|
|
|
|
const onSubmit = async (data: RenumberCueData) => {
|
|
clearErrors();
|
|
try {
|
|
const { prefix, start, increment } = data;
|
|
const orderedEvents = orderEntries(Array.from(selectedEvents), flatOrder);
|
|
await renumberCues(orderedEvents, prefix, start, increment);
|
|
onClose();
|
|
} catch (error) {
|
|
const message = maybeAxiosError(error);
|
|
setError('root', { message });
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Dialog
|
|
isOpen={isOpen}
|
|
onClose={onClose}
|
|
title='Renumber cues'
|
|
showCloseButton
|
|
showBackdrop
|
|
bodyElements={
|
|
<form id='renumber-cues-form' onSubmit={handleSubmit(onSubmit)} className={style.fields}>
|
|
<div className={style.field}>
|
|
<label className={style.label}>
|
|
Prefix
|
|
<Input
|
|
{...register('prefix')}
|
|
type='text'
|
|
maxLength={8}
|
|
height='large'
|
|
fluid
|
|
autoComplete='off'
|
|
placeholder='A'
|
|
/>
|
|
</label>
|
|
</div>
|
|
<div className={style.field}>
|
|
<label className={style.label}>
|
|
Start
|
|
<Input
|
|
{...register('start')}
|
|
type='number'
|
|
required
|
|
step={0.001}
|
|
height='large'
|
|
fluid
|
|
autoComplete='off'
|
|
placeholder='10'
|
|
/>
|
|
</label>
|
|
</div>
|
|
<div className={style.field}>
|
|
<label className={style.label}>
|
|
Increment
|
|
<Input
|
|
{...register('increment')}
|
|
type='number'
|
|
required
|
|
step={0.001}
|
|
height='large'
|
|
fluid
|
|
autoComplete='off'
|
|
placeholder='0.1'
|
|
/>
|
|
</label>
|
|
</div>
|
|
{errors.root && <p className={style.error}>{errors.root.message}</p>}
|
|
</form>
|
|
}
|
|
footerElements={
|
|
<>
|
|
<Button type='button' variant='subtle-white' onClick={onClose} disabled={isSubmitting}>
|
|
Cancel
|
|
</Button>
|
|
<Button type='submit' variant='primary' form='renumber-cues-form' loading={isSubmitting}>
|
|
Renumber
|
|
</Button>
|
|
</>
|
|
}
|
|
/>
|
|
);
|
|
}
|
|
|
|
interface RenumberCuesDialogState {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
onOpen: () => void;
|
|
}
|
|
|
|
export const useRenumberCuesDialogStore = create<RenumberCuesDialogState>()((set) => ({
|
|
isOpen: false,
|
|
onClose: () => {
|
|
set({ isOpen: false });
|
|
},
|
|
onOpen: () => {
|
|
set({ isOpen: true });
|
|
},
|
|
}));
|