Skip to content

Conversation

@Jondyr
Copy link
Member

@Jondyr Jondyr commented Oct 30, 2025

Description

Adds support for new feature flag addInstanceIdentifierToLayoutRequests from app-lib-dotnet#1544. If this feature is toggled on, the frontend will request layouts from a new endpoint that allows the app developer to access instance related data (allowing e.g. custom layouts for an instance).

Related Issue(s)

Verification/QA

  • Manual functionality testing
    • I have tested these changes manually
    • Creator of the original issue (or service owner) has been contacted for manual testing (or will be contacted when released in alpha)
    • No testing done/necessary
  • Automated tests
    • Unit test(s) have been added/updated
    • Cypress E2E test(s) have been added/updated
    • No automatic tests are needed here (no functional changes/additions)
    • I want someone to help me make some tests
  • UU/WCAG (follow these guidelines until we have our own)
    • I have tested with a screen reader/keyboard navigation/automated wcag validator
    • No testing done/necessary (no DOM/visual changes)
    • I want someone to help me perform accessibility testing
  • User documentation @ altinn-studio-docs
    • Has been added/updated
    • No functionality has been changed/added, so no documentation is needed
    • I will do that later/have created an issue
  • Support in Altinn Studio
    • Issue(s) created for support in Studio
    • This change/feature does not require any changes to Altinn Studio
  • Sprint board
    • The original issue (or this PR itself) has been added to the Team Apps project and to the current sprint board
    • I don't have permissions to do that, please help me out
  • Labels
    • I have added a kind/* and backport* label to this PR for proper release notes grouping
    • I don't have permissions to add labels, please help me out

Summary by CodeRabbit

  • New Features

    • Optionally include an instance identifier when requesting layouts.
    • Layout fetching can be toggled via an application feature flag to use instance-aware requests.
    • Requests now choose instance-specific or standard layout endpoints based on feature availability.
  • Tests

    • Added tests verifying instance-aware layout URL construction.
    • Test setup now requires explicit handling of instance-aware layout requests.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 30, 2025

📝 Walkthrough

Walkthrough

Adds support for instance-scoped layout requests behind a backend feature flag: extends backend feature types, adds an instance-layout URL helper and query, conditionally uses per-instance fetch in the layouts context when flagged and instanceId exists, and updates tests and test mocks.

Changes

Cohort / File(s) Summary
Type Definition
src/features/applicationMetadata/types.ts
Added addInstanceIdentifierToLayoutRequests: boolean to the IBackendFeaturesState interface.
Layout Integration
src/features/form/layout/LayoutsContext.tsx
Uses useApplicationMetadata and useLaxInstanceId; conditionally calls fetchLayoutsForInstance(layoutSetId, instanceId) when features.addInstanceIdentifierToLayoutRequests is true and instanceId exists, otherwise falls back to fetchLayouts(layoutSetId).
Query Layer
src/queries/queries.ts
Added exported fetchLayoutsForInstance(layoutSetId: string, instanceId: string): Promise<ILayoutCollection> which uses the new instance-specific URL helper. Existing fetchLayouts left unchanged.
URL Helper & Tests
src/utils/urls/appUrlHelper.ts, src/utils/urls/appUrlHelper.test.ts
Added getInstanceLayoutsUrl(layoutSetId: string, instanceId: string) returning ${appPath}/instances/${instanceId}/layouts/${layoutSetId}; added test asserting the instance-aware URL contains the instanceId and layout path.
Test Mocks
src/test/renderWithProviders.tsx
Added default mock for fetchLayoutsForInstance that rejects with 'fetchLayoutsForInstance not mocked', requiring tests to override it when instance-scoped fetch is exercised.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to tests that may now hit the new default mock in src/test/renderWithProviders.tsx and need to override fetchLayoutsForInstance.
  • Verify the conditional gating in LayoutsContext.tsx correctly handles absence of instanceId and feature flag false.
  • Confirm getInstanceLayoutsUrl path format aligns with server routing and other URL helpers.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main feature: instance contextual layout fetching, which aligns with the changes adding instance-aware layout requests.
Description check ✅ Passed The description covers the main purpose, related PR, verification checklist with manual testing and unit tests completed, and properly addresses accessibility and documentation considerations.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/instance-contextual-layout-fetching

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Jondyr Jondyr added backport-ignore This PR is a new feature and should not be cherry-picked onto release branches squad/utforming Issues that belongs to the named squad. labels Oct 30, 2025
@Jondyr Jondyr linked an issue Oct 30, 2025 that may be closed by this pull request
4 tasks
@Jondyr Jondyr added the kind/product-feature Pull requests containing new features label Oct 30, 2025
@Jondyr Jondyr moved this to 👷 In progress in Team Altinn Studio Nov 10, 2025
@Jondyr Jondyr self-assigned this Nov 10, 2025
@Jondyr Jondyr added the squad/data Issues that belongs to the named squad. label Nov 10, 2025
@Jondyr Jondyr marked this pull request as ready for review November 10, 2025 11:23
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0baa59 and b739ebc.

📒 Files selected for processing (4)
  • src/features/applicationMetadata/types.ts (1 hunks)
  • src/features/form/layout/LayoutsContext.tsx (2 hunks)
  • src/queries/queries.ts (1 hunks)
  • src/utils/urls/appUrlHelper.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid using any and unnecessary type casts (as Type) in TypeScript; prefer precise typings and refactor existing casts/anys
For TanStack Query, use objects to manage query keys and functions, and centralize shared options via queryOptions

Files:

  • src/queries/queries.ts
  • src/utils/urls/appUrlHelper.ts
  • src/features/applicationMetadata/types.ts
  • src/features/form/layout/LayoutsContext.tsx
🧠 Learnings (3)
📚 Learning: 2025-08-22T13:53:28.252Z
Learnt from: CR
Repo: Altinn/app-frontend-react PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-22T13:53:28.252Z
Learning: Applies to **/*.test.{ts,tsx} : In tests, use `renderWithProviders` from `src/test/renderWithProviders.tsx` to supply required form layout context

Applied to files:

  • src/features/form/layout/LayoutsContext.tsx
📚 Learning: 2025-08-22T13:53:28.252Z
Learnt from: CR
Repo: Altinn/app-frontend-react PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-22T13:53:28.252Z
Learning: Applies to src/features/*/Provider.tsx : Place feature-specific context providers as `Provider.tsx` within each feature directory under `src/features/`

Applied to files:

  • src/features/form/layout/LayoutsContext.tsx
📚 Learning: 2025-08-28T12:00:32.967Z
Learnt from: olemartinorg
Repo: Altinn/app-frontend-react PR: 3645
File: src/features/datamodel/DataModelsProvider.tsx:172-175
Timestamp: 2025-08-28T12:00:32.967Z
Learning: In DataModelsProvider.tsx, the effect that processes referenced data types must run for both stateless and non-stateless apps. The `isFetching` guard is appropriate because stateless apps don't fetch instance data (useInstanceDataQuery is disabled with `enabled: !isStateless`) but still need the data type processing to occur.

Applied to files:

  • src/features/form/layout/LayoutsContext.tsx
🧬 Code graph analysis (2)
src/queries/queries.ts (4)
src/layout/layout.ts (1)
  • ILayoutCollection (85-85)
src/utils/network/sharedNetworking.ts (1)
  • httpGet (7-13)
src/utils/network/networking.ts (1)
  • httpGet (10-17)
src/utils/urls/appUrlHelper.ts (1)
  • getLayoutsUrl (188-193)
src/features/form/layout/LayoutsContext.tsx (3)
src/features/instance/InstanceContext.tsx (1)
  • useLaxInstanceId (58-62)
src/features/applicationMetadata/ApplicationMetadataProvider.tsx (1)
  • useApplicationMetadata (67-67)
src/queries/queries.ts (1)
  • fetchLayouts (293-294)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install
🔇 Additional comments (4)
src/features/applicationMetadata/types.ts (1)

54-56: LGTM! Clean feature flag addition.

The new feature flag is well-named and follows the established pattern in the interface. The comment clearly describes its purpose.

src/features/form/layout/LayoutsContext.tsx (1)

9-9: LGTM! Appropriate imports for the new feature.

The new imports support instance-aware layout fetching and are correctly sourced.

Also applies to: 16-16

src/queries/queries.ts (1)

293-294: LGTM! Clean function signature extension.

The optional instanceId parameter is correctly typed and forwarded to getLayoutsUrl. The change maintains backward compatibility.

src/utils/urls/appUrlHelper.ts (1)

188-193: LGTM! Clean conditional URL construction.

The function correctly constructs instance-scoped URLs when instanceId is provided and falls back to the standard API endpoint otherwise. The logic is clear and follows REST conventions.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b739ebc and 63c92a0.

📒 Files selected for processing (1)
  • src/utils/urls/appUrlHelper.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid using any and unnecessary type casts (as Type) in TypeScript; prefer precise typings and refactor existing casts/anys
For TanStack Query, use objects to manage query keys and functions, and centralize shared options via queryOptions

Files:

  • src/utils/urls/appUrlHelper.ts

@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from 63c92a0 to 559868f Compare November 10, 2025 13:10
@Jondyr Jondyr moved this from 👷 In progress to 🔎 In review in Team Altinn Studio Nov 12, 2025
@Jondyr Jondyr removed their assignment Nov 12, 2025
Copy link
Contributor

@Magnusrm Magnusrm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! ⭐

I have a suggestion below that you can apply if you agree with it. The current implementation should also be fine 😊

@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from 40079a6 to df5bac7 Compare November 12, 2025 09:24
@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from df5bac7 to 4aaddfc Compare November 12, 2025 09:29
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/features/form/layout/LayoutsContext.tsx (1)

40-42: Critical: Query key still missing instanceId, causing cache collisions.

This critical issue was raised in a previous review but hasn't been addressed. When addInstanceIdentifierToLayoutRequests is enabled and the same layoutSetId is used across different instances, React Query will serve stale cached layouts from a previous instance because the query key doesn't distinguish between instances.

Apply this diff to include instanceId in the query key when the feature flag is enabled:

   const { fetchLayouts } = useAppQueries();
   const instanceId = useLaxInstanceId();
   const features = useApplicationMetadata().features ?? {};
+  const shouldUseInstanceEndpoint = features.addInstanceIdentifierToLayoutRequests && instanceId;
 
   return {
-    queryKey: ['formLayouts', layoutSetId, enabled],
+    queryKey: ['formLayouts', layoutSetId, enabled, shouldUseInstanceEndpoint ? instanceId : null],
     queryFn: layoutSetId
       ? async () => {
-          const shouldUseInstanceEndpoint = features.addInstanceIdentifierToLayoutRequests && instanceId;
           const layouts = shouldUseInstanceEndpoint

This ensures different cache entries for each instance when the feature is enabled, preventing stale data from being served.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df5bac7 and 4aaddfc.

📒 Files selected for processing (5)
  • src/features/form/layout/LayoutsContext.tsx (2 hunks)
  • src/queries/queries.ts (2 hunks)
  • src/test/renderWithProviders.tsx (1 hunks)
  • src/utils/urls/appUrlHelper.test.ts (2 hunks)
  • src/utils/urls/appUrlHelper.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/utils/urls/appUrlHelper.test.ts
  • src/queries/queries.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid using any and unnecessary type casts (as Type) in TypeScript; prefer precise typings and refactor existing casts/anys
For TanStack Query, use objects to manage query keys and functions, and centralize shared options via queryOptions

Files:

  • src/test/renderWithProviders.tsx
  • src/features/form/layout/LayoutsContext.tsx
  • src/utils/urls/appUrlHelper.ts
🧠 Learnings (6)
📚 Learning: 2025-08-22T13:53:28.252Z
Learnt from: CR
Repo: Altinn/app-frontend-react PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-22T13:53:28.252Z
Learning: Applies to **/*.test.{ts,tsx} : In tests, use `renderWithProviders` from `src/test/renderWithProviders.tsx` to supply required form layout context

Applied to files:

  • src/test/renderWithProviders.tsx
  • src/features/form/layout/LayoutsContext.tsx
📚 Learning: 2025-10-14T09:01:40.985Z
Learnt from: lassopicasso
Repo: Altinn/app-frontend-react PR: 3654
File: src/layout/ImageUpload/ImageUploadSummary2/ImageUploadSummary2.tsx:49-53
Timestamp: 2025-10-14T09:01:40.985Z
Learning: In the Altinn app-frontend-react codebase, when data integrity is guaranteed through business logic and parent components guard rendering (e.g., `storedImage ? <Component /> : undefined`), non-null assertions on guaranteed fields like `storedImage!.data?.filename` are acceptable and preferred over optional chaining with fallbacks.

Applied to files:

  • src/features/form/layout/LayoutsContext.tsx
📚 Learning: 2025-09-08T10:35:54.904Z
Learnt from: bjosttveit
Repo: Altinn/app-frontend-react PR: 3676
File: .github/scripts/revert.sh:71-72
Timestamp: 2025-09-08T10:35:54.904Z
Learning: In the Altinn app-frontend-react repository, the Azure storage paths in revert.sh use the structure "$AZURE_TARGET_URI/toolkits/$APP_FULL/" and "$AZURE_TARGET_URI/toolkits/$APP_MAJOR/" without requiring "altinn-app-frontend" in the path.

Applied to files:

  • src/features/form/layout/LayoutsContext.tsx
📚 Learning: 2025-08-22T13:53:28.252Z
Learnt from: CR
Repo: Altinn/app-frontend-react PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-22T13:53:28.252Z
Learning: Applies to src/features/*/Provider.tsx : Place feature-specific context providers as `Provider.tsx` within each feature directory under `src/features/`

Applied to files:

  • src/features/form/layout/LayoutsContext.tsx
📚 Learning: 2025-08-28T12:00:32.967Z
Learnt from: olemartinorg
Repo: Altinn/app-frontend-react PR: 3645
File: src/features/datamodel/DataModelsProvider.tsx:172-175
Timestamp: 2025-08-28T12:00:32.967Z
Learning: In DataModelsProvider.tsx, the effect that processes referenced data types must run for both stateless and non-stateless apps. The `isFetching` guard is appropriate because stateless apps don't fetch instance data (useInstanceDataQuery is disabled with `enabled: !isStateless`) but still need the data type processing to occur.

Applied to files:

  • src/features/form/layout/LayoutsContext.tsx
📚 Learning: 2025-09-03T14:23:33.606Z
Learnt from: olemartinorg
Repo: Altinn/app-frontend-react PR: 3645
File: src/features/receipt/FixWrongReceiptType.tsx:16-34
Timestamp: 2025-09-03T14:23:33.606Z
Learning: In FixWrongReceiptType.tsx, brief ping-ponging between receipt routes during instance data loading is acceptable because the instance data is typically already fetched when this component runs. The author considers this a non-issue.

Applied to files:

  • src/utils/urls/appUrlHelper.ts
🧬 Code graph analysis (1)
src/features/form/layout/LayoutsContext.tsx (3)
src/features/instance/InstanceContext.tsx (1)
  • useLaxInstanceId (58-62)
src/features/applicationMetadata/ApplicationMetadataProvider.tsx (1)
  • useApplicationMetadata (67-67)
src/queries/queries.ts (2)
  • fetchLayoutsForInstance (296-297)
  • fetchLayouts (294-294)
🔇 Additional comments (4)
src/test/renderWithProviders.tsx (1)

155-155: LGTM! Consistent test mock addition.

The fetchLayoutsForInstance mock follows the same pattern as fetchLayouts (line 154), correctly requiring tests to explicitly override this query when exercising the per-instance layout fetch path.

src/utils/urls/appUrlHelper.ts (1)

189-190: LGTM! Clean URL helper implementation.

The function follows the established pattern for instance-scoped endpoints in this file and constructs the URL path consistently with other helpers like getFileUploadUrl and getValidationUrl.

src/features/form/layout/LayoutsContext.tsx (2)

9-9: LGTM! Import additions support the feature correctly.

The new imports (useApplicationMetadata, useLaxInstanceId, fetchLayoutsForInstance) are appropriately scoped and necessary for the instance-contextual layout fetching feature.

Also applies to: 16-16, 19-19


37-38: LGTM! Hook usage is appropriately defensive.

The useLaxInstanceId() correctly returns undefined when there's no instance, and the ?? {} fallback on line 38 provides proper safety for the features object.

@sonarqubecloud
Copy link

@Jondyr Jondyr enabled auto-merge (squash) November 12, 2025 11:26
@Jondyr Jondyr merged commit 31dc201 into main Nov 13, 2025
16 checks passed
@Jondyr Jondyr deleted the feat/instance-contextual-layout-fetching branch November 13, 2025 10:09
@github-project-automation github-project-automation bot moved this from 🔎 In review to ✅ Done in Team Altinn Studio Nov 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-ignore This PR is a new feature and should not be cherry-picked onto release branches kind/product-feature Pull requests containing new features squad/data Issues that belongs to the named squad. squad/utforming Issues that belongs to the named squad.

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

Add Instance contextual layout fetching/resource interface

2 participants