diff --git a/src/App.tsx b/src/App.tsx index 7d2cacf2fd..50f692e131 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,8 +8,8 @@ import { Entrypoint } from 'src/features/entrypoint/Entrypoint'; import { InstanceProvider } from 'src/features/instance/InstanceContext'; import { PartySelection } from 'src/features/instantiate/containers/PartySelection'; import { InstanceSelectionWrapper } from 'src/features/instantiate/selection/InstanceSelection'; +import { TaskKeys } from 'src/features/navigation/useNavigatePage'; import { CustomReceipt, DefaultReceipt } from 'src/features/receipt/ReceiptContainer'; -import { TaskKeys } from 'src/hooks/useNavigatePage'; import { PresentationType } from 'src/types'; export const App = () => ( diff --git a/src/components/form/Form.tsx b/src/components/form/Form.tsx index 7078c2fc2d..115c94a60e 100644 --- a/src/components/form/Form.tsx +++ b/src/components/form/Form.tsx @@ -14,6 +14,12 @@ import { useNavigateToNode, useRegisterNodeNavigationHandler } from 'src/feature import { useUiConfigContext } from 'src/features/form/layout/UiConfigContext'; import { usePageSettings } from 'src/features/form/layoutSettings/LayoutSettingsContext'; import { useLanguage } from 'src/features/language/useLanguage'; +import { + useCurrentView, + useIdValidPageId, + useNavigateToPage, + useStartUrl, +} from 'src/features/navigation/useNavigatePage'; import { SearchParams, useNavigate, @@ -25,7 +31,6 @@ import { } from 'src/features/routing/AppRoutingContext'; import { useOnFormSubmitValidation } from 'src/features/validation/callbacks/onFormSubmitValidation'; import { useTaskErrors } from 'src/features/validation/selectors/taskErrors'; -import { useCurrentView, useNavigatePage, useStartUrl } from 'src/hooks/useNavigatePage'; import { getComponentCapabilities } from 'src/layout'; import { GenericComponentById } from 'src/layout/GenericComponent'; import { getPageTitle } from 'src/utils/getPageTitle'; @@ -49,7 +54,8 @@ export function Form() { } export function FormPage({ currentPageId }: { currentPageId: string | undefined }) { - const { isValidPageId, navigateToPage } = useNavigatePage(); + const isValidPageId = useIdValidPageId(); + const { mutateAsync: navigateToPage } = useNavigateToPage(); const appName = useAppName(); const appOwner = useAppOwner(); const { langAsString } = useLanguage(); @@ -62,12 +68,15 @@ export function FormPage({ currentPageId }: { currentPageId: string | undefined useRegisterNodeNavigationHandler(async (targetNode, options) => { const targetView = targetNode?.pageKey; if (targetView && targetView !== currentPageId) { - await navigateToPage(targetView, { - ...options?.pageNavOptions, - shouldFocusComponent: options?.shouldFocus ?? options?.pageNavOptions?.shouldFocusComponent ?? true, - replace: - window.location.href.includes(SearchParams.FocusComponentId) || - window.location.href.includes(SearchParams.ExitSubform), + await navigateToPage({ + page: targetView, + options: { + ...options?.pageNavOptions, + shouldFocusComponent: options?.shouldFocus ?? options?.pageNavOptions?.shouldFocusComponent ?? true, + replace: + window.location.href.includes(SearchParams.FocusComponentId) || + window.location.href.includes(SearchParams.ExitSubform), + }, }); return true; } @@ -157,7 +166,8 @@ function useRedirectToStoredPage() { const pageKey = useCurrentView(); const instanceOwnerPartyId = useNavigationParam('instanceOwnerPartyId'); const instanceGuid = useNavigationParam('instanceGuid'); - const { isValidPageId, navigateToPage } = useNavigatePage(); + const isValidPageId = useIdValidPageId(); + const { mutate: navigateToPage } = useNavigateToPage(); const applicationMetadataId = useApplicationMetadata()?.id; const instanceId = `${instanceOwnerPartyId}/${instanceGuid}`; @@ -168,7 +178,7 @@ function useRedirectToStoredPage() { const lastVisitedPage = localStorage.getItem(currentViewCacheKey); if (lastVisitedPage !== null && isValidPageId(lastVisitedPage)) { localStorage.removeItem(currentViewCacheKey); - navigateToPage(lastVisitedPage, { replace: true }); + navigateToPage({ page: lastVisitedPage, options: { replace: true } }); } } }, [pageKey, currentViewCacheKey, isValidPageId, navigateToPage]); diff --git a/src/components/form/LinkToPotentialPage.tsx b/src/components/form/LinkToPotentialPage.tsx index 3ae19696e8..5e09b5a0bd 100644 --- a/src/components/form/LinkToPotentialPage.tsx +++ b/src/components/form/LinkToPotentialPage.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Link } from 'react-router-dom'; import type { LinkProps } from 'react-router-dom'; -import { useNavigatePage } from 'src/hooks/useNavigatePage'; +import { useIdValidPageId } from 'src/features/navigation/useNavigatePage'; import { Hidden } from 'src/utils/layout/NodesContext'; type Props = LinkProps & { children?: React.ReactNode }; @@ -16,7 +16,7 @@ export const LinkToPotentialPage = (props: Props) => { const page = parts[parts.length - 1]; const isHiddenPage = Hidden.useIsHiddenPage(page); - const { isValidPageId } = useNavigatePage(); + const isValidPageId = useIdValidPageId(); const shouldShowLink = isValidPageId(page) && !isHiddenPage; if (shouldShowLink) { diff --git a/src/components/presentation/BackNavigationButton.tsx b/src/components/presentation/BackNavigationButton.tsx index 82047afd6a..0eeb14340c 100644 --- a/src/components/presentation/BackNavigationButton.tsx +++ b/src/components/presentation/BackNavigationButton.tsx @@ -8,13 +8,13 @@ import cn from 'classnames'; import { Button } from 'src/app-components/Button/Button'; import classes from 'src/components/presentation/BackNavigationButton.module.css'; import { useAppQueries } from 'src/core/contexts/AppQueriesProvider'; -import { useIsProcessing } from 'src/core/contexts/processingContext'; import { Lang } from 'src/features/language/Lang'; import { useLanguage } from 'src/features/language/useLanguage'; +import { useExitSubform } from 'src/features/navigation/useNavigatePage'; import { useCurrentParty } from 'src/features/party/PartiesProvider'; import { useIsSubformPage, useNavigationParam } from 'src/features/routing/AppRoutingContext'; import { useIsMobile } from 'src/hooks/useDeviceWidths'; -import { useNavigatePage } from 'src/hooks/useNavigatePage'; +import { useHasLongLivedMutations } from 'src/hooks/useHasLongLivedMutations'; import { returnUrlToMessagebox } from 'src/utils/urls/urlHelper'; export function BackNavigationButton(props: Parameters[0]) { @@ -24,8 +24,9 @@ export function BackNavigationButton(props: Parameters[0]) { const mainPageKey = useNavigationParam('mainPageKey'); const isSubform = useIsSubformPage(); const { returnUrl, isFetchingReturnUrl } = useReturnUrl(); - const { exitSubform } = useNavigatePage(); - const { performProcess, isAnyProcessing, isThisProcessing: isExitingSubform } = useIsProcessing(); + const { mutateAsync: exitSubform, isPending: isExitingSubform } = useExitSubform(); + + const hasLongLivedMutations = useHasLongLivedMutations(); const messageBoxUrl = returnUrlToMessagebox(window.location.host, party?.partyId); @@ -42,8 +43,8 @@ export function BackNavigationButton(props: Parameters[0]) { if (isSubform) { return ( diff --git a/src/layout/Button/ButtonComponent.tsx b/src/layout/Button/ButtonComponent.tsx index 9e9da35795..b962a127f5 100644 --- a/src/layout/Button/ButtonComponent.tsx +++ b/src/layout/Button/ButtonComponent.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { Button } from 'src/app-components/Button/Button'; -import { useIsProcessing } from 'src/core/contexts/processingContext'; import { useHasPendingAttachments } from 'src/features/attachments/hooks'; import { useSetReturnToView } from 'src/features/form/layout/PageNavigationContext'; import { useLaxProcessData, useTaskTypeFromBackend } from 'src/features/instance/ProcessContext'; @@ -9,6 +8,7 @@ import { useProcessNext } from 'src/features/instance/useProcessNext'; import { Lang } from 'src/features/language/Lang'; import { useLanguage } from 'src/features/language/useLanguage'; import { useIsSubformPage } from 'src/features/routing/AppRoutingContext'; +import { useHasLongLivedMutations } from 'src/hooks/useHasLongLivedMutations'; import { getComponentFromMode } from 'src/layout/Button/getComponentFromMode'; import { ComponentStructureWrapper } from 'src/layout/ComponentStructureWrapper'; import { ProcessTaskType } from 'src/types'; @@ -31,8 +31,9 @@ export const ButtonComponent = ({ node, ...componentProps }: IButtonReceivedProp const currentTaskType = useTaskTypeFromBackend(); const { actions, write } = useLaxProcessData()?.currentTask || {}; const attachmentsPending = useHasPendingAttachments(); - const processNext = useProcessNext(); - const { performProcess, isAnyProcessing, isThisProcessing } = useIsProcessing(); + const { processNext, isPending: isThisProcessing } = useProcessNext(); + const hasLongLivedMutations = useHasLongLivedMutations(); + const setReturnToView = useSetReturnToView(); if (useIsSubformPage()) { @@ -40,7 +41,7 @@ export const ButtonComponent = ({ node, ...componentProps }: IButtonReceivedProp } const disabled = - isAnyProcessing || + hasLongLivedMutations || attachmentsPending || (currentTaskType === ProcessTaskType.Data && !write) || (currentTaskType === ProcessTaskType.Confirm && !actions?.confirm); @@ -62,15 +63,14 @@ export const ButtonComponent = ({ node, ...componentProps }: IButtonReceivedProp ); } - const submitTask = () => - performProcess(async () => { - setReturnToView?.(undefined); - if (currentTaskType === ProcessTaskType.Data) { - await processNext(); - } else if (currentTaskType === ProcessTaskType.Confirm) { - await processNext({ action: 'confirm' }); - } - }); + async function submitTask() { + setReturnToView?.(undefined); + if (currentTaskType === ProcessTaskType.Data) { + await processNext(); + } else if (currentTaskType === ProcessTaskType.Confirm) { + await processNext({ action: 'confirm' }); + } + } return ( diff --git a/src/layout/CustomButton/CustomButtonComponent.tsx b/src/layout/CustomButton/CustomButtonComponent.tsx index 502846a6fb..34e322fd36 100644 --- a/src/layout/CustomButton/CustomButtonComponent.tsx +++ b/src/layout/CustomButton/CustomButtonComponent.tsx @@ -5,15 +5,21 @@ import { useMutation } from '@tanstack/react-query'; import { Button } from 'src/app-components/Button/Button'; import { useAppMutations } from 'src/core/contexts/AppQueriesProvider'; -import { useIsProcessing } from 'src/core/contexts/processingContext'; import { useResetScrollPosition } from 'src/core/ui/useResetScrollPosition'; import { FD } from 'src/features/formData/FormDataWrite'; import { useLaxProcessData } from 'src/features/instance/ProcessContext'; import { Lang } from 'src/features/language/Lang'; import { useCurrentLanguage } from 'src/features/language/LanguageProvider'; +import { + useExitSubform, + useNavigateToNextPage, + useNavigateToPage, + useNavigateToPreviousPage, +} from 'src/features/navigation/useNavigatePage'; +import { performActionMutationKeys } from 'src/features/payment/usePerformPaymentMutation'; import { useIsSubformPage, useNavigationParam } from 'src/features/routing/AppRoutingContext'; import { useOnPageNavigationValidation } from 'src/features/validation/callbacks/onPageNavigationValidation'; -import { useNavigatePage } from 'src/hooks/useNavigatePage'; +import { useHasLongLivedMutations } from 'src/hooks/useHasLongLivedMutations'; import { ComponentStructureWrapper } from 'src/layout/ComponentStructureWrapper'; import { isSpecificClientAction } from 'src/layout/CustomButton/typeHelpers'; import { NodesInternal } from 'src/utils/layout/NodesContext'; @@ -25,6 +31,11 @@ import type * as CBTypes from 'src/layout/CustomButton/config.generated'; import type { ClientActionHandlers } from 'src/layout/CustomButton/typeHelpers'; import type { IInstance, IUserAction } from 'src/types/shared'; +const customButtonMutationKeys = { + all: () => ['custom-button'] as const, + specific: (id: string) => [...customButtonMutationKeys.all(), id] as const, +}; + type Props = PropsFromGenericComponent<'CustomButton'>; type UpdatedDataModels = { @@ -67,15 +78,18 @@ const isClientAction = (action: CBTypes.CustomAction): action is CBTypes.ClientA const isServerAction = (action: CBTypes.CustomAction): action is CBTypes.ServerAction => action.type === 'ServerAction'; function useHandleClientActions(): UseHandleClientActions { - const { navigateToPage, navigateToNextPage, navigateToPreviousPage, exitSubform } = useNavigatePage(); + const { mutateAsync: exitSubform } = useExitSubform(); + const { mutateAsync: navigateToNextPage } = useNavigateToNextPage(); + const { mutateAsync: navigateToPreviousPage } = useNavigateToPreviousPage(); + const { mutateAsync: navigateToPage } = useNavigateToPage(); const mainPageKey = useNavigationParam('mainPageKey'); const isSubformPage = useIsSubformPage(); const frontendActions: ClientActionHandlers = useMemo( () => ({ - nextPage: navigateToNextPage, - previousPage: navigateToPreviousPage, - navigateToPage: async ({ page }) => navigateToPage(page), + nextPage: () => navigateToNextPage({}), + previousPage: () => navigateToPreviousPage({}), + navigateToPage, closeSubform: exitSubform, }), [exitSubform, navigateToNextPage, navigateToPage, navigateToPreviousPage], @@ -152,50 +166,55 @@ type UsePerformActionMutation = { handleServerAction: (props: PerformActionMutationProps) => Promise; }; -function useHandleServerActionMutation(acquireLock: FormDataLocking): UsePerformActionMutation { +function usePerformActionMutation() { const { doPerformAction } = useAppMutations(); - const instanceOwnerPartyId = useNavigationParam('instanceOwnerPartyId'); const instanceGuid = useNavigationParam('instanceGuid'); - const { handleClientActions, handleDataModelUpdate } = useHandleClientActions(); - const markNotReady = NodesInternal.useMarkNotReady(); + const instanceOwnerPartyId = useNavigationParam('instanceOwnerPartyId'); const selectedLanguage = useCurrentLanguage(); - const { mutateAsync, isPending } = useMutation({ - mutationFn: async ({ action, buttonId }: PerformActionMutationProps) => { - if (!instanceGuid || !instanceOwnerPartyId) { - throw Error('Cannot perform action without partyId and instanceGuid'); - } - return doPerformAction(instanceOwnerPartyId, instanceGuid, { action: action.id, buttonId }, selectedLanguage); - }, + const mutationFn = async ({ action, buttonId }: PerformActionMutationProps) => { + if (!instanceGuid || !instanceOwnerPartyId) { + throw Error('Cannot perform action without partyId and instanceGuid'); + } + return doPerformAction(instanceOwnerPartyId, instanceGuid, { action: action.id, buttonId }, selectedLanguage); + }; + + return useMutation({ + mutationKey: performActionMutationKeys.withAction({ partyId: instanceOwnerPartyId, instanceGuid }), + mutationFn, }); +} - const handleServerAction = useCallback( - async ({ action, buttonId }: PerformActionMutationProps) => { - const lock = await acquireLock(); - try { - const result = await mutateAsync({ action, buttonId }); +function useHandleServerActionMutation(acquireLock: FormDataLocking): UsePerformActionMutation { + const { handleClientActions, handleDataModelUpdate } = useHandleClientActions(); + const markNotReady = NodesInternal.useMarkNotReady(); - // Server actions can bring back changes to the data model, which could cause the node tree to update. Marking - // it as not ready now will prevent some re-renders with stale data while the result is handled later. - markNotReady(); + const { mutateAsync, isPending } = usePerformActionMutation(); - await handleDataModelUpdate(lock, result); - if (result.clientActions) { - await handleClientActions(result.clientActions); - } - } catch (error) { - if (lock.isLocked()) { - lock.unlock(); - } - if (error?.response?.data?.error?.message !== undefined) { - toast(, { type: 'error' }); - } else { - toast(, { type: 'error' }); - } + const handleServerAction = async ({ action, buttonId }: PerformActionMutationProps) => { + const lock = await acquireLock(); + try { + const result = await mutateAsync({ action, buttonId }); + + // Server actions can bring back changes to the data model, which could cause the node tree to update. Marking + // it as not ready now will prevent some re-renders with stale data while the result is handled later. + markNotReady(); + + await handleDataModelUpdate(lock, result); + if (result.clientActions) { + await handleClientActions(result.clientActions); } - }, - [handleClientActions, handleDataModelUpdate, acquireLock, mutateAsync, markNotReady], - ); + } catch (error) { + if (lock.isLocked()) { + lock.unlock(); + } + if (error?.response?.data?.error?.message !== undefined) { + toast(, { type: 'error' }); + } else { + toast(, { type: 'error' }); + } + } + }; return { handleServerAction, isPending }; } @@ -243,7 +262,7 @@ export const CustomButtonComponent = ({ node }: Props) => { const { handleClientActions } = useHandleClientActions(); const { handleServerAction } = useHandleServerActionMutation(acquireLock); const onPageNavigationValidation = useOnPageNavigationValidation(); - const { performProcess, isAnyProcessing, isThisProcessing } = useIsProcessing(); + const hasLongLivedMutations = useHasLongLivedMutations(); const getScrollPosition = React.useCallback( () => document.querySelector(`[data-componentid="${id}"]`)?.getClientRects().item(0)?.y, @@ -254,7 +273,7 @@ export const CustomButtonComponent = ({ node }: Props) => { const isPermittedToPerformActions = actions .filter((action) => action.type === 'ServerAction') .reduce((acc, action) => acc && isAuthorized(action.id), true); - const disabled = !isPermittedToPerformActions || isAnyProcessing; + const disabled = !isPermittedToPerformActions || hasLongLivedMutations; const isSubformCloseButton = actions.filter((action) => action.id === 'closeSubform').length > 0; let interceptedButtonStyle = buttonStyle ?? 'secondary'; @@ -268,8 +287,9 @@ export const CustomButtonComponent = ({ node }: Props) => { buttonText = 'general.done'; } - const onClick = () => - performProcess(async () => { + const { mutate: handleClick, isPending: isThisProcessing } = useMutation({ + mutationKey: customButtonMutationKeys.specific(id), + mutationFn: async () => { for (const action of actions) { if (action.validation) { const prevScrollPosition = getScrollPosition(); @@ -286,7 +306,8 @@ export const CustomButtonComponent = ({ node }: Props) => { await handleServerAction({ action, buttonId: id }); } } - }); + }, + }); const style = buttonStyles[interceptedButtonStyle]; @@ -295,7 +316,7 @@ export const CustomButtonComponent = ({ node }: Props) => { )} {showNextButton && ( diff --git a/src/layout/Payment/PaymentComponent.tsx b/src/layout/Payment/PaymentComponent.tsx index d8ded011be..f5374a7a9c 100644 --- a/src/layout/Payment/PaymentComponent.tsx +++ b/src/layout/Payment/PaymentComponent.tsx @@ -1,15 +1,16 @@ import React from 'react'; import { Alert } from '@digdir/designsystemet-react'; +import { useMutation } from '@tanstack/react-query'; import { Button } from 'src/app-components/Button/Button'; -import { useIsProcessing } from 'src/core/contexts/processingContext'; import { useProcessNext } from 'src/features/instance/useProcessNext'; import { Lang } from 'src/features/language/Lang'; import { usePaymentInformation } from 'src/features/payment/PaymentInformationProvider'; import { usePayment } from 'src/features/payment/PaymentProvider'; import { PaymentStatus } from 'src/features/payment/types'; import { useIsSubformPage } from 'src/features/routing/AppRoutingContext'; +import { useHasLongLivedMutations } from 'src/hooks/useHasLongLivedMutations'; import { ComponentStructureWrapper } from 'src/layout/ComponentStructureWrapper'; import classes from 'src/layout/Payment/PaymentComponent.module.css'; import { PaymentDetailsTable } from 'src/layout/PaymentDetails/PaymentDetailsTable'; @@ -17,8 +18,9 @@ import { useNodeItem } from 'src/utils/layout/useNodeItem'; import type { PropsFromGenericComponent } from 'src/layout'; export const PaymentComponent = ({ node }: PropsFromGenericComponent<'Payment'>) => { - const processNext = useProcessNext(); - const { performProcess, isAnyProcessing, process } = useIsProcessing<'next' | 'reject'>(); + const { processNext } = useProcessNext(); + const hasLongLivedMutations = useHasLongLivedMutations(); + const paymentInfo = usePaymentInformation(); const { performPayment, paymentError } = usePayment(); const { title, description } = useNodeItem(node, (i) => i.textResourceBindings) ?? {}; @@ -27,6 +29,14 @@ export const PaymentComponent = ({ node }: PropsFromGenericComponent<'Payment'>) throw new Error('Cannot use PaymentComponent in a subform'); } + const { mutate: handleReject, isPending: isRejecting } = useMutation({ + mutationFn: async () => await processNext({ action: 'reject' }), + }); + + const { mutate: handleNext, isPending: isConfirming } = useMutation({ + mutationFn: async () => await processNext({ action: 'confirm' }), + }); + return (
@@ -52,9 +62,9 @@ export const PaymentComponent = ({ node }: PropsFromGenericComponent<'Payment'>) <> @@ -69,9 +79,9 @@ export const PaymentComponent = ({ node }: PropsFromGenericComponent<'Payment'>) {paymentInfo?.status === PaymentStatus.Paid && ( diff --git a/src/layout/Subform/SubformComponent.tsx b/src/layout/Subform/SubformComponent.tsx index 2c1b0896cb..c6b5692752 100644 --- a/src/layout/Subform/SubformComponent.tsx +++ b/src/layout/Subform/SubformComponent.tsx @@ -8,7 +8,6 @@ import dot from 'dot-object'; import { Button } from 'src/app-components/Button/Button'; import { Flex } from 'src/app-components/Flex/Flex'; import { Caption } from 'src/components/form/caption/Caption'; -import { useIsProcessing } from 'src/core/contexts/processingContext'; import { useDataTypeFromLayoutSet } from 'src/features/form/layout/LayoutsContext'; import { FD } from 'src/features/formData/FormDataWrite'; import { useFormDataQuery } from 'src/features/formData/useFormDataQuery'; @@ -19,6 +18,7 @@ import { useIsSubformPage, useNavigate } from 'src/features/routing/AppRoutingCo import { useAddEntryMutation, useDeleteEntryMutation } from 'src/features/subformData/useSubformMutations'; import { isSubformValidation } from 'src/features/validation'; import { useComponentValidationsForNode } from 'src/features/validation/selectors/componentValidationsForNode'; +import { useHasLongLivedMutations } from 'src/hooks/useHasLongLivedMutations'; import { ComponentStructureWrapper } from 'src/layout/ComponentStructureWrapper'; import classes from 'src/layout/Subform/SubformComponent.module.css'; import { useNodeItem } from 'src/utils/layout/useNodeItem'; @@ -51,27 +51,25 @@ export function SubformComponent({ node }: PropsFromGenericComponent<'Subform'>) } const { langAsString } = useLanguage(); - const addEntryMutation = useAddEntryMutation(dataType); + const { mutateAsync: addEntry, isPending: isAdding } = useAddEntryMutation(dataType); const dataElements = useStrictDataElements(dataType); const navigate = useNavigate(); const lock = FD.useLocking(id); - const { performProcess, isAnyProcessing: isAddingDisabled, isThisProcessing: isAdding } = useIsProcessing(); const [subformEntries, updateSubformEntries] = useState(dataElements); + const isAddingDisabled = useHasLongLivedMutations(); const subformIdsWithError = useComponentValidationsForNode(node).find(isSubformValidation)?.subformDataElementIds; - - const addEntry = () => - performProcess(async () => { - const currentLock = await lock(); - try { - const result = await addEntryMutation.mutateAsync({}); - navigate(`${node.id}/${result.id}`); - } catch { - // NOTE: Handled by useAddEntryMutation - } finally { - currentLock.unlock(); - } - }); + async function handleAddEntry() { + const currentLock = await lock(); + try { + const result = await addEntry({}); + navigate(`${node.id}/${result.id}`); + } catch { + // NOTE: Handled by useAddEntryMutation + } finally { + currentLock.unlock(); + } + } return ( @@ -150,11 +148,11 @@ export function SubformComponent({ node }: PropsFromGenericComponent<'Subform'>) size='md' disabled={isAddingDisabled} isLoading={isAdding} - onClick={async () => await addEntry()} + onClick={handleAddEntry} onKeyUp={async (event: React.KeyboardEvent) => { const allowedKeys = ['enter', ' ', 'spacebar']; if (allowedKeys.includes(event.key.toLowerCase())) { - await addEntry(); + handleAddEntry(); } }} variant='secondary' diff --git a/src/layout/Subform/SubformWrapper.tsx b/src/layout/Subform/SubformWrapper.tsx index f656796df6..22bc7e2011 100644 --- a/src/layout/Subform/SubformWrapper.tsx +++ b/src/layout/Subform/SubformWrapper.tsx @@ -7,8 +7,8 @@ import { useTaskStore } from 'src/core/contexts/taskStoreContext'; import { Loader } from 'src/core/loading/Loader'; import { FormProvider } from 'src/features/form/FormContext'; import { useDataTypeFromLayoutSet } from 'src/features/form/layout/LayoutsContext'; +import { useNavigateToPage } from 'src/features/navigation/useNavigatePage'; import { useNavigationParam } from 'src/features/routing/AppRoutingContext'; -import { useNavigatePage } from 'src/hooks/useNavigatePage'; import { ProcessTaskType } from 'src/types'; import { useNodeItem } from 'src/utils/layout/useNodeItem'; import type { LayoutNode } from 'src/utils/layout/LayoutNode'; @@ -33,10 +33,10 @@ export function SubformForm() { export const RedirectBackToMainForm = () => { const mainPageKey = useNavigationParam('mainPageKey'); - const { navigateToPage } = useNavigatePage(); + const { mutate: navigateToPage } = useNavigateToPage(); useEffect(() => { - navigateToPage(mainPageKey); + navigateToPage({ page: mainPageKey }); }, [navigateToPage, mainPageKey]); return ; diff --git a/src/layout/Summary2/CommonSummaryComponents/EditButton.tsx b/src/layout/Summary2/CommonSummaryComponents/EditButton.tsx index 214c5e8f93..2376349f3d 100644 --- a/src/layout/Summary2/CommonSummaryComponents/EditButton.tsx +++ b/src/layout/Summary2/CommonSummaryComponents/EditButton.tsx @@ -8,9 +8,9 @@ import { useNavigateToNode } from 'src/features/form/layout/NavigateToNode'; import { useSetReturnToView, useSetSummaryNodeOfOrigin } from 'src/features/form/layout/PageNavigationContext'; import { Lang } from 'src/features/language/Lang'; import { useLanguage } from 'src/features/language/useLanguage'; +import { useCurrentView } from 'src/features/navigation/useNavigatePage'; import { usePdfModeActive } from 'src/features/pdf/PDFWrapper'; import { useIsMobile } from 'src/hooks/useDeviceWidths'; -import { useCurrentView } from 'src/hooks/useNavigatePage'; import { useNodeItem } from 'src/utils/layout/useNodeItem'; import type { NavigationResult } from 'src/features/form/layout/NavigateToNode'; import type { LayoutNode } from 'src/utils/layout/LayoutNode'; diff --git a/src/layout/Summary2/SummaryComponent2/LayoutSetSummary.tsx b/src/layout/Summary2/SummaryComponent2/LayoutSetSummary.tsx index fa2ac40ad0..1e84a2df19 100644 --- a/src/layout/Summary2/SummaryComponent2/LayoutSetSummary.tsx +++ b/src/layout/Summary2/SummaryComponent2/LayoutSetSummary.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { usePageOrder } from 'src/hooks/useNavigatePage'; +import { usePageOrder } from 'src/features/navigation/useNavigatePage'; import { LayoutSetSummaryAccordion } from 'src/layout/Summary2/CommonSummaryComponents/LayoutSetSummaryAccordion'; import { PageSummary } from 'src/layout/Summary2/SummaryComponent2/PageSummary'; import { useSummary2Store } from 'src/layout/Summary2/summaryStoreContext';