fix(twenty-front): new layout fast-follows — settings drawer, loading & command menu (#21389)

Second batch of new-layout fast-follows (master:
twentyhq/core-team-issues#2478). All changes verified live against a
running workspace.

## Settings drawer & header
- **twentyhq/core-team-issues#2489** — sidebar icons render as plain
16px icons, no background tiles.
- **twentyhq/core-team-issues#2488** — Advanced toggle spans the full
drawer width; yellow dot removed.
- **twentyhq/core-team-issues#2497** — page title stays centered in the
settings header (breadcrumb stays left).
- **twentyhq/core-team-issues#2490** — Exit Settings control aligned to
the workspace switcher (24px, matching padding/gap).
- **twentyhq/core-team-issues#2499** — 2px vertical gap restored between
collapsible drawer section items.
- **twentyhq/core-team-issues#2491** — settings drawer rhythm now
matches the main app (28px items, 2px gaps, 28px section headers).
- **twentyhq/core-team-issues#2492** — Home/Chat tab switch no longer
flickers: both tab subtrees stay mounted (a shared
`NavigationDrawerTabbedContent` toggles visibility instead of remounting
+ flashing the chat skeleton).

## Loading states
- **twentyhq/core-team-issues#2486** — metadata loading shows an empty
body (no dense skeleton rows).
- **twentyhq/core-team-issues#2487** — settings table keeps its layout
while loading, with the shimmer localized to the first row's first cell.

## Command menu & navigation
- **twentyhq/core-team-issues#2501** — navigation section header height
matches the nav item rhythm (28px).
- **twentyhq/core-team-issues#2502 (part 1)** — the page side-panel
toggle stays as the dots glyph while the command menu is open, instead
of morphing into a second close control.

## New-field flow
- **twentyhq/core-team-issues#2494** — the new-field stepper moved from
a breadcrumb dropdown into a centered secondary wizard bar (back chevron
+ Save on the configure step); breadcrumb stays clean and the object
label is the centered title.

## Descoped (substantive bugs already fixed)
- **twentyhq/core-team-issues#2500** — command-menu highlight right
gutter: the menu-item base measures full-width, so it's likely a
scrollbar gutter on the list, not the shared component. Left for a
focused follow-up.
- **twentyhq/core-team-issues#2502 part 2** — moving the command-menu
close from left to right is cosmetic (the duplicate-control bug is fixed
by part 1) and would touch the shared `SidePanelTopBar` used by
search/AI panels.

## Verification
typecheck (tsgo) + oxlint + oxfmt green for all changed files; each
change DOM-measured / screenshotted in the running app.
This commit is contained in:
Félix Malfait
2026-06-10 11:02:36 +02:00
committed by GitHub
parent 6525af5ba4
commit adba66caea
16 changed files with 161 additions and 245 deletions
@@ -1,9 +1,8 @@
import { isDDLLockedState } from '@/client-config/states/isDDLLockedState';
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsDataModelNewFieldBreadcrumbDropDown } from '@/settings/data-model/components/SettingsDataModelNewFieldBreadcrumbDropDown';
import { SettingsWizardStepBar } from '@/settings/components/layout/SettingsWizardStepBar';
import { FIELD_NAME_MAXIMUM_LENGTH } from '@/settings/data-model/constants/FieldNameMaximumLength';
import { SettingsDataModelFieldIconLabelForm } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldIconLabelForm';
import { SettingsDataModelFieldSettingsFormCard } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard';
@@ -23,6 +22,7 @@ import {
} from 'twenty-shared/types';
import { getSettingsPath, isDefined } from 'twenty-shared/utils';
import { H2Title } from 'twenty-ui-deprecated/display';
import { Button } from 'twenty-ui-deprecated/input';
import { Section } from 'twenty-ui-deprecated/layout';
import { type z } from 'zod';
import { FieldMetadataType } from '~/generated-metadata/graphql';
@@ -181,7 +181,7 @@ export const SettingsObjectNewFieldConfigure = () => {
{...formConfig}
>
<SettingsPageLayout
title={t`2. Configure field`}
title={activeObjectMetadataItem.labelPlural}
links={[
{
children: t`Workspace`,
@@ -197,26 +197,28 @@ export const SettingsObjectNewFieldConfigure = () => {
objectNamePlural,
}),
},
{ children: <SettingsDataModelNewFieldBreadcrumbDropDown /> },
{ children: t`New field` },
]}
actionButton={
<SaveAndCancelButtons
isLoading={isSaving}
isSaveDisabled={!canSave}
isCancelDisabled={isSubmitting}
onCancel={() =>
secondaryBar={
<SettingsWizardStepBar
label={t`2. Configure field`}
onBack={() =>
navigate(
SettingsPath.ObjectNewFieldSelect,
{
objectNamePlural,
},
{
fieldType,
},
{ objectNamePlural },
{ fieldType },
)
}
onSave={formConfig.handleSubmit(handleSave)}
trailing={
<Button
title={t`Save`}
variant="primary"
size="small"
accent="blue"
onClick={formConfig.handleSubmit(handleSave)}
disabled={!canSave || isSaving}
/>
}
/>
}
>
@@ -1,11 +1,11 @@
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsDataModelNewFieldBreadcrumbDropDown } from '@/settings/data-model/components/SettingsDataModelNewFieldBreadcrumbDropDown';
import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout';
import { SettingsWizardStepBar } from '@/settings/components/layout/SettingsWizardStepBar';
import { SETTINGS_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
import { SettingsObjectNewFieldSelector } from '@/settings/data-model/fields/forms/components/SettingsObjectNewFieldSelector';
import { type FieldType } from '@/settings/data-model/types/FieldType';
import { type SettingsFieldType } from '@/settings/data-model/types/SettingsFieldType';
import { SettingsPageLayout } from '@/settings/components/layout/SettingsPageLayout';
import { zodResolver } from '@hookform/resolvers/zod';
import { t } from '@lingui/core/macro';
import { useEffect } from 'react';
@@ -65,7 +65,7 @@ export const SettingsObjectNewFieldSelect = () => {
{...formMethods}
>
<SettingsPageLayout
title={t`1. Select a field type`}
title={activeObjectMetadataItem.labelPlural}
links={[
{
children: t`Workspace`,
@@ -78,8 +78,11 @@ export const SettingsObjectNewFieldSelect = () => {
objectNamePlural,
}),
},
{ children: <SettingsDataModelNewFieldBreadcrumbDropDown /> },
{ children: t`New field` },
]}
secondaryBar={
<SettingsWizardStepBar label={t`1. Select a field type`} />
}
>
<SettingsPageContainer>
<SettingsObjectNewFieldSelector