Repository navigation
Commit cc378e9
fix(plugin-list,plugin-grid): list empty state tells no-access and "mine" apart from no records (#25987)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi96DHp4dBaqUvVq8hBV3bCkw)_
Fixes #25898
Clause-②: no
Metadata-protocol: none
## What changes
An empty list chose its copy from the user's query and the view's
declared filter alone. Two cases from the card's table were wrong:
- **No filter, caller may not create.** A member who may read none of an
object's records and holds no create grant was told "Nothing here yet /
Create your first record to get started." beside no Create button. Once
the permission answer has loaded, a caller without the `listNew` verdict
of the affordance-to-grant map (managed-object policy, effective API
operations and the caller's create grant, the same verdict the page's
own New reads) now gets "No records you can see / There are no records
here that you have access to. If you expected to see some, ask your
administrator for access." The add-record action is not drawn for that
caller, even on a view whose `addRecord` is enabled.
- **A "my" view.** When the view's declared filter names the signed-in
user (a comparand equal to the caller's id, which is what a
host-resolved `{current_user_id}` becomes, or the placeholder itself),
the empty state reads "Nothing of yours yet / This view lists only
records that are yours, and you don't have any yet." instead of "No
records match this view's filter.", with the add-record action only
under the create grant.
Unchanged: the first-run copy and action for a caller who may create,
the user-query copy, the plain view-filter copy, an authored
`emptyState` (it still wins), the 403 error panel (its own state,
untouched), and every surface with no permission provider mounted
(fail-open, as the affordance map is).
Where it lands, following the card's measured producers:
- `ListEmptyState` (plugin-list, module-internal) makes the decision:
two new optional props, `baseFilterNamesCurrentUser` and `mayCreate`
(`false` is a known denial, absent is "not known"), and the exported
helper `filterNamesCurrentUser`.
- `ListView` (grid and gallery visualizations) passes both from the
empty-state call site: the resolved declared filter against the session
scope's `currentUserId`, and `resolveAffordance('listNew', …)` once
`usePermissions().isLoaded`.
- `ObjectGallery` (standalone) passes the same two facts.
- `ObjectGrid`'s default empty state makes the same decision in its own
empty-state region (it draws no add-record action, as before).
plugin-grid and plugin-list do not depend on each other, so the filter
walk is restated there in a few lines.
- `@object-ui/i18n`: `list.ownedNoneTitle`, `list.ownedNoneMessage`,
`list.noneVisibleTitle`, `list.noneVisibleMessage` in all ten packs, and
in the two in-code English fallback tables (`LIST_DEFAULT_TRANSLATIONS`,
ObjectGrid's).
- `scripts/sdui-manifest.record.json`: the registry-source hash
re-recorded by `node scripts/gen-sdui-manifest-node.mjs`, which every
`ui/packages/**` source change requires (`check-sdui-manifest`); the
manifest itself is byte-identical.
The copy is generic rather than naming the object ("你没有可查看的工单" in the
card) so it needs no plural forms across ten locales; the zh pack reads
「没有你可查看的记录」 and 「你还没有负责的记录」.
## Tests
At head `8878ebe8` (implementation unchanged since `be788ede`; later
commits are the main merge and the manifest record):
- New: `ListView.emptyStateAccess-25898.test.tsx` (9),
`ObjectGallery.emptyStateAccess-25898.test.tsx` (4),
`ObjectGrid.emptyStateAccess-25898.test.tsx` (5), through the real
`MePermissionsProvider` and `FilterScopeProvider`: 3 files, 18 tests
passed.
- Reverse verification: the four source files and the locale packs
restored to the base commit `38050ced` with the tests kept: 11 failed /
7 passed, exactly the predicted split (every no-access, "mine" and zh
row red; the create-grant, no-provider and plain-filter controls green).
Restored from `HEAD` afterwards, `git diff HEAD` empty.
- `vitest run packages/plugin-list/ packages/plugin-grid/ packages/i18n/
packages/plugin-form/src/affordanceGrantMap-12082.test.tsx` (the
affordance census included): 498 files passed, 5253 tests passed, 13
skipped.
- `type-check` for `@object-ui/plugin-list`, `@object-ui/plugin-grid`,
`@object-ui/i18n`: clean.
- `node scripts/pm/dispatch-gates.mjs --commands`: 47 derived families
run locally, all exit 0 (`check-sdui-manifest` exited 1 before the
record was regenerated and 0 after); `--ran` reconciliation: 47
accounted, 0 not measured.
## Acceptance notes
- The `{current_user_id}` walk is shape-agnostic: any string comparand
equal to the caller's id counts, so a filter like `owner = me OR status
= open` also reads "Nothing of yours yet". Views of that shape are rare;
the copy is still true of the caller's own records.
- The toolbar's add-record buttons (top and bottom) still follow
`addRecord.enabled` alone inside `ListView`; the console host already
withholds `addRecord` without the create grant, so only a non-console
host could show them to a caller without the grant. Left out of this
card's empty-state scope; noted, not filed.
- A shared home for the decision in `@object-ui/core` would let
`ObjectGrid` and `ListEmptyState` share one function; core is outside
this card's claimed surface, so the grid restates it.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01RYq63NT6L4eGmQNvE9e7D8)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 6444288 commit cc378e9
19 files changed
Lines changed: 578 additions & 15 deletions
File tree
- .changeset
- scripts
- ui/packages
- i18n/src/locales
- plugin-grid/src
- __tests__
- plugin-list/src
- __tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
| 52 | + | |
53 | 53 | | |
54 | 54 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
843 | 843 | | |
844 | 844 | | |
845 | 845 | | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
846 | 850 | | |
847 | 851 | | |
848 | 852 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
753 | 753 | | |
754 | 754 | | |
755 | 755 | | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
756 | 760 | | |
757 | 761 | | |
758 | 762 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1036 | 1036 | | |
1037 | 1037 | | |
1038 | 1038 | | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
1039 | 1043 | | |
1040 | 1044 | | |
1041 | 1045 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
779 | 779 | | |
780 | 780 | | |
781 | 781 | | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
782 | 786 | | |
783 | 787 | | |
784 | 788 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
774 | 774 | | |
775 | 775 | | |
776 | 776 | | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
777 | 781 | | |
778 | 782 | | |
779 | 783 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
753 | 753 | | |
754 | 754 | | |
755 | 755 | | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
756 | 760 | | |
757 | 761 | | |
758 | 762 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
753 | 753 | | |
754 | 754 | | |
755 | 755 | | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
756 | 760 | | |
757 | 761 | | |
758 | 762 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
774 | 774 | | |
775 | 775 | | |
776 | 776 | | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
777 | 781 | | |
778 | 782 | | |
779 | 783 | | |
| |||
0 commit comments