Skip to content

Fetch page layout by objectMetadataId when feature flag is enabled#17644

Draft
Copilot wants to merge 18 commits intomainfrom
copilot/fetch-configuration-backend
Draft

Fetch page layout by objectMetadataId when feature flag is enabled#17644
Copilot wants to merge 18 commits intomainfrom
copilot/fetch-configuration-backend

Conversation

Copy link
Contributor

Copilot AI commented Feb 2, 2026

When IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED is enabled, page layouts for records should be fetched from the backend by querying with objectMetadataId and filtering by type=RECORD_PAGE, rather than using hardcoded layout IDs.

Changes

Created FIND_PAGE_LAYOUTS GraphQL query:

  • New file: packages/twenty-front/src/modules/page-layout/graphql/queries/findPageLayouts.ts
  • Queries getPageLayouts(objectMetadataId: String) to fetch page layouts for a specific object

Modified useRecordPageLayoutId hook:

  • When feature flag is enabled: Queries backend with objectMetadataId to find the RECORD_PAGE layout dynamically
  • When feature flag is disabled: Uses existing logic with hardcoded default layout IDs
  • Proper loading state handling to prevent layout flash
  • Fallback to mock layouts if no backend data is found

Reverted PageLayoutInitializationQueryEffect:

  • Removed feature flag logic from this component (moved to hook level)
  • Component now behaves exactly as before

Behavior

For record page layouts (feature flag enabled):

  1. Query backend: getPageLayouts(objectMetadataId: <objectMetadataId>)
  2. Filter results for type=RECORD_PAGE
  3. Use dynamic pageLayoutId from backend (not hardcoded)
  4. Return null while loading
  5. Fallback to mocks if no data found

For record page layouts (feature flag disabled):

  • Use hardcoded default layout IDs (original behavior)

For dashboards:

  • Unchanged - uses pageLayoutId from dashboard record
// New query
const { data: pageLayoutsData, loading } = useQuery(FIND_PAGE_LAYOUTS, {
  variables: {
    objectMetadataId: objectMetadataItem?.id,
  },
  skip: !isRecordPageLayoutEditingEnabled || !objectMetadataItem?.id,
});

// Dynamic pageLayoutId determination
const pageLayoutId = useMemo(() => {
  if (isRecordPageLayoutEditingEnabled) {
    if (loading) return null;
    
    const recordPageLayout = pageLayoutsData?.getPageLayouts?.find(
      (layout) => layout.type === PageLayoutType.RECORD_PAGE,
    );
    
    if (recordPageLayout) return recordPageLayout.id;
  }
  
  return getRecordPageLayoutId({ record, targetObjectNameSingular });
}, [isRecordPageLayoutEditingEnabled, loading, pageLayoutsData, record, targetObjectNameSingular]);

The pageLayoutId is no longer hardcoded/guessable when the feature flag is active - it's dynamically fetched from the backend based on the object's metadata ID.

Original prompt

Start implementation

[Chronological Review: The conversation began with the user requesting to fetch configuration from the backend for record page layouts when a specific feature flag is active. The user indicated that the current implementation uses mocks and that the configuration is now seeded in the database. The user then specified additional requirements regarding handling cases where the backend returns no data and ensuring records have a populated pageLayoutId. The conversation has focused on planning the implementation of these requirements.]

[Intent Mapping:

  1. "I want you to fetch the configuration from the backend when the IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED feature flag is active." - User wants to change the source of record page layouts from mocks to backend data based on a feature flag.
  2. "Handle the case where backend returns no data." - User wants to implement fallback logic using mocks if the backend does not return data.
  3. "Ensure records have pageLayoutId populated." - User wants to ensure that records are linked to the correct page layout based on specific criteria.]

[Technical Inventory:

  • Feature Flag: IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED - Used to toggle between mock data and backend data.
  • Database Tables: pageLayout, pageLayoutTab, pageLayoutWidgets - Where the configuration is seeded.
  • TypeScript: The code is written in TypeScript, specifically in the file PageLayoutInitializationQueryEffect.tsx.]

[Code Archaeology:

  • File: PageLayoutInitializationQueryEffect.tsx
    • Purpose: This file is responsible for initializing the page layout based on the provided layout ID.
    • Current State: The user is working on modifying this file to implement the new requirements.
    • Key Code Segments: The function getDefaultLayoutById is defined to retrieve layouts by ID, but further implementation is needed to fetch from the backend.
    • Dependencies: The file interacts with the backend to fetch layout configurations.]

[Progress Assessment:

  • Completed Tasks: The user has identified the need to switch from mocks to backend data and has seeded the database with necessary configurations.
  • Partially Complete Work: The user is in the process of planning how to implement the fetching of configurations and handling cases where no data is returned from the backend.]

[Context Validation: All critical information for continuation is captured, including the need to implement backend fetching, fallback logic, and ensuring records are linked to the correct page layout.]

[Recent Commands Analysis:

  • Last Agent Commands: The user requested a plan to implement the fetching of configurations and handling of edge cases.
  • Tool Results Summary: No specific tool results were returned as the conversation focused on planning and requirements gathering.
  • Pre-Summary State: The agent was actively discussing the implementation plan for fetching configurations and handling backend responses when the token budget was exceeded.
  • Operation Context: These commands were executed to align the implementation with the user's goals of transitioning from mock data to a more dynamic backend-driven approach.]
1. Conversation Overview: - Primary Objectives: 1. "I want you to fetch the configuration from the backend when the `IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED` feature flag is active." 2. "Handle the case where backend returns no data." 3. "Ensure records have pageLayoutId populated." - Session Context: The conversation has focused on transitioning from mock data to backend data for record page layouts, with specific requirements for handling data retrieval and ensuring proper linking of records to layouts. - User Intent Evolution: The user initially sought to implement backend fetching and has since specified additional requirements for error handling and data integrity.
  1. Technical Foundation:
  • Feature Flag: IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED - Toggles between mock and backend data.
  • Database Tables: pageLayout, pageLayoutTab, pageLayoutWidgets - Configuration storage.
  • TypeScript: The implementation is in TypeScript, specifically in PageLayoutInitializationQueryEffect.tsx.
  1. Codebase Status:
  • File Name: PageLayoutInitializationQueryEffect.tsx
    • Purpose: Initializes the page layout based on layout ID.
    • Current State: User is modifying this file to implement new requirements.
    • Key Code Segments: Function getDefaultLayoutById retrieves layouts by ID.
    • Dependencies: Interacts with backend for layout configurations.
  1. Problem Resolution:
  • Issues Encountered: Need to handle cases where the backend returns no data and ensure records are linked to layouts.
  • Solutions Implemented: User has outlined requirements for fallback logic and data linking.
  • Debugging Context: No specific debugging has been reported yet; focus is on planning.
  • Lessons Learned: Importance of robust error handling and data integrity in fetching...

Created from VS Code.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits February 2, 2026 16:38
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement fetching configuration from backend for record layouts Enable backend fetch for page layouts when editing flag is active Feb 2, 2026
Copilot AI requested a review from Devessier February 2, 2026 16:43
@Devessier
Copy link
Contributor

@copilot you missed one important point: the pageLayoutId won't be guessable as it used to be here.

The behavior we want:

For dashboards

dashboards table contains a column referencing a pageLayout. Once you fetched the selected dashboard's data, you know which pageLayout to fetch. That's fine and we don't want to change this behavior.

For record page layouts

For record page layouts, you must determine the page layout to render by fetching in the pageLayouts table the record with type=RECORD_PAGE AND objectMedataId=<selected record's object metadata id>. This is mandatory. I want you to implement this behavior if the IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED feature flag is active.

If IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED isn't active, I want you to keep using the record page layouts mocks I wrote.

- Created FIND_PAGE_LAYOUTS query to fetch layouts by objectMetadataId
- Modified useRecordPageLayoutId to query backend for RECORD_PAGE layouts when feature flag is enabled
- Reverted PageLayoutInitializationQueryEffect changes (logic now in useRecordPageLayoutId)
- Falls back to mock layouts when feature flag is disabled or no backend data found

Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 2, 2026

@copilot you missed one important point: the pageLayoutId won't be guessable as it used to be here.

The behavior we want:
...

I've implemented the requested behavior. The changes now correctly:

  1. For record page layouts with feature flag enabled: Query getPageLayouts(objectMetadataId: <objectMetadataId>) to find the layout with type=RECORD_PAGE for the object
  2. For record page layouts with feature flag disabled: Use the existing mock layouts
  3. For dashboards: Keep the existing behavior (unchanged)

Key changes in commit f15e605:

  • Created FIND_PAGE_LAYOUTS GraphQL query
  • Modified useRecordPageLayoutId to fetch from backend by objectMetadataId when the feature flag is active
  • Reverted PageLayoutInitializationQueryEffect to its original state (logic moved to the hook level)

The pageLayoutId is no longer hardcoded/guessed - it's dynamically fetched from the backend based on the object's metadata ID.

Copilot AI and others added 5 commits February 2, 2026 17:09
…ageLayouts

- Skip query when objectMetadataItem is not yet loaded
- Rename query from FindPageLayouts to GetPageLayouts to match resolver name

Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
- Moved query from dashboards module to page-layout module for better code organization
- Updated import path in useRecordPageLayoutId

Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
- Return null while page layouts are loading to prevent showing wrong layout
- Add pageLayoutsLoading to dependency array for proper memoization

Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
- Use optional chaining for objectMetadataItem.id in variables
- Make skip condition more explicit with separate checks

Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Copilot AI changed the title Enable backend fetch for page layouts when editing flag is active Fetch page layout by objectMetadataId when feature flag is enabled Feb 2, 2026
@charlesBochet
Copy link
Member

I don't really see the point to use this instead of the IDE. Looks slower to iterate and to control IMO

@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

TODOs/FIXMEs:

  • // TODO: remove this once the frontend consumes the new type: packages/twenty-front/src/modules/page-layout/utils/transformPageLayout.ts

Generated by 🚫 dangerJS against 5b44636

@Devessier Devessier force-pushed the copilot/fetch-configuration-backend branch from 506f390 to 4513e0b Compare February 5, 2026 13:45
@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:36085

This environment will automatically shut down when the PR is closed or after 5 hours.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants