diff --git a/packages/twenty-front/src/modules/page-layout/components/PageLayoutInitializationQueryEffect.tsx b/packages/twenty-front/src/modules/page-layout/components/PageLayoutInitializationQueryEffect.tsx index 8376e0dab8..f9affeb06e 100644 --- a/packages/twenty-front/src/modules/page-layout/components/PageLayoutInitializationQueryEffect.tsx +++ b/packages/twenty-front/src/modules/page-layout/components/PageLayoutInitializationQueryEffect.tsx @@ -1,11 +1,13 @@ import { useBasePageLayout } from '@/page-layout/hooks/useBasePageLayout'; import { usePageLayoutWithRelationWidgets } from '@/page-layout/hooks/usePageLayoutWithRelationWidgets'; +import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode'; import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState'; import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState'; import { pageLayoutIsInitializedComponentState } from '@/page-layout/states/pageLayoutIsInitializedComponentState'; import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState'; import { type PageLayout } from '@/page-layout/types/PageLayout'; import { convertPageLayoutToTabLayouts } from '@/page-layout/utils/convertPageLayoutToTabLayouts'; +import { isPageLayoutEmpty } from '@/page-layout/utils/isPageLayoutEmpty'; import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState'; import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState'; import { useStore } from 'jotai'; @@ -15,12 +17,10 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; type PageLayoutInitializationQueryEffectProps = { pageLayoutId: string; - onInitialized?: (pageLayout: PageLayout) => void; }; export const PageLayoutInitializationQueryEffect = ({ pageLayoutId, - onInitialized, }: PageLayoutInitializationQueryEffectProps) => { const [pageLayoutIsInitialized, setPageLayoutIsInitialized] = useAtomComponentState(pageLayoutIsInitializedComponentState); @@ -29,6 +29,9 @@ export const PageLayoutInitializationQueryEffect = ({ const pageLayout = usePageLayoutWithRelationWidgets(basePageLayout); + const { setIsPageLayoutInEditMode } = + useSetIsPageLayoutInEditMode(pageLayoutId); + const pageLayoutPersistedComponentCallbackState = useAtomComponentStateCallbackState(pageLayoutPersistedComponentState); @@ -48,22 +51,26 @@ export const PageLayoutInitializationQueryEffect = ({ if (!isDeeplyEqual(layout, currentPersisted)) { store.set(pageLayoutPersistedComponentCallbackState, layout); - store.set(pageLayoutDraftComponentCallbackState, { - id: layout.id, - name: layout.name, - type: layout.type, - objectMetadataId: layout.objectMetadataId, - tabs: layout.tabs, - }); - - const tabLayouts = convertPageLayoutToTabLayouts(layout); - store.set(pageLayoutCurrentLayoutsComponentCallbackState, tabLayouts); } + + store.set(pageLayoutDraftComponentCallbackState, { + id: layout.id, + name: layout.name, + type: layout.type, + objectMetadataId: layout.objectMetadataId, + tabs: layout.tabs, + }); + + const tabLayouts = convertPageLayoutToTabLayouts(layout); + store.set(pageLayoutCurrentLayoutsComponentCallbackState, tabLayouts); + + setIsPageLayoutInEditMode(isPageLayoutEmpty(layout)); }, [ pageLayoutCurrentLayoutsComponentCallbackState, pageLayoutDraftComponentCallbackState, pageLayoutPersistedComponentCallbackState, + setIsPageLayoutInEditMode, store, ], ); @@ -71,14 +78,12 @@ export const PageLayoutInitializationQueryEffect = ({ useEffect(() => { if (!pageLayoutIsInitialized && isDefined(pageLayout)) { initializePageLayout(pageLayout); - onInitialized?.(pageLayout); setPageLayoutIsInitialized(true); } }, [ initializePageLayout, pageLayoutIsInitialized, pageLayout, - onInitialized, setPageLayoutIsInitialized, ]); diff --git a/packages/twenty-front/src/modules/page-layout/components/PageLayoutRenderer.tsx b/packages/twenty-front/src/modules/page-layout/components/PageLayoutRenderer.tsx index 966fec5ab1..281997f3f2 100644 --- a/packages/twenty-front/src/modules/page-layout/components/PageLayoutRenderer.tsx +++ b/packages/twenty-front/src/modules/page-layout/components/PageLayoutRenderer.tsx @@ -1,11 +1,8 @@ import { PageLayoutInitializationQueryEffect } from '@/page-layout/components/PageLayoutInitializationQueryEffect'; import { PageLayoutRelationWidgetsSyncEffect } from '@/page-layout/components/PageLayoutRelationWidgetsSyncEffect'; import { PageLayoutRendererContent } from '@/page-layout/components/PageLayoutRendererContent'; -import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode'; import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext'; -import { type PageLayout } from '@/page-layout/types/PageLayout'; import { getTabListInstanceIdFromPageLayoutAndRecord } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutAndRecord'; -import { isPageLayoutEmpty } from '@/page-layout/utils/isPageLayoutEmpty'; import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext'; import { TabListComponentInstanceContext } from '@/ui/layout/tab-list/states/contexts/TabListComponentInstanceContext'; import 'react-grid-layout/css/styles.css'; @@ -18,19 +15,8 @@ type PageLayoutRendererProps = { export const PageLayoutRenderer = ({ pageLayoutId, }: PageLayoutRendererProps) => { - const { setIsPageLayoutInEditMode } = - useSetIsPageLayoutInEditMode(pageLayoutId); - const { targetRecordIdentifier, layoutType } = useLayoutRenderingContext(); - const onInitialized = (pageLayout: PageLayout) => { - if (isPageLayoutEmpty(pageLayout)) { - setIsPageLayoutInEditMode(true); - } else { - setIsPageLayoutInEditMode(false); - } - }; - const tabListInstanceId = getTabListInstanceIdFromPageLayoutAndRecord({ pageLayoutId, layoutType, @@ -48,10 +34,7 @@ export const PageLayoutRenderer = ({ instanceId: tabListInstanceId, }} > - + 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 991aeac0a4..958fe7725d 100644 --- a/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx +++ b/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx @@ -1,4 +1,3 @@ -import { useNavigatePageLayoutSidePanel } from '@/side-panel/pages/page-layout/hooks/useNavigatePageLayoutSidePanel'; import { PageLayoutLeftPanel } from '@/page-layout/components/PageLayoutLeftPanel'; import { PageLayoutTabList } from '@/page-layout/components/PageLayoutTabList'; import { PageLayoutTabListEffect } from '@/page-layout/components/PageLayoutTabListEffect'; @@ -15,17 +14,18 @@ import { getTabsByDisplayMode } from '@/page-layout/utils/getTabsByDisplayMode'; import { getTabsWithVisibleWidgets } from '@/page-layout/utils/getTabsWithVisibleWidgets'; import { shouldEnableTabEditingFeatures } from '@/page-layout/utils/shouldEnableTabEditingFeatures'; import { sortTabsByPosition } from '@/page-layout/utils/sortTabsByPosition'; +import { useNavigatePageLayoutSidePanel } from '@/side-panel/pages/page-layout/hooks/useNavigatePageLayoutSidePanel'; import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; -import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; +import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState'; import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; import { SidePanelPages } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; -import { useIsMobile } from 'twenty-ui/utilities'; import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { useIsMobile } from 'twenty-ui/utilities'; const StyledContainer = styled.div<{ hasPinnedTab: boolean }>` display: grid; @@ -115,6 +115,10 @@ export const PageLayoutRendererContent = () => { const sortedTabs = sortTabsByPosition(tabsToRenderInTabList); + const activeTabExistsInCurrentPageLayout = currentPageLayout.tabs.some( + (tab) => tab.id === activeTabId, + ); + return ( {isDefined(pinnedLeftTab) && ( @@ -151,7 +155,7 @@ export const PageLayoutRendererContent = () => { )} defaultEnableXScroll={false} > - {isDefined(activeTabId) && ( + {isDefined(activeTabId) && activeTabExistsInCurrentPageLayout && ( )} diff --git a/packages/twenty-front/src/modules/page-layout/hooks/useCurrentPageLayout.ts b/packages/twenty-front/src/modules/page-layout/hooks/useCurrentPageLayout.ts index 621d6d70db..109239bb96 100644 --- a/packages/twenty-front/src/modules/page-layout/hooks/useCurrentPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/hooks/useCurrentPageLayout.ts @@ -2,6 +2,7 @@ import { isPageLayoutInEditModeComponentState } from '@/page-layout/states/isPag import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState'; import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; +import { isNonEmptyString } from '@sniptt/guards'; export const useCurrentPageLayout = () => { const pageLayoutPersisted = useAtomComponentStateValue( @@ -16,8 +17,12 @@ export const useCurrentPageLayout = () => { isPageLayoutInEditModeComponentState, ); + const isDraftInitialized = isNonEmptyString(pageLayoutDraft.id); + const currentPageLayout = isPageLayoutInEditMode - ? pageLayoutDraft + ? isDraftInitialized + ? pageLayoutDraft + : pageLayoutPersisted : pageLayoutPersisted; return { currentPageLayout }; diff --git a/packages/twenty-front/src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectFormObjectLevelTableRow.tsx b/packages/twenty-front/src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectFormObjectLevelTableRow.tsx index e2f7f193b7..89f462ef25 100644 --- a/packages/twenty-front/src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectFormObjectLevelTableRow.tsx +++ b/packages/twenty-front/src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectFormObjectLevelTableRow.tsx @@ -19,6 +19,7 @@ const StyledPermissionContent = styled.div` align-items: center; display: flex; gap: ${themeCssVariables.spacing[2]}; + white-space: nowrap; `; const StyledPermissionLabel = styled.span` @@ -30,6 +31,7 @@ const StyledOverrideInfo = styled.div` color: ${themeCssVariables.font.color.tertiary}; display: flex; gap: ${themeCssVariables.spacing[1]}; + white-space: nowrap; `; type OverridableCheckboxType = 'no_cta' | 'default' | 'override'; diff --git a/packages/twenty-front/src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableRow.tsx b/packages/twenty-front/src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableRow.tsx index 56824c1674..15685e9f96 100644 --- a/packages/twenty-front/src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableRow.tsx +++ b/packages/twenty-front/src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableRow.tsx @@ -12,6 +12,7 @@ const StyledPermissionContent = styled.div` align-items: center; display: flex; gap: ${themeCssVariables.spacing[2]}; + white-space: nowrap; `; const StyledPermissionLabel = styled.span` @@ -23,6 +24,7 @@ const StyledOverrideInfo = styled.div` color: ${themeCssVariables.font.color.tertiary}; display: flex; gap: ${themeCssVariables.spacing[1]}; + white-space: nowrap; `; type SettingsRolePermissionsObjectsTableRowProps = { diff --git a/packages/twenty-front/src/modules/side-panel/pages/page-layout/hooks/usePageLayoutFromContextStoreTargetedRecord.ts b/packages/twenty-front/src/modules/side-panel/pages/page-layout/hooks/usePageLayoutFromContextStoreTargetedRecord.ts index bb2b2640f7..b7e2ffcb5a 100644 --- a/packages/twenty-front/src/modules/side-panel/pages/page-layout/hooks/usePageLayoutFromContextStoreTargetedRecord.ts +++ b/packages/twenty-front/src/modules/side-panel/pages/page-layout/hooks/usePageLayoutFromContextStoreTargetedRecord.ts @@ -1,7 +1,9 @@ import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; +import { currentPageLayoutIdState } from '@/page-layout/states/currentPageLayoutIdState'; import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; +import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; export const usePageLayoutIdFromContextStoreTargetedRecord = () => { const contextStoreTargetedRecordsRule = useAtomComponentStateValue( @@ -21,5 +23,9 @@ export const usePageLayoutIdFromContextStoreTargetedRecord = () => { const recordStore = useAtomFamilyStateValue(recordStoreFamilyState, recordId); - return { pageLayoutId: recordStore?.pageLayoutId }; + const currentPageLayoutId = useAtomStateValue(currentPageLayoutIdState); + + return { + pageLayoutId: recordStore?.pageLayoutId ?? currentPageLayoutId, + }; }; diff --git a/packages/twenty-front/src/modules/ui/input/components/SettingsTextInput.tsx b/packages/twenty-front/src/modules/ui/input/components/SettingsTextInput.tsx index 0576d6452a..28fa767983 100644 --- a/packages/twenty-front/src/modules/ui/input/components/SettingsTextInput.tsx +++ b/packages/twenty-front/src/modules/ui/input/components/SettingsTextInput.tsx @@ -29,7 +29,6 @@ export const SettingsTextInput = ({ autoFocusOnMount, autoSelectOnMount, dataTestId, - className, ...props }: SettingsTextInputProps) => { const inputRef = useRef(null);