Fix empty record page on system objects for non-English workspace members (#20235)
## 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 `<PageLayoutMainContent />` 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 <img width="1262" height="722" alt="Screenshot 2026-05-04 at 15 15 54" src="https://github.com/user-attachments/assets/348c9e9d-0ae1-4046-8ead-470ed8263cb5" /> ## After <img width="1281" height="658" alt="Screenshot 2026-05-04 at 15 15 36" src="https://github.com/user-attachments/assets/7a9953b1-7320-4f1a-8c02-1688d3eda3ae" /> ## Note Next step should be to backfill those system objects with real record page layouts so we can remove this filter logic
This commit is contained in:
+10
-6
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user