From 0bb345b75f92d3e08520151805bd751a1ec2dc5e Mon Sep 17 00:00:00 2001 From: Weiko Date: Mon, 4 May 2026 15:36:36 +0200 Subject: [PATCH] Fix empty record page on system objects for non-English workspace members (#20235) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Context Since #19890 (Translate standard page layouts), the server's `PageLayoutTab.title` resolver translates standard tab titles at query time. A workspace member in French viewing a `messageChannel` (or any system object with a standard page layout) receives `tab.title = "Accueil"` / `"Chronologie"` instead of `"Home"` / `"Timeline"`. The `SYSTEM_OBJECT_TABS` guard in `PageLayoutTabsRenderer` was comparing against an English-only literal allow-list, so every tab was dropped, `sortedTabs` became empty, and `` never mounted — the record page rendered blank (no fields, timeline, email thread, etc.). ## Fix Only run the allow-list filter when the resolved layout is the synthetic `DEFAULT_RECORD_PAGE_LAYOUT` (the client-side fallback for the few system objects with no server-side standard page layout config, e.g. `workspaceMember`, `attachment`, `message`). That layout ships hardcoded English tabs, so the English allow-list still works in every locale. System objects that do have a server-side standard page layout (`messageChannel`, `connectedAccount`, `workflowRun`, …) are no longer filtered at all, the server only ever persists Home/Timeline/Flow tabs for them, so no filter is needed. ## Before Screenshot 2026-05-04 at 15 15 54 ## After Screenshot 2026-05-04 at 15 15 36 ## Note Next step should be to backfill those system objects with real record page layouts so we can remove this filter logic --- .../components/PageLayoutTabsRenderer.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/twenty-front/src/modules/page-layout/components/PageLayoutTabsRenderer.tsx b/packages/twenty-front/src/modules/page-layout/components/PageLayoutTabsRenderer.tsx index 3a851d3133..ae18ac4506 100644 --- a/packages/twenty-front/src/modules/page-layout/components/PageLayoutTabsRenderer.tsx +++ b/packages/twenty-front/src/modules/page-layout/components/PageLayoutTabsRenderer.tsx @@ -3,6 +3,7 @@ import { type FlatObjectMetadataItem } from '@/metadata-store/types/FlatObjectMe import { PageLayoutLeftPanel } from '@/page-layout/components/PageLayoutLeftPanel'; import { PageLayoutTabList } from '@/page-layout/components/PageLayoutTabList'; import { PageLayoutTabListEffect } from '@/page-layout/components/PageLayoutTabListEffect'; +import { DEFAULT_RECORD_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultRecordPageLayoutId'; import { PAGE_LAYOUT_LEFT_PANEL_CONTAINER_WIDTH } from '@/page-layout/constants/PageLayoutLeftPanelContainerWidth'; import { useCurrentPageLayoutOrThrow } from '@/page-layout/hooks/useCurrentPageLayoutOrThrow'; import { useIsPageLayoutInEditMode } from '@/page-layout/hooks/useIsPageLayoutInEditMode'; @@ -25,7 +26,6 @@ import { styled } from '@linaria/react'; import { isDefined } from 'twenty-shared/utils'; import { useIsMobile } from 'twenty-ui/utilities'; import { FeatureFlagKey } from '~/generated-metadata/graphql'; - const StyledContainer = styled.div<{ hasPinnedTab: boolean }>` display: grid; grid-template-columns: ${({ hasPinnedTab }) => @@ -104,11 +104,15 @@ export const PageLayoutTabsRenderer = () => { const SYSTEM_OBJECT_TABS = ['Home', 'Timeline', 'Overview', 'Flow']; - const tabsForCurrentObject = isSystemObject - ? tabsWithVisibleWidgets.filter((tab) => - SYSTEM_OBJECT_TABS.includes(tab.title), - ) - : tabsWithVisibleWidgets; + const isUsingDefaultRecordPageLayout = + currentPageLayout.id === DEFAULT_RECORD_PAGE_LAYOUT_ID; + + const tabsForCurrentObject = + isSystemObject && isUsingDefaultRecordPageLayout + ? tabsWithVisibleWidgets.filter((tab) => + SYSTEM_OBJECT_TABS.includes(tab.title), + ) + : tabsWithVisibleWidgets; const { tabsToRenderInTabList, pinnedLeftTab } = getTabsByDisplayMode({ tabs: tabsForCurrentObject,