431f6ae98f
## What Replaces `SubMenuTopBarContainer` with a settings-specific `SettingsPageLayout` that puts the whole page chrome — breadcrumb, centered title, actions, an optional secondary bar (tabs or wizard step), and the 760px body — inside **one rounded card**, with `SidePanelForDesktop` as a sibling. Title, tabs and body content share one centered vertical axis at every card width. Supersedes #21122. One PR, no feature flag. ## New components (`@/settings/components/layout/`) - **SettingsPageLayout** — owns the rounded card + side-panel sibling, `useCommandMenuHotKeys`, mobile command menu - **SettingsPageHeader** — breadcrumb · centered title · actions in a symmetric `1fr auto 1fr` grid (symmetric padding throughout) - **SettingsSecondaryBar** — the secondary row, bracketed by top + bottom borders - **SettingsTabBar** — centered tabs reusing `activeTabIdComponentState` + `TabListFromUrlOptionalEffect` for URL-hash sync (does not touch the shared `TabList`) - **SettingsWizardStepBar** — back arrow · "N. Label" · optional trailing slot ## Migrations - Bulk rename across ~80 call sites (`SubMenuTopBarContainer` → `SettingsPageLayout`); old component deleted. - 5 tab pages (AI, APIs & Webhooks, Applications, Members, Role) + the Data Model object-detail page render their tabs in `secondaryBar` (object-detail keeps "See records" / "New Field" in the header actions). - The 2 role object-level steps render the wizard step bar with working back navigation. - Accounts consolidated into **General / Emails / Calendars** tabs; standalone `SettingsAccountsEmails` / `SettingsAccountsCalendars` pages + routes + stories removed. `SettingsPath.AccountsEmails` / `AccountsCalendars` now resolve to `accounts#emails` / `accounts#calendars`, so existing `getSettingsPath()` links deep-link to the right tab via the existing hash sync — no call-site changes. ## Verification - `nx typecheck twenty-front` and `nx lint twenty-front` both clean. - Browser (logged-in workspace): title / tab / body / card centers align on a single axis at multiple widths — width-invariant, so alignment holds when the AI side panel (a sibling) shrinks the card. Rounded card with even gaps on all four sides; tab row bracketed by two 1px lines; no-tab pages render header → body with no lines; wizard back navigation works; `…/accounts#emails` opens the Emails tab. The shared `PageHeader` and `TabList` are untouched. The settings side panel itself isn't wired to open yet — that's a follow-up PR.
63 lines
2.3 KiB
TypeScript
63 lines
2.3 KiB
TypeScript
import { t } from '@lingui/core/macro';
|
|
import { AppBasePath, AppPath, SettingsPath } from 'twenty-shared/types';
|
|
|
|
enum SettingsPathPrefixes {
|
|
Accounts = `${AppBasePath.Settings}/${SettingsPath.Accounts}`,
|
|
Experience = `${AppBasePath.Settings}/${SettingsPath.Experience}`,
|
|
Profile = `${AppBasePath.Settings}/${SettingsPath.ProfilePage}`,
|
|
Objects = `${AppBasePath.Settings}/${SettingsPath.Objects}`,
|
|
Members = `${AppBasePath.Settings}/${SettingsPath.WorkspaceMembersPage}`,
|
|
ApiWebhooks = `${AppBasePath.Settings}/${SettingsPath.ApiWebhooks}`,
|
|
LogicFunctions = `${AppBasePath.Settings}/${SettingsPath.LogicFunctions}`,
|
|
Integration = `${AppBasePath.Settings}/${SettingsPath.Integrations}`,
|
|
General = `${AppBasePath.Settings}/${SettingsPath.General}`,
|
|
Community = `${AppBasePath.Settings}/${SettingsPath.Community}`,
|
|
}
|
|
|
|
const getPathnameOrPrefix = (pathname: string) => {
|
|
for (const prefix of Object.values(SettingsPathPrefixes)) {
|
|
if (pathname.startsWith(prefix)) {
|
|
return prefix;
|
|
}
|
|
}
|
|
return pathname;
|
|
};
|
|
|
|
export const getPageTitleFromPath = (pathname: string): string => {
|
|
const pathnameOrPrefix = getPathnameOrPrefix(pathname);
|
|
switch (pathnameOrPrefix) {
|
|
case AppPath.Verify:
|
|
return t`Verify`;
|
|
case AppPath.SignInUp:
|
|
return t`Sign in or Create an account`;
|
|
case AppPath.Invite:
|
|
return t`Invite`;
|
|
case AppPath.CreateWorkspace:
|
|
return t`Create Workspace`;
|
|
case AppPath.CreateProfile:
|
|
return t`Create Profile`;
|
|
case SettingsPathPrefixes.Experience:
|
|
return t`Experience - Settings`;
|
|
case SettingsPathPrefixes.Accounts:
|
|
return t`Account - Settings`;
|
|
case SettingsPathPrefixes.Profile:
|
|
return t`Profile - Settings`;
|
|
case SettingsPathPrefixes.Members:
|
|
return t`Members - Settings`;
|
|
case SettingsPathPrefixes.Objects:
|
|
return t`Data model - Settings`;
|
|
case SettingsPathPrefixes.ApiWebhooks:
|
|
return t`API Keys - Settings`;
|
|
case SettingsPathPrefixes.LogicFunctions:
|
|
return t`Functions - Settings`;
|
|
case SettingsPathPrefixes.Integration:
|
|
return t`Integrations - Settings`;
|
|
case SettingsPathPrefixes.General:
|
|
return t`General - Settings`;
|
|
case SettingsPathPrefixes.Community:
|
|
return t`Community - Settings`;
|
|
default:
|
|
return 'Twenty';
|
|
}
|
|
};
|