diff --git a/src/core/contexts/TaskOverrides.tsx b/src/core/contexts/TaskOverrides.tsx new file mode 100644 index 0000000000..8af2ed08f4 --- /dev/null +++ b/src/core/contexts/TaskOverrides.tsx @@ -0,0 +1,32 @@ +import React, { createContext, useContext } from 'react'; +import type { PropsWithChildren } from 'react'; + +interface TaskOverridesContext { + taskId?: string; + dataModelType?: string; + dataModelElementId?: string; + layoutSetId?: string; +} + +const Context = createContext({}); +Context.displayName = 'TaskOverridesContext'; + +type Props = PropsWithChildren & TaskOverridesContext; +export function TaskOverrides({ children, ...overrides }: Props) { + const parentContext = useContext(Context); + + return ( + + {children} + + ); +} + +export const useTaskOverrides = () => useContext(Context); diff --git a/src/core/contexts/taskStoreContext.tsx b/src/core/contexts/taskStoreContext.tsx deleted file mode 100644 index ceb9c6eb07..0000000000 --- a/src/core/contexts/taskStoreContext.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React, { createContext, useContext, useState } from 'react'; - -type TaskState = { - overriddenTaskId?: string; - overriddenDataModelType?: string; - overriddenDataElementId?: string; - overriddenLayoutSetId?: string; - depth?: number; -}; - -type TaskActions = { - setOverriddenLayoutSetId: (layoutSetId: string) => void; - setOverriddenDataModelType: (dataModelType: string) => void; - setOverriddenDataModelDataElementId: (dataElementId: string) => void; - setTaskId: (taskId: string) => void; - setDepth: (depth: number) => void; - clearTaskId: () => void; -}; - -const TaskContext = createContext<(TaskState & TaskActions) | null>(null); - -export function TaskStoreProvider({ children }: React.PropsWithChildren) { - const [state, setState] = useState({ - overriddenTaskId: undefined, - overriddenDataModelType: undefined, - overriddenDataElementId: undefined, - overriddenLayoutSetId: undefined, - depth: 1, - }); - - const actions: TaskActions = { - setTaskId: (overriddenTaskId: string) => setState((s) => ({ ...s, overriddenTaskId })), - setOverriddenLayoutSetId: (overriddenLayoutSetId: string) => setState((s) => ({ ...s, overriddenLayoutSetId })), - setOverriddenDataModelType: (overriddenDataModelType: string) => - setState((s) => ({ ...s, overriddenDataModelType })), - setOverriddenDataModelDataElementId: (overriddenDataElementId: string) => - setState((s) => ({ ...s, overriddenDataElementId })), - clearTaskId: () => setState((s) => ({ ...s, overriddenTaskId: '' })), - setDepth: (depth: number) => setState((s) => ({ ...s, depth })), - }; - - return {children}; -} - -export const useTaskStore = (selector: (state: TaskState & TaskActions) => T) => { - const context = useContext(TaskContext); - if (!context) { - throw new Error('useTaskStore must be used within TaskStoreProvider'); - } - return selector(context); -}; diff --git a/src/features/attachments/StoreAttachmentsInNode.tsx b/src/features/attachments/StoreAttachmentsInNode.tsx index 1857cbe9e6..85abbb4c60 100644 --- a/src/features/attachments/StoreAttachmentsInNode.tsx +++ b/src/features/attachments/StoreAttachmentsInNode.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from 'react'; import deepEqual from 'fast-deep-equal'; -import { useTaskStore } from 'src/core/contexts/taskStoreContext'; +import { useTaskOverrides } from 'src/core/contexts/TaskOverrides'; import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider'; import { isAttachmentUploaded } from 'src/features/attachments/index'; import { DEFAULT_DEBOUNCE_TIMEOUT } from 'src/features/formData/types'; @@ -89,15 +89,14 @@ function useNodeAttachments(): AttachmentRecord { const { indexedId, baseId } = parent; const nodeData = useFormDataFor(baseId) as IComponentFormData>; - const overriddenTaskId = useTaskStore((state) => state.overriddenTaskId); + const overriddenTaskId = useTaskOverrides()?.taskId; const application = useApplicationMetadata(); const currentTask = useProcessQuery().data?.currentTask?.elementId; const data = useInstanceDataElements(baseId); const mappedAttachments = useMemoDeepEqual(() => { - const taskId = overriddenTaskId ? overriddenTaskId : currentTask; - + const taskId = overriddenTaskId ?? currentTask; return mapAttachments(indexedId, baseId, data, application, taskId, nodeData); }, [indexedId, baseId, data, application, currentTask, nodeData, overriddenTaskId]); diff --git a/src/features/datamodel/DataModelsProvider.tsx b/src/features/datamodel/DataModelsProvider.tsx index 09e134e6cf..01aab4d887 100644 --- a/src/features/datamodel/DataModelsProvider.tsx +++ b/src/features/datamodel/DataModelsProvider.tsx @@ -6,7 +6,7 @@ import deepEqual from 'fast-deep-equal'; import { createStore } from 'zustand'; import type { JSONSchema7 } from 'json-schema'; -import { useTaskStore } from 'src/core/contexts/taskStoreContext'; +import { useTaskOverrides } from 'src/core/contexts/TaskOverrides'; import { createZustandContext } from 'src/core/contexts/zustandContext'; import { DisplayError } from 'src/core/errorHandling/DisplayError'; import { Loader } from 'src/core/loading/Loader'; @@ -170,8 +170,9 @@ function DataModelsLoader() { const layoutSetId = useCurrentLayoutSetId(); // Subform - const overriddenDataElementId = useTaskStore((state) => state.overriddenDataElementId); - const overriddenDataType = useTaskStore((state) => state.overriddenDataModelType); + const overrides = useTaskOverrides(); + const overriddenDataElementId = overrides?.dataModelElementId; + const overriddenDataType = overrides?.dataModelType; // Find all data types referenced in dataModelBindings in the layout useEffect(() => { diff --git a/src/features/datamodel/useBindingSchema.tsx b/src/features/datamodel/useBindingSchema.tsx index 9ae752f133..0fb64249e2 100644 --- a/src/features/datamodel/useBindingSchema.tsx +++ b/src/features/datamodel/useBindingSchema.tsx @@ -2,7 +2,7 @@ import { useCallback, useMemo } from 'react'; import type { JSONSchema7 } from 'json-schema'; -import { useTaskStore } from 'src/core/contexts/taskStoreContext'; +import { useTaskOverrides } from 'src/core/contexts/TaskOverrides'; import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider'; import { getCurrentDataTypeForApplication, @@ -34,7 +34,7 @@ export function useCurrentDataModelDataElementId() { const layoutSets = useLayoutSets(); const taskId = useProcessTaskId(); - const overriddenDataElementId = useTaskStore((s) => s.overriddenDataElementId); + const overriddenDataElementId = useTaskOverrides()?.dataModelElementId; // Instance data elements will update often (after each save), so we have to use a selector to make // sure components don't re-render too often. @@ -130,7 +130,7 @@ export function useDataModelUrl({ dataType, dataElementId, language, prefillFrom } export function useCurrentDataModelName() { - const overriddenDataModelType = useTaskStore((state) => state.overriddenDataModelType); + const overriddenDataModelType = useTaskOverrides()?.dataModelType; const application = useApplicationMetadata(); const layoutSets = useLayoutSets(); diff --git a/src/features/devtools/components/LayoutInspector/LayoutInspector.tsx b/src/features/devtools/components/LayoutInspector/LayoutInspector.tsx index f2334d1910..a44c6ec894 100644 --- a/src/features/devtools/components/LayoutInspector/LayoutInspector.tsx +++ b/src/features/devtools/components/LayoutInspector/LayoutInspector.tsx @@ -10,7 +10,8 @@ import { LayoutInspectorItem } from 'src/features/devtools/components/LayoutInsp import { SplitView } from 'src/features/devtools/components/SplitView/SplitView'; import { useDevToolsStore } from 'src/features/devtools/data/DevToolsStore'; import { useLayoutValidationForPage } from 'src/features/devtools/layoutValidation/useLayoutValidation'; -import { useLayouts, useLayoutSetId } from 'src/features/form/layout/LayoutsContext'; +import { useLayouts } from 'src/features/form/layout/LayoutsContext'; +import { useLayoutSetIdFromUrl } from 'src/features/form/layoutSets/useCurrentLayoutSet'; import { useCurrentView } from 'src/hooks/useNavigatePage'; import { parseAndCleanText } from 'src/language/sharedLanguage'; import type { LayoutContextValue } from 'src/features/form/layout/LayoutsContext'; @@ -20,7 +21,7 @@ export const LayoutInspector = () => { const setSelectedComponent = useDevToolsStore((state) => state.actions.layoutInspectorSet); const currentView = useCurrentView(); const layouts = useLayouts(); - const currentLayoutSetId = useLayoutSetId(); + const currentLayoutSetId = useLayoutSetIdFromUrl(); const [componentProperties, setComponentProperties] = useState(null); const [propertiesHaveChanged, setPropertiesHaveChanged] = useState(false); const [error, setError] = useState(false); diff --git a/src/features/form/layout/LayoutsContext.tsx b/src/features/form/layout/LayoutsContext.tsx index a590aaa5fd..5af44595dd 100644 --- a/src/features/form/layout/LayoutsContext.tsx +++ b/src/features/form/layout/LayoutsContext.tsx @@ -6,16 +6,14 @@ import { useAppQueries } from 'src/core/contexts/AppQueriesProvider'; import { ContextNotProvided } from 'src/core/contexts/context'; import { delayedContext } from 'src/core/contexts/delayedContext'; import { createQueryContext } from 'src/core/contexts/queryContext'; -import { useTaskStore } from 'src/core/contexts/taskStoreContext'; import { useCurrentDataModelName } from 'src/features/datamodel/useBindingSchema'; import { cleanLayout } from 'src/features/form/layout/cleanLayout'; import { makeLayoutLookups } from 'src/features/form/layout/makeLayoutLookups'; import { applyLayoutQuirks } from 'src/features/form/layout/quirks'; import { useLayoutSets } from 'src/features/form/layoutSets/LayoutSetsProvider'; -import { useCurrentLayoutSetId } from 'src/features/form/layoutSets/useCurrentLayoutSet'; +import { useLayoutSetIdFromUrl } from 'src/features/form/layoutSets/useCurrentLayoutSet'; import { useInstanceDataQuery } from 'src/features/instance/InstanceContext'; import { useProcessQuery } from 'src/features/instance/useProcessQuery'; -import { useNavigationParam } from 'src/hooks/navigation'; import { makeLikertChildId } from 'src/layout/Likert/Generator/makeLikertChildId'; import type { QueryDefinition } from 'src/core/queries/usePrefetchQuery'; import type { CompExternal, ILayoutCollection, ILayouts } from 'src/layout/layout'; @@ -45,7 +43,7 @@ export function useLayoutQueryDef( function useLayoutQuery() { const { data: process } = useProcessQuery(); - const currentLayoutSetId = useLayoutSetId(); + const currentLayoutSetId = useLayoutSetIdFromUrl(); const defaultDataModel = useCurrentDataModelName() ?? 'unknown'; const hasInstance = !!useInstanceDataQuery().data; @@ -78,30 +76,6 @@ const { Provider, useCtx, useLaxCtx } = delayedContext(() => }), ); -export function useLayoutSetId() { - const layoutSets = useLayoutSets(); - const currentProcessLayoutSetId = useCurrentLayoutSetId(); - const taskId = useNavigationParam('taskId'); - - const overriddenLayoutSetId = useTaskStore((state) => state.overriddenLayoutSetId); - - if (overriddenLayoutSetId) { - return overriddenLayoutSetId; - } - - const layoutSetId = - taskId != null - ? layoutSets.find((set) => { - if (set.tasks?.length) { - return set.tasks.includes(taskId); - } - return false; - })?.id - : undefined; - - return layoutSetId ?? currentProcessLayoutSetId; -} - export function useDataTypeFromLayoutSet(layoutSetName: string | undefined) { const layoutSets = useLayoutSets(); return layoutSets.find((set) => set.id === layoutSetName)?.dataType; diff --git a/src/features/form/layoutSets/useCurrentLayoutSet.ts b/src/features/form/layoutSets/useCurrentLayoutSet.ts index 7da7aff85d..7b26a21302 100644 --- a/src/features/form/layoutSets/useCurrentLayoutSet.ts +++ b/src/features/form/layoutSets/useCurrentLayoutSet.ts @@ -1,19 +1,31 @@ import { ContextNotProvided } from 'src/core/contexts/context'; -import { useTaskStore } from 'src/core/contexts/taskStoreContext'; +import { useTaskOverrides } from 'src/core/contexts/TaskOverrides'; import { useLaxApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider'; import { getCurrentLayoutSet } from 'src/features/applicationMetadata/appMetadataUtils'; import { useLaxLayoutSets } from 'src/features/form/layoutSets/LayoutSetsProvider'; import { useProcessTaskId } from 'src/features/instance/useProcessTaskId'; +import { useNavigationParam } from 'src/hooks/navigation'; -export function useCurrentLayoutSetId() { - return useCurrentLayoutSet()?.id; +/** + * This is a variant that prefers the taskId from the URL. The alternative useCurrentLayoutSetId() and + * useCurrentLayoutSet() will prefer the taskId from the current process state (i.e., where the process is right now, + * not necessarily what the user is looking at right now). + */ +export function useLayoutSetIdFromUrl() { + const taskId = useNavigationParam('taskId'); + return useCurrentLayoutSetId(taskId); } -export function useCurrentLayoutSet() { +export function useCurrentLayoutSetId(taskId?: string) { + return useCurrentLayoutSet(taskId)?.id; +} + +export function useCurrentLayoutSet(_taskId?: string) { const application = useLaxApplicationMetadata(); const layoutSets = useLaxLayoutSets(); - const taskId = useProcessTaskId(); - const overriddenLayoutSetId = useTaskStore((state) => state.overriddenLayoutSetId); + const processTaskId = useProcessTaskId(); + const taskId = _taskId ?? processTaskId; + const overriddenLayoutSetId = useTaskOverrides()?.layoutSetId; if (application === ContextNotProvided || layoutSets === ContextNotProvided) { return undefined; diff --git a/src/features/form/layoutSettings/LayoutSettingsContext.tsx b/src/features/form/layoutSettings/LayoutSettingsContext.tsx index 01ea3ebc18..3241600abe 100644 --- a/src/features/form/layoutSettings/LayoutSettingsContext.tsx +++ b/src/features/form/layoutSettings/LayoutSettingsContext.tsx @@ -7,8 +7,8 @@ import { useAppQueries } from 'src/core/contexts/AppQueriesProvider'; import { ContextNotProvided } from 'src/core/contexts/context'; import { delayedContext } from 'src/core/contexts/delayedContext'; import { createQueryContext } from 'src/core/contexts/queryContext'; -import { useLayoutSetId } from 'src/features/form/layout/LayoutsContext'; import { useLaxGlobalUISettings } from 'src/features/form/layoutSets/LayoutSetsProvider'; +import { useLayoutSetIdFromUrl } from 'src/features/form/layoutSets/useCurrentLayoutSet'; import { useShallowMemo } from 'src/hooks/useShallowMemo'; import type { QueryDefinition } from 'src/core/queries/usePrefetchQuery'; import type { GlobalPageSettings, ILayoutSettings, NavigationPageGroup } from 'src/layout/common.generated'; @@ -23,7 +23,7 @@ export function useLayoutSettingsQueryDef(layoutSetId?: string): QueryDefinition } function useLayoutSettingsQuery() { - const layoutSetId = useLayoutSetId(); + const layoutSetId = useLayoutSetIdFromUrl(); const query = useQuery(useLayoutSettingsQueryDef(layoutSetId)); useEffect(() => { diff --git a/src/features/instance/useProcessTaskId.ts b/src/features/instance/useProcessTaskId.ts index 188d71d2a0..7da47a19c3 100644 --- a/src/features/instance/useProcessTaskId.ts +++ b/src/features/instance/useProcessTaskId.ts @@ -1,9 +1,9 @@ -import { useTaskStore } from 'src/core/contexts/taskStoreContext'; +import { useTaskOverrides } from 'src/core/contexts/TaskOverrides'; import { useProcessQuery } from 'src/features/instance/useProcessQuery'; import { useNavigationParam } from 'src/hooks/navigation'; export function useProcessTaskId() { - const overriddenTaskId = useTaskStore((state) => state.overriddenTaskId); + const overriddenTaskId = useTaskOverrides()?.taskId; const processTaskId = useProcessQuery().data?.currentTask?.elementId; const urlTaskId = useNavigationParam('taskId'); return overriddenTaskId ?? processTaskId ?? urlTaskId; diff --git a/src/features/instantiate/containers/InstantiationContainer.tsx b/src/features/instantiate/containers/InstantiationContainer.tsx index 90fcb8a06b..e2e763df4b 100644 --- a/src/features/instantiate/containers/InstantiationContainer.tsx +++ b/src/features/instantiate/containers/InstantiationContainer.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { ReadyForPrint } from 'src/components/ReadyForPrint'; -import { TaskStoreProvider } from 'src/core/contexts/taskStoreContext'; import { RenderStart } from 'src/core/ui/RenderStart'; import { Footer } from 'src/features/footer/Footer'; import classes from 'src/features/instantiate/containers/InstantiationContainer.module.css'; @@ -19,15 +18,13 @@ export function InstantiationContainer({ children }: IInstantiateContainerProps) const profile = useProfile(); return ( - - -
- -
{children}
-
- -
-
-
+ +
+ +
{children}
+
+ +
+
); } diff --git a/src/features/instantiate/selection/InstanceSelection.tsx b/src/features/instantiate/selection/InstanceSelection.tsx index 572d52e90e..f6392c1677 100644 --- a/src/features/instantiate/selection/InstanceSelection.tsx +++ b/src/features/instantiate/selection/InstanceSelection.tsx @@ -10,7 +10,6 @@ import { ErrorListFromInstantiation, ErrorReport } from 'src/components/message/ import { PresentationComponent } from 'src/components/presentation/Presentation'; import { ReadyForPrint } from 'src/components/ReadyForPrint'; import { useIsProcessing } from 'src/core/contexts/processingContext'; -import { TaskStoreProvider } from 'src/core/contexts/taskStoreContext'; import { useAppName, useAppOwner } from 'src/core/texts/appTexts'; import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider'; import { @@ -44,16 +43,14 @@ function getDateDisplayString(timeStamp: string) { } export const InstanceSelectionWrapper = () => ( - - - - - - - + + + + + ); function InstanceSelection() { @@ -237,7 +234,7 @@ function InstanceSelection() { ); return ( - + <> {`${getPageTitle(appName, langAsString('instance_selection.left_of'), appOwner)}`}
@@ -289,7 +286,7 @@ function InstanceSelection() {
-
+ ); } diff --git a/src/index.tsx b/src/index.tsx index 85c330901c..b9b3930c83 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -22,7 +22,6 @@ import { ViewportWrapper } from 'src/components/ViewportWrapper'; import { KeepAliveProvider } from 'src/core/auth/KeepAliveProvider'; import { AppQueriesProvider } from 'src/core/contexts/AppQueriesProvider'; import { ProcessingProvider } from 'src/core/contexts/processingContext'; -import { TaskStoreProvider } from 'src/core/contexts/taskStoreContext'; import { DisplayErrorProvider } from 'src/core/errorHandling/DisplayErrorProvider'; import { ApplicationMetadataProvider } from 'src/features/applicationMetadata/ApplicationMetadataProvider'; import { ApplicationSettingsProvider } from 'src/features/applicationSettings/ApplicationSettingsProvider'; @@ -93,41 +92,37 @@ function Root() { return ( <> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + ); } diff --git a/src/layout/FileUpload/FileUploadTable/FileTableRow.tsx b/src/layout/FileUpload/FileUploadTable/FileTableRow.tsx index b93837e4d4..5abf1109d8 100644 --- a/src/layout/FileUpload/FileUploadTable/FileTableRow.tsx +++ b/src/layout/FileUpload/FileUploadTable/FileTableRow.tsx @@ -3,7 +3,7 @@ import React from 'react'; import classNames from 'classnames'; import { AltinnLoader } from 'src/components/AltinnLoader'; -import { useTaskStore } from 'src/core/contexts/taskStoreContext'; +import { useTaskOverrides } from 'src/core/contexts/TaskOverrides'; import { isAttachmentUploaded } from 'src/features/attachments'; import { FileScanResults } from 'src/features/attachments/types'; import { Lang } from 'src/features/language/Lang'; @@ -40,9 +40,7 @@ export function FileTableRow({ const pdfModeActive = usePdfModeActive(); const readableSize = getSizeWithUnit(attachment.data.size, 2); - const overriddenTaskId = useTaskStore((state) => state.overriddenTaskId); - - const hasOverridenTaskId = !!overriddenTaskId; + const hasOverriddenTaskId = Boolean(useTaskOverrides()?.taskId); const uniqueId = isAttachmentUploaded(attachment) ? attachment.data.id : attachment.data.temporaryId; @@ -78,7 +76,7 @@ export function FileTableRow({ className={rowStyle} id={`altinn-file-list-row-${uniqueId}`} tabIndex={0} - style={hasOverridenTaskId ? { padding: '8px 0' } : {}} + style={hasOverriddenTaskId ? { padding: '8px 0' } : {}} > ) { - const isDone = useDoOverride(baseComponentId); - - if (!isDone) { - return ; - } - - return {children}; + return ( + + {children} + + ); } export function SubformForm() { @@ -44,35 +42,14 @@ export const RedirectBackToMainForm = () => { return ; }; -export const useDoOverrideSummary = (dataElementId: string, layoutSet: string, dataType: string) => { - const setOverriddenLayoutSetId = useTaskStore((state) => state.setOverriddenLayoutSetId); - const setOverriddenDataModelType = useTaskStore((state) => state.setOverriddenDataModelType); - const setOverriddenDataModelDataElementId = useTaskStore((state) => state.setOverriddenDataModelDataElementId); - - const isDone = useTaskStore( - (s) => - s.overriddenDataModelType === dataType && - s.overriddenDataElementId === dataElementId && - s.overriddenLayoutSetId === layoutSet, - ); - - useEffect(() => { - setOverriddenLayoutSetId?.(layoutSet); - setOverriddenDataModelType?.(dataType); - setOverriddenDataModelDataElementId?.(dataElementId!); - }, [ - dataElementId, - dataType, - layoutSet, - setOverriddenDataModelType, - setOverriddenDataModelDataElementId, - setOverriddenLayoutSetId, - ]); - - return isDone; -}; - -export const useDoOverride = (baseComponentId: string, providedDataElementId?: string) => { +export function SubformOverrideWrapper({ + baseComponentId, + providedDataElementId, + children, +}: PropsWithChildren<{ + baseComponentId: string; + providedDataElementId?: string; +}>) { const dataElementId = useNavigationParam('dataElementId'); const actualDataElementId = providedDataElementId ? providedDataElementId : dataElementId; const { layoutSet, id } = useItemWhenType(baseComponentId, 'Subform'); @@ -82,28 +59,13 @@ export const useDoOverride = (baseComponentId: string, providedDataElementId?: s throw new Error(`Unable to find data type for subform with id ${id}`); } - const setOverriddenLayoutSetId = useTaskStore((state) => state.setOverriddenLayoutSetId); - const setOverriddenDataModelType = useTaskStore((state) => state.setOverriddenDataModelType); - const setOverriddenDataModelDataElementId = useTaskStore((state) => state.setOverriddenDataModelDataElementId); - const isDone = useTaskStore( - (s) => - s.overriddenDataModelType === dataType && - s.overriddenDataElementId === actualDataElementId && - s.overriddenLayoutSetId === layoutSet, + return ( + + {children} + ); - - useEffect(() => { - setOverriddenLayoutSetId?.(layoutSet); - setOverriddenDataModelType?.(dataType); - setOverriddenDataModelDataElementId?.(actualDataElementId!); - }, [ - actualDataElementId, - dataType, - layoutSet, - setOverriddenDataModelType, - setOverriddenDataModelDataElementId, - setOverriddenLayoutSetId, - ]); - - return isDone; -}; +} diff --git a/src/layout/Subform/Summary/SubformSummaryComponent2.tsx b/src/layout/Subform/Summary/SubformSummaryComponent2.tsx index 3e7d925096..bd275934fc 100644 --- a/src/layout/Subform/Summary/SubformSummaryComponent2.tsx +++ b/src/layout/Subform/Summary/SubformSummaryComponent2.tsx @@ -1,16 +1,15 @@ -import React, { type PropsWithChildren } from 'react'; +import React, { Fragment, type PropsWithChildren } from 'react'; import { Heading, Paragraph } from '@digdir/designsystemet-react'; import { Flex } from 'src/app-components/Flex/Flex'; import { Label, LabelInner } from 'src/components/label/Label'; -import { TaskStoreProvider } from 'src/core/contexts/taskStoreContext'; +import { TaskOverrides } from 'src/core/contexts/TaskOverrides'; import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider'; import { FormProvider } from 'src/features/form/FormContext'; import { useDataTypeFromLayoutSet, useLayoutLookups } from 'src/features/form/layout/LayoutsContext'; import { useInstanceDataElements } from 'src/features/instance/InstanceContext'; import { Lang } from 'src/features/language/Lang'; -import { useDoOverrideSummary } from 'src/layout/Subform/SubformWrapper'; import classes from 'src/layout/Subform/Summary/SubformSummaryComponent2.module.css'; import { SubformSummaryTable } from 'src/layout/Subform/Summary/SubformSummaryTable'; import { @@ -56,7 +55,7 @@ const SummarySubformWrapperInner = ({ )} {dataElements?.map((element, idx) => ( - +
- + ))} ); @@ -88,12 +87,11 @@ const DoSummaryWrapper = ({ baseComponentId: string; }>) => { const item = useItemWhenType(baseComponentId, 'Subform'); - const isDone = useDoOverrideSummary(dataElement.id, layoutSet, dataElement.dataType); const { isSubformDataFetching, subformData, subformDataError } = useSubformFormData(dataElement.id); const subformDataSources = useExpressionDataSourcesForSubform(dataElement.dataType, subformData, entryDisplayName); - if (!isDone || isSubformDataFetching) { + if (isSubformDataFetching) { return null; } @@ -104,36 +102,42 @@ const DoSummaryWrapper = ({ return (
- - - -
- - {subformEntryName && ( - - {subformEntryName} - - )} -
+ + + + +
+ + {subformEntryName && ( + + {subformEntryName} + + )} +
+
+
- -
-
+ +
); }; diff --git a/src/layout/Subform/index.tsx b/src/layout/Subform/index.tsx index f99eafc4ee..923d1d0a24 100644 --- a/src/layout/Subform/index.tsx +++ b/src/layout/Subform/index.tsx @@ -2,7 +2,6 @@ import React, { forwardRef } from 'react'; import { Route, Routes } from 'react-router-dom'; import type { JSX, ReactNode } from 'react'; -import { TaskStoreProvider } from 'src/core/contexts/taskStoreContext'; import { type ComponentValidation } from 'src/features/validation'; import { type SummaryRendererProps } from 'src/layout/LayoutComponent'; import { SubformDef } from 'src/layout/Subform/config.def.generated'; @@ -25,22 +24,20 @@ export class Subform extends SubformDef implements ValidateComponent, SubRouting subRouting({ baseComponentId }: { baseComponentId: string }): ReactNode { return ( - - - - - - } - /> - } - /> - - + + + + + } + /> + } + /> + ); } diff --git a/src/layout/Summary2/CommonSummaryComponents/EditButton.tsx b/src/layout/Summary2/CommonSummaryComponents/EditButton.tsx index 6561eec026..5ad657f951 100644 --- a/src/layout/Summary2/CommonSummaryComponents/EditButton.tsx +++ b/src/layout/Summary2/CommonSummaryComponents/EditButton.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { PencilIcon } from '@navikt/aksel-icons'; import { Button } from 'src/app-components/Button/Button'; -import { useTaskStore } from 'src/core/contexts/taskStoreContext'; +import { useTaskOverrides } from 'src/core/contexts/TaskOverrides'; import { useSetReturnToView, useSetSummaryNodeOfOrigin } from 'src/features/form/layout/PageNavigationContext'; import { Lang } from 'src/features/language/Lang'; import { useLanguage } from 'src/features/language/useLanguage'; @@ -66,8 +66,9 @@ export function EditButton({ const titleTrb = textResourceBindings && 'title' in textResourceBindings ? textResourceBindings.title : undefined; const accessibleTitle = titleTrb ? langAsString(titleTrb) : ''; - const overriddenTaskId = useTaskStore((state) => state.overriddenTaskId); - const overriddenDataElementId = useTaskStore((state) => state.overriddenDataElementId); + const overrides = useTaskOverrides(); + const overriddenTaskId = overrides?.taskId; + const overriddenDataElementId = overrides?.dataModelElementId; const indexedId = useIndexedId(targetBaseComponentId, skipLastIdMutator); const summary2Id = useSummaryProp('id'); @@ -79,7 +80,7 @@ export function EditButton({ return null; } - if (pdfModeActive || (overriddenTaskId && overriddenTaskId?.length > 0)) { + if (pdfModeActive || overriddenTaskId?.length) { return null; } diff --git a/src/layout/Summary2/SummaryComponent2/SummaryComponent2.tsx b/src/layout/Summary2/SummaryComponent2/SummaryComponent2.tsx index 286e491227..bb66f7618c 100644 --- a/src/layout/Summary2/SummaryComponent2/SummaryComponent2.tsx +++ b/src/layout/Summary2/SummaryComponent2/SummaryComponent2.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { TaskStoreProvider } from 'src/core/contexts/taskStoreContext'; import { ComponentSummary } from 'src/layout/Summary2/SummaryComponent2/ComponentSummary'; import { LayoutSetSummary } from 'src/layout/Summary2/SummaryComponent2/LayoutSetSummary'; import { TaskSummaryWrapper } from 'src/layout/Summary2/SummaryComponent2/TaskSummaryWrapper'; @@ -29,13 +28,11 @@ function SummaryBody({ target }: SummaryBodyProps) { function SummaryComponent2Inner({ baseComponentId }: Pick, 'baseComponentId'>) { const target = useExternalItem(baseComponentId, 'Summary2').target; return ( - - - - - - - + + + + + ); } diff --git a/src/layout/Summary2/SummaryComponent2/TaskSummaryWrapper.tsx b/src/layout/Summary2/SummaryComponent2/TaskSummaryWrapper.tsx index d08db2552a..1f2b244350 100644 --- a/src/layout/Summary2/SummaryComponent2/TaskSummaryWrapper.tsx +++ b/src/layout/Summary2/SummaryComponent2/TaskSummaryWrapper.tsx @@ -1,6 +1,6 @@ -import React, { useEffect } from 'react'; +import React from 'react'; -import { useTaskStore } from 'src/core/contexts/taskStoreContext'; +import { TaskOverrides } from 'src/core/contexts/TaskOverrides'; import { FormProvider } from 'src/features/form/FormContext'; import { useLayoutSets } from 'src/features/form/layoutSets/LayoutSetsProvider'; import { useNavigationParam } from 'src/hooks/navigation'; @@ -12,43 +12,17 @@ interface TaskSummaryProps { } export function TaskSummaryWrapper({ taskId, children }: React.PropsWithChildren) { - const setTaskId = useTaskStore((state) => state.setTaskId); - const setOverriddenDataModelType = useTaskStore((state) => state.setOverriddenDataModelType); - const setOverriddenDataModelDataElementId = useTaskStore((state) => state.setOverriddenDataModelDataElementId); - const setOverriddenLayoutSetId = useTaskStore((state) => state.setOverriddenLayoutSetId); - const currentTaskId = useNavigationParam('taskId'); - const overriddenTaskId = useTaskStore((state) => state.overriddenTaskId); - const notCurrentTask = overriddenTaskId && overriddenTaskId !== currentTaskId; - const layoutSets = useLayoutSets(); - - useEffect(() => { - if (taskId) { - const layoutSetForTask = layoutSets.find((set) => set.tasks?.includes(taskId)); - setTaskId && setTaskId(taskId); - if (layoutSetForTask) { - setOverriddenDataModelType && setOverriddenDataModelType(layoutSetForTask.dataType); - setOverriddenLayoutSetId && setOverriddenLayoutSetId(layoutSetForTask.id); - } - } - }, [ - layoutSets, - setOverriddenDataModelType, - setOverriddenDataModelDataElementId, - setOverriddenLayoutSetId, - setTaskId, - taskId, - ]); - - if (taskId && overriddenTaskId !== taskId) { - // Wait for the task to be set correctly - return null; - } - - if (notCurrentTask) { - return {children}; - } - - return children; + const layoutSetForTask = taskId ? layoutSets.find((set) => set.tasks?.includes(taskId)) : undefined; + + return ( + + {taskId && taskId !== currentTaskId ? {children} : children} + + ); } diff --git a/src/queries/formPrefetcher.ts b/src/queries/formPrefetcher.ts index 49dd67f498..c46dc1055c 100644 --- a/src/queries/formPrefetcher.ts +++ b/src/queries/formPrefetcher.ts @@ -1,7 +1,8 @@ import { usePrefetchQuery } from 'src/core/queries/usePrefetchQuery'; import { useCurrentDataModelDataElementId, useCurrentDataModelName } from 'src/features/datamodel/useBindingSchema'; import { useDynamicsQueryDef } from 'src/features/form/dynamics/DynamicsContext'; -import { useLayoutQueryDef, useLayoutSetId } from 'src/features/form/layout/LayoutsContext'; +import { useLayoutQueryDef } from 'src/features/form/layout/LayoutsContext'; +import { useLayoutSetIdFromUrl } from 'src/features/form/layoutSets/useCurrentLayoutSet'; import { useLayoutSettingsQueryDef } from 'src/features/form/layoutSettings/LayoutSettingsContext'; import { useRulesQueryDef } from 'src/features/form/rules/RulesContext'; import { useLaxInstanceId } from 'src/features/instance/InstanceContext'; @@ -15,7 +16,7 @@ import { useIsPdf } from 'src/hooks/useIsPdf'; * Prefetches requests happening in the FormProvider */ export function FormPrefetcher() { - const layoutSetId = useLayoutSetId(); + const layoutSetId = useLayoutSetIdFromUrl(); const isPDF = useIsPdf(); const dataTypeId = useCurrentDataModelName() ?? 'unknown'; const instanceId = useLaxInstanceId(); diff --git a/src/test/renderWithProviders.tsx b/src/test/renderWithProviders.tsx index 7e9b3b2a57..fd3db7d6ba 100644 --- a/src/test/renderWithProviders.tsx +++ b/src/test/renderWithProviders.tsx @@ -20,7 +20,6 @@ import { getPartyMock } from 'src/__mocks__/getPartyMock'; import { paymentResponsePayload } from 'src/__mocks__/getPaymentPayloadMock'; import { getTextResourcesMock } from 'src/__mocks__/getTextResourcesMock'; import { AppQueriesProvider } from 'src/core/contexts/AppQueriesProvider'; -import { TaskStoreProvider } from 'src/core/contexts/taskStoreContext'; import { RenderStart } from 'src/core/ui/RenderStart'; import { ApplicationMetadataProvider } from 'src/features/applicationMetadata/ApplicationMetadataProvider'; import { ApplicationSettingsProvider } from 'src/features/applicationSettings/ApplicationSettingsProvider'; @@ -330,34 +329,32 @@ function DefaultProviders({ children, queries, queryClient, Router = DefaultRout queryClient={queryClient} > - - - - - - - - - - - - - - - {children} - - - - - - - - - - - - - + + + + + + + + + + + + + + {children} + + + + + + + + + + + + ); @@ -383,13 +380,11 @@ function MinimalProviders({ children, queries, queryClient, Router = DefaultRout {...queries} queryClient={queryClient} > - - - - {children} - - - + + + {children} + + ); } diff --git a/src/utils/layout/all.test.tsx b/src/utils/layout/all.test.tsx index 8c7bbf47c0..70d7c9698d 100644 --- a/src/utils/layout/all.test.tsx +++ b/src/utils/layout/all.test.tsx @@ -9,7 +9,6 @@ import type { JSONSchema7 } from 'json-schema'; import { ignoredConsoleMessages } from 'test/e2e/support/fail-on-console-log'; -import { TaskStoreProvider } from 'src/core/contexts/taskStoreContext'; import { quirks } from 'src/features/form/layout/quirks'; import { GenericComponent } from 'src/layout/GenericComponent'; import { SubformWrapper } from 'src/layout/Subform/SubformWrapper'; @@ -80,11 +79,7 @@ function RenderAllComponents() { * Makes sure we go one level deeper into the subform context when testing subforms */ function SubformTestWrapper({ baseId, children }: PropsWithChildren<{ baseId: string }>) { - return ( - - {children} - - ); + return {children}; } const windowLoggers = ['logError', 'logErrorOnce', 'logWarn', 'logWarnOnce', 'logInfo', 'logInfoOnce'];