Skip to content

Commit 31dc201

Browse files
authored
feat: instance contextual layout fetching (#3818)
1 parent 41959ab commit 31dc201

File tree

6 files changed

+30
-2
lines changed

6 files changed

+30
-2
lines changed

src/features/applicationMetadata/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,5 @@ export interface IPartyTypesAllowed {
5252

5353
export interface IBackendFeaturesState {
5454
jsonObjectInDataResponse: boolean; // Extended attachment validation
55+
addInstanceIdentifierToLayoutRequests: boolean; // Add instance identifier to layout requests
5556
}

src/features/form/layout/LayoutsContext.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ import { useAppQueries } from 'src/core/contexts/AppQueriesProvider';
66
import { ContextNotProvided } from 'src/core/contexts/context';
77
import { delayedContext } from 'src/core/contexts/delayedContext';
88
import { createQueryContext } from 'src/core/contexts/queryContext';
9+
import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider';
910
import { useCurrentDataModelName } from 'src/features/datamodel/useBindingSchema';
1011
import { cleanLayout } from 'src/features/form/layout/cleanLayout';
1112
import { makeLayoutLookups } from 'src/features/form/layout/makeLayoutLookups';
1213
import { applyLayoutQuirks } from 'src/features/form/layout/quirks';
1314
import { useLayoutSets } from 'src/features/form/layoutSets/LayoutSetsProvider';
1415
import { useLayoutSetIdFromUrl } from 'src/features/form/layoutSets/useCurrentLayoutSet';
15-
import { useInstanceDataQuery } from 'src/features/instance/InstanceContext';
16+
import { useInstanceDataQuery, useLaxInstanceId } from 'src/features/instance/InstanceContext';
1617
import { useProcessQuery } from 'src/features/instance/useProcessQuery';
1718
import { makeLikertChildId } from 'src/layout/Likert/Generator/makeLikertChildId';
19+
import { fetchLayoutsForInstance } from 'src/queries/queries';
1820
import type { QueryDefinition } from 'src/core/queries/usePrefetchQuery';
1921
import type { CompExternal, ILayoutCollection, ILayouts } from 'src/layout/layout';
2022
import type { IExpandedWidthLayouts, IHiddenLayoutsExternal } from 'src/types';
@@ -32,10 +34,20 @@ export function useLayoutQueryDef(
3234
layoutSetId?: string,
3335
): QueryDefinition<LayoutContextValue> {
3436
const { fetchLayouts } = useAppQueries();
37+
const instanceId = useLaxInstanceId();
38+
const features = useApplicationMetadata().features ?? {};
39+
3540
return {
3641
queryKey: ['formLayouts', layoutSetId, enabled],
3742
queryFn: layoutSetId
38-
? () => fetchLayouts(layoutSetId).then((layouts) => processLayouts(layouts, layoutSetId, defaultDataModelType))
43+
? async () => {
44+
const shouldUseInstanceEndpoint = features.addInstanceIdentifierToLayoutRequests && instanceId;
45+
const layouts = shouldUseInstanceEndpoint
46+
? await fetchLayoutsForInstance(layoutSetId, instanceId)
47+
: await fetchLayouts(layoutSetId);
48+
49+
return processLayouts(layouts, layoutSetId, defaultDataModelType);
50+
}
3951
: skipToken,
4052
enabled: enabled && !!layoutSetId,
4153
};

src/queries/queries.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
getFileUploadUrl,
2828
getFileUploadUrlOld,
2929
getFooterLayoutUrl,
30+
getInstanceLayoutsUrl,
3031
getInstantiateUrl,
3132
getJsonSchemaUrl,
3233
getLayoutSetsUrl,
@@ -292,6 +293,9 @@ export const fetchLayoutSets = (): Promise<ILayoutSets> => httpGet(getLayoutSets
292293

293294
export const fetchLayouts = (layoutSetId: string): Promise<ILayoutCollection> => httpGet(getLayoutsUrl(layoutSetId));
294295

296+
export const fetchLayoutsForInstance = (layoutSetId: string, instanceId: string): Promise<ILayoutCollection> =>
297+
httpGet(getInstanceLayoutsUrl(layoutSetId, instanceId));
298+
295299
export const fetchLayoutSettings = (layoutSetId: string): Promise<ILayoutSettings> =>
296300
httpGet(getLayoutSettingsUrl(layoutSetId));
297301

src/test/renderWithProviders.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ const defaultQueryMocks: AppQueries = {
152152
fetchPostPlace: async () => ({ valid: true, result: 'OSLO' }),
153153
fetchLayoutSettings: async () => ({ pages: { order: [] } }),
154154
fetchLayouts: () => Promise.reject(new Error('fetchLayouts not mocked')),
155+
fetchLayoutsForInstance: () => Promise.reject(new Error('fetchLayoutsForInstance not mocked')),
155156
fetchBackendValidations: async () => [],
156157
fetchBackendValidationsForDataElement: async () => [],
157158
fetchPaymentInformation: async () => paymentResponsePayload,

src/utils/urls/appUrlHelper.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
getEnvironmentLoginUrl,
66
getFetchFormDynamicsUrl,
77
getHostname,
8+
getInstanceLayoutsUrl,
89
getInstantiateUrl,
910
getLayoutSettingsUrl,
1011
getLayoutsUrl,
@@ -379,6 +380,13 @@ describe('Frontend urlHelper.ts', () => {
379380
});
380381
});
381382

383+
describe('getInstanceLayoutsUrl', () => {
384+
it('should include instance ID in layout URL when provided', () => {
385+
const result = getInstanceLayoutsUrl('custom-layout.json', 'instanceId-1234');
386+
expect(result).toBe('https://local.altinn.cloud/ttd/test/instances/instanceId-1234/layouts/custom-layout.json');
387+
});
388+
});
389+
382390
describe('getLayoutSettingsUrl', () => {
383391
it('should return layout as passed argument', () => {
384392
const result = getLayoutSettingsUrl('custom-layout.json');

src/utils/urls/appUrlHelper.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ export const getLayoutSetsUrl = () => `${appPath}/api/layoutsets`;
186186
export const getFooterLayoutUrl = () => `${appPath}/api/v1/footer`;
187187
export const getFetchFormDynamicsUrl = (layoutSetId: string) => `${appPath}/api/ruleconfiguration/${layoutSetId}`;
188188
export const getLayoutsUrl = (layoutSetId: string) => `${appPath}/api/layouts/${layoutSetId}`;
189+
export const getInstanceLayoutsUrl = (layoutSetId: string, instanceId: string) =>
190+
`${appPath}/instances/${instanceId}/layouts/${layoutSetId}`;
189191
export const getRulehandlerUrl = (layoutSet: string) => `${appPath}/api/rulehandler/${layoutSet}`;
190192
export const getActiveInstancesUrl = (partyId: number) => `${appPath}/instances/${partyId}/active`;
191193
export const getInstanceUiUrl = (instanceId: string) => `${appPath}#/instance/${instanceId}`;

0 commit comments

Comments
 (0)