mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-05 14:29:20 +00:00
refactor: allow submitting same value
This commit is contained in:
committed by
Carlos Valente
parent
b173b5a8e8
commit
b38a7e5c92
@@ -16,6 +16,7 @@ export default function useReactiveTextInput(
|
|||||||
submitOnEnter?: boolean;
|
submitOnEnter?: boolean;
|
||||||
submitOnCtrlEnter?: boolean;
|
submitOnCtrlEnter?: boolean;
|
||||||
onCancelUpdate?: () => void;
|
onCancelUpdate?: () => void;
|
||||||
|
allowSubmitSameValue?: boolean;
|
||||||
},
|
},
|
||||||
): UseReactiveTextInputReturn {
|
): UseReactiveTextInputReturn {
|
||||||
const [text, setText] = useState<string>(initialText);
|
const [text, setText] = useState<string>(initialText);
|
||||||
@@ -48,7 +49,7 @@ export default function useReactiveTextInput(
|
|||||||
const handleSubmit = useCallback(
|
const handleSubmit = useCallback(
|
||||||
(valueToSubmit: string) => {
|
(valueToSubmit: string) => {
|
||||||
// No need to update if it hasn't changed
|
// No need to update if it hasn't changed
|
||||||
if (valueToSubmit === initialText) {
|
if (valueToSubmit === initialText && !options?.allowSubmitSameValue) {
|
||||||
options?.onCancelUpdate?.();
|
options?.onCancelUpdate?.();
|
||||||
} else {
|
} else {
|
||||||
const cleanVal = valueToSubmit.trim();
|
const cleanVal = valueToSubmit.trim();
|
||||||
|
|||||||
@@ -225,38 +225,32 @@ export const useEventAction = () => {
|
|||||||
*/
|
*/
|
||||||
const updateTimer = useCallback(
|
const updateTimer = useCallback(
|
||||||
async (eventId: string, field: TimeField, value: string, lockOnUpdate?: boolean) => {
|
async (eventId: string, field: TimeField, value: string, lockOnUpdate?: boolean) => {
|
||||||
let newValMillis = 0;
|
// an empty value with no lock has no domain validity
|
||||||
|
if (!lockOnUpdate && value === '') {
|
||||||
// check for previous keyword
|
return;
|
||||||
if (value === 'p' || value === 'prev' || value === 'previous') {
|
|
||||||
newValMillis = getPreviousEnd();
|
|
||||||
|
|
||||||
// check for adding time keyword
|
|
||||||
} else if (value.startsWith('+') || value.startsWith('p+') || value.startsWith('p +')) {
|
|
||||||
// TODO: is this logic solid?
|
|
||||||
const remainingString = value.substring(1);
|
|
||||||
newValMillis = getPreviousEnd() + parseUserTime(remainingString);
|
|
||||||
} else {
|
|
||||||
newValMillis = parseUserTime(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dont allow timer values over 23:59:59
|
const newEvent: Partial<OntimeEvent> = {
|
||||||
const cappedMillis = Math.min(newValMillis, dayInMs - MILLIS_PER_SECOND);
|
|
||||||
const newEvent = {
|
|
||||||
id: eventId,
|
id: eventId,
|
||||||
[field]: cappedMillis,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// check if we should lock the field
|
// check if we should lock the field
|
||||||
if (lockOnUpdate) {
|
if (lockOnUpdate) {
|
||||||
if (field === 'timeEnd') {
|
if (field === 'timeEnd') {
|
||||||
newEvent.timeStrategy = TimeStrategy.LockEnd;
|
// an empty value indicates that we should unlock the field
|
||||||
|
newEvent.timeStrategy = value === '' ? TimeStrategy.LockDuration : TimeStrategy.LockEnd;
|
||||||
|
newEvent.timeEnd = value === '' ? undefined : calculateNewValue();
|
||||||
} else if (field === 'duration') {
|
} else if (field === 'duration') {
|
||||||
newEvent.timeStrategy = TimeStrategy.LockDuration;
|
// an empty value indicates that we should unlock the field
|
||||||
} else if (field === 'timeStart' && value === '') {
|
newEvent.timeStrategy = value === '' ? TimeStrategy.LockEnd : TimeStrategy.LockDuration;
|
||||||
// if user removes the time start, we should link to the previous
|
newEvent.duration = value === '' ? undefined : calculateNewValue();
|
||||||
newEvent.linkStart = 'true';
|
} else if (field === 'timeStart') {
|
||||||
|
// an empty values means we should link to the previous
|
||||||
|
newEvent.linkStart = value === '' ? 'true' : null;
|
||||||
|
newEvent.timeStart = value === '' ? undefined : calculateNewValue();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
newEvent[field] = calculateNewValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -265,6 +259,31 @@ export const useEventAction = () => {
|
|||||||
logAxiosError('Error updating event', error);
|
logAxiosError('Error updating event', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility function to calculate the new time value
|
||||||
|
*/
|
||||||
|
function calculateNewValue(): number {
|
||||||
|
let newValMillis = 0;
|
||||||
|
|
||||||
|
// check for previous keyword
|
||||||
|
if (value === 'p' || value === 'prev' || value === 'previous') {
|
||||||
|
newValMillis = getPreviousEnd();
|
||||||
|
|
||||||
|
// check for adding time keyword
|
||||||
|
} else if (value.startsWith('+') || value.startsWith('p+') || value.startsWith('p +')) {
|
||||||
|
// TODO: is this logic solid?
|
||||||
|
const remainingString = value.substring(1);
|
||||||
|
newValMillis = getPreviousEnd() + parseUserTime(remainingString);
|
||||||
|
} else {
|
||||||
|
newValMillis = parseUserTime(value);
|
||||||
|
}
|
||||||
|
// dont allow timer values over 23:59:59
|
||||||
|
return Math.min(newValMillis, dayInMs - MILLIS_PER_SECOND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility function to get the previous event end time
|
||||||
|
*/
|
||||||
function getPreviousEnd(): number {
|
function getPreviousEnd(): number {
|
||||||
const cachedRundown = queryClient.getQueryData<RundownCached>(RUNDOWN);
|
const cachedRundown = queryClient.getQueryData<RundownCached>(RUNDOWN);
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -5,16 +5,18 @@ import useReactiveTextInput from '../../../../common/components/input/text-input
|
|||||||
|
|
||||||
interface SingleLineCellProps {
|
interface SingleLineCellProps {
|
||||||
initialValue: string;
|
initialValue: string;
|
||||||
|
allowSubmitSameValue?: boolean;
|
||||||
handleUpdate: (newValue: string) => void;
|
handleUpdate: (newValue: string) => void;
|
||||||
handleCancelUpdate?: () => void;
|
handleCancelUpdate?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SingleLineCell = forwardRef((props: SingleLineCellProps, inputRef) => {
|
const SingleLineCell = forwardRef((props: SingleLineCellProps, inputRef) => {
|
||||||
const { initialValue, handleUpdate, handleCancelUpdate } = props;
|
const { initialValue, allowSubmitSameValue, handleUpdate, handleCancelUpdate } = props;
|
||||||
const ref = useRef<HTMLInputElement | null>(null);
|
const ref = useRef<HTMLInputElement | null>(null);
|
||||||
const submitCallback = useCallback((newValue: string) => handleUpdate(newValue), [handleUpdate]);
|
const submitCallback = useCallback((newValue: string) => handleUpdate(newValue), [handleUpdate]);
|
||||||
|
|
||||||
const { value, onChange, onBlur, onKeyDown } = useReactiveTextInput(initialValue, submitCallback, ref, {
|
const { value, onChange, onBlur, onKeyDown } = useReactiveTextInput(initialValue, submitCallback, ref, {
|
||||||
|
allowSubmitSameValue,
|
||||||
submitOnEnter: true, // single line should submit on enter
|
submitOnEnter: true, // single line should submit on enter
|
||||||
submitOnCtrlEnter: true,
|
submitOnCtrlEnter: true,
|
||||||
onCancelUpdate: handleCancelUpdate,
|
onCancelUpdate: handleCancelUpdate,
|
||||||
|
|||||||
+6
-3
@@ -41,8 +41,9 @@ export default function TimeInputDuration(props: TimeInputDurationProps) {
|
|||||||
(newValue: string) => {
|
(newValue: string) => {
|
||||||
setIsEditing(false);
|
setIsEditing(false);
|
||||||
|
|
||||||
// Check if there is anything there
|
// if the user sends an empty string, we want to clear the value
|
||||||
if (newValue === '') {
|
if (newValue === '') {
|
||||||
|
onSubmit(newValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,14 +60,15 @@ export default function TimeInputDuration(props: TimeInputDurationProps) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valueInMillis === initialValue) {
|
// if the value is the same, we may still want to push the lock change
|
||||||
|
if (valueInMillis === initialValue && lockedValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit(newValue);
|
onSubmit(newValue);
|
||||||
setValue(Number(newValue));
|
setValue(Number(newValue));
|
||||||
},
|
},
|
||||||
[initialValue, onSubmit],
|
[initialValue, lockedValue, onSubmit],
|
||||||
);
|
);
|
||||||
|
|
||||||
// duration times have a special format
|
// duration times have a special format
|
||||||
@@ -77,6 +79,7 @@ export default function TimeInputDuration(props: TimeInputDurationProps) {
|
|||||||
<SingleLineCell
|
<SingleLineCell
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
initialValue={timeString}
|
initialValue={timeString}
|
||||||
|
allowSubmitSameValue={!lockedValue} // if the value is not locked, submitting will lock the value
|
||||||
handleUpdate={handleUpdate}
|
handleUpdate={handleUpdate}
|
||||||
handleCancelUpdate={handleFakeBlur}
|
handleCancelUpdate={handleFakeBlur}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user