From e58668003d01876eee5b26f07afac23f001fd227 Mon Sep 17 00:00:00 2001 From: Baptiste Devessier Date: Tue, 21 Oct 2025 13:01:43 +0200 Subject: [PATCH] Support side panel in record page layout (#15216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Demo https://github.com/user-attachments/assets/078b67d3-52d7-4ddf-a65a-fb002f82cfdd Closes https://github.com/twentyhq/core-team-issues/issues/1731 --------- Co-authored-by: Félix Malfait --- .../hooks/useRecordShowContainerTabs.ts | 2 - .../layouts/dashboard-record-layout.ts | 27 -- .../components/PageLayoutLeftPanel.tsx | 35 ++ .../components/PageLayoutRendererContent.tsx | 34 +- .../components/PageLayoutTabHeader.tsx | 28 ++ .../__tests__/getTabsByDisplayMode.test.ts | 444 ++++++++++++++++++ .../page-layout/utils/getTabsByDisplayMode.ts | 38 ++ .../components/ShowPageLeftContainer.tsx | 5 +- .../components/ShowPageSubContainer.tsx | 2 +- 9 files changed, 563 insertions(+), 52 deletions(-) delete mode 100644 packages/twenty-front/src/modules/object-record/record-show/layouts/dashboard-record-layout.ts create mode 100644 packages/twenty-front/src/modules/page-layout/components/PageLayoutLeftPanel.tsx create mode 100644 packages/twenty-front/src/modules/page-layout/components/PageLayoutTabHeader.tsx create mode 100644 packages/twenty-front/src/modules/page-layout/utils/__tests__/getTabsByDisplayMode.test.ts create mode 100644 packages/twenty-front/src/modules/page-layout/utils/getTabsByDisplayMode.ts diff --git a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowContainerTabs.ts b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowContainerTabs.ts index f0e4303734d..09fddeb00c8 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowContainerTabs.ts +++ b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowContainerTabs.ts @@ -5,7 +5,6 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions'; import { BASE_RECORD_LAYOUT } from '@/object-record/record-show/layouts/base-record-layout'; import { COMPANY_RECORD_LAYOUT } from '@/object-record/record-show/layouts/company-record-layout'; -import { DASHBOARD_RECORD_LAYOUT } from '@/object-record/record-show/layouts/dashboard-record-layout'; import { NOTE_RECORD_LAYOUT } from '@/object-record/record-show/layouts/note-record-layout'; import { OPPORTUNITY_RECORD_LAYOUT } from '@/object-record/record-show/layouts/opportunity-record-layout'; import { PERSON_RECORD_LAYOUT } from '@/object-record/record-show/layouts/person-record-layout'; @@ -34,7 +33,6 @@ const OBJECT_SPECIFIC_LAYOUTS: Partial< [CoreObjectNameSingular.Workflow]: WORKFLOW_RECORD_LAYOUT, [CoreObjectNameSingular.WorkflowVersion]: WORKFLOW_VERSION_RECORD_LAYOUT, [CoreObjectNameSingular.WorkflowRun]: WORKFLOW_RUN_RECORD_LAYOUT, - [CoreObjectNameSingular.Dashboard]: DASHBOARD_RECORD_LAYOUT, }; export const useRecordShowContainerTabs = ( diff --git a/packages/twenty-front/src/modules/object-record/record-show/layouts/dashboard-record-layout.ts b/packages/twenty-front/src/modules/object-record/record-show/layouts/dashboard-record-layout.ts deleted file mode 100644 index de8d3305491..00000000000 --- a/packages/twenty-front/src/modules/object-record/record-show/layouts/dashboard-record-layout.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { CardType } from '@/object-record/record-show/types/CardType'; -import { type RecordLayout } from '@/object-record/record-show/types/RecordLayout'; - -export const DASHBOARD_RECORD_LAYOUT: RecordLayout = { - hideSummaryAndFields: true, - hideFieldsInSidePanel: true, - tabs: { - dashboard: { - title: 'Dashboard', - position: 101, - icon: 'IconLayoutDashboard', - cards: [{ type: CardType.DashboardCard }], - hide: { - ifMobile: false, - ifDesktop: false, - ifInRightDrawer: false, - ifFeaturesDisabled: [], - ifRequiredObjectsInactive: [], - ifRelationsMissing: [], - }, - }, - timeline: null, - tasks: null, - notes: null, - files: null, - }, -}; diff --git a/packages/twenty-front/src/modules/page-layout/components/PageLayoutLeftPanel.tsx b/packages/twenty-front/src/modules/page-layout/components/PageLayoutLeftPanel.tsx new file mode 100644 index 00000000000..79a8367420a --- /dev/null +++ b/packages/twenty-front/src/modules/page-layout/components/PageLayoutLeftPanel.tsx @@ -0,0 +1,35 @@ +import { SummaryCard } from '@/object-record/record-show/components/SummaryCard'; +import { PageLayoutGridLayout } from '@/page-layout/components/PageLayoutGridLayout'; +import { useCurrentPageLayout } from '@/page-layout/hooks/useCurrentPageLayout'; +import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext'; +import { useTargetRecord } from '@/ui/layout/contexts/useTargetRecord'; +import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer'; +import { PageLayoutType } from '~/generated/graphql'; + +type PageLayoutLeftPanelProps = { + pinnedLeftTabId: string; +}; + +export const PageLayoutLeftPanel = ({ + pinnedLeftTabId, +}: PageLayoutLeftPanelProps) => { + const { currentPageLayout } = useCurrentPageLayout(); + const targetRecordIdentifier = useTargetRecord(); + const { isInRightDrawer } = useLayoutRenderingContext(); + + if (currentPageLayout?.type !== PageLayoutType.RECORD_PAGE) { + return null; + } + + return ( + + + + + + ); +}; diff --git a/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx b/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx index 0773d3931c3..08a4ec2b132 100644 --- a/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx +++ b/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx @@ -1,15 +1,16 @@ -import { SummaryCard } from '@/object-record/record-show/components/SummaryCard'; import { PageLayoutGridLayout } from '@/page-layout/components/PageLayoutGridLayout'; +import { PageLayoutLeftPanel } from '@/page-layout/components/PageLayoutLeftPanel'; +import { PageLayoutTabHeader } from '@/page-layout/components/PageLayoutTabHeader'; import { useCreatePageLayoutTab } from '@/page-layout/hooks/useCreatePageLayoutTab'; import { useCurrentPageLayout } from '@/page-layout/hooks/useCurrentPageLayout'; import { isPageLayoutInEditModeComponentState } from '@/page-layout/states/isPageLayoutInEditModeComponentState'; import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutId'; +import { getTabsByDisplayMode } from '@/page-layout/utils/getTabsByDisplayMode'; import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext'; -import { useTargetRecord } from '@/ui/layout/contexts/useTargetRecord'; import { ShowPageContainer } from '@/ui/layout/page/components/ShowPageContainer'; -import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; +import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import styled from '@emotion/styled'; @@ -44,7 +45,6 @@ const StyledScrollWrapper = styled(ScrollWrapper)` export const PageLayoutRendererContent = () => { const { currentPageLayout } = useCurrentPageLayout(); - const targetRecordIdentifier = useTargetRecord(); const { isInRightDrawer } = useLayoutRenderingContext(); const isPageLayoutInEditMode = useRecoilComponentValue( @@ -57,29 +57,22 @@ export const PageLayoutRendererContent = () => { const handleAddTab = isPageLayoutInEditMode ? createPageLayoutTab : undefined; + const isMobile = useIsMobile(); + if (!isDefined(currentPageLayout)) { return null; } - const tabsToRenderInTabList = currentPageLayout.tabs.filter( - (tab) => tab.selfDisplayMode !== 'pinned-left', - ); - const pinnedLeftTab = currentPageLayout.tabs.find( - (tab) => tab.selfDisplayMode === 'pinned-left', - ); + const { tabsToRenderInTabList, pinnedLeftTab } = getTabsByDisplayMode({ + pageLayout: currentPageLayout, + isMobile, + isInRightDrawer, + }); return ( {isDefined(pinnedLeftTab) && ( - - - - - + )} @@ -92,6 +85,9 @@ export const PageLayoutRendererContent = () => { )} onAddTab={handleAddTab} /> + + + { + const { currentPageLayout } = useCurrentPageLayout(); + const targetRecordIdentifier = useTargetRecord(); + const { isInRightDrawer } = useLayoutRenderingContext(); + const isMobile = useIsMobile(); + + if ( + currentPageLayout?.type !== PageLayoutType.RECORD_PAGE || + !(isMobile || isInRightDrawer) + ) { + return null; + } + + return ( + + ); +}; diff --git a/packages/twenty-front/src/modules/page-layout/utils/__tests__/getTabsByDisplayMode.test.ts b/packages/twenty-front/src/modules/page-layout/utils/__tests__/getTabsByDisplayMode.test.ts new file mode 100644 index 00000000000..6eb0516d9bb --- /dev/null +++ b/packages/twenty-front/src/modules/page-layout/utils/__tests__/getTabsByDisplayMode.test.ts @@ -0,0 +1,444 @@ +import { type DraftPageLayout } from '@/page-layout/types/draft-page-layout'; +import { type PageLayoutTab } from '@/page-layout/types/PageLayoutTab'; +import { PageLayoutType } from '~/generated/graphql'; +import { getTabsByDisplayMode } from '../getTabsByDisplayMode'; + +describe('getTabsByDisplayMode', () => { + const createMockTab = ( + id: string, + selfDisplayMode?: 'pinned-left', + ): PageLayoutTab => ({ + id, + pageLayoutId: 'page-layout-1', + title: `Tab ${id}`, + position: 0, + widgets: [], + createdAt: '2024-01-01T00:00:00.000Z', + updatedAt: '2024-01-01T00:00:00.000Z', + selfDisplayMode, + }); + + const createMockPageLayout = (tabs: PageLayoutTab[]): DraftPageLayout => ({ + id: 'page-layout-1', + name: 'Test Layout', + type: PageLayoutType.RECORD_PAGE, + objectMetadataId: null, + tabs, + }); + + describe('when isMobile is true', () => { + it('should return all tabs in tabsToRenderInTabList', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2'), + createMockTab('tab-3', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: true, + isInRightDrawer: false, + }); + + expect(result.tabsToRenderInTabList).toEqual(tabs); + expect(result.tabsToRenderInTabList).toHaveLength(3); + }); + + it('should return undefined for pinnedLeftTab', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: true, + isInRightDrawer: false, + }); + + expect(result.pinnedLeftTab).toBeUndefined(); + }); + + it('should handle empty tabs array', () => { + const pageLayout = createMockPageLayout([]); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: true, + isInRightDrawer: false, + }); + + expect(result.tabsToRenderInTabList).toEqual([]); + expect(result.pinnedLeftTab).toBeUndefined(); + }); + + it('should return all tabs even when all are pinned-left', () => { + const tabs = [ + createMockTab('tab-1', 'pinned-left'), + createMockTab('tab-2', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: true, + isInRightDrawer: false, + }); + + expect(result.tabsToRenderInTabList).toEqual(tabs); + expect(result.tabsToRenderInTabList).toHaveLength(2); + }); + }); + + describe('when isInRightDrawer is true', () => { + it('should return all tabs in tabsToRenderInTabList', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2'), + createMockTab('tab-3', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: true, + }); + + expect(result.tabsToRenderInTabList).toEqual(tabs); + expect(result.tabsToRenderInTabList).toHaveLength(3); + }); + + it('should return undefined for pinnedLeftTab', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: true, + }); + + expect(result.pinnedLeftTab).toBeUndefined(); + }); + + it('should handle empty tabs array', () => { + const pageLayout = createMockPageLayout([]); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: true, + }); + + expect(result.tabsToRenderInTabList).toEqual([]); + expect(result.pinnedLeftTab).toBeUndefined(); + }); + + it('should return all tabs even when all are pinned-left', () => { + const tabs = [ + createMockTab('tab-1', 'pinned-left'), + createMockTab('tab-2', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: true, + }); + + expect(result.tabsToRenderInTabList).toEqual(tabs); + expect(result.tabsToRenderInTabList).toHaveLength(2); + }); + }); + + describe('when isMobile is false and isInRightDrawer is false', () => { + it('should filter out pinned-left tabs from tabsToRenderInTabList', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2', 'pinned-left'), + createMockTab('tab-3'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(result.tabsToRenderInTabList).toHaveLength(2); + expect(result.tabsToRenderInTabList).toEqual([tabs[0], tabs[2]]); + expect( + result.tabsToRenderInTabList.every( + (tab) => tab.selfDisplayMode !== 'pinned-left', + ), + ).toBe(true); + }); + + it('should return the pinned-left tab in pinnedLeftTab', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2', 'pinned-left'), + createMockTab('tab-3'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(result.pinnedLeftTab).toBeDefined(); + expect(result.pinnedLeftTab?.id).toBe('tab-2'); + expect(result.pinnedLeftTab?.selfDisplayMode).toBe('pinned-left'); + }); + + it('should return undefined for pinnedLeftTab when no pinned tab exists', () => { + const tabs = [createMockTab('tab-1'), createMockTab('tab-2')]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(result.pinnedLeftTab).toBeUndefined(); + expect(result.tabsToRenderInTabList).toEqual(tabs); + }); + + it('should return all tabs in tabsToRenderInTabList when no pinned tabs exist', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2'), + createMockTab('tab-3'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(result.tabsToRenderInTabList).toEqual(tabs); + expect(result.tabsToRenderInTabList).toHaveLength(3); + }); + + it('should handle empty tabs array', () => { + const pageLayout = createMockPageLayout([]); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(result.tabsToRenderInTabList).toEqual([]); + expect(result.pinnedLeftTab).toBeUndefined(); + }); + + it('should return first pinned-left tab when multiple exist', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2', 'pinned-left'), + createMockTab('tab-3', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(result.pinnedLeftTab?.id).toBe('tab-2'); + expect(result.tabsToRenderInTabList).toHaveLength(1); + expect(result.tabsToRenderInTabList[0].id).toBe('tab-1'); + }); + + it('should return empty array when all tabs are pinned-left', () => { + const tabs = [ + createMockTab('tab-1', 'pinned-left'), + createMockTab('tab-2', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(result.tabsToRenderInTabList).toEqual([]); + expect(result.pinnedLeftTab?.id).toBe('tab-1'); + }); + }); + + describe('edge cases', () => { + it('should handle single tab without pinned-left display mode', () => { + const tabs = [createMockTab('tab-1')]; + const pageLayout = createMockPageLayout(tabs); + + const resultMobile = getTabsByDisplayMode({ + pageLayout, + isMobile: true, + isInRightDrawer: false, + }); + const resultDesktop = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(resultMobile.tabsToRenderInTabList).toEqual(tabs); + expect(resultMobile.pinnedLeftTab).toBeUndefined(); + + expect(resultDesktop.tabsToRenderInTabList).toEqual(tabs); + expect(resultDesktop.pinnedLeftTab).toBeUndefined(); + }); + + it('should handle single tab with pinned-left display mode', () => { + const tabs = [createMockTab('tab-1', 'pinned-left')]; + const pageLayout = createMockPageLayout(tabs); + + const resultMobile = getTabsByDisplayMode({ + pageLayout, + isMobile: true, + isInRightDrawer: false, + }); + const resultDesktop = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(resultMobile.tabsToRenderInTabList).toEqual(tabs); + expect(resultMobile.pinnedLeftTab).toBeUndefined(); + + expect(resultDesktop.tabsToRenderInTabList).toEqual([]); + expect(resultDesktop.pinnedLeftTab).toEqual(tabs[0]); + }); + + it('should not mutate the original page layout', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + const originalTabsLength = pageLayout.tabs.length; + + getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(pageLayout.tabs).toHaveLength(originalTabsLength); + expect(pageLayout.tabs).toEqual(tabs); + }); + + it('should handle tabs with additional properties', () => { + const tabWithExtraProps: PageLayoutTab = { + ...createMockTab('tab-1'), + layoutMode: 'grid' as const, + }; + const pageLayout = createMockPageLayout([tabWithExtraProps]); + + const result = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(result.tabsToRenderInTabList[0].layoutMode).toBe('grid'); + }); + }); + + describe('consistency between mobile and desktop', () => { + it('should return consistent results for the same input', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const result1 = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + const result2 = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(result1).toEqual(result2); + }); + + it('should show different results for mobile vs desktop', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const mobileResult = getTabsByDisplayMode({ + pageLayout, + isMobile: true, + isInRightDrawer: false, + }); + const desktopResult = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: false, + }); + + expect(mobileResult.tabsToRenderInTabList.length).toBe(2); + expect(desktopResult.tabsToRenderInTabList.length).toBe(1); + + expect(mobileResult.pinnedLeftTab).toBeUndefined(); + expect(desktopResult.pinnedLeftTab).toBeDefined(); + }); + }); + + describe('when both isMobile and isInRightDrawer are true', () => { + it('should behave the same as when only one is true', () => { + const tabs = [ + createMockTab('tab-1'), + createMockTab('tab-2', 'pinned-left'), + ]; + const pageLayout = createMockPageLayout(tabs); + + const resultBothTrue = getTabsByDisplayMode({ + pageLayout, + isMobile: true, + isInRightDrawer: true, + }); + const resultOnlyMobile = getTabsByDisplayMode({ + pageLayout, + isMobile: true, + isInRightDrawer: false, + }); + const resultOnlyRightDrawer = getTabsByDisplayMode({ + pageLayout, + isMobile: false, + isInRightDrawer: true, + }); + + expect(resultBothTrue).toEqual(resultOnlyMobile); + expect(resultBothTrue).toEqual(resultOnlyRightDrawer); + expect(resultBothTrue.tabsToRenderInTabList).toEqual(tabs); + expect(resultBothTrue.pinnedLeftTab).toBeUndefined(); + }); + }); +}); diff --git a/packages/twenty-front/src/modules/page-layout/utils/getTabsByDisplayMode.ts b/packages/twenty-front/src/modules/page-layout/utils/getTabsByDisplayMode.ts new file mode 100644 index 00000000000..f10f4b98f8e --- /dev/null +++ b/packages/twenty-front/src/modules/page-layout/utils/getTabsByDisplayMode.ts @@ -0,0 +1,38 @@ +import { type DraftPageLayout } from '@/page-layout/types/draft-page-layout'; +import { type PageLayout } from '@/page-layout/types/PageLayout'; +import { PageLayoutType } from '~/generated/graphql'; + +type GetTabsByDisplayModeParams = { + pageLayout: PageLayout | DraftPageLayout; + isMobile: boolean; + isInRightDrawer: boolean; +}; + +export const getTabsByDisplayMode = ({ + pageLayout, + isMobile, + isInRightDrawer, +}: GetTabsByDisplayModeParams) => { + if ( + isMobile || + isInRightDrawer || + pageLayout.type !== PageLayoutType.RECORD_PAGE + ) { + return { + tabsToRenderInTabList: pageLayout.tabs, + pinnedLeftTab: undefined, + }; + } + + const tabsToRenderInTabList = pageLayout.tabs.filter( + (tab) => tab.selfDisplayMode !== 'pinned-left', + ); + const pinnedLeftTab = pageLayout.tabs.find( + (tab) => tab.selfDisplayMode === 'pinned-left', + ); + + return { + tabsToRenderInTabList, + pinnedLeftTab, + }; +}; diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageLeftContainer.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageLeftContainer.tsx index 114dbccc2d1..5261441f12e 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageLeftContainer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageLeftContainer.tsx @@ -30,15 +30,14 @@ const StyledIntermediateContainer = styled.div` `; export type ShowPageLeftContainerProps = { - forceMobile: boolean; children: ReactNode; }; export const ShowPageLeftContainer = ({ - forceMobile = false, children, }: ShowPageLeftContainerProps) => { - const isMobile = useIsMobile() || forceMobile; + const isMobile = useIsMobile(); + return ( {isMobile ? ( diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSubContainer.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSubContainer.tsx index 2f5b5108915..aacf3040335 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSubContainer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSubContainer.tsx @@ -117,7 +117,7 @@ export const ShowPageSubContainer = ({ value={{ instanceId: tabListComponentId }} > {displaySummaryAndFields && ( - + {summaryCard} {fieldsCard}