mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-18 13:44:12 +00:00
fix forms stale (#419)
* feat: create loader component * fix: prevent stale data in forms
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useFieldArray, useForm } from 'react-hook-form';
|
||||
import { Alert, AlertDescription, AlertIcon, AlertTitle, Button, IconButton, Input, Switch } from '@chakra-ui/react';
|
||||
import { IoOpenOutline } from '@react-icons/all-files/io5/IoOpenOutline';
|
||||
@@ -9,6 +10,7 @@ import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBt
|
||||
import useAliases from '../../../common/hooks-query/useAliases';
|
||||
import { useEmitLog } from '../../../common/stores/logger';
|
||||
import { handleLinks } from '../../../common/utils/linkUtils';
|
||||
import ModalLoader from '../modal-loader/ModalLoader';
|
||||
import { inputProps } from '../modalHelper';
|
||||
import ModalLink from '../ModalLink';
|
||||
import OntimeModalFooter from '../OntimeModalFooter';
|
||||
@@ -21,7 +23,7 @@ const aliasesDocsUrl = 'https://ontime.gitbook.io/v2/features/url-aliases';
|
||||
type Aliases = { aliases: Alias[] };
|
||||
|
||||
export default function AliasesForm() {
|
||||
const { data, status, refetch } = useAliases();
|
||||
const { data, status, isFetching, refetch } = useAliases();
|
||||
const { emitError } = useEmitLog();
|
||||
const {
|
||||
control,
|
||||
@@ -32,12 +34,21 @@ export default function AliasesForm() {
|
||||
} = useForm<Aliases>({
|
||||
defaultValues: { aliases: data },
|
||||
values: { aliases: data || [] },
|
||||
resetOptions: {
|
||||
keepDirtyValues: true,
|
||||
},
|
||||
});
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
name: 'aliases',
|
||||
control,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
reset(data);
|
||||
}
|
||||
}, [data, reset]);
|
||||
|
||||
const onSubmit = async (formData: Aliases) => {
|
||||
try {
|
||||
await postAliases(formData.aliases);
|
||||
@@ -67,6 +78,10 @@ export default function AliasesForm() {
|
||||
const disableInputs = status === 'loading';
|
||||
const hasTooManyOptions = fields.length >= 20;
|
||||
|
||||
if (isFetching) {
|
||||
return <ModalLoader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} id='aliases' className={style.sectionContainer}>
|
||||
<div style={{ height: '16px' }} />
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Input, Select } from '@chakra-ui/react';
|
||||
import type { Settings } from 'ontime-types';
|
||||
@@ -6,6 +7,7 @@ import { postSettings } from '../../../common/api/ontimeApi';
|
||||
import useSettings from '../../../common/hooks-query/useSettings';
|
||||
import { useEmitLog } from '../../../common/stores/logger';
|
||||
import { isOnlyNumbers } from '../../../common/utils/regex';
|
||||
import ModalLoader from '../modal-loader/ModalLoader';
|
||||
import ModalSplitInput from '../ModalSplitInput';
|
||||
import OntimeModalFooter from '../OntimeModalFooter';
|
||||
|
||||
@@ -14,7 +16,7 @@ import ModalPinInput from './ModalPinInput';
|
||||
import style from './SettingsModal.module.scss';
|
||||
|
||||
export default function AppSettingsModal() {
|
||||
const { data, status, refetch } = useSettings();
|
||||
const { data, status, isFetching, refetch } = useSettings();
|
||||
const { emitError } = useEmitLog();
|
||||
const {
|
||||
handleSubmit,
|
||||
@@ -24,8 +26,17 @@ export default function AppSettingsModal() {
|
||||
} = useForm<Settings>({
|
||||
defaultValues: data,
|
||||
values: data,
|
||||
resetOptions: {
|
||||
keepDirtyValues: true,
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
reset(data);
|
||||
}
|
||||
}, [data, reset]);
|
||||
|
||||
const onSubmit = async (formData: Settings) => {
|
||||
try {
|
||||
await postSettings(formData);
|
||||
@@ -42,6 +53,10 @@ export default function AppSettingsModal() {
|
||||
|
||||
const disableInputs = status === 'loading';
|
||||
|
||||
if (isFetching) {
|
||||
return <ModalLoader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} id='app-settings' className={style.sectionContainer}>
|
||||
<ModalSplitInput
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Alert, AlertDescription, AlertIcon, AlertTitle, Input } from '@chakra-ui/react';
|
||||
import { UserFields } from 'ontime-types';
|
||||
@@ -5,6 +6,7 @@ import { UserFields } from 'ontime-types';
|
||||
import { postUserFields } from '../../../common/api/ontimeApi';
|
||||
import useUserFields from '../../../common/hooks-query/useUserFields';
|
||||
import { useEmitLog } from '../../../common/stores/logger';
|
||||
import ModalLoader from '../modal-loader/ModalLoader';
|
||||
import { inputProps } from '../modalHelper';
|
||||
import ModalLink from '../ModalLink';
|
||||
import ModalSplitInput from '../ModalSplitInput';
|
||||
@@ -15,7 +17,7 @@ import style from './SettingsModal.module.scss';
|
||||
const userFieldsDocsUrl = 'https://ontime.gitbook.io/v2/features/user-fields';
|
||||
|
||||
export default function CuesheetSettings() {
|
||||
const { data, status, refetch } = useUserFields();
|
||||
const { data, status, isFetching, refetch } = useUserFields();
|
||||
const { emitError } = useEmitLog();
|
||||
const {
|
||||
handleSubmit,
|
||||
@@ -25,8 +27,17 @@ export default function CuesheetSettings() {
|
||||
} = useForm<UserFields>({
|
||||
defaultValues: data,
|
||||
values: data,
|
||||
resetOptions: {
|
||||
keepDirtyValues: true,
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
reset(data);
|
||||
}
|
||||
}, [data, reset]);
|
||||
|
||||
const onSubmit = async (formData: UserFields) => {
|
||||
try {
|
||||
await postUserFields(formData);
|
||||
@@ -43,6 +54,10 @@ export default function CuesheetSettings() {
|
||||
|
||||
const disableInputs = status === 'loading';
|
||||
|
||||
if (isFetching) {
|
||||
return <ModalLoader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} id='cuesheet-settings' className={style.sectionContainer}>
|
||||
<div style={{ height: '16px' }} />
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Input, Textarea } from '@chakra-ui/react';
|
||||
import { EventData } from 'ontime-types';
|
||||
@@ -5,6 +6,7 @@ import { EventData } from 'ontime-types';
|
||||
import { postEventData } from '../../../common/api/eventDataApi';
|
||||
import useEventData from '../../../common/hooks-query/useEventData';
|
||||
import { useEmitLog } from '../../../common/stores/logger';
|
||||
import ModalLoader from '../modal-loader/ModalLoader';
|
||||
import { inputProps } from '../modalHelper';
|
||||
import ModalInput from '../ModalInput';
|
||||
import OntimeModalFooter from '../OntimeModalFooter';
|
||||
@@ -12,7 +14,7 @@ import OntimeModalFooter from '../OntimeModalFooter';
|
||||
import style from './SettingsModal.module.scss';
|
||||
|
||||
export default function EventDataForm() {
|
||||
const { data, status, refetch } = useEventData();
|
||||
const { data, status, isFetching, refetch } = useEventData();
|
||||
const { emitError } = useEmitLog();
|
||||
const {
|
||||
handleSubmit,
|
||||
@@ -22,8 +24,17 @@ export default function EventDataForm() {
|
||||
} = useForm<EventData>({
|
||||
defaultValues: data,
|
||||
values: data,
|
||||
resetOptions: {
|
||||
keepDirtyValues: true,
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
reset(data);
|
||||
}
|
||||
}, [data, reset]);
|
||||
|
||||
const onSubmit = async (formData: EventData) => {
|
||||
try {
|
||||
await postEventData(formData);
|
||||
@@ -40,6 +51,10 @@ export default function EventDataForm() {
|
||||
|
||||
const disableInputs = status === 'loading';
|
||||
|
||||
if (isFetching) {
|
||||
return <ModalLoader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} id='event-data' className={style.sectionContainer}>
|
||||
<ModalInput
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
.grow {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Input, Switch } from '@chakra-ui/react';
|
||||
import { ViewSettings } from 'ontime-types';
|
||||
@@ -10,6 +11,7 @@ import { mtm } from '../../../common/utils/timeConstants';
|
||||
import { inputProps } from '../modalHelper';
|
||||
import ModalInput from '../ModalInput';
|
||||
import ModalSplitInput from '../ModalSplitInput';
|
||||
import ModalLoader from '../modal-loader/ModalLoader';
|
||||
import OntimeModalFooter from '../OntimeModalFooter';
|
||||
|
||||
import InputMillisWithString from './InputMillisWithString';
|
||||
@@ -17,7 +19,7 @@ import InputMillisWithString from './InputMillisWithString';
|
||||
import style from './SettingsModal.module.scss';
|
||||
|
||||
export default function ViewSettingsForm() {
|
||||
const { data, status, refetch } = useViewSettings();
|
||||
const { data, status, refetch, isFetching } = useViewSettings();
|
||||
const { emitError } = useEmitLog();
|
||||
const {
|
||||
control,
|
||||
@@ -28,8 +30,17 @@ export default function ViewSettingsForm() {
|
||||
} = useForm<ViewSettings>({
|
||||
defaultValues: data,
|
||||
values: data,
|
||||
resetOptions: {
|
||||
keepDirtyValues: true,
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
reset(data);
|
||||
}
|
||||
}, [data, reset]);
|
||||
|
||||
const onSubmit = async (formData: ViewSettings) => {
|
||||
const parsedWarningThreshold = dirtyFields?.warningThreshold
|
||||
? // @ts-expect-error -- trust me
|
||||
@@ -65,6 +76,10 @@ export default function ViewSettingsForm() {
|
||||
|
||||
const disableInputs = status === 'loading';
|
||||
|
||||
if (isFetching) {
|
||||
return <ModalLoader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} id='view-settings' className={style.sectionContainer}>
|
||||
<span className={style.title}>General view settings</span>
|
||||
|
||||
Reference in New Issue
Block a user