From cd15d108b9a1d1896036a33b8f83213874da6d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Tue, 2 Jun 2026 08:44:18 +0200 Subject: [PATCH 01/17] feat(settings): move settings chrome into a single rounded card Replace SubMenuTopBarContainer with SettingsPageLayout: the breadcrumb, centered title, actions, an optional secondary bar (tabs or wizard step) and the 760px body now live inside one rounded card, with SidePanelForDesktop as a sibling. Title, tabs and body share one centered axis regardless of card width. - Add SettingsPageLayout, SettingsPageHeader, SettingsSecondaryBar, SettingsTabBar and SettingsWizardStepBar under @/settings/components/layout - Migrate the AI, APIs & Webhooks, Applications, Members and Role pages plus the object detail page to render their tabs in the secondary bar - Render the two role object-level steps in a wizard step bar with working back navigation - Consolidate Accounts into General/Emails/Calendars tabs; AccountsEmails and AccountsCalendars now resolve to accounts#emails and accounts#calendars so existing links deep-link via hash sync --- .../modules/app/components/SettingsRoutes.tsx | 22 ---- ...gsAccountsEditImapSmtpCaldavConnection.tsx | 6 +- .../SettingsAccountsNewEmailGroupChannel.tsx | 6 +- ...ngsAccountsNewImapSmtpCaldavConnection.tsx | 6 +- .../components/layout/SettingsPageHeader.tsx | 85 ++++++++++++++ .../components/layout/SettingsPageLayout.tsx | 106 +++++++++++++++++ .../layout/SettingsSecondaryBar.tsx | 21 ++++ .../components/layout/SettingsTabBar.tsx | 77 ++++++++++++ .../layout/SettingsWizardStepBar.tsx | 66 +++++++++++ .../SettingsDevelopersWebhookForm.tsx | 7 +- .../components/SettingPublicDomain.tsx | 6 +- .../components/SettingsCustomDomain.tsx | 6 +- .../domains/components/SettingsSubdomain.tsx | 6 +- ...gsRolePermissionsObjectLevelObjectForm.tsx | 25 +++- .../roles/role/components/SettingsRole.tsx | 23 ++-- .../components/SubMenuTopBarContainer.tsx | 84 ------------- .../src/pages/settings/SettingsBilling.tsx | 6 +- .../src/pages/settings/SettingsProfile.tsx | 6 +- .../SettingsTwoFactorAuthenticationMethod.tsx | 6 +- .../src/pages/settings/SettingsUsage.tsx | 6 +- .../settings/SettingsUsageUserDetail.tsx | 13 +- .../src/pages/settings/SettingsWorkspace.tsx | 6 +- .../pages/settings/SettingsWorkspaceEmail.tsx | 6 +- .../settings/accounts/SettingsAccounts.tsx | 96 +++++++++++---- .../accounts/SettingsAccountsCalendars.tsx | 34 ------ ...tingsAccountsConfigurationStepCalendar.tsx | 6 +- ...SettingsAccountsConfigurationStepEmail.tsx | 6 +- .../accounts/SettingsAccountsEmails.tsx | 34 ------ .../settings/accounts/SettingsNewAccount.tsx | 6 +- .../SettingsAccountsCalendars.stories.tsx | 104 ---------------- .../SettingsAccountsEmails.stories.tsx | 111 ------------------ .../settings/admin-panel/SettingsAdmin.tsx | 6 +- .../SettingsAdminAiProviderDetail.tsx | 6 +- ...cationRegistrationConfigVariableDetail.tsx | 6 +- ...ingsAdminApplicationRegistrationDetail.tsx | 6 +- .../SettingsAdminConfigVariableDetails.tsx | 6 +- .../SettingsAdminIndicatorHealthStatus.tsx | 6 +- .../SettingsAdminInferredVersion.tsx | 6 +- .../SettingsAdminInstanceStatus.tsx | 6 +- .../admin-panel/SettingsAdminNewAiModel.tsx | 6 +- .../SettingsAdminNewAiProvider.tsx | 6 +- .../admin-panel/SettingsAdminQueueDetail.tsx | 6 +- .../admin-panel/SettingsAdminUserDetail.tsx | 6 +- .../SettingsAdminWorkspaceChatThread.tsx | 6 +- .../SettingsAdminWorkspaceDetail.tsx | 6 +- .../SettingsAdminWorkspacesStatus.tsx | 6 +- .../src/pages/settings/ai/SettingsAI.tsx | 18 +-- .../pages/settings/ai/SettingsAgentForm.tsx | 6 +- .../settings/ai/SettingsAgentTurnDetail.tsx | 14 +-- .../pages/settings/ai/SettingsAiPrompts.tsx | 6 +- .../settings/ai/SettingsAiUsageUserDetail.tsx | 10 +- .../pages/settings/ai/SettingsSkillForm.tsx | 6 +- .../pages/settings/ai/SettingsToolDetail.tsx | 6 +- ...ttingsApplicationCommandMenuItemDetail.tsx | 6 +- .../SettingsApplicationConnectionDetail.tsx | 6 +- .../SettingsApplicationDetails.tsx | 6 +- ...ettingsApplicationFrontComponentDetail.tsx | 6 +- ...SettingsApplicationRegistrationDetails.tsx | 6 +- .../applications/SettingsApplications.tsx | 15 ++- .../SettingsAvailableApplicationDetails.tsx | 6 +- ...ttingsApplicationConnectionDetail.test.tsx | 4 +- ...cationRegistrationConfigVariableDetail.tsx | 6 +- .../settings/data-model/SettingsNewObject.tsx | 6 +- .../data-model/SettingsObjectDetailPage.tsx | 62 +++++----- .../data-model/SettingsObjectFieldEdit.tsx | 6 +- .../data-model/SettingsObjectOverview.tsx | 6 +- .../settings/data-model/SettingsObjects.tsx | 6 +- .../SettingsObjectNewFieldConfigure.tsx | 6 +- .../SettingsObjectNewFieldSelect.tsx | 6 +- .../new-index/SettingsObjectNewIndex.tsx | 6 +- .../SettingsDevelopersApiKeyDetail.tsx | 6 +- .../api-keys/SettingsDevelopersApiKeysNew.tsx | 6 +- .../webhooks/components/SettingsWebhooks.tsx | 6 +- .../SettingsEmailingDomainDetail.tsx | 6 +- .../SettingsNewEmailingDomain.tsx | 6 +- .../enterprise/SettingsEnterprise.tsx | 6 +- .../pages/settings/layout/SettingsLayout.tsx | 6 +- .../SettingsLayoutDetailScaffold.tsx | 6 +- .../SettingsLogicFunctionDetail.tsx | 6 +- .../members/SettingsWorkspaceMember.tsx | 6 +- .../members/SettingsWorkspaceMembers.tsx | 12 +- .../roles/SettingsRoleAddObjectLevel.tsx | 15 ++- .../components/SettingsExperience.tsx | 6 +- .../settings/security/SettingsSecurity.tsx | 6 +- .../SettingsSecurityApprovedAccessDomain.tsx | 6 +- .../SettingsSecuritySSOIdentifyProvider.tsx | 6 +- .../settings/updates/SettingsUpdates.tsx | 6 +- .../workspace/SettingsApiWebhooks.tsx | 19 +-- ...ttingsWorkspaceEmailGroupChannelDetail.tsx | 6 +- .../twenty-shared/src/types/SettingsPath.ts | 4 +- 90 files changed, 759 insertions(+), 706 deletions(-) create mode 100644 packages/twenty-front/src/modules/settings/components/layout/SettingsPageHeader.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/layout/SettingsPageLayout.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/layout/SettingsSecondaryBar.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/layout/SettingsTabBar.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/layout/SettingsWizardStepBar.tsx delete mode 100644 packages/twenty-front/src/modules/ui/layout/page/components/SubMenuTopBarContainer.tsx delete mode 100644 packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx delete mode 100644 packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmails.tsx delete mode 100644 packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx delete mode 100644 packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsEmails.stories.tsx diff --git a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx index 5e250fbd180eb..e03a103f9017a 100644 --- a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx +++ b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx @@ -24,20 +24,6 @@ const SettingsRestPlayground = lazy(() => ), ); -const SettingsAccountsCalendars = lazy(() => - import('~/pages/settings/accounts/SettingsAccountsCalendars').then( - (module) => ({ - default: module.SettingsAccountsCalendars, - }), - ), -); - -const SettingsAccountsEmails = lazy(() => - import('~/pages/settings/accounts/SettingsAccountsEmails').then((module) => ({ - default: module.SettingsAccountsEmails, - })), -); - const SettingsAccountsConfiguration = lazy(() => import('~/pages/settings/accounts/SettingsAccountsConfiguration').then( (module) => ({ @@ -631,14 +617,6 @@ export const SettingsRoutes = ({ isAdminPageEnabled }: SettingsRoutesProps) => ( path={SettingsPath.AccountsConfiguration} element={} /> - } - /> - } - /> } diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEditImapSmtpCaldavConnection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEditImapSmtpCaldavConnection.tsx index 08072ca8dbcb4..2915570c6d628 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEditImapSmtpCaldavConnection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEditImapSmtpCaldavConnection.tsx @@ -5,7 +5,7 @@ import { useParams } from 'react-router-dom'; import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { SettingsPath } from 'twenty-shared/types'; import { Loader } from 'twenty-ui/feedback'; @@ -64,7 +64,7 @@ export const SettingsAccountsEditImapSmtpCaldavConnection = () => { const renderForm = () => ( // oxlint-disable-next-line react/jsx-props-no-spreading - { existingProtocols={existingProtocols} /> - + ); diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsNewEmailGroupChannel.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsNewEmailGroupChannel.tsx index fa07c2abc00a0..d5439a90ad1ae 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsNewEmailGroupChannel.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsNewEmailGroupChannel.tsx @@ -12,7 +12,7 @@ import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useNavigateSettings } from '~/hooks/useNavigateSettings'; export const SettingsAccountsNewEmailGroupChannel = () => { @@ -45,7 +45,7 @@ export const SettingsAccountsNewEmailGroupChannel = () => { }, [createEmailGroupChannel, handle, navigate, enqueueErrorSnackBar, t]); return ( - { /> - + ); }; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsNewImapSmtpCaldavConnection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsNewImapSmtpCaldavConnection.tsx index d8e1c23e73e5a..bda25b5aef660 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsNewImapSmtpCaldavConnection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsNewImapSmtpCaldavConnection.tsx @@ -3,7 +3,7 @@ import { FormProvider } from 'react-hook-form'; import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; @@ -30,7 +30,7 @@ export const SettingsAccountsNewImapSmtpCaldavConnection = () => { return ( // oxlint-disable-next-line react/jsx-props-no-spreading - { - + ); }; diff --git a/packages/twenty-front/src/modules/settings/components/layout/SettingsPageHeader.tsx b/packages/twenty-front/src/modules/settings/components/layout/SettingsPageHeader.tsx new file mode 100644 index 0000000000000..35579a604fc32 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/layout/SettingsPageHeader.tsx @@ -0,0 +1,85 @@ +import { useNavigationDrawerExpanded } from '@/navigation/hooks/useNavigationDrawerExpanded'; +import { + Breadcrumb, + type BreadcrumbProps, +} from '@/ui/navigation/bread-crumb/components/Breadcrumb'; +import { NavigationDrawerCollapseButton } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerCollapseButton'; +import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; +import { styled } from '@linaria/react'; +import { type ReactNode } from 'react'; +import { isDefined } from 'twenty-shared/utils'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; + +type SettingsPageHeaderProps = { + links: BreadcrumbProps['links']; + title?: ReactNode; + tag?: ReactNode; + actionButton?: ReactNode; +}; + +// Header row inside the settings card. Symmetric padding + 1fr / auto / 1fr grid +// keep the title centered on the same vertical axis as the tabs and body content. +const StyledHeader = styled.div` + align-items: center; + box-sizing: border-box; + display: grid; + gap: ${themeCssVariables.spacing[2]}; + grid-template-columns: 1fr auto 1fr; + padding: ${themeCssVariables.spacing[3]}; + width: 100%; +`; + +const StyledLeft = styled.div` + align-items: center; + display: flex; + gap: ${themeCssVariables.spacing[1]}; + justify-self: start; + min-width: 0; + overflow: hidden; +`; + +const StyledTitle = styled.div` + align-items: center; + color: ${themeCssVariables.font.color.primary}; + display: flex; + font-size: ${themeCssVariables.font.size.md}; + font-weight: ${themeCssVariables.font.weight.semiBold}; + gap: ${themeCssVariables.spacing[2]}; + min-width: 0; + text-align: center; +`; + +const StyledRight = styled.div` + align-items: center; + display: flex; + gap: ${themeCssVariables.spacing[2]}; + justify-content: flex-end; + justify-self: end; + min-width: 0; +`; + +export const SettingsPageHeader = ({ + links, + title, + tag, + actionButton, +}: SettingsPageHeaderProps) => { + const isMobile = useIsMobile(); + const isNavigationDrawerExpanded = useNavigationDrawerExpanded(); + + return ( + + + {!isNavigationDrawerExpanded && ( + + )} + + + + {!isMobile && isDefined(title) && title} + {!isMobile && tag} + + {actionButton} + + ); +}; diff --git a/packages/twenty-front/src/modules/settings/components/layout/SettingsPageLayout.tsx b/packages/twenty-front/src/modules/settings/components/layout/SettingsPageLayout.tsx new file mode 100644 index 0000000000000..9c011f00c6bf1 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/layout/SettingsPageLayout.tsx @@ -0,0 +1,106 @@ +import { CommandMenuForMobile } from '@/command-menu/components/CommandMenuForMobile'; +import { useCommandMenuHotKeys } from '@/command-menu/hooks/useCommandMenuHotKeys'; +import { InformationBannerWrapper } from '@/information-banner/components/InformationBannerWrapper'; +import { SettingsPageHeader } from '@/settings/components/layout/SettingsPageHeader'; +import { SettingsSecondaryBar } from '@/settings/components/layout/SettingsSecondaryBar'; +import { SidePanelForDesktop } from '@/side-panel/components/SidePanelForDesktop'; +import { type BreadcrumbProps } from '@/ui/navigation/bread-crumb/components/Breadcrumb'; +import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; +import { styled } from '@linaria/react'; +import { type JSX, type ReactNode } from 'react'; +import { isDefined } from 'twenty-shared/utils'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; + +const SETTINGS_CONTENT_MAX_WIDTH = 760; + +type SettingsPageLayoutProps = { + links: BreadcrumbProps['links']; + title?: ReactNode; + actionButton?: ReactNode; + secondaryBar?: ReactNode; + children: ReactNode; + // className styles the root; tag renders beside the centered title. + className?: string; + tag?: JSX.Element; +}; + +const StyledRoot = styled.div<{ isMobile: boolean }>` + display: flex; + flex: 1; + flex-direction: row; + min-height: 0; + min-width: 0; + padding: ${({ isMobile }) => + isMobile ? themeCssVariables.spacing[1] : themeCssVariables.spacing[2]}; +`; + +const StyledMainCardWrapper = styled.div` + display: flex; + flex: 1 1 0; + min-width: 0; + width: 0; +`; + +// The single rounded card that bounds the whole settings chrome: header, secondary +// bar and body all live inside it, against the noisy background that shows in the gap. +const StyledCard = styled.div` + background: ${themeCssVariables.background.primary}; + border: 1px solid ${themeCssVariables.border.color.medium}; + border-radius: ${themeCssVariables.border.radius.md}; + box-sizing: border-box; + display: flex; + flex: 1; + flex-direction: column; + min-height: 0; + overflow: hidden; + width: 100%; +`; + +// flex: 1 + min-height: 0 keep this in the card's overflow chain so the scroll +// happens inside the body rather than collapsing to content height. +const StyledBodyContent = styled.div` + display: flex; + flex: 1; + flex-direction: column; + margin: 0 auto; + max-width: ${SETTINGS_CONTENT_MAX_WIDTH}px; + min-height: 0; + width: 100%; +`; + +export const SettingsPageLayout = ({ + links, + title, + actionButton, + secondaryBar, + children, + tag, + className, +}: SettingsPageLayoutProps) => { + const isMobile = useIsMobile(); + + useCommandMenuHotKeys(); + + return ( + + + + + {isDefined(secondaryBar) && ( + {secondaryBar} + )} + + + {children} + + + + {isMobile ? : } + + ); +}; diff --git a/packages/twenty-front/src/modules/settings/components/layout/SettingsSecondaryBar.tsx b/packages/twenty-front/src/modules/settings/components/layout/SettingsSecondaryBar.tsx new file mode 100644 index 0000000000000..353cc1f6156c5 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/layout/SettingsSecondaryBar.tsx @@ -0,0 +1,21 @@ +import { styled } from '@linaria/react'; +import { type ReactNode } from 'react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; + +// The secondary row that sits between the header and the body, bracketed by a +// top + bottom border. Holds either or . +const StyledSecondaryBar = styled.div` + align-items: center; + border-bottom: 1px solid ${themeCssVariables.border.color.light}; + border-top: 1px solid ${themeCssVariables.border.color.light}; + box-sizing: border-box; + display: flex; + flex-shrink: 0; + min-height: ${themeCssVariables.spacing[10]}; + padding: 0 ${themeCssVariables.spacing[3]}; + width: 100%; +`; + +export const SettingsSecondaryBar = ({ children }: { children: ReactNode }) => ( + {children} +); diff --git a/packages/twenty-front/src/modules/settings/components/layout/SettingsTabBar.tsx b/packages/twenty-front/src/modules/settings/components/layout/SettingsTabBar.tsx new file mode 100644 index 0000000000000..9933462add199 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/layout/SettingsTabBar.tsx @@ -0,0 +1,77 @@ +import { TabListFromUrlOptionalEffect } from '@/ui/layout/tab-list/components/TabListFromUrlOptionalEffect'; +import { TAB_LIST_GAP } from '@/ui/layout/tab-list/constants/TabListGap'; +import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; +import { TabListComponentInstanceContext } from '@/ui/layout/tab-list/states/contexts/TabListComponentInstanceContext'; +import { type SingleTabProps } from '@/ui/layout/tab-list/types/SingleTabProps'; +import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState'; +import { styled } from '@linaria/react'; +import { useEffect } from 'react'; +import { TabButton } from 'twenty-ui/input'; + +type SettingsTabBarProps = { + tabs: SingleTabProps[]; + componentInstanceId: string; + loading?: boolean; +}; + +const StyledTabBar = styled.div` + display: flex; + flex: 1; + gap: ${TAB_LIST_GAP}px; + justify-content: center; + min-width: 0; +`; + +// Centered settings tab row. Shares the same component-scoped activeTabId atom + +// URL hash sync as the shared TabList, so pages keep reading activeTabId by their +// existing componentInstanceId while the bar lives in the header instead of the body. +export const SettingsTabBar = ({ + tabs, + componentInstanceId, + loading, +}: SettingsTabBarProps) => { + const visibleTabs = tabs.filter((tab) => !tab.hide); + + const [activeTabId, setActiveTabId] = useAtomComponentState( + activeTabIdComponentState, + componentInstanceId, + ); + + const activeTabExists = visibleTabs.some((tab) => tab.id === activeTabId); + const initialActiveTabId = activeTabExists ? activeTabId : visibleTabs[0]?.id; + + useEffect(() => { + setActiveTabId(initialActiveTabId ?? null); + }, [initialActiveTabId, setActiveTabId]); + + if (visibleTabs.length === 0) { + return null; + } + + return ( + + tab.id)} + /> + + {visibleTabs.map((tab) => ( + + ))} + + + ); +}; diff --git a/packages/twenty-front/src/modules/settings/components/layout/SettingsWizardStepBar.tsx b/packages/twenty-front/src/modules/settings/components/layout/SettingsWizardStepBar.tsx new file mode 100644 index 0000000000000..537d80862f121 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/layout/SettingsWizardStepBar.tsx @@ -0,0 +1,66 @@ +import { styled } from '@linaria/react'; +import { type ReactNode } from 'react'; +import { IconChevronLeft } from 'twenty-ui/display'; +import { LightIconButton } from 'twenty-ui/input'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; + +type SettingsWizardStepBarProps = { + label: ReactNode; + onBack?: () => void; + trailing?: ReactNode; +}; + +const StyledStepBar = styled.div` + align-items: center; + display: grid; + flex: 1; + grid-template-columns: 1fr auto 1fr; + min-width: 0; +`; + +const StyledLeft = styled.div` + align-items: center; + display: flex; + justify-self: start; + min-width: 0; +`; + +const StyledLabel = styled.div` + color: ${themeCssVariables.font.color.primary}; + font-size: ${themeCssVariables.font.size.md}; + font-weight: ${themeCssVariables.font.weight.semiBold}; + justify-self: center; + min-width: 0; + text-align: center; +`; + +const StyledRight = styled.div` + align-items: center; + display: flex; + gap: ${themeCssVariables.spacing[2]}; + justify-content: flex-end; + justify-self: end; + min-width: 0; +`; + +// Wizard step row: back arrow left, "N. Label" centered, optional trailing button right. +export const SettingsWizardStepBar = ({ + label, + onBack, + trailing, +}: SettingsWizardStepBarProps) => ( + + + {onBack && ( + + )} + + {label} + {trailing} + +); diff --git a/packages/twenty-front/src/modules/settings/developers/components/SettingsDevelopersWebhookForm.tsx b/packages/twenty-front/src/modules/settings/developers/components/SettingsDevelopersWebhookForm.tsx index d955f1f52a014..497a93148b25e 100644 --- a/packages/twenty-front/src/modules/settings/developers/components/SettingsDevelopersWebhookForm.tsx +++ b/packages/twenty-front/src/modules/settings/developers/components/SettingsDevelopersWebhookForm.tsx @@ -9,7 +9,7 @@ import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput'; import { TextArea } from '@/ui/input/components/TextArea'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; import { useModal } from '@/ui/layout/modal/hooks/useModal'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { Trans, useLingui } from '@lingui/react/macro'; import { SettingsPath } from 'twenty-shared/types'; import { @@ -72,9 +72,8 @@ export const SettingsDevelopersWebhookForm = ({ return ( // oxlint-disable-next-line react/jsx-props-no-spreading - )} - + {!isCreationMode && ( { }; return ( - { /> - + ); }; diff --git a/packages/twenty-front/src/modules/settings/domains/components/SettingsCustomDomain.tsx b/packages/twenty-front/src/modules/settings/domains/components/SettingsCustomDomain.tsx index 94bcefaffa600..d921fe9e29ba3 100644 --- a/packages/twenty-front/src/modules/settings/domains/components/SettingsCustomDomain.tsx +++ b/packages/twenty-front/src/modules/settings/domains/components/SettingsCustomDomain.tsx @@ -7,7 +7,7 @@ import { SettingsDomainRecords } from '@/settings/domains/components/SettingsDom import { useSettingsCustomDomain } from '@/settings/domains/hooks/useSettingsCustomDomain'; import { customDomainRecordsState } from '@/settings/domains/states/customDomainRecordsState'; import { TextInput } from '@/ui/input/components/TextInput'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { Trans, useLingui } from '@lingui/react/macro'; import { styled } from '@linaria/react'; @@ -62,7 +62,7 @@ export const SettingsCustomDomain = () => { } = useSettingsCustomDomain(); return ( - { )} - + ); }; diff --git a/packages/twenty-front/src/modules/settings/domains/components/SettingsSubdomain.tsx b/packages/twenty-front/src/modules/settings/domains/components/SettingsSubdomain.tsx index 722e15071fa24..27b11e0544abf 100644 --- a/packages/twenty-front/src/modules/settings/domains/components/SettingsSubdomain.tsx +++ b/packages/twenty-front/src/modules/settings/domains/components/SettingsSubdomain.tsx @@ -8,7 +8,7 @@ import { } from '@/settings/domains/hooks/useSettingsSubdomain'; import { TextInput } from '@/ui/input/components/TextInput'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { Trans, useLingui } from '@lingui/react/macro'; import { styled } from '@linaria/react'; @@ -41,7 +41,7 @@ export const SettingsSubdomain = () => { return ( <> - { - + { const [searchParams] = useSearchParams(); + const navigate = useNavigate(); const fromAgentId = searchParams.get('fromAgent'); const currentWorkspace = useAtomStateValue(currentWorkspaceState); @@ -119,6 +121,13 @@ export const SettingsRolePermissionsObjectLevelObjectForm = ({ ? getSettingsPath(SettingsPath.AiAgentDetail, { agentId: agent.id }) : getSettingsPath(SettingsPath.RoleDetail, { roleId }); + const previousStepPath = `${getSettingsPath(SettingsPath.RoleAddObjectLevel, { + roleId, + })}${fromAgentId ? `?fromAgent=${fromAgentId}` : ''}`; + + const headerTitle = + fromAgentId && isDefined(agent) ? agent.label : settingsDraftRole.label; + const objectPredicates = settingsDraftRole.rowLevelPermissionPredicates?.filter( (predicate) => predicate.objectMetadataId === objectMetadataItem.id, @@ -138,8 +147,8 @@ export const SettingsRolePermissionsObjectLevelObjectForm = ({ const isFinishDisabled = hasInvalidPredicate; return ( - } + secondaryBar={ + navigate(previousStepPath)} + /> + } > - + ); }; diff --git a/packages/twenty-front/src/modules/settings/roles/role/components/SettingsRole.tsx b/packages/twenty-front/src/modules/settings/roles/role/components/SettingsRole.tsx index 4996e35b1f53d..87facfdd173db 100644 --- a/packages/twenty-front/src/modules/settings/roles/role/components/SettingsRole.tsx +++ b/packages/twenty-front/src/modules/settings/roles/role/components/SettingsRole.tsx @@ -10,8 +10,8 @@ import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDr import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState'; import { settingsRolesIsLoadingState } from '@/settings/roles/states/settingsRolesIsLoadingState'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; -import { TabList } from '@/ui/layout/tab-list/components/TabList'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; +import { SettingsTabBar } from '@/settings/components/layout/SettingsTabBar'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import { useLoadCurrentUser } from '@/users/hooks/useLoadCurrentUser'; @@ -134,8 +134,16 @@ export const SettingsRole = ({ roleId, isCreateMode }: SettingsRoleProps) => { } return ( - } + secondaryBar={ + + } links={[ { children: t`Workspace`, @@ -165,13 +173,6 @@ export const SettingsRole = ({ roleId, isCreateMode }: SettingsRoleProps) => { } > - {activeTabId === SETTINGS_ROLE_DETAIL_TABS.TABS_IDS.ASSIGNMENT && ( )} @@ -189,6 +190,6 @@ export const SettingsRole = ({ roleId, isCreateMode }: SettingsRoleProps) => { /> )} - + ); }; diff --git a/packages/twenty-front/src/modules/ui/layout/page/components/SubMenuTopBarContainer.tsx b/packages/twenty-front/src/modules/ui/layout/page/components/SubMenuTopBarContainer.tsx deleted file mode 100644 index 1a68e76e93641..0000000000000 --- a/packages/twenty-front/src/modules/ui/layout/page/components/SubMenuTopBarContainer.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { InformationBannerWrapper } from '@/information-banner/components/InformationBannerWrapper'; -import { MainContainerLayoutWithSidePanel } from '@/object-record/components/MainContainerLayoutWithSidePanel'; -import { - Breadcrumb, - type BreadcrumbProps, -} from '@/ui/navigation/bread-crumb/components/Breadcrumb'; -import { isDefined } from 'twenty-shared/utils'; -import { styled } from '@linaria/react'; -import { type JSX, type ReactNode } from 'react'; -import { PageHeader } from './PageHeader'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; - -type SubMenuTopBarContainerProps = { - children: JSX.Element | JSX.Element[]; - title?: string | JSX.Element; - reserveTitleSpace?: boolean; - actionButton?: ReactNode; - className?: string; - links: BreadcrumbProps['links']; - tag?: JSX.Element; -}; - -const SETTINGS_CONTENT_MAX_WIDTH = 760; - -const StyledContainer = styled.div` - display: flex; - flex-direction: column; - width: 100%; -`; - -// flex: 1 + min-height: 0 are required for PagePanel's overflow chain — the -// child must participate in the flex height calc rather than collapse to content. -const StyledBodyContentWrapper = styled.div` - display: flex; - flex: 1; - flex-direction: column; - margin: 0 auto; - max-width: ${SETTINGS_CONTENT_MAX_WIDTH}px; - min-height: 0; - width: 100%; -`; - -const StyledTitle = styled.span<{ reserveTitleSpace?: boolean }>` - color: ${themeCssVariables.font.color.primary}; - display: flex; - font-size: ${themeCssVariables.font.size.lg}; - font-weight: ${themeCssVariables.font.weight.semiBold}; - gap: ${themeCssVariables.spacing[2]}; - line-height: 1.2; - margin: ${themeCssVariables.spacing[8]} ${themeCssVariables.spacing[8]} - ${themeCssVariables.spacing[2]}; - min-height: ${({ reserveTitleSpace }) => - reserveTitleSpace ? themeCssVariables.spacing[5] : 'none'}; -`; - -export const SubMenuTopBarContainer = ({ - children, - title, - tag, - reserveTitleSpace, - actionButton, - className, - links, -}: SubMenuTopBarContainerProps) => { - return ( - - }> - {actionButton} - - - - - {(isDefined(title) || reserveTitleSpace === true) && ( - - {title} - {tag} - - )} - {children} - - - - ); -}; diff --git a/packages/twenty-front/src/pages/settings/SettingsBilling.tsx b/packages/twenty-front/src/pages/settings/SettingsBilling.tsx index 3a566f18a8ee2..ff1a4224fcf6e 100644 --- a/packages/twenty-front/src/pages/settings/SettingsBilling.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsBilling.tsx @@ -1,7 +1,7 @@ import { Trans, useLingui } from '@lingui/react/macro'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { SettingsBillingContent } from '@/settings/billing/components/SettingsBillingContent'; import { getSettingsPath } from 'twenty-shared/utils'; import { SettingsPath } from 'twenty-shared/types'; @@ -15,7 +15,7 @@ export const SettingsBilling = () => { const { isPlansLoaded } = usePlans(); return ( - { ]} > {currentWorkspace && isPlansLoaded ? : <>} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/SettingsProfile.tsx b/packages/twenty-front/src/pages/settings/SettingsProfile.tsx index 075064b719440..840f858b709e6 100644 --- a/packages/twenty-front/src/pages/settings/SettingsProfile.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsProfile.tsx @@ -8,7 +8,7 @@ import { NameFields } from '@/settings/profile/components/NameFields'; import { WorkspaceMemberPictureUploader } from '@/settings/workspace-member/components/WorkspaceMemberPictureUploader'; import { useCanChangePassword } from '@/settings/profile/hooks/useCanChangePassword'; import { useCurrentUserWorkspaceTwoFactorAuthentication } from '@/settings/two-factor-authentication/hooks/useCurrentUserWorkspaceTwoFactorAuthentication'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { Trans, useLingui } from '@lingui/react/macro'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { SettingsPath } from 'twenty-shared/types'; @@ -35,7 +35,7 @@ export const SettingsProfile = () => { } return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx b/packages/twenty-front/src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx index f30ad05db3d51..742ce9f2dd601 100644 --- a/packages/twenty-front/src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx @@ -12,7 +12,7 @@ import { TwoFactorAuthenticationVerificationForSettings } from '@/settings/two-f import { useCurrentUserWorkspaceTwoFactorAuthentication } from '@/settings/two-factor-authentication/hooks/useCurrentUserWorkspaceTwoFactorAuthentication'; import { useTwoFactorVerificationForSettings } from '@/settings/two-factor-authentication/hooks/useTwoFactorVerificationForSettings'; import { extractSecretFromOtpUri } from '@/settings/two-factor-authentication/utils/extractSecretFromOtpUri'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; import { H2Title } from 'twenty-ui/display'; @@ -110,7 +110,7 @@ export const SettingsTwoFactorAuthenticationMethod = () => { return ( // oxlint-disable-next-line react/jsx-props-no-spreading - { )} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/SettingsUsage.tsx b/packages/twenty-front/src/pages/settings/SettingsUsage.tsx index ff861926a3faf..d74283c89203c 100644 --- a/packages/twenty-front/src/pages/settings/SettingsUsage.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsUsage.tsx @@ -1,7 +1,7 @@ import { Trans, useLingui } from '@lingui/react/macro'; import { SettingsUsageAnalyticsSection } from '@/settings/usage/components/SettingsUsageAnalyticsSection'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { getSettingsPath } from 'twenty-shared/utils'; import { SettingsPath } from 'twenty-shared/types'; @@ -9,7 +9,7 @@ export const SettingsUsage = () => { const { t } = useLingui(); return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/SettingsUsageUserDetail.tsx b/packages/twenty-front/src/pages/settings/SettingsUsageUserDetail.tsx index e8f984b6b9761..d7367f761970f 100644 --- a/packages/twenty-front/src/pages/settings/SettingsUsageUserDetail.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsUsageUserDetail.tsx @@ -6,7 +6,7 @@ import { UsageDailyChartSection } from '@/settings/usage/components/UsageDailyCh import { UsageSectionSkeleton } from '@/settings/usage/components/UsageSectionSkeleton'; import { useUsageAnalyticsData } from '@/settings/usage/hooks/useUsageAnalyticsData'; import { useUsageValueFormatter } from '@/settings/usage/hooks/useUsageValueFormatter'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; import { Trans, useLingui } from '@lingui/react/macro'; @@ -89,10 +89,7 @@ export const SettingsUsageUserDetail = () => { if (isInitialLoading) { return ( - + { - + ); } return ( - + { sectionId="user-type" /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/SettingsWorkspace.tsx b/packages/twenty-front/src/pages/settings/SettingsWorkspace.tsx index 81f8680426c23..8c783635bb813 100644 --- a/packages/twenty-front/src/pages/settings/SettingsWorkspace.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsWorkspace.tsx @@ -5,7 +5,7 @@ import { SettingsWorkspaceDomainCard } from '@/settings/domains/components/Setti import { DeleteWorkspace } from '@/settings/profile/components/DeleteWorkspace'; import { NameField } from '@/settings/workspace/components/NameField'; import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { SettingsPath } from 'twenty-shared/types'; @@ -21,7 +21,7 @@ export const SettingsWorkspace = () => { ); return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/SettingsWorkspaceEmail.tsx b/packages/twenty-front/src/pages/settings/SettingsWorkspaceEmail.tsx index d2b5d9bccc63e..ccc396e3e433c 100644 --- a/packages/twenty-front/src/pages/settings/SettingsWorkspaceEmail.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsWorkspaceEmail.tsx @@ -4,7 +4,7 @@ import { isEmailGroupEnabledState } from '@/client-config/states/isEmailGroupEna import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsWorkspaceEmailGroupSection } from '@/settings/workspace/components/SettingsWorkspaceEmailGroupSection'; import { SettingsWorkspaceEmailingDomainsSection } from '@/settings/workspace/components/SettingsWorkspaceEmailingDomainsSection'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { FeatureFlagKey, SettingsPath } from 'twenty-shared/types'; @@ -25,7 +25,7 @@ export const SettingsWorkspaceEmail = () => { const showEmailGroupSection = isEmailGroupEnabled; return ( - { {showEmailGroupSection && } - + ); }; diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccounts.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccounts.tsx index a25028f81e107..2b58fb788e1e5 100644 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccounts.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccounts.tsx @@ -1,34 +1,70 @@ -import { SettingsPath } from 'twenty-shared/types'; -import { SettingsSectionSkeletonLoader } from '@/settings/components/SettingsSectionSkeletonLoader'; import { SettingsAccountsBlocklistSection } from '@/settings/accounts/components/SettingsAccountsBlocklistSection'; +import { SettingsAccountsCalendarChannelsContainer } from '@/settings/accounts/components/SettingsAccountsCalendarChannelsContainer'; import { SettingsAccountsConnectedAccountsListCard } from '@/settings/accounts/components/SettingsAccountsConnectedAccountsListCard'; +import { SettingsAccountsMessageChannelsContainer } from '@/settings/accounts/components/SettingsAccountsMessageChannelsContainer'; import { SettingsAccountsSettingsSection } from '@/settings/accounts/components/SettingsAccountsSettingsSection'; import { useMyConnectedAccounts } from '@/settings/accounts/hooks/useMyConnectedAccounts'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsSectionSkeletonLoader } from '@/settings/components/SettingsSectionSkeletonLoader'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; +import { SettingsTabBar } from '@/settings/components/layout/SettingsTabBar'; +import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; +import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import { useLingui } from '@lingui/react/macro'; +import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; -import { H2Title } from 'twenty-ui/display'; +import { + H2Title, + IconCalendarEvent, + IconMail, + IconSettings, +} from 'twenty-ui/display'; import { Section } from 'twenty-ui/layout'; +const SETTINGS_ACCOUNTS_TABS_INSTANCE_ID = 'settings-accounts-tabs'; + +// Tab ids double as URL hashes (#emails, #calendars), so SettingsPath.AccountsEmails +// and AccountsCalendars deep-link straight to the matching tab via hash sync. +const ACCOUNTS_TAB_GENERAL = 'general'; +const ACCOUNTS_TAB_EMAILS = 'emails'; +const ACCOUNTS_TAB_CALENDARS = 'calendars'; + export const SettingsAccounts = () => { const { t } = useLingui(); const { accounts: allAccounts, loading } = useMyConnectedAccounts(); - return ( - - - {loading ? ( + const activeTabId = useAtomComponentStateValue( + activeTabIdComponentState, + SETTINGS_ACCOUNTS_TABS_INSTANCE_ID, + ); + + const tabs = [ + { id: ACCOUNTS_TAB_GENERAL, title: t`General`, Icon: IconSettings }, + { id: ACCOUNTS_TAB_EMAILS, title: t`Emails`, Icon: IconMail }, + { + id: ACCOUNTS_TAB_CALENDARS, + title: t`Calendars`, + Icon: IconCalendarEvent, + }, + ]; + + const renderActiveTabContent = () => { + switch (activeTabId) { + case ACCOUNTS_TAB_EMAILS: + return ( +
+ +
+ ); + case ACCOUNTS_TAB_CALENDARS: + return ( +
+ +
+ ); + default: + return loading ? ( ) : ( <> @@ -44,8 +80,28 @@ export const SettingsAccounts = () => { - )} -
-
+ ); + } + }; + + return ( + + } + links={[ + { + children: t`User`, + href: getSettingsPath(SettingsPath.ProfilePage), + }, + { children: t`Account` }, + ]} + > + {renderActiveTabContent()} + ); }; diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx deleted file mode 100644 index 3211c3bedf885..0000000000000 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsCalendars.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { SettingsAccountsCalendarChannelsContainer } from '@/settings/accounts/components/SettingsAccountsCalendarChannelsContainer'; -import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; -import { Trans, useLingui } from '@lingui/react/macro'; -import { SettingsPath } from 'twenty-shared/types'; -import { getSettingsPath } from 'twenty-shared/utils'; -import { Section } from 'twenty-ui/layout'; - -export const SettingsAccountsCalendars = () => { - const { t } = useLingui(); - - return ( - User, - href: getSettingsPath(SettingsPath.ProfilePage), - }, - { - children: Accounts, - href: getSettingsPath(SettingsPath.Accounts), - }, - { children: Calendars }, - ]} - > - -
- -
-
-
- ); -}; diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx index 5cf5c512ec7db..6b957b454838f 100644 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx @@ -4,7 +4,7 @@ import { type CalendarChannel } from '@/accounts/types/CalendarChannel'; import { type MessageChannel } from '@/accounts/types/MessageChannel'; import { SettingsAccountsCalendarChannelDetails } from '@/settings/accounts/components/SettingsAccountsCalendarChannelDetails'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath, isDefined } from 'twenty-shared/utils'; import { IconDeviceFloppy } from 'twenty-ui/display'; @@ -29,7 +29,7 @@ export const SettingsAccountsConfigurationStepCalendar = ({ const stepTitle = t`${stepNumber}. Calendar`; return ( - - + ); }; diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx index e438e489af461..6aa71e4ca0511 100644 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx @@ -3,7 +3,7 @@ import { Trans, useLingui } from '@lingui/react/macro'; import { type MessageChannel } from '@/accounts/types/MessageChannel'; import { SettingsAccountsMessageChannelDetails } from '@/settings/accounts/components/SettingsAccountsMessageChannelDetails'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; import { IconChevronRight, IconPlus } from 'twenty-ui/display'; @@ -27,7 +27,7 @@ export const SettingsAccountsConfigurationStepEmail = ({ const { t } = useLingui(); return ( - - + ); }; diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmails.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmails.tsx deleted file mode 100644 index 67cdf0bb41eb1..0000000000000 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmails.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { SettingsAccountsMessageChannelsContainer } from '@/settings/accounts/components/SettingsAccountsMessageChannelsContainer'; -import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; -import { useLingui } from '@lingui/react/macro'; -import { SettingsPath } from 'twenty-shared/types'; -import { getSettingsPath } from 'twenty-shared/utils'; -import { Section } from 'twenty-ui/layout'; - -export const SettingsAccountsEmails = () => { - const { t } = useLingui(); - - return ( - - -
- -
-
-
- ); -}; diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsNewAccount.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsNewAccount.tsx index b76a080e27750..30bbedff85906 100644 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsNewAccount.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/SettingsNewAccount.tsx @@ -1,13 +1,13 @@ import { SettingsNewAccountSection } from '@/settings/accounts/components/SettingsNewAccountSection'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { t } from '@lingui/core/macro'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; export const SettingsNewAccount = () => { return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx b/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx deleted file mode 100644 index 209cb396d9ffb..0000000000000 --- a/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsCalendars.stories.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { type Meta, type StoryObj } from '@storybook/react-vite'; -import { HttpResponse, graphql } from 'msw'; -import { SettingsAccountsCalendars } from '~/pages/settings/accounts/SettingsAccountsCalendars'; - -import { - PageDecorator, - type PageDecoratorArgs, -} from '~/testing/decorators/PageDecorator'; -import { graphqlMocks } from '~/testing/graphqlMocks'; - -const meta: Meta = { - title: 'Pages/Settings/Accounts/SettingsAccountsCalendars', - component: SettingsAccountsCalendars, - decorators: [PageDecorator], - args: { - routePath: '/settings/accounts/calendars', - }, - parameters: { - layout: 'fullscreen', - msw: graphqlMocks, - }, -}; - -export default meta; - -export type Story = StoryObj; - -export const NoConnectedAccount: Story = {}; - -export const TwoConnectedAccounts: Story = { - parameters: { - msw: { - handlers: [ - ...graphqlMocks.handlers, - graphql.query('MyConnectedAccounts', () => { - return HttpResponse.json({ - data: { - myConnectedAccounts: [ - { - id: '20202020-954c-4d76-9a87-e5f072d4b7ef', - handle: 'test.test@gmail.com', - provider: 'google', - authFailedAt: null, - scopes: ['calendar'], - handleAliases: '', - lastSignedInAt: null, - userWorkspaceId: '20202020-03f2-4d83-b0d5-2ec2bcee72d4', - connectionProviderId: null, - name: 'Test User', - visibility: 'SHARE_EVERYTHING', - lastCredentialsRefreshedAt: null, - connectionParameters: null, - createdAt: '2024-07-03T20:03:35.064Z', - updatedAt: '2024-07-03T20:03:35.064Z', - }, - ], - }, - }); - }), - graphql.query('MyCalendarChannels', () => { - return HttpResponse.json({ - data: { - myCalendarChannels: [ - { - id: '20202020-ef5a-4822-9e08-ce6e6a4dcb6f', - handle: 'test.test@gmail.com', - connectedAccountId: '20202020-954c-4d76-9a87-e5f072d4b7ef', - isSyncEnabled: true, - syncStage: 'CALENDAR_EVENT_LIST_FETCH_PENDING', - syncStatus: 'COMPLETED', - visibility: 'SHARE_EVERYTHING', - contactAutoCreationPolicy: 'SENT', - isContactAutoCreationEnabled: true, - createdAt: '2024-07-03T20:03:11.903Z', - updatedAt: '2024-07-03T20:03:11.903Z', - }, - { - id: '20202020-ef5a-4822-9e08-ce6e6a4dcb6a', - handle: 'test.test2@gmail.com', - connectedAccountId: '20202020-954c-4d76-9a87-e5f072d4b7ef', - isSyncEnabled: true, - syncStage: 'PARTIAL_CALENDAR_EVENT_LIST_FETCH_PENDING', - syncStatus: 'COMPLETED', - visibility: 'SHARE_EVERYTHING', - contactAutoCreationPolicy: 'SENT', - isContactAutoCreationEnabled: true, - createdAt: '2024-07-03T20:03:11.903Z', - updatedAt: '2024-07-03T20:03:11.903Z', - }, - ], - }, - }); - }), - graphql.query('MyMessageChannels', () => { - return HttpResponse.json({ - data: { - myMessageChannels: [], - }, - }); - }), - ], - }, - }, -}; diff --git a/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsEmails.stories.tsx b/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsEmails.stories.tsx deleted file mode 100644 index e34f9581d0ce4..0000000000000 --- a/packages/twenty-front/src/pages/settings/accounts/__stories__/SettingsAccountsEmails.stories.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { type Meta, type StoryObj } from '@storybook/react-vite'; -import { HttpResponse, graphql } from 'msw'; - -import { - PageDecorator, - type PageDecoratorArgs, -} from '~/testing/decorators/PageDecorator'; -import { graphqlMocks } from '~/testing/graphqlMocks'; - -import { SettingsAccountsEmails } from '~/pages/settings/accounts/SettingsAccountsEmails'; - -const meta: Meta = { - title: 'Pages/Settings/Accounts/SettingsAccountsEmails', - component: SettingsAccountsEmails, - decorators: [PageDecorator], - args: { - routePath: '/settings/accounts/emails', - }, - parameters: { - layout: 'fullscreen', - msw: graphqlMocks, - }, -}; - -export default meta; - -export type Story = StoryObj; - -export const NoConnectedAccount: Story = {}; - -export const TwoConnectedAccounts: Story = { - parameters: { - msw: { - handlers: [ - ...graphqlMocks.handlers, - graphql.query('MyConnectedAccounts', () => { - return HttpResponse.json({ - data: { - myConnectedAccounts: [ - { - id: '20202020-954c-4d76-9a87-e5f072d4b7ef', - handle: 'test.test@gmail.com', - provider: 'google', - authFailedAt: null, - scopes: ['email'], - handleAliases: '', - lastSignedInAt: null, - userWorkspaceId: '20202020-03f2-4d83-b0d5-2ec2bcee72d4', - connectionProviderId: null, - name: 'Test User', - visibility: 'SHARE_EVERYTHING', - lastCredentialsRefreshedAt: null, - connectionParameters: null, - createdAt: '2024-07-03T20:03:35.064Z', - updatedAt: '2024-07-03T20:03:35.064Z', - }, - ], - }, - }); - }), - graphql.query('MyMessageChannels', () => { - return HttpResponse.json({ - data: { - myMessageChannels: [ - { - id: '20202020-ef5a-4822-9e08-ce6e6a4dcb6f', - handle: 'test.test@gmail.com', - connectedAccountId: '20202020-954c-4d76-9a87-e5f072d4b7ef', - type: 'email', - isSyncEnabled: true, - syncStage: 'MESSAGE_LIST_FETCH_PENDING', - syncStatus: 'COMPLETED', - visibility: 'SHARE_EVERYTHING', - contactAutoCreationPolicy: 'SENT', - isContactAutoCreationEnabled: true, - excludeNonProfessionalEmails: true, - excludeGroupEmails: true, - createdAt: '2024-07-03T20:03:11.903Z', - updatedAt: '2024-07-03T20:03:11.903Z', - }, - { - id: '20202020-ef5a-4822-9e08-ce6e6a4dcb6a', - handle: 'test.test2@gmail.com', - connectedAccountId: '20202020-954c-4d76-9a87-e5f072d4b7ef', - type: 'email', - isSyncEnabled: true, - syncStage: 'MESSAGE_LIST_FETCH_PENDING', - syncStatus: 'COMPLETED', - visibility: 'SHARE_EVERYTHING', - contactAutoCreationPolicy: 'SENT', - isContactAutoCreationEnabled: true, - excludeNonProfessionalEmails: true, - excludeGroupEmails: true, - createdAt: '2024-07-03T20:03:11.903Z', - updatedAt: '2024-07-03T20:03:11.903Z', - }, - ], - }, - }); - }), - graphql.query('MyCalendarChannels', () => { - return HttpResponse.json({ - data: { - myCalendarChannels: [], - }, - }); - }), - ], - }, - }, -}; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdmin.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdmin.tsx index e17eba5ec6ef6..da303a0a60eb8 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdmin.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdmin.tsx @@ -1,6 +1,6 @@ import { SettingsAdminContent } from '@/settings/admin-panel/components/SettingsAdminContent'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useLingui } from '@lingui/react/macro'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; @@ -9,7 +9,7 @@ export const SettingsAdmin = () => { const { t } = useLingui(); return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminAiProviderDetail.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminAiProviderDetail.tsx index 3d9a93014e0f6..6b36f157d6c15 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminAiProviderDetail.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminAiProviderDetail.tsx @@ -40,7 +40,7 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContain import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; import { useModal } from '@/ui/layout/modal/hooks/useModal'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { type AdminAiModelConfig, SetAdminAiModelEnabledDocument, @@ -303,7 +303,7 @@ export const SettingsAdminAiProviderDetail = () => { } return ( - { confirmButtonText={t`Remove`} confirmButtonAccent="danger" /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminApplicationRegistrationConfigVariableDetail.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminApplicationRegistrationConfigVariableDetail.tsx index 8ff039323acd1..3a33e24f5ea4c 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminApplicationRegistrationConfigVariableDetail.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminApplicationRegistrationConfigVariableDetail.tsx @@ -8,7 +8,7 @@ import { } from '~/generated-admin/graphql'; import { useApolloAdminClient } from '@/settings/admin-panel/apollo/hooks/useApolloAdminClient'; import { APPLICATION_REGISTRATION_ADMIN_PATH } from '@/settings/admin-panel/apps/constants/ApplicationRegistrationAdminPath'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { getSettingsPath } from 'twenty-shared/utils'; import { SettingsPath } from 'twenty-shared/types'; import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader'; @@ -73,7 +73,7 @@ export const SettingsAdminApplicationRegistrationConfigVariableDetail = () => { }; return ( - { variable={variable} onUpdateVariable={onUpdateVariable} /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminApplicationRegistrationDetail.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminApplicationRegistrationDetail.tsx index 001df7de7117e..eb2fb0f01e8e0 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminApplicationRegistrationDetail.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminApplicationRegistrationDetail.tsx @@ -4,7 +4,7 @@ import { FindOneAdminApplicationRegistrationDocument } from '~/generated-admin/g import { getSettingsPath, isDefined } from 'twenty-shared/utils'; import { SettingsPath } from 'twenty-shared/types'; import { useLingui } from '@lingui/react/macro'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useApolloAdminClient } from '@/settings/admin-panel/apollo/hooks/useApolloAdminClient'; import { APPLICATION_REGISTRATION_ADMIN_PATH } from '@/settings/admin-panel/apps/constants/ApplicationRegistrationAdminPath'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; @@ -102,7 +102,7 @@ export const SettingsAdminApplicationRegistrationDetail = () => { }; return ( - { /> {renderActiveTabContent()} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx index 8af066cf7aaa3..a9d386f7395ee 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx @@ -9,7 +9,7 @@ import { ConfigVariableValueInput } from '@/settings/admin-panel/config-variable import { useConfigVariableActions } from '@/settings/admin-panel/config-variables/hooks/useConfigVariableActions'; import { ConfigVariableEdit } from '@/settings/config-variables/components/ConfigVariableEdit'; import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { SettingsPath, type ConfigVariableValue } from 'twenty-shared/types'; import { getSettingsPath, isDefined } from 'twenty-shared/utils'; @@ -97,7 +97,7 @@ export const SettingsAdminConfigVariableDetails = () => { }; return ( - { /> } /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx index 513aa90bd8419..aefaaaba30357 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx @@ -4,7 +4,7 @@ import { SettingsAdminIndicatorHealthStatusContent } from '@/settings/admin-pane import { SettingsAdminIndicatorHealthContext } from '@/settings/admin-panel/health-status/contexts/SettingsAdminIndicatorHealthContext'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { styled } from '@linaria/react'; import { useLingui } from '@lingui/react/macro'; import { useParams } from 'react-router-dom'; @@ -47,7 +47,7 @@ export const SettingsAdminIndicatorHealthStatus = () => { } return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminInferredVersion.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminInferredVersion.tsx index 57e49e7a06f28..a76178e477e33 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminInferredVersion.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminInferredVersion.tsx @@ -2,7 +2,7 @@ import { useApolloAdminClient } from '@/settings/admin-panel/apollo/hooks/useApo import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsTableCard } from '@/settings/components/SettingsTableCard'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useMutation, useQuery } from '@apollo/client/react'; import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; @@ -63,7 +63,7 @@ export const SettingsAdminInferredVersion = () => { }; return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminInstanceStatus.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminInstanceStatus.tsx index d2ed70884e5ae..530328b950f23 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminInstanceStatus.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminInstanceStatus.tsx @@ -3,7 +3,7 @@ import { getUpgradeHealthStatusBadge } from '@/settings/admin-panel/utils/getUpg import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsTableCard } from '@/settings/components/SettingsTableCard'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { UserContext } from '@/users/contexts/UserContext'; import { useMutation, useQuery } from '@apollo/client/react'; @@ -94,7 +94,7 @@ export const SettingsAdminInstanceStatus = () => { }; return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminNewAiModel.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminNewAiModel.tsx index 339044bfff65a..a34ac244f01e8 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminNewAiModel.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminNewAiModel.tsx @@ -23,7 +23,7 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContain import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { Select } from '@/ui/input/components/Select'; import { TextInput } from '@/ui/input/components/TextInput'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { Checkbox, Toggle } from 'twenty-ui/input'; const StyledComboInputContainer = styled.div` @@ -278,7 +278,7 @@ export const SettingsAdminNewAiModel = () => { return (
- { /> - +
); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx index abc5c9961577b..fb1203a9cbc89 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx @@ -25,7 +25,7 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContain import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { Select } from '@/ui/input/components/Select'; import { TextInput } from '@/ui/input/components/TextInput'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; type ModelsDevProvider = { id: string; modelCount: number; npm: AiSdkPackage }; @@ -229,7 +229,7 @@ export const SettingsAdminNewAiProvider = () => { return (
- { )} - +
); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx index 9385c34fd8052..f4a0c05ae5c79 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx @@ -1,6 +1,6 @@ import { SettingsAdminQueueJobsTable } from '@/settings/admin-panel/health-status/components/SettingsAdminQueueJobsTable'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { plural, t } from '@lingui/core/macro'; import { useState } from 'react'; import { useParams } from 'react-router-dom'; @@ -52,7 +52,7 @@ export const SettingsAdminQueueDetail = () => { : t`Loading retention configuration...`; return ( - { /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminUserDetail.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminUserDetail.tsx index e2e222c259148..0b4837560d5d6 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminUserDetail.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminUserDetail.tsx @@ -19,7 +19,7 @@ import { useHandleImpersonate } from '@/settings/admin-panel/hooks/useHandleImpe import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader'; import { SettingsTableCard } from '@/settings/components/SettingsTableCard'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceLogo'; @@ -123,7 +123,7 @@ export const SettingsAdminUserDetail = () => { } return ( - { )} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceChatThread.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceChatThread.tsx index 53e42f652ed99..ba13817a90d1b 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceChatThread.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceChatThread.tsx @@ -11,7 +11,7 @@ import { SettingsAdminChatThreadMessageList } from '@/settings/admin-panel/compo import { GET_ADMIN_CHAT_THREAD_MESSAGES } from '@/settings/admin-panel/graphql/queries/getAdminChatThreadMessages'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { H2Title } from 'twenty-ui/display'; import { Section } from 'twenty-ui/layout'; import { type GetAdminChatThreadMessagesQuery } from '~/generated-admin/graphql'; @@ -40,7 +40,7 @@ export const SettingsAdminWorkspaceChatThread = () => { } return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceDetail.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceDetail.tsx index a2f82505fe5d1..1becb061c3884 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceDetail.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspaceDetail.tsx @@ -21,7 +21,7 @@ import { useHandleImpersonate } from '@/settings/admin-panel/hooks/useHandleImpe import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { Table } from '@/ui/layout/table/components/Table'; @@ -201,7 +201,7 @@ export const SettingsAdminWorkspaceDetail = () => { } return ( - { )} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspacesStatus.tsx b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspacesStatus.tsx index ff3b7327d71e8..e84719994f4cb 100644 --- a/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspacesStatus.tsx +++ b/packages/twenty-front/src/pages/settings/admin-panel/SettingsAdminWorkspacesStatus.tsx @@ -3,7 +3,7 @@ import { SettingsAdminWorkspacesByHealthAccordion } from '@/settings/admin-panel import { SettingsAdminWorkspacesStatusSummaryCard } from '@/settings/admin-panel/health-status/components/SettingsAdminWorkspacesStatusSummaryCard'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useMutation, useQuery } from '@apollo/client/react'; import { styled } from '@linaria/react'; import { plural, t } from '@lingui/core/macro'; @@ -70,7 +70,7 @@ export const SettingsAdminWorkspacesStatus = () => { }; return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/ai/SettingsAI.tsx b/packages/twenty-front/src/pages/settings/ai/SettingsAI.tsx index e971ece7b5cb1..5c069f20b88d1 100644 --- a/packages/twenty-front/src/pages/settings/ai/SettingsAI.tsx +++ b/packages/twenty-front/src/pages/settings/ai/SettingsAI.tsx @@ -1,7 +1,7 @@ import { SettingsDiscoveryHeroCard } from '@/settings/components/SettingsDiscoveryHeroCard'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; -import { TabList } from '@/ui/layout/tab-list/components/TabList'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; +import { SettingsTabBar } from '@/settings/components/layout/SettingsTabBar'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import { SettingsPath } from 'twenty-shared/types'; @@ -76,8 +76,14 @@ export const SettingsAI = () => { const isUsageTab = resolvedTabId === SETTINGS_AI_TABS.TABS_IDS.USAGE; return ( - + } actionButton={ isSkillsTab ? ( @@ -136,16 +142,12 @@ export const SettingsAI = () => { playButtonAriaLabel={t`Watch AI demo`} /> - {isOverviewTab && } {isModelsTab && } {isSkillsTab && } {isToolsTab && } {isUsageTab && } - + ); }; diff --git a/packages/twenty-front/src/pages/settings/ai/SettingsAgentForm.tsx b/packages/twenty-front/src/pages/settings/ai/SettingsAgentForm.tsx index 6dfdd573b8bcd..7d8c933d89992 100644 --- a/packages/twenty-front/src/pages/settings/ai/SettingsAgentForm.tsx +++ b/packages/twenty-front/src/pages/settings/ai/SettingsAgentForm.tsx @@ -10,7 +10,7 @@ import { useSaveDraftRoleToDB } from '@/settings/roles/role/hooks/useSaveDraftRo import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState'; import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; @@ -401,7 +401,7 @@ export const SettingsAgentForm = ({ mode }: { mode: 'create' | 'edit' }) => { return ( <> - { )} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/ai/SettingsAgentTurnDetail.tsx b/packages/twenty-front/src/pages/settings/ai/SettingsAgentTurnDetail.tsx index ad4429d27c8ab..2e22bf74308a2 100644 --- a/packages/twenty-front/src/pages/settings/ai/SettingsAgentTurnDetail.tsx +++ b/packages/twenty-front/src/pages/settings/ai/SettingsAgentTurnDetail.tsx @@ -1,7 +1,7 @@ import { AiChatAssistantMessageRenderer } from '@/ai/components/AiChatAssistantMessageRenderer'; import { mapDBMessagesToUIMessages } from '@/ai/utils/mapDBMessagesToUIMessages'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { Table } from '@/ui/layout/table/components/Table'; import { TableCell } from '@/ui/layout/table/components/TableCell'; import { TableHeader } from '@/ui/layout/table/components/TableHeader'; @@ -74,7 +74,7 @@ export const SettingsAgentTurnDetail = () => { if (loading) { return ( - { - + ); } if (!turn) { return ( - {
{t`Turn not found`}
-
+ ); } return ( - { )} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/ai/SettingsAiPrompts.tsx b/packages/twenty-front/src/pages/settings/ai/SettingsAiPrompts.tsx index fda214ee600be..1a055f1ee590c 100644 --- a/packages/twenty-front/src/pages/settings/ai/SettingsAiPrompts.tsx +++ b/packages/twenty-front/src/pages/settings/ai/SettingsAiPrompts.tsx @@ -3,7 +3,7 @@ import { styled } from '@linaria/react'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { FormAdvancedTextFieldInput } from '@/object-record/record-field/ui/form-types/components/FormAdvancedTextFieldInput'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { useQuery } from '@apollo/client/react'; import { t } from '@lingui/core/macro'; @@ -71,7 +71,7 @@ export const SettingsAiPrompts = () => { : ''; return ( - { - + ); }; diff --git a/packages/twenty-front/src/pages/settings/ai/SettingsAiUsageUserDetail.tsx b/packages/twenty-front/src/pages/settings/ai/SettingsAiUsageUserDetail.tsx index d642d30078fe1..5e36bfb816c00 100644 --- a/packages/twenty-front/src/pages/settings/ai/SettingsAiUsageUserDetail.tsx +++ b/packages/twenty-front/src/pages/settings/ai/SettingsAiUsageUserDetail.tsx @@ -6,7 +6,7 @@ import { UsageDailyChartSection } from '@/settings/usage/components/UsageDailyCh import { UsageSectionSkeleton } from '@/settings/usage/components/UsageSectionSkeleton'; import { AI_OPERATION_TYPES } from '@/settings/usage/constants/AiOperationTypes'; import { useUsageAnalyticsData } from '@/settings/usage/hooks/useUsageAnalyticsData'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { t } from '@lingui/core/macro'; import { Trans, useLingui } from '@lingui/react/macro'; import { useParams } from 'react-router-dom'; @@ -49,7 +49,7 @@ export const SettingsAiUsageUserDetail = () => { if (isInitialLoading) { return ( - @@ -57,12 +57,12 @@ export const SettingsAiUsageUserDetail = () => { - + ); } return ( - + {!hasAnyData && (
@@ -102,6 +102,6 @@ export const SettingsAiUsageUserDetail = () => { sectionId="ai-user-model" /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/ai/SettingsSkillForm.tsx b/packages/twenty-front/src/pages/settings/ai/SettingsSkillForm.tsx index c3b6e72af76fe..4e53cb4e08f04 100644 --- a/packages/twenty-front/src/pages/settings/ai/SettingsSkillForm.tsx +++ b/packages/twenty-front/src/pages/settings/ai/SettingsSkillForm.tsx @@ -13,7 +13,7 @@ import { IconPicker } from '@/ui/input/components/IconPicker'; import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput'; import { TextArea } from '@/ui/input/components/TextArea'; import { TitleInput } from '@/ui/input/components/TitleInput'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { t } from '@lingui/core/macro'; import { AppPath, SettingsPath } from 'twenty-shared/types'; import { getSettingsPath, isDefined } from 'twenty-shared/utils'; @@ -422,7 +422,7 @@ export const SettingsSkillForm = ({ mode }: { mode: 'create' | 'edit' }) => { ); return ( - { confirmButtonText={t`Delete`} loading={isSubmitting} /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/ai/SettingsToolDetail.tsx b/packages/twenty-front/src/pages/settings/ai/SettingsToolDetail.tsx index bffbf5c3e43f6..6aa721e6abf7c 100644 --- a/packages/twenty-front/src/pages/settings/ai/SettingsToolDetail.tsx +++ b/packages/twenty-front/src/pages/settings/ai/SettingsToolDetail.tsx @@ -14,7 +14,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { TextArea } from '@/ui/input/components/TextArea'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; import { useModal } from '@/ui/layout/modal/hooks/useModal'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath, isDefined, isValidUuid } from 'twenty-shared/utils'; @@ -169,7 +169,7 @@ export const SettingsToolDetail = () => { }; return ( - { confirmButtonText={t`Delete`} loading={isDeleting} /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationCommandMenuItemDetail.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationCommandMenuItemDetail.tsx index 76deaf83c0311..c676dfbc887bd 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationCommandMenuItemDetail.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationCommandMenuItemDetail.tsx @@ -1,6 +1,6 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsSectionSkeletonLoader } from '@/settings/components/SettingsSectionSkeletonLoader'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useQuery } from '@apollo/client/react'; import { t } from '@lingui/core/macro'; import { useParams } from 'react-router-dom'; @@ -52,7 +52,7 @@ export const SettingsApplicationCommandMenuItemDetail = () => { ]; return ( - @@ -76,6 +76,6 @@ export const SettingsApplicationCommandMenuItemDetail = () => { /> )} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationConnectionDetail.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationConnectionDetail.tsx index 04b7a9b14d2b9..61996313f87dc 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationConnectionDetail.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationConnectionDetail.tsx @@ -23,7 +23,7 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContain import { SettingsSectionSkeletonLoader } from '@/settings/components/SettingsSectionSkeletonLoader'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; import { useModal } from '@/ui/layout/modal/hooks/useModal'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { Table } from '@/ui/layout/table/components/Table'; import { TableCell } from '@/ui/layout/table/components/TableCell'; import { TableHeader } from '@/ui/layout/table/components/TableHeader'; @@ -283,7 +283,7 @@ export const SettingsApplicationConnectionDetail = () => { : []; return ( - { )} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx index 8d4ce446ee5c5..99bb28a26fc60 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx @@ -8,7 +8,7 @@ import { objectMetadataItemsSelector } from '@/object-metadata/states/objectMeta import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFlag'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import type { SingleTabProps } from '@/ui/layout/tab-list/types/SingleTabProps'; @@ -325,7 +325,7 @@ export const SettingsApplicationDetails = () => { return ( - { {renderActiveTabContent()} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationFrontComponentDetail.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationFrontComponentDetail.tsx index dcee044fdea37..a37ea6290cb6b 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationFrontComponentDetail.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationFrontComponentDetail.tsx @@ -1,6 +1,6 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsSectionSkeletonLoader } from '@/settings/components/SettingsSectionSkeletonLoader'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; @@ -97,7 +97,7 @@ export const SettingsApplicationFrontComponentDetail = () => { }; return ( - @@ -105,6 +105,6 @@ export const SettingsApplicationFrontComponentDetail = () => { {loading ? : renderActiveTabContent()} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx index 5dfa07d69057e..b5c71f0652cc0 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx @@ -1,4 +1,4 @@ -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useQuery } from '@apollo/client/react'; import { useParams } from 'react-router-dom'; import { SettingsPath } from 'twenty-shared/types'; @@ -94,7 +94,7 @@ export const SettingsApplicationRegistrationDetails = () => { }; return ( - { /> {renderActiveTabContent()} - + ); }; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsApplications.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsApplications.tsx index d788ae11c233a..c8a3259cacc6b 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsApplications.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsApplications.tsx @@ -1,8 +1,8 @@ import { SettingsDiscoveryHeroCard } from '@/settings/components/SettingsDiscoveryHeroCard'; import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFlag'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; -import { TabList } from '@/ui/layout/tab-list/components/TabList'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; +import { SettingsTabBar } from '@/settings/components/layout/SettingsTabBar'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; @@ -68,8 +68,14 @@ export const SettingsApplications = () => { }; return ( - + } links={[ { children: t`Workspace`, @@ -107,9 +113,8 @@ export const SettingsApplications = () => { playButtonAriaLabel={t`Watch apps demo`} />
- {renderActiveTabContent()}
-
+ ); }; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx index c1816f1941b04..81522da345c5b 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx @@ -4,7 +4,7 @@ import { useInstallMarketplaceAppWithPermissionValidation } from '@/marketplace/ import { useUpgradeApplication } from '@/marketplace/hooks/useUpgradeApplication'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFlag'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; @@ -271,7 +271,7 @@ export const SettingsAvailableApplicationDetails = () => { return ( - { /> {renderActiveTabContent()} - + ({ ), })); -jest.mock('@/ui/layout/page/components/SubMenuTopBarContainer', () => ({ - SubMenuTopBarContainer: ({ children }: { children: ReactNode }) => ( +jest.mock('@/settings/components/layout/SettingsPageLayout', () => ({ + SettingsPageLayout: ({ children }: { children: ReactNode }) => ( <>{children} ), })); diff --git a/packages/twenty-front/src/pages/settings/applications/components/SettingsApplicationRegistrationConfigVariableDetail.tsx b/packages/twenty-front/src/pages/settings/applications/components/SettingsApplicationRegistrationConfigVariableDetail.tsx index 72184c8ece51c..bd2c2fd8cf188 100644 --- a/packages/twenty-front/src/pages/settings/applications/components/SettingsApplicationRegistrationConfigVariableDetail.tsx +++ b/packages/twenty-front/src/pages/settings/applications/components/SettingsApplicationRegistrationConfigVariableDetail.tsx @@ -6,7 +6,7 @@ import { UpdateApplicationRegistrationVariableDocument, } from '~/generated-metadata/graphql'; import { useMutation, useQuery } from '@apollo/client/react'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { getSettingsPath } from 'twenty-shared/utils'; import { SettingsPath } from 'twenty-shared/types'; import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader'; @@ -67,7 +67,7 @@ export const SettingsApplicationRegistrationConfigVariableDetail = () => { }; return ( - { variable={variable} onUpdateVariable={onUpdateVariable} /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/data-model/SettingsNewObject.tsx b/packages/twenty-front/src/pages/settings/data-model/SettingsNewObject.tsx index 49c61f2961672..3ae5923088315 100644 --- a/packages/twenty-front/src/pages/settings/data-model/SettingsNewObject.tsx +++ b/packages/twenty-front/src/pages/settings/data-model/SettingsNewObject.tsx @@ -10,7 +10,7 @@ import { settingsDataModelObjectAboutFormSchema, } from '@/settings/data-model/validation-schemas/settingsDataModelObjectAboutFormSchema'; import { isDDLLockedState } from '@/client-config/states/isDDLLockedState'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { zodResolver } from '@hookform/resolvers/zod'; import { useLingui } from '@lingui/react/macro'; @@ -77,7 +77,7 @@ export const SettingsNewObject = () => { return ( // oxlint-disable-next-line react/jsx-props-no-spreading - { /> - + ); }; diff --git a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectDetailPage.tsx b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectDetailPage.tsx index 11aec7d2a8293..49dd24b7347ed 100644 --- a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectDetailPage.tsx +++ b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectDetailPage.tsx @@ -6,8 +6,8 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContain import { ObjectFields } from '@/settings/data-model/object-details/components/tabs/ObjectFields'; import { ObjectLayout } from '@/settings/data-model/object-details/components/tabs/ObjectLayout'; import { ObjectSettings } from '@/settings/data-model/object-details/components/tabs/ObjectSettings'; -import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; -import { TabList } from '@/ui/layout/tab-list/components/TabList'; +import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout'; +import { SettingsTabBar } from '@/settings/components/layout/SettingsTabBar'; import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { styled } from '@linaria/react'; @@ -133,7 +133,7 @@ export const SettingsObjectDetailPage = () => { return ( <> - { }, ]} actionButton={ - !readonly && - activeTabId === SETTINGS_OBJECT_DETAIL_TABS.TABS_IDS.FIELDS && ( - -