Repository navigation
Commit f8633c7
fix(app-shell): permission grid signals cut columns and pins its Object column and field header (#27909)
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgDFH4S5pR1C8YvYCWWsZfXx)_
## 维护者速读
- 改了什么:权限集编辑器的对象矩阵(Setup 页与 Studio Access 的 Objects
页同一套)在列被截断时右边缘出现渐隐提示;Object 列钉在左边(手机上只显示对象名,留出滚动空间);展开字段行后,字段表头(Field /
Read / Edit / When)钉在矩阵表头下面;同一对象里两个字段同名(如 Owner)时,把 API 名作为区分文字显示出来。
- 为什么改:1440 宽时 Bulk 列被截而没有任何提示;手机上横向滚动后看不到每行是哪个对象;展开字段后顶部只剩 C/R/U/D…
的对象表头,压在字段行上,对不上 Read/Edit 列;showcase 的项目和发票对象各有两个都叫「Owner」的字段。
- 风险与回滚:只改前端样式与布局,权限数据、保存内容不变;回滚即 revert 本 PR。
- 先看:`MatrixScrollPane.tsx`(新文件,渐隐提示);`PermissionMatrixEditor.tsx` 的
`STICKY_OBJECT_CELL` / `FIELD_HEAD_CELL` 两个常量及其使用处;`FieldsSubTable` 里的
`sharesLabel`。
- 两分钟验证:`pnpm --dir ui exec vitest run
packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.gridChrome-27866.test.tsx`,预期
9 条全部通过。
- 需要你做的:无,席位落地。
Fixes #27866
Clause-②: no
Metadata-protocol: none
## What changes
All in `ui/packages/app-shell/src/views/metadata-admin/` (app-shell is
private; it ships inside `@object-ui/console`):
- **Overflow cue.** New `MatrixScrollPane.tsx` replaces the bare
`overflow-auto` box around the matrix, on the routed page
(`PermissionTable`) and the Studio Objects tab (`StudioObjectMatrix`).
It reads its own box on scroll and on resize (`readPaneOverflow`) and,
while columns are cut on the right, draws an `aria-hidden` fade over the
pane's right edge (`perm-matrix-overflow-cue`); the fade goes once the
last column is in view. It also stamps `data-scrolled-x` once the pane
has scrolled sideways.
- **Pinned Object column.** `STICKY_OBJECT_CELL` pins the Object header
and every object row's first cell to the pane's left edge over an opaque
background, and draws the column's right edge while `data-scrolled-x` is
set. Row tints (the routed page's hover, the Studio row's active state)
are laid on as a background image so the pinned cell keeps them. On a
phone the routed page's Object column is `w-36` (was `w-72`) and the
`(api_name)` aside is hidden below `sm`, so the pinned column takes ~178
px of 390 instead of ~332.
- **Field header pinned under the matrix header.** `FIELD_HEAD_CELL`
pins the field sub-table's header cells to `top-9`, under the matrix
header row (now `h-9` on the routed page; the Studio row already was),
while the sub-table is in view. Field rows scrolled under the matrix
header are labelled by their own Field / Read / Edit / When columns, not
by the object columns above.
- **Shared labels.** When two of an object's offered fields share a
label (case-insensitive), each row draws its `(api_name)` in the
foreground, monospace, instead of the muted aside, and carries
`data-shared-label`.
No i18n key, no export from a published package, no metadata change.
## Tests
`PermissionMatrixEditor.gridChrome-27866.test.tsx` (9 tests):
`readPaneOverflow` cases, then on both renderings: the cue shows while
the stubbed pane is cut and goes at the end (and for a grid that fits),
`data-scrolled-x` follows; the Object header and row cells are pinned
(CONTROL: a box cell is not); the field header cells pin `top-9` under
an `h-9` header row (CONTROL: field rows do not); `owner` / `owner_id`
both "Owner" draw their API names in the foreground (CONTROL: `status`
keeps the muted aside).
<details><summary>Readings</summary>
- New file at 02dbcde: Test Files 1 passed, Tests 9 passed (9), lock
VERDICT command-exit 0.
- Ablation: `PermissionMatrixEditor.tsx` restored to `origin/main` under
a trap (markers `STICKY_OBJECT_CELL` and `MatrixScrollPane` counted 0),
same file: Tests 8 failed, 1 passed (the pure `readPaneOverflow` case),
VERDICT command-exit 1; restored by `git checkout HEAD`, `git diff HEAD`
empty, blob hash equal to HEAD. Tests import `src`, so no dist rebuild.
- Every test file naming `PermissionMatrixEditor` or `MatrixScrollPane`
(48 files): Test Files 48 passed (48), Tests 340 passed (340), VERDICT
command-exit 0.
- `pnpm --filter @object-ui/app-shell run type-check` (tsc --noEmit and
tsconfig.test.json): VERDICT command-exit 0.
</details>
## Acceptance notes
Re-driven on stock `examples/app-showcase --seed-admin --fresh` (admin,
Chromium, Setup, permission set `member_default`) before and after the
change, routed page:
- [x] **1440 px: cut columns are signalled.** Before: the pane is 1184
px wide, the grid 1304 px, the Bulk header spans 1372–1560 against a
pane edge at 1440, no cue. After: the fade is present at scroll 0 and
gone at the end (scrollLeft 120), where the Bulk header's right edge
equals the pane's (1440).
- [x] **Phone: the Object column stays visible.** Before at 390×844:
scrolled to the end, the Object column is gone. After: the Object header
and first row cell stay at left 0 (header 0–178) with the pane scrolled
914 px.
- [x] **No two fields carry the same label.** On `main` both rows
already showed their API names as a muted aside (`Owner (owner)`, `Owner
(owner_id)` on `showcase_project`, and the same pair on
`showcase_invoice`); they now draw the API name as the distinguishing
text. The duplicate itself is metadata: the showcase authors a text
field `owner` labelled "Owner" beside the platform-injected `owner_id`,
also "Owner". That half is outside this card's file surface
(`examples/app-showcase`, and the injected label under `packages/**`),
named, not done. No two columns share a label.
- [x] **With field rows expanded, each header sits over its column.**
Before: scrolled into `showcase_project`'s field rows, the only header
in view was the object header (C at 584 … Read scope at 1063) while the
field Read box sat at 1044. After: the field header pins at top 495,
right under the object header (459 + 36), with Read at 1036 over the
Read boxes.
Not re-driven live: the Studio Objects tab (pinned by the same tests on
that rendering). The fade is drawn over the whole pane's right edge, so
on the routed page it also lies over the right margin of the advanced
facets and Assigned Users below the grid while columns are cut.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CYzrSNZwgsCPhWGAbi)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent d3b0a40 commit f8633c7
4 files changed
Lines changed: 355 additions & 20 deletions
File tree
- .changeset
- ui/packages/app-shell/src/views/metadata-admin
| 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 | + | |
| 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 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 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 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
0 commit comments