From fa3bfd337c28c672e79bf8ce2677e8c6beb70e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20=C3=98sttveit?= Date: Fri, 10 Jan 2025 15:42:17 +0100 Subject: [PATCH 1/2] fix data model reader not getting updated by action result --- src/features/formData/FormDataReaders.tsx | 4 +- src/features/formData/FormDataWrite.tsx | 51 +++++++++++++++-------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/features/formData/FormDataReaders.tsx b/src/features/formData/FormDataReaders.tsx index 2a708d759f..b40fc810f5 100644 --- a/src/features/formData/FormDataReaders.tsx +++ b/src/features/formData/FormDataReaders.tsx @@ -198,8 +198,8 @@ function SpecificDataModelFetcher({ reader, isAvailable }: { reader: DataModelRe const dataType = reader.getName(); const dataElements = useLaxInstanceDataElements(dataType); const dataElementId = getFirstDataElementId(dataElements, dataType); - const url = useDataModelUrl({ includeRowIds: false, dataType, dataElementId, language: useCurrentLanguage() }); - const enabled = isAvailable && reader.isLoading(); + const url = useDataModelUrl({ includeRowIds: true, dataType, dataElementId, language: useCurrentLanguage() }); + const enabled = isAvailable; const { data, error } = useFormDataQuery(enabled ? url : undefined); const { updateModel } = useCtx(); diff --git a/src/features/formData/FormDataWrite.tsx b/src/features/formData/FormDataWrite.tsx index 8d354d0e39..0cb0f48141 100644 --- a/src/features/formData/FormDataWrite.tsx +++ b/src/features/formData/FormDataWrite.tsx @@ -86,10 +86,11 @@ const { function useFormDataSaveMutation() { const { doPatchFormData, doPostStatelessFormData } = useAppMutations(); const getDataModelUrl = useGetDataModelUrl(); + const updateQueryCache = useUpdateQueryCache(); const instanceId = useLaxInstanceId(); const multiPatchUrl = instanceId ? getMultiPatchUrl(instanceId) : undefined; const currentLanguage = useAsRef(useCurrentLanguage()); - const dataModelsRef = useAsRef(useSelector((state) => state.dataModels)); + const dataModelsRef = useSelectorAsRef((state) => state.dataModels); const saveFinished = useSelector((s) => s.saveFinished); const cancelSave = useSelector((s) => s.cancelSave); const isStateless = useApplicationMetadata().isStatelessApp; @@ -99,21 +100,6 @@ function useFormDataSaveMutation() { FormDataContext >(useStore()); const useIsSavingRef = useAsRef(useIsSaving()); - const queryClient = useQueryClient(); - - // This updates the query cache with the new data models every time a save has finished. This means we won't have to - // refetch the data from the backend if the providers suddenly change (i.e. when navigating back and forth between - // the main form and a subform). - function updateQueryCache(result: FDSaveFinished) { - for (const { dataType, data, dataElementId } of result.newDataModels) { - const url = getDataModelUrl({ dataType, dataElementId, includeRowIds: true }); - if (!url) { - continue; - } - const queryKey = getFormDataQueryKey(url); - queryClient.setQueryData(queryKey, data); - } - } const mutation = useMutation({ mutationKey: ['saveFormData'], @@ -261,7 +247,7 @@ function useFormDataSaveMutation() { cancelSave(); }, onSuccess: (result) => { - result && updateQueryCache(result); + result && updateQueryCache(result.newDataModels); result && saveFinished(result); !result && cancelSave(); }, @@ -288,6 +274,28 @@ export function useIsSaving() { ); } +// This updates the query cache with the new data models every time a save has finished. This means we won't have to +// refetch the data from the backend if the providers suddenly change (i.e. when navigating back and forth between +// the main form and a subform). +function useUpdateQueryCache() { + const getDataModelUrl = useGetDataModelUrl(); + const queryClient = useQueryClient(); + + return useCallback( + (newDataModels: { dataType?: string; dataElementId?: string; data: unknown }[]) => { + for (const { dataType, data, dataElementId } of newDataModels) { + const url = getDataModelUrl({ dataType, dataElementId, includeRowIds: true }); + if (!url) { + continue; + } + const queryKey = getFormDataQueryKey(url); + queryClient.setQueryData(queryKey, data); + } + }, + [getDataModelUrl, queryClient], + ); +} + export function FormDataWriteProvider({ children }: PropsWithChildren) { const proxies = useFormDataWriteProxies(); const ruleConnections = useRuleConnections(); @@ -792,6 +800,8 @@ export const FD = { * in a certain state. Locking will effectively ignore all saving until you unlock it again. */ useLocking(lockId: string) { + const updateQueryCache = useUpdateQueryCache(); + const rawLock = useSelector((s) => s.lock); const rawUnlock = useSelector((s) => s.unlock); @@ -835,10 +845,15 @@ export const FD = { return false; } + const updatedDataModels = + actionResult?.updatedDataModels && + Object.entries(actionResult.updatedDataModels).map(([dataElementId, data]) => ({ dataElementId, data })); + + updatedDataModels && updateQueryCache(updatedDataModels); rawUnlock(actionResult); return true; }, - [isLockedByMeRef, isLockedRef, lockId, lockedByRef, rawUnlock], + [isLockedByMeRef, isLockedRef, lockId, lockedByRef, rawUnlock, updateQueryCache], ); return useMemo( From 96964ae1fc9676e06e6a62e2690c6c6f9d8ba755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20=C3=98sttveit?= Date: Fri, 10 Jan 2025 16:07:40 +0100 Subject: [PATCH 2/2] fix test --- src/features/formData/FormDataReaders.test.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/features/formData/FormDataReaders.test.tsx b/src/features/formData/FormDataReaders.test.tsx index ecee191368..442215c2b9 100644 --- a/src/features/formData/FormDataReaders.test.tsx +++ b/src/features/formData/FormDataReaders.test.tsx @@ -95,8 +95,7 @@ async function render(props: TestProps) { function urlFor(dataModelName: string) { for (const [uuid, name] of Object.entries(idToNameMap)) { if (name === dataModelName) { - const isDefault = dataModelName === props.defaultDataModel; - return `https://local.altinn.cloud/ttd/test/instances/${instanceId}/data/${uuid}?includeRowId=${isDefault.toString()}&language=nb`; + return `https://local.altinn.cloud/ttd/test/instances/${instanceId}/data/${uuid}?includeRowId=true&language=nb`; } } return false;