Skip to content

Console integration: consume new engine schema capabilities (HeaderBar, ViewSwitcher, SidebarNav, Airtable UX) #911

@hotlong

Description

@hotlong

Background

PR #903, #905, #907 extended the engine packages with significant new schema capabilities:

  • HeaderBarSchema now supports search, actions, rightContent slots
  • BreadcrumbItem supports siblings dropdown navigation
  • SidebarNav supports badge, children (nested items), searchEnabled
  • ViewSwitcherSchema supports allowCreateView, viewActions
  • i18n unified across data-table, ListView toolbar, ObjectGrid
  • Airtable UX: singleClickEdit, selectionStyle, compact density, auto column widths, ghost rows, localized dates

Problem: All 3 PRs modified only packages/* (engine layer). Console (apps/console/) was not updated to consume these new capabilities. The engine has the schema expressiveness, but Console still hardcodes the equivalent UI.

Reference Screenshots

CRM Project Task page (before optimization):
image1

Airtable Interface (target benchmark):
image2


Task 1: [P0] AppHeader.tsx → Consume HeaderBarSchema

Current State

apps/console/src/components/AppHeader.tsx (~280 lines) hardcodes:

  • ⌘K search button (desktop <button> + mobile <Button>)
  • Breadcrumb with siblings dropdown (custom DropdownMenu)
  • ConnectionStatus component
  • PresenceAvatars (realtime presence)
  • ActivityFeed (notification bell)
  • HelpCircle button
  • ModeToggle (theme switcher)
  • LocaleSwitcher

All of these are not configured via schema — they're JSX in AppHeader.

Engine Capability (already merged in #905)

HeaderBarSchema now supports:

// packages/types/src/navigation.ts
interface HeaderBarSchema {
  crumbs?: BreadcrumbItem[];  // with siblings dropdown support
  search?: { enabled: boolean; placeholder?: string; shortcut?: string };
  actions?: SchemaNode[];      // right-side action slots
  rightContent?: SchemaNode;   // custom right content area
}

The header-bar renderer in packages/components/src/renderers/navigation/header-bar.tsx renders all of these from schema.

Required Changes

File: apps/console/src/components/AppHeader.tsx

Option A (Recommended): Hybrid approach — Keep AppHeader as a thin wrapper that builds a HeaderBarSchema and delegates to the header-bar renderer, while keeping Console-specific concerns (presence polling, activity feed data fetching) in AppHeader.

// AppHeader builds schema from route + props, then renders via header-bar
const headerSchema: HeaderBarSchema = {
  type: 'header-bar',
  crumbs: breadcrumbItems.map(item => ({
    label: item.label,
    href: item.href,
    siblings: item.siblings,
  })),
  search: { enabled: true, placeholder: 'Search...', shortcut: '⌘K' },
  actions: [
    // ConnectionStatus, PresenceAvatars, ActivityFeed, Help, ModeToggle, LocaleSwitcher
    // rendered as schema nodes or via rightContent slot
  ],
};
return <SchemaRenderer schema={headerSchema} />;

Option B: Incremental — Keep current JSX structure but pass siblings through the existing breadcrumb rendering (already partially done), and ensure the search button dispatches the ⌘K event consistently.

Acceptance Criteria

  • Breadcrumbs render via BreadcrumbItem.siblings (already partially done, verify working)
  • Search triggers ⌘K command palette
  • Right-side actions (presence, activity, help, theme, locale) render correctly
  • Mobile responsive behavior preserved (sidebar trigger, truncated breadcrumbs, icon-only buttons)
  • No visual regression vs current AppHeader

Task 2: [P0] Console ObjectView → Pass allowCreateView & viewActions to ViewSwitcher

Current State

apps/console/src/components/ObjectView.tsx builds viewSwitcherSchema in the buildViewSwitcherSchema() function (around L477-504):

// Current: only sets type, variant, position, views, defaultView, activeView
return {
  type: 'view-switcher' as const,
  variant: 'tabs',
  position: 'top',
  persistPreference: true,
  storageKey: `view-pref-${schema.objectName}`,
  defaultView: (activeView?.type || 'grid') as ViewType,
  activeView: (activeView?.type || 'grid') as ViewType,
  views: viewsPropResolved.map(v => ({ ... })),
  // ❌ MISSING: allowCreateView, viewActions
};

Engine Capability (already merged in #905)

ViewSwitcherSchema now supports:

interface ViewSwitcherSchema {
  allowCreateView?: boolean;
  viewActions?: Array<{
    type: 'share' | 'settings' | 'duplicate' | 'delete';
    icon?: string;
  }>;
}

ViewSwitcher.tsx renders a + button and per-view action icons with onCreateView and onViewAction callbacks.

Required Changes

File: apps/console/src/components/ObjectView.tsx

  1. In buildViewSwitcherSchema(), add:
return {
  ...existing,
  allowCreateView: isAdmin,  // only admins can create views
  viewActions: isAdmin ? [
    { type: 'settings' },
    { type: 'share' },
    { type: 'duplicate' },
    { type: 'delete' },
  ] : [],
};
  1. Pass callback handlers to <ViewSwitcher> (or via PluginObjectView):
onCreateView={() => {
  setViewConfigPanelMode('create');
  setShowViewConfigPanel(true);
}}
onViewAction={(actionType, viewType) => {
  if (actionType === 'settings') {
    handleViewChange(viewType);
    setViewConfigPanelMode('edit');
    setShowViewConfigPanel(true);
  }
  // handle share, duplicate, delete...
}}

Note

Console's ViewTabBar already has onAddView, onConfigView, onShareView, onDuplicateView, onDeleteView callbacks wired (L760-779). The new viewActions on ViewSwitcher is a parallel path for non-Console consumers. Console should wire both consistently.

Acceptance Criteria

  • ViewSwitcher renders + button when isAdmin
  • Per-view action icons (settings/share/duplicate/delete) appear on hover
  • Clicking settings opens ViewConfigPanel in edit mode
  • Clicking + opens ViewConfigPanel in create mode
  • Non-admin users see no action buttons

Task 3: [P1] SidebarNav usage in Storybook/non-Console contexts

Current State

Console uses AppSchemaRenderer + NavigationRenderer for sidebar, which already has badge/group/search via the NavigationItem type. The SidebarNav component from packages/layout/src/SidebarNav.tsx is used in Storybook stories and simpler layouts.

Engine Capability (merged in #905)

SidebarNav now supports:

  • NavItem.badge / NavItem.badgeVariant
  • NavItem.children (nested collapsible items)
  • SidebarNavProps.searchEnabled / searchPlaceholder
  • NavGroup type for grouped navigation

Required Changes

File: apps/console/src/components/AppSidebar.tsxNo change needed (already uses NavigationRenderer)

Files to update:

  • Storybook stories that use SidebarNav — add examples with badges, nested items, search
  • Documentation in content/docs/guide/layout.md — add SidebarNav enhanced props examples

Acceptance Criteria

  • Storybook has SidebarNav story with badges, nested items, search filter
  • Documentation updated with new NavItem/NavGroup API examples

Task 4: [P1] Airtable UX defaults propagation to Console ObjectView

Current State

#907 changed engine defaults:

  • ObjectGrid.rowHeight default → 'compact' (was 'medium')
  • ListView.density default → 'compact' (was 'comfortable')
  • singleClickEdit default → true for ObjectGrid
  • Date formatting → browser locale (was 'en-US')

These should auto-propagate since Console uses PluginObjectViewListViewObjectGrid. However, Console's ObjectView.tsx may override some of these when building objectViewSchema:

// apps/console/src/components/ObjectView.tsx L632-665
const objectViewSchema = useMemo(() => ({
  type: 'object-view' as const,
  objectName: objectDef.name,
  // Does it override rowHeight or density?
  ...
}), [...]);

Required Changes

File: apps/console/src/components/ObjectView.tsx

  1. Verify Console's objectViewSchema does NOT override rowHeight, density, or singleClickEdit (let engine defaults flow through)
  2. If Console has explicit overrides, remove them or align with new Airtable defaults
  3. Verify date columns in CRM demo render localized dates (not ISO strings)

Acceptance Criteria

  • ObjectGrid renders with compact (32px) rows by default
  • Single-click on a cell enters edit mode
  • Date columns show localized format (e.g., 2024/2/1 in zh-CN locale)
  • Density toggle in toolbar still works and highlights 'compact' as default

Task 5: [P2] i18n consistency verification in Console

Current State

#905 added useTableTranslation(), useGridTranslation(), 17 new list.* i18n keys across 10 locale files. Console's ObjectView.tsx uses useObjectTranslation() for its own UI strings.

Required Changes

File: apps/console/src/components/ObjectView.tsx

  1. Verify the + 新建 button uses t('console.objectView.new') (already does per L694)
  2. Verify toolbar buttons (Filter, Group, Sort) come from useListViewTranslation() in the engine (no Console override)
  3. Verify pagination footer 7 条记录 / Page 1 of 1 (7 total) both render in the same locale
  4. Test by switching locale to zh-CN and confirming all text is Chinese, no English fallbacks

Acceptance Criteria

  • Full zh-CN rendering: no mixed English/Chinese in toolbar, pagination, or headers
  • Full en-US rendering: no Chinese leaking through
  • All 10 supported locales have complete translations for new

Required Changes

Files:

  • apps/console/src/components/DashboardView.tsx �� verify filter chip i18n
  • Verify ObjectChart integration with the config panel uses latest schema capabilities
  • No major code changes expected; primarily verification and minor i18n fixes

Acceptance Criteria

  • Dashboard filter chips are i18n-ized (no hardcoded Chinese/English)
  • Chart config panel labels are translated
  • KPI cards format numbers correctly per locale (e.g., $804,000 in en-US, ¥804,000 in zh-CN)

Summary Matrix

# Task Priority File(s) Type
1 AppHeader → HeaderBarSchema 🔴 P0 apps/console/src/components/AppHeader.tsx Refactor
2 ViewSwitcher allowCreateView/viewActions 🔴 P0 apps/console/src/components/ObjectView.tsx Integration
3 SidebarNav stories/docs 🟡 P1 Storybook, docs Documentation
4 Airtable UX defaults verification 🟡 P1 apps/console/src/components/ObjectView.tsx Verification
5 i18n consistency verification 🟢 P2 apps/console/src/components/ObjectView.tsx Testing

Definition of Done

  • Console CRM demo page renders with: schema-driven header, ViewSwitcher with create/actions, compact grid, localized dates, unified i18n
  • No visual regression in existing Console functionality
  • All existing tests pass; new tests added for:
    • AppHeader schema rendering
    • ViewSwitcher action button callbacks
    • i18n locale switching (zh-CN, en-US, ja-JP)
  • ROADMAP.md updated to reflect Console integration completion
  • Storybook stories updated for SidebarNav enhanced props

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions