Skip to content

List empty state: when the reader's own filter or search leaves no rows, offer 「清除筛选」 — today the copy says to clear them and the only button is 「添加记录」 #28908

Closed

Description

@objectstack-fleet

epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff

Filed by the record-page epic seat from a second console review under epic #26676. An independent reviewer walked the console on main bdb19ca6d9, with examples/app-crm as the backend, at 1440 and 390 px. The seat then re-read the evidence. The maintainer approved the seat's checked list: 「Fable 评估(核对后) 同意立卡」 (2026-11-02). Code readings below are on main 5e1b9b0a77. No domain:* label is set: triage routes this card.

Observed

Leads → filter 状态 等于 Contacted → 0 rows. The copy reads 「没有符合当前筛选或搜索条件的记录,试试调整或清除它们」, and the only button is 「添加记录」. The reader has to go back to the toolbar's small filter badge. A click on the button creates a record while the list is filtered.

Reading

  • ui/packages/plugin-list/src/ListView.tsx:6666: onClearSearch is passed only when searchTerm is non-empty, so a filter alone never offers a clear action.
  • ui/packages/plugin-list/src/ListEmptyState.tsx:209-237 already draws a clear action and already groups it beside the add action.

Target

  1. When the reader's own query (search term, or filters the reader added) is what empties the list, the empty state offers one clear action that removes that query. 「添加记录」 stays as the secondary action.
  2. A filter declared by the view is not the reader's query, so this action does not remove it.
  3. No new key and no new option.

Acceptance

  • Filter to zero rows: 「清除筛选」 is the primary button, a click restores the rows, and the filter badge clears.
  • Search to zero rows behaves as today.
  • A view that is empty with no reader query shows no clear action.
  • Tests pin the three cases.

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: priority:p2 · domain:ui · pm:queue · 2026-11-02T05:11Z

    ⛔ Not a claim.

    • Read fresh. ListView.tsx:6666 (ui/packages/plugin-list) passes onClearSearch only for a search term. A list emptied by the reader's own filter therefore offers just 「添加记录」, while ListEmptyState.tsx:209-237 already draws a clear action. This is a user-visible feature with no new key, so it is p2 in domain:ui, and it goes to pm:queue.

    Generated by Claude Code

  2. added
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    domain:uiDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    on Nov 2, 2026
  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Claim: PM loop round 16 · 2026-11-02T05:20Z
    Session: session_01QsR2jS5v57GVJJL1k8m1nN (card thread, os-dev); dispatched by seat session session_01QsR2jUJ19MstFvFhjgiYTu
    Account: zhuangjianguo
    Branch: claude/project-thread-ayrsgr (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-28908
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: ui/packages/plugin-list/src/ListView.tsx (the empty-state handoff to ListEmptyState), ui/packages/plugin-list/src/ListEmptyState.tsx, the list.* keys in ui/packages/i18n/src/locales/* only if a key is missing, their tests, and a root .changeset (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6569603013
    Premise: holds (at origin/main 62b3ec36: ListEmptyState offers a clear-search action only (ListEmptyState.tsx:209 onClearSearch); a reader-added filter that empties the list gets no clear action)
    Serial constraints cleared: none known. #28966 (tree empty state, seat 1) follows on the same seam; #28911 and #28948 edit other parts of ListView.tsx in parallel.

  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 2, 2026
  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Claim amended · 2026-11-02T05:22Z · after the dev's pre-code reading (origin/main 62b3ec36). This changes one declaration line and names the i18n edit. It adds to claim 6569718286. Branch, session and size are unchanged.

    • Measured: the list.* namespace has no "Clear filters" string, only list.clear and list.clearSearch. ListEmptyState is module-internal, so a new prop on it widens nothing.
    • File surface (confirmed): one new UI string list.clearFilters (en "Clear filters", zh 清除筛选) in every ui/packages/i18n/src/locales/* pack and in plugin-list's LIST_DEFAULT_TRANSLATIONS. No metadata key.
    • Declaration (changed): Clause-②: yes (widening): one new key on @object-ui/i18n's catalogue, following the grid: "select all matching" banner counts every match, but the bulk action processes only the first 5000 #28552 precedent. Metadata-protocol: none is unchanged.
    • Scope: the action clears the search box, the filter panel's conditions and the "In a queue" toggle. The view's declared filter is never touched. User-filter chips stay out of scope: UserFilters is uncontrolled, each chip clears in place, and an outside reset would need a remount (ui/AGENTS.md Convert to monorepo with scoped packages #8).
  6. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jS5v57GVJJL1k8m1nN
    os-dev-report

    {
      "issue": 28908,
      "status": "done",
      "branch": "claude/project-thread-ayrsgr",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29047",
      "session": "session_01QsR2jS5v57GVJJL1k8m1nN",
      "premise_still_valid": true,
      "summary": "A list emptied by a filter the reader applied (filter panel conditions or the In a queue toggle) now draws Clear filters as the primary empty-state action, with Add record as the secondary; one click clears the panel group (emitted through onFilterChange, so the badge clears), releases the queue toggle and clears the search. Search-only keeps today's Clear search beside the primary Add record; a list emptied by the view's declared filter alone shows no clear action, and the declared filter is never removed. One new UI string list.clearFilters in all ten locale packs and LIST_DEFAULT_TRANSLATIONS (Clause-② yes (widening) per claim amendment 6569743409). User-filter chips stay out of scope, noted in Acceptance notes.",
      "tests": "New ListView.emptyStateClearFilters-28908.test.tsx: 7/7 passed. pnpm --dir ui exec vitest run packages/plugin-list/ packages/i18n/ (locked, maxWorkers=2) at f44092be: 274 files passed, 3172 passed / 13 skipped. vitest run scripts/: 169 files passed, 2 skipped, 4900 tests. After merging origin/main (ceaa4f90): closure rebuilt 49/49, packages/i18n/ + 15 empty-state plugin-list files + new file: 109 files, 1694 passed / 13 skipped. Ablation via ablation-replace.mjs (anchor '? handleClearReaderQuery' -> undefined callback): 4 failed / 3 passed as predicted; restore blob == HEAD, git diff HEAD empty.",
      "gates": "dispatch-gates --ran: 34 derived, 34 run, 0 NOT MEASURED, all exit 0 (at f44092be). turbo type-check plugin-list + i18n: 51/51 at f44092be and at ceaa4f90. eslint changed files: 0 errors. check:new-line-citations: 0 new. PR-body gates (check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword, check-empty-changeset) on the final body: exit 0 each. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "3 — issue_read x3 (get, get_comments x2); no write tools",
      "api_writes": "1 — relay pr_create POST /repos/objectstack-ai/objectstack/pulls (request fw-20261102T062424Z-ecb5ba, read-back identical 8006 bytes); plus this report comment via post-stamped",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed · user-filter chips (UserFilters, uncontrolled) cannot be reset from the empty state without a remount; a chip-only empty list keeps the add-only state. A controlled-selection API on UserFilters would close it. dedupe words: UserFilters reset, chip clear empty state, uncontrolled user filters"
      ]
    }
  7. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Landed · 2026-11-02T08:04Z · PR #29047 merged through the merge queue as b889c40a at 2026-11-02T08:02Z (GitHub's clock). ACCEPT 6570883356 at head ceaa4f90.

    probe before (b889c40a~1) now (origin/main)
    clearFilters in ui/packages/i18n/src/locales/en.ts 1 2
    ListView.emptyStateClearFilters-28908.test.tsx exists no yes

    Fixes #28908 closed this card. pm:dispatched comes off in the same stroke as this note. #29052 (a list emptied by a user-filter chip alone) stays open as its own card.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:uiDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions