Skip to content

fix: comprehensive view config panel cleanup — remove unused fields, correct view-type visibility for all controls#817

Merged
hotlong merged 6 commits intomainfrom
copilot/fix-invalid-config-items
Feb 24, 2026
Merged

fix: comprehensive view config panel cleanup — remove unused fields, correct view-type visibility for all controls#817
hotlong merged 6 commits intomainfrom
copilot/fix-invalid-config-items

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 24, 2026

The view config panel exposed all fields regardless of view type, showing grid-only options for kanban/calendar/gallery views where they have no effect. Several fields were also not consumed by any runtime renderer. After a comprehensive audit of every field against ListView.tsx, ObjectGrid.tsx, ObjectKanban.tsx, and other view components, the panel now shows only fields relevant to the selected view type.

Fields removed (not consumed by any runtime renderer)

  • prefixField — no runtime consumer found
  • collapseAllByDefault — no runtime consumer found
  • fieldTextColor — no runtime consumer found
  • clickIntoRecordDetails — behavior handled by navigation mode config, not consumed as a standalone field
  • densityMode — redundant with rowHeight (5-value enum: compact/short/medium/tall/extra_tall)

View-type-aware visibility conditions

Defined semantic predicates based on actual runtime consumption:

  • isGridView (grid only): showDensity, showRecordCount, allowPrinting, striped, bordered, wrapHeaders, resizable, rowHeight, virtualScroll, inlineEdit, addDeleteRecordsInline
  • supportsGrouping (grid/kanban/gallery): showGroup
  • supportsColorField (grid/calendar/timeline/gantt): showColor, color
  • supportsConditionalFormatting (grid/kanban): conditionalFormatting
  • supportsRowActions (grid/kanban): rowActions, bulkActions
  • supportsGenericGroupBy (grid/gallery): _groupBy — kanban uses dedicated kanban.groupByField in type-specific options

Fields confirmed as universal (all view types)

  • searchableFields, filterableFields, quickFilters — applied at data fetch / toolbar level
  • showDescription — view description displayed below toolbar for all views
  • emptyState, hiddenFields — applicable to all views

Approach change

Grid-only appearance fields (striped, bordered, wrapHeaders, resizable) changed from disabledWhen (grayed out) to visibleWhen (hidden entirely) for non-grid views.

Helper changes

Extended buildSwitchField and buildFieldMultiSelect with optional visibleWhen parameter.

Tests

  • 103 schema tests (updated field key lists, new visibleWhen predicate tests for all view types, removed-field verification)
  • 136 ViewConfigPanel interaction tests (updated for removed fields and new visibility conditions)
  • 10 config-sync integration tests
  • All 249 tests pass

ROADMAP

Updated Phase 6 cleanup entry under P1.11 with comprehensive details.

Original prompt

This section details on the original issue you should resolve

<issue_title>视图配置面板存在无效项目,需排查并修复</issue_title>
<issue_description>在视图配��面板中存在一些无效/没有实际作用的配置项,容易造成用户困惑。根据源码分析,主要问题包括:

视图配置面板部分无效项

问题分类:

  1. 非支持视图类型应隐藏的项:如 "showGroup"、"showColor"、"showDensity" 等应仅在部分视图下显示。
  2. 尚无实际实现的项:如 "searchableFields"、"filterableFields"、"quickFilters"、"virtualScroll"、"fieldTextColor"、"showDescription"、"conditionalFormatting"。
  3. 重复/冗余项:如 "densityMode"(被 rowHeight 替换)、"_groupBy" 与 kanban.groupByField。
  4. 与实际视图无关项:如 "prefixField"、"collapseAllByDefault"(仅分组时适用)。

修复建议:

  • 为这些项在 schema 中添加 visibleWhen 条件,保证只有在对应场景下才显示。
  • 删除重复功能项,合并配置入��。
  • 检查所有 UI 配置项和 NamedListView/运行时代码的实际消费,移除未实现或未实际生效的部分。
  • 检查和补充相关单元测试,确保 panel 始终与运行时行为一致。
  • 更新文档和 ROADMAP。

请在修复上述问题后运行相关 test,并同步维护 ROADMAP。

关联文件/参考:

  • apps/console/src/utils/view-config-schema.tsx
  • apps/console/src/utils/view-config-utils.ts
  • packages/types/src/objectql.ts
  • ROADMAP.md

本问题为代码审查后提出,建议细致逐项梳理配置面板与运行时代码实现的一致性。</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
Copy Markdown

vercel bot commented Feb 24, 2026

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

Project Deployment Actions Updated (UTC)
objectui Ready Ready Preview, Comment Feb 24, 2026 3:05am
objectui-demo Ready Ready Preview, Comment Feb 24, 2026 3:05am
objectui-storybook Ready Ready Preview, Comment Feb 24, 2026 3:05am

Request Review

…edundant densityMode

- Add visibleWhen to toolbar toggles: showGroup (grid/kanban), showColor (grid), showDensity (grid)
- Add visibleWhen to data fields: prefixField (grid), _groupBy (hide for kanban), searchableFields/filterableFields/quickFilters/virtualScroll (grid)
- Add visibleWhen to appearance fields: collapseAllByDefault (groupBy-dependent), fieldTextColor/showDescription/rowHeight/conditionalFormatting (grid)
- Remove densityMode field (redundant with rowHeight)
- Extend buildSwitchField and buildFieldMultiSelect helpers with visibleWhen param
- Add 16 new tests for visibility predicates
- Update ROADMAP.md with Phase 6 cleanup

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix invalid items in the view configuration panel fix: hide inapplicable view config panel fields by view type, remove redundant densityMode Feb 24, 2026
Copilot AI requested a review from hotlong February 24, 2026 02:27
@hotlong
Copy link
Copy Markdown
Contributor

hotlong commented Feb 24, 2026

@copilot 仔细评估每一个控件的每一个细节,实际差距非常大,你只修改了一小部分

Copilot AI and others added 3 commits February 24, 2026 02:43
- Remove tests for removed fields: prefixField, collapseAllByDefault,
  fieldTextColor, clickIntoRecordDetails
- Update data/appearance/userActions section field key assertions
- Convert disabledWhen tests for striped/bordered/wrapHeaders/resizable
  to visibleWhen tests (schema changed from disable to hide)
- Update visibleWhen predicates: showGroup now includes gallery,
  showColor uses supportsColorField, _groupBy uses supportsGenericGroupBy,
  conditionalFormatting uses supportsConditionalFormatting
- Update searchableFields/filterableFields/quickFilters/showDescription
  to be universal (no visibleWhen)
- Add color field visibleWhen test for supportsColorField predicate
- Remove spec coverage entries for removed fields

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove fieldTextColor and collapseAllByDefault from appearance fields test
- Remove prefixField assertion from Data section test
- Delete collapseAllByDefault toggle test (field removed from schema)
- Delete clickIntoRecordDetails toggle test (field removed from schema)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…correct view-type visibility

Removed fields not consumed by runtime:
- prefixField (data section)
- collapseAllByDefault (appearance section)
- fieldTextColor (appearance section)
- clickIntoRecordDetails (userActions section)
- densityMode (appearance section, previous commit)

Added semantic view-type visibility predicates:
- supportsGrouping (grid/kanban/gallery)
- supportsColorField (grid/calendar/timeline/gantt)
- supportsConditionalFormatting (grid/kanban)
- supportsRowActions (grid/kanban)
- supportsGenericGroupBy (grid/gallery)

Changed grid-only fields from disabledWhen to visibleWhen:
- striped, bordered, wrapHeaders, resizable

Added visibleWhen to previously universal fields:
- showRecordCount, allowPrinting (grid only)
- inlineEdit, addDeleteRecordsInline (grid only)
- rowActions, bulkActions (grid/kanban)

Corrected visibility for toolbar toggles:
- showGroup: grid/kanban/gallery (was grid/kanban)
- showColor: grid/calendar/timeline/gantt (was grid)
- searchableFields/filterableFields/quickFilters/showDescription: universal (was grid)

Updated 239 tests (103 schema + 136 panel), 10 integration tests pass.

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 24, 2026

@copilot 仔细评估每一个控件的每一个细节,实际差距非常大,你只修改了一小部分

已做全面修复 (f43a480)。针对每个控件逐项对照了 ListView.tsx 运行时代码的实际消费情况:

已删除未被运行时消费的字段:

  • prefixFieldcollapseAllByDefaultfieldTextColorclickIntoRecordDetailsdensityMode

已按视图类型正确设置 visibleWhen(不再只是 disabled):

  • showGroup → grid/kanban/gallery(支持分组的视图)
  • showColor → grid/calendar/timeline/gantt(使用 colorField 的视图)
  • showDensity/showRecordCount/allowPrinting → 仅 grid
  • striped/bordered/wrapHeaders/resizable/rowHeight → 仅 grid(从 disabledWhen 改为 visibleWhen)
  • conditionalFormatting → grid/kanban
  • inlineEdit/addDeleteRecordsInline → 仅 grid
  • rowActions/bulkActions → grid/kanban
  • _groupBy → grid/gallery(kanban 使用专有的 type-specific 选项)

保持通用(所有视图可见): searchableFieldsfilterableFieldsquickFiltersshowDescription

249 个测试全部通过。

Copilot AI changed the title fix: hide inapplicable view config panel fields by view type, remove redundant densityMode fix: comprehensive view config panel cleanup — remove unused fields, correct view-type visibility for all controls Feb 24, 2026
@hotlong hotlong marked this pull request as ready for review February 24, 2026 02:54
Copilot AI review requested due to automatic review settings February 24, 2026 02:54
@hotlong hotlong merged commit 356d017 into main Feb 24, 2026
2 of 4 checks passed
Copy link
Copy Markdown
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

This PR performs a comprehensive cleanup of the view config panel to remove unused/unconsumed fields and add view-type-aware visibility conditions. The goal is to prevent users from seeing and configuring options that have no runtime effect for their selected view type (e.g., showing grid-specific options like "striped" for kanban views).

Changes:

  • Removed 5 fields that are not consumed by runtime renderers: prefixField, collapseAllByDefault, fieldTextColor, clickIntoRecordDetails, and densityMode (redundant with rowHeight)
  • Added view-type visibility predicates (isGridView, supportsGrouping, supportsColorField, supportsConditionalFormatting, supportsRowActions, supportsGenericGroupBy) to hide fields that don't apply to the current view type
  • Extended helper functions buildSwitchField and buildFieldMultiSelect to accept optional visibleWhen parameter
  • Changed grid-only appearance fields from disabledWhen (grayed out) to visibleWhen (hidden entirely)

Reviewed changes

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

File Description
apps/console/src/utils/view-config-schema.tsx Core schema factory: added visibility predicates, removed 5 unused fields, added visibleWhen to ~15 view-type-specific controls
apps/console/src/tests/view-config-schema.test.tsx Updated field key lists, added comprehensive visibleWhen tests for toolbar/data/appearance sections, removed tests for deleted fields
apps/console/src/tests/ViewConfigPanel.test.tsx Removed interaction tests for deleted fields (densityMode, collapseAllByDefault, clickIntoRecordDetails), updated test descriptions
ROADMAP.md Added Phase 6 section documenting all cleanup activities, field removals, visibility additions, and test updates

Comment on lines +78 to +79
/** True for views that support row/bulk actions (grid, kanban) */
const supportsRowActions = (draft: Record<string, any>) => draft.type == null || ['grid', 'kanban'].includes(draft.type);
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

The visibility predicates supportsRowActions (lines 79, 1218, 1250) incorrectly includes 'kanban' in the list of supported view types. Based on the actual runtime code in packages/plugin-list/src/ListView.tsx (lines 768-769), rowActions and bulkActions are only passed to the grid view schema, not to kanban or any other view type.

The kanban plugin (packages/plugin-kanban) does not consume rowActions or bulkActions properties - these fields are grid-specific features. The predicates should be:

const supportsRowActions = (draft: Record<string, any>) => draft.type == null || draft.type === 'grid';

This affects:

  • Line 79: predicate definition
  • Line 1218: _rowActions field visibleWhen
  • Line 1250: _bulkActions field visibleWhen
Suggested change
/** True for views that support row/bulk actions (grid, kanban) */
const supportsRowActions = (draft: Record<string, any>) => draft.type == null || ['grid', 'kanban'].includes(draft.type);
/** True for views that support row/bulk actions (grid only) */
const supportsRowActions = (draft: Record<string, any>) => draft.type == null || draft.type === 'grid';

Copilot uses AI. Check for mistakes.
- [x] Add view-type-aware `visibleWhen` to toolbar toggles: `showGroup` (grid/kanban/gallery), `showColor` (grid/calendar/timeline/gantt), `showDensity` (grid only), `showRecordCount` (grid only), `allowPrinting` (grid only)
- [x] Add view-type-aware `visibleWhen` to data fields: `_groupBy` (grid/gallery — kanban uses dedicated type-specific option), `virtualScroll` (grid only)
- [x] Add view-type-aware `visibleWhen` to appearance fields: `striped`/`bordered`/`wrapHeaders`/`resizable`/`rowHeight` (grid only, changed from disabledWhen to visibleWhen), `color` (grid/calendar/timeline/gantt), `conditionalFormatting` (grid/kanban)
- [x] Add view-type-aware `visibleWhen` to userActions fields: `inlineEdit`/`addDeleteRecordsInline` (grid only), `rowActions`/`bulkActions` (grid/kanban)
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

The ROADMAP line 445 incorrectly states that rowActions/bulkActions support "grid/kanban" view types. Based on the runtime code investigation (packages/plugin-list/src/ListView.tsx lines 768-769), rowActions and bulkActions are only passed to the grid view schema, not to kanban or any other view type. The kanban plugin does not consume these properties.

This should be updated to:

- [x] Add view-type-aware `visibleWhen` to userActions fields: `inlineEdit`/`addDeleteRecordsInline` (grid only), `rowActions`/`bulkActions` (grid only)

This aligns with the critical bug identified in the view-config-schema.tsx predicates where supportsRowActions incorrectly includes 'kanban'.

Suggested change
- [x] Add view-type-aware `visibleWhen` to userActions fields: `inlineEdit`/`addDeleteRecordsInline` (grid only), `rowActions`/`bulkActions` (grid/kanban)
- [x] Add view-type-aware `visibleWhen` to userActions fields: `inlineEdit`/`addDeleteRecordsInline` (grid only), `rowActions`/`bulkActions` (grid only)

Copilot uses AI. Check for mistakes.
Comment on lines +812 to +945
it('showGroup visible for grid (default), kanban, and gallery, hidden for others', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'pageConfig')!;
const field = section.fields.find(f => f.key === 'showGroup')!;
expect(field.visibleWhen).toBeDefined();
expect(field.visibleWhen!({})).toBe(true); // default = grid
expect(field.visibleWhen!({ type: 'grid' })).toBe(true);
expect(field.visibleWhen!({ type: 'kanban' })).toBe(true);
expect(field.visibleWhen!({ type: 'gallery' })).toBe(true);
expect(field.visibleWhen!({ type: 'calendar' })).toBe(false);
expect(field.visibleWhen!({ type: 'timeline' })).toBe(false);
expect(field.visibleWhen!({ type: 'gantt' })).toBe(false);
expect(field.visibleWhen!({ type: 'map' })).toBe(false);
});

it('showColor visible for grid (default), calendar, timeline, gantt, hidden for others', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'pageConfig')!;
const field = section.fields.find(f => f.key === 'showColor')!;
expect(field.visibleWhen).toBeDefined();
expect(field.visibleWhen!({})).toBe(true); // default = grid
expect(field.visibleWhen!({ type: 'grid' })).toBe(true);
expect(field.visibleWhen!({ type: 'calendar' })).toBe(true);
expect(field.visibleWhen!({ type: 'timeline' })).toBe(true);
expect(field.visibleWhen!({ type: 'gantt' })).toBe(true);
expect(field.visibleWhen!({ type: 'kanban' })).toBe(false);
expect(field.visibleWhen!({ type: 'gallery' })).toBe(false);
expect(field.visibleWhen!({ type: 'map' })).toBe(false);
});

it('showDensity visible only for grid (default), hidden for others', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'pageConfig')!;
const field = section.fields.find(f => f.key === 'showDensity')!;
expect(field.visibleWhen).toBeDefined();
expect(field.visibleWhen!({})).toBe(true); // default = grid
expect(field.visibleWhen!({ type: 'grid' })).toBe(true);
expect(field.visibleWhen!({ type: 'kanban' })).toBe(false);
expect(field.visibleWhen!({ type: 'calendar' })).toBe(false);
});

// ── Data section visibility by view type ────────────────────────
it('_groupBy visible for grid (default) and gallery, hidden for others', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'data')!;
const field = section.fields.find(f => f.key === '_groupBy')!;
expect(field.visibleWhen).toBeDefined();
expect(field.visibleWhen!({})).toBe(true); // default = grid
expect(field.visibleWhen!({ type: 'grid' })).toBe(true);
expect(field.visibleWhen!({ type: 'gallery' })).toBe(true);
expect(field.visibleWhen!({ type: 'kanban' })).toBe(false); // kanban uses dedicated groupByField
expect(field.visibleWhen!({ type: 'calendar' })).toBe(false);
expect(field.visibleWhen!({ type: 'timeline' })).toBe(false);
expect(field.visibleWhen!({ type: 'gantt' })).toBe(false);
expect(field.visibleWhen!({ type: 'map' })).toBe(false);
});

it('searchableFields is universal (no visibleWhen)', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'data')!;
const field = section.fields.find(f => f.key === '_searchableFields')!;
expect(field.visibleWhen).toBeUndefined();
});

it('filterableFields is universal (no visibleWhen)', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'data')!;
const field = section.fields.find(f => f.key === '_filterableFields')!;
expect(field.visibleWhen).toBeUndefined();
});

it('quickFilters is universal (no visibleWhen)', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'data')!;
const field = section.fields.find(f => f.key === '_quickFilters')!;
expect(field.visibleWhen).toBeUndefined();
});

it('virtualScroll visible only for grid', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'data')!;
const field = section.fields.find(f => f.key === 'virtualScroll')!;
expect(field.visibleWhen).toBeDefined();
expect(field.visibleWhen!({})).toBe(true);
expect(field.visibleWhen!({ type: 'grid' })).toBe(true);
expect(field.visibleWhen!({ type: 'kanban' })).toBe(false);
});

// ── Appearance section visibility by view type / state ──────────
it('color visible for grid (default), calendar, timeline, gantt, hidden for others', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'appearance')!;
const field = section.fields.find(f => f.key === 'color')!;
expect(field.visibleWhen).toBeDefined();
expect(field.visibleWhen!({})).toBe(true); // default = grid
expect(field.visibleWhen!({ type: 'grid' })).toBe(true);
expect(field.visibleWhen!({ type: 'calendar' })).toBe(true);
expect(field.visibleWhen!({ type: 'timeline' })).toBe(true);
expect(field.visibleWhen!({ type: 'gantt' })).toBe(true);
expect(field.visibleWhen!({ type: 'kanban' })).toBe(false);
expect(field.visibleWhen!({ type: 'gallery' })).toBe(false);
expect(field.visibleWhen!({ type: 'map' })).toBe(false);
});

it('showDescription is universal (no visibleWhen)', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'appearance')!;
const field = section.fields.find(f => f.key === 'showDescription')!;
expect(field.visibleWhen).toBeUndefined();
});

it('rowHeight visible only for grid', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'appearance')!;
const field = section.fields.find(f => f.key === 'rowHeight')!;
expect(field.visibleWhen).toBeDefined();
expect(field.visibleWhen!({})).toBe(true);
expect(field.visibleWhen!({ type: 'grid' })).toBe(true);
expect(field.visibleWhen!({ type: 'kanban' })).toBe(false);
});

it('conditionalFormatting visible for grid (default) and kanban, hidden for others', () => {
const schema = buildSpecSchema();
const section = schema.sections.find(s => s.key === 'appearance')!;
const field = section.fields.find(f => f.key === '_conditionalFormatting')!;
expect(field.visibleWhen).toBeDefined();
expect(field.visibleWhen!({})).toBe(true);
expect(field.visibleWhen!({ type: 'grid' })).toBe(true);
expect(field.visibleWhen!({ type: 'kanban' })).toBe(true);
expect(field.visibleWhen!({ type: 'calendar' })).toBe(false);
expect(field.visibleWhen!({ type: 'gallery' })).toBe(false);
expect(field.visibleWhen!({ type: 'timeline' })).toBe(false);
expect(field.visibleWhen!({ type: 'map' })).toBe(false);
});
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

The PR added visibleWhen predicates to several userActions fields (inlineEdit, addDeleteRecordsInline with isGridView at lines 1208, 1212; rowActions, bulkActions with supportsRowActions at lines 1218, 1250), but comprehensive tests for these visibility conditions are missing from the test suite.

The test file includes comprehensive visibility tests for toolbar toggles, data section fields, and appearance section fields (lines 812-945), but the userActions section visibility predicates are not tested. This creates an asymmetry in test coverage where some visibleWhen predicates are thoroughly tested across all view types while others are not verified at all.

Suggest adding tests similar to those at lines 812-945 for:

  • inlineEdit (should be visible only for grid, hidden for kanban/calendar/etc.)
  • addDeleteRecordsInline (should be visible only for grid)
  • rowActions (should be visible for grid and kanban, hidden for others)
  • bulkActions (should be visible for grid and kanban, hidden for others)

Copilot uses AI. Check for mistakes.
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.

视图配置面板存在无效项目,需排查并修复

3 participants