fix: custom project data

This commit is contained in:
Carlos Valente
2025-07-25 18:54:27 +02:00
committed by Carlos Valente
parent bda01c886e
commit dc3a32d2bc
3 changed files with 26 additions and 13 deletions
@@ -1,8 +1,8 @@
import { useQuery } from '@tanstack/react-query';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
import { PROJECT_DATA } from '../api/constants';
import { getProjectData } from '../api/project';
import { getProjectData, postProjectData } from '../api/project';
import { projectDataPlaceholder } from '../models/ProjectData';
export default function useProjectData() {
@@ -10,11 +10,25 @@ export default function useProjectData() {
queryKey: PROJECT_DATA,
queryFn: getProjectData,
placeholderData: (previousData, _previousQuery) => previousData,
retry: 5,
retryDelay: (attempt) => attempt * 2500,
refetchInterval: queryRefetchIntervalSlow,
networkMode: 'always',
});
return { data: data ?? projectDataPlaceholder, status, isFetching, isError, refetch };
}
export function useUpdateProjectData() {
const queryClient = useQueryClient();
const updateFn = useMutation({
mutationFn: postProjectData,
onSuccess: (newProjectData) => {
queryClient.setQueryData(PROJECT_DATA, newProjectData);
},
});
return {
updateProjectData: updateFn.mutateAsync,
isMutating: updateFn.isPending,
isMutatingError: updateFn.isError,
};
}
@@ -4,12 +4,12 @@ import { IoAdd, IoDownloadOutline, IoTrash } from 'react-icons/io5';
import { type ProjectData } from 'ontime-types';
import { projectLogoPath } from '../../../../common/api/constants';
import { postProjectData, uploadProjectLogo } from '../../../../common/api/project';
import { uploadProjectLogo } from '../../../../common/api/project';
import { maybeAxiosError } from '../../../../common/api/utils';
import Button from '../../../../common/components/buttons/Button';
import Input from '../../../../common/components/input/input/Input';
import Textarea from '../../../../common/components/input/textarea/Textarea';
import useProjectData from '../../../../common/hooks-query/useProjectData';
import useProjectData, { useUpdateProjectData } from '../../../../common/hooks-query/useProjectData';
import { preventEscape } from '../../../../common/utils/keyEvent';
import { validateLogo } from '../../../../common/utils/uploadUtils';
import { documentationUrl } from '../../../../externals';
@@ -19,7 +19,8 @@ import style from './SettingsPanel.module.scss';
export default function ProjectData() {
'use no memo'; // RHF and react-compiler don't seem to get along
const { data, status, refetch } = useProjectData();
const { data, status } = useProjectData();
const { updateProjectData } = useUpdateProjectData();
const {
handleSubmit,
@@ -93,16 +94,14 @@ export default function ProjectData() {
const onSubmit = async (formData: ProjectData) => {
try {
await postProjectData(formData);
await updateProjectData(formData);
} catch (error) {
const message = maybeAxiosError(error);
setError('root', { message });
} finally {
await refetch();
}
};
// populate with new data if we get an update
// reset data to the initial state
const onReset = () => {
reset(data);
};
@@ -11,7 +11,7 @@ export const projectSanitiser = [
body('custom').optional().isArray(),
body('custom.*.title').optional().isString().trim().notEmpty(),
body('custom.*.value').optional().isString().trim().notEmpty(),
body('custom.*.url').optional().isString().trim().notEmpty(),
body('custom.*.url').optional().isString().trim(),
requestValidationFunction,
];