Skip to content

Comments

Optimize ViewConfigPanel to align with Airtable property panel UX#690

Merged
hotlong merged 4 commits intomainfrom
copilot/optimize-view-config-panel
Feb 21, 2026
Merged

Optimize ViewConfigPanel to align with Airtable property panel UX#690
hotlong merged 4 commits intomainfrom
copilot/optimize-view-config-panel

Conversation

Copy link
Contributor

Copilot AI commented Feb 21, 2026

Restructures the right-side ViewConfigPanel from a flat form layout to an Airtable-style property panel with hierarchical navigation, collapsible sections, compact summary rows, and expanded appearance/user-action controls.

Panel header

  • Breadcrumb hierarchy: Page › List / Page › Kanban etc., replacing generic "Configure View" title

Collapsible sections

  • Data, Appearance, User Actions sections toggle via chevron with aria-expanded
  • Sort/Filter/Fields rows show compact summaries ("2 sorts", "5 visible") and expand inline editors on click

Data section restructured

  • Sort by / Filter by: summary ConfigRows → expandable inline builders
  • Group by: universal field selector (auto-propagates to kanban.groupByField)
  • Prefix field: new field selector
  • Fields: summary with visible count → expandable column checkboxes
  • Type-specific fields (kanban/calendar/map/gallery/timeline/gantt) inlined here
  • Calendar gains endDateField support
  • Search/filter/sort enable toggles moved here from removed "User Filters" section

Appearance section

New fields matching Airtable: Color, Field text color, Row height (4 icon buttons as role="radiogroup"), Wrap headers, Show field descriptions, Collapse all by default

User actions section

New toggles: Edit records inline, Add/delete records inline, Click into record details. Existing Add record via form and Allow export consolidated here (removed standalone "Advanced" section).

i18n

17 new keys added to all 11 locales (en, zh, ja, de, fr, es, ar, ru, pt, ko). Missing keys (createView, typeOptions, etc.) backfilled for non-English locales.

Tests

62 tests passing — 11 existing tests updated for new expandable sub-row pattern, 13 new tests covering breadcrumb, section collapse, appearance fields, user actions, calendar endDateField, and data sub-section toggle.

Original prompt

This section details on the original issue you should resolve

<issue_title>优化列表视图右侧属性面板,对齐Airtable体验,支持多视图类型字段</issue_title>
<issue_description>参考 Airtable 列表视图的右侧属性面板(见截图),优化 ObjectUI 的 ViewConfigPanel:

Airtable属性面板截图

优化要点

  • 层次结构分组,面板 header 显示 Page > List/Kanban/Gallery
  • Data 区可动态展示 Sort by、Group by、Prefix field、Fields(见截图右侧Data部分)
  • 支持多视图类型,如 Grid/Kanban/Calendar/Gallery/Timeline/Gantt/Map,切换时属性动态变化,例:Kanban 必须有 Group by,Calendar 必须有 Start Date/End Date
  • Appearance 区可选:Color、Field text color、Row height(图标切换尺寸)、Wrap headers、Show field descriptions、Collapse all by default
  • User actions 区可选:Edit records inline、Add/delete records inline、Click into record details
  • 属性面板所有交互和字段都应贴近 Airtable,用于提升用户体验

子任务建议

  • 引入 type-specific option 展现逻辑,所有视图类型字段动态显示
  • Data 区域属性基于视图类型变化
  • Appearance、User actions 区域优化交互与布局
  • 支持面板 header 上的层次结构导航
  • 支持属性折叠/展开,与Airtable类似
  • 支持面板字段国际化、图标与交互风格
  • 回归全部类型(Grid、Kanban、Calendar、Gallery、Timeline、Gantt、Map)

如需设计稿请补充需求。</issue_description>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

@vercel
Copy link

vercel bot commented Feb 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectui Ready Ready Preview, Comment Feb 21, 2026 7:52am
objectui-demo Ready Ready Preview, Comment Feb 21, 2026 7:52am
objectui-storybook Ready Ready Preview, Comment Feb 21, 2026 7:52am

Request Review

…ible sections, new appearance/user-action fields, breadcrumb header, and i18n for all 11 locales

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI and others added 2 commits February 21, 2026 07:43
…dcrumb, collapsible sections, appearance and user actions fields; update ROADMAP.md

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…height buttons for accessibility

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Optimize ViewConfigPanel for better Airtable-like experience Optimize ViewConfigPanel to align with Airtable property panel UX Feb 21, 2026
Copilot AI requested a review from hotlong February 21, 2026 07:49
@hotlong hotlong marked this pull request as ready for review February 21, 2026 07:50
Copilot AI review requested due to automatic review settings February 21, 2026 07:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Restructures the Console’s ViewConfigPanel into an Airtable-style property panel with breadcrumb header, collapsible sections, compact summary rows, and expanded appearance/user-action controls, plus corresponding i18n and test updates.

Changes:

  • Refactors ViewConfigPanel UI into collapsible Data/Appearance/User Actions sections with expandable Sort/Filter/Fields sub-rows and a breadcrumb header.
  • Adds new config controls (appearance + user actions) and calendar endDateField selection.
  • Updates i18n across locales, expands/updates tests, and marks the work completed in the roadmap.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
apps/console/src/components/ViewConfigPanel.tsx Implements the new Airtable-style layout, collapsible sections, and new config controls.
apps/console/src/tests/ViewConfigPanel.test.tsx Updates existing tests for the new expandable pattern and adds new coverage for breadcrumb/sections/new fields.
packages/i18n/src/locales/en.ts Adds new translation keys used by the redesigned panel.
packages/i18n/src/locales/zh.ts Backfills/adds new translation keys for redesigned panel.
packages/i18n/src/locales/ja.ts Backfills/adds new translation keys for redesigned panel.
packages/i18n/src/locales/de.ts Backfills/adds new translation keys for redesigned panel.
packages/i18n/src/locales/fr.ts Backfills/adds new translation keys for redesigned panel.
packages/i18n/src/locales/es.ts Backfills/adds new translation keys for redesigned panel.
packages/i18n/src/locales/ar.ts Backfills/adds new translation keys for redesigned panel.
packages/i18n/src/locales/ru.ts Backfills/adds new translation keys for redesigned panel.
packages/i18n/src/locales/pt.ts Backfills/adds new translation keys for redesigned panel.
packages/i18n/src/locales/ko.ts Backfills/adds new translation keys for redesigned panel.
ROADMAP.md Marks the newly delivered panel UX items as completed.

Comment on lines +548 to +550
updateDraft('groupBy', e.target.value);
if (viewType === 'kanban') {
handleTypeOptionChange('kanban', 'groupByField', e.target.value);
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Group by" selector writes a flat groupBy property and (for kanban) updates kanban.groupByField, but the runtime view schema builders read options.kanban.groupField (and warn on flat keys in dev). This means changing Group by in the panel may not actually change kanban grouping and can trigger spec-compliance warnings. Consider removing the flat groupBy write and updating kanban.groupField (optionally mirroring to kanban.groupByField for backward compatibility) instead.

Suggested change
updateDraft('groupBy', e.target.value);
if (viewType === 'kanban') {
handleTypeOptionChange('kanban', 'groupByField', e.target.value);
const value = e.target.value;
if (viewType === 'kanban') {
// For kanban, use options.kanban.groupField as the canonical key
handleTypeOptionChange('kanban', 'groupField', value);
// Mirror to groupByField for backward compatibility
handleTypeOptionChange('kanban', 'groupByField', value);
} else {
// Preserve existing flat groupBy behavior for non-kanban views
updateDraft('groupBy', value);

Copilot uses AI. Check for mistakes.
Comment on lines +628 to +629
value={draft.kanban?.groupByField || draft.kanban?.groupField || ''}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => handleTypeOptionChange('kanban', 'groupByField', e.target.value)}
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For kanban, the panel renders both the universal "Group by" row and a type-specific "Group by field" select. These controls can diverge (type-specific updates only kanban.groupByField), and it’s redundant UX. Suggest keeping a single source of truth (either remove the type-specific row for kanban or have both update the same underlying key(s), e.g. kanban.groupField).

Suggested change
value={draft.kanban?.groupByField || draft.kanban?.groupField || ''}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => handleTypeOptionChange('kanban', 'groupByField', e.target.value)}
value={draft.kanban?.groupField || draft.kanban?.groupByField || ''}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
const value = e.target.value;
handleTypeOptionChange('kanban', 'groupField', value);
handleTypeOptionChange('kanban', 'groupByField', value);
}}

Copilot uses AI. Check for mistakes.
Comment on lines +935 to +936
checked={hasExport}
onCheckedChange={(checked: boolean) => updateDraft('allowExport', checked)}
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The export toggle’s checked state is derived from hasExport, which is true when draft.exportOptions is defined. If exportOptions is set, toggling "Allow export" off only updates allowExport but the switch will remain on (and export remains enabled) because exportOptions is still present. Consider making the switch state depend on allowExport (and/or clearing exportOptions when disabling) so the control can actually turn export off.

Suggested change
checked={hasExport}
onCheckedChange={(checked: boolean) => updateDraft('allowExport', checked)}
checked={draft.allowExport !== false && hasExport}
onCheckedChange={(checked: boolean) => {
updateDraft('allowExport', checked);
if (!checked) {
updateDraft('exportOptions', undefined);
}
}}

Copilot uses AI. Check for mistakes.
Comment on lines +837 to +860
<div className="flex gap-0.5" data-testid="appearance-rowHeight" role="radiogroup" aria-label={t('console.objectView.rowHeight')}>
{ROW_HEIGHT_OPTIONS.map(opt => (
<button
key={opt.value}
type="button"
role="radio"
aria-checked={(draft.rowHeight || 'short') === opt.value}
aria-label={opt.value}
data-testid={`row-height-${opt.value}`}
className={`h-7 w-7 rounded border flex items-center justify-center ${
(draft.rowHeight || 'short') === opt.value
? 'border-primary bg-primary/10 text-primary'
: 'border-input text-muted-foreground hover:bg-accent/50'
}`}
onClick={() => updateDraft('rowHeight', opt.value)}
title={opt.value}
>
<div className={`flex flex-col items-center justify-center w-4 h-4 ${opt.gapClass}`}>
<div className="w-3.5 h-px bg-current rounded-full" />
<div className="w-3.5 h-px bg-current rounded-full" />
<div className="w-3.5 h-px bg-current rounded-full" />
</div>
</button>
))}
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The row height control uses role="radiogroup"/role="radio" but doesn’t implement the expected roving tabIndex/arrow-key keyboard interaction, and each radio’s aria-label is the raw internal value ("short", "medium", etc.) rather than a localized label. Consider using native radio inputs or adding keyboard handling + localized labels to match ARIA radio patterns.

Suggested change
<div className="flex gap-0.5" data-testid="appearance-rowHeight" role="radiogroup" aria-label={t('console.objectView.rowHeight')}>
{ROW_HEIGHT_OPTIONS.map(opt => (
<button
key={opt.value}
type="button"
role="radio"
aria-checked={(draft.rowHeight || 'short') === opt.value}
aria-label={opt.value}
data-testid={`row-height-${opt.value}`}
className={`h-7 w-7 rounded border flex items-center justify-center ${
(draft.rowHeight || 'short') === opt.value
? 'border-primary bg-primary/10 text-primary'
: 'border-input text-muted-foreground hover:bg-accent/50'
}`}
onClick={() => updateDraft('rowHeight', opt.value)}
title={opt.value}
>
<div className={`flex flex-col items-center justify-center w-4 h-4 ${opt.gapClass}`}>
<div className="w-3.5 h-px bg-current rounded-full" />
<div className="w-3.5 h-px bg-current rounded-full" />
<div className="w-3.5 h-px bg-current rounded-full" />
</div>
</button>
))}
<div
className="flex gap-0.5"
data-testid="appearance-rowHeight"
aria-label={t('console.objectView.rowHeight')}
>
{ROW_HEIGHT_OPTIONS.map(opt => {
const isSelected = (draft.rowHeight || 'short') === opt.value;
const label = t(`console.objectView.rowHeight.${opt.value}`);
return (
<label
key={opt.value}
className={`h-7 w-7 rounded border flex items-center justify-center cursor-pointer ${
isSelected
? 'border-primary bg-primary/10 text-primary'
: 'border-input text-muted-foreground hover:bg-accent/50'
}`}
title={label}
>
<input
type="radio"
name="rowHeight"
value={opt.value}
checked={isSelected}
onChange={() => updateDraft('rowHeight', opt.value)}
aria-label={label}
className="sr-only"
/>
<div
className={`flex flex-col items-center justify-center w-4 h-4 ${opt.gapClass}`}
data-testid={`row-height-${opt.value}`}
>
<div className="w-3.5 h-px bg-current rounded-full" />
<div className="w-3.5 h-px bg-current rounded-full" />
<div className="w-3.5 h-px bg-current rounded-full" />
</div>
</label>
);
})}

Copilot uses AI. Check for mistakes.
@hotlong hotlong merged commit fd054a9 into main Feb 21, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

优化列表视图右侧属性面板,对齐Airtable体验,支持多视图类型字段

2 participants