Repository navigation
fix(plugin-list): a list view locked by lockedBy alone shows its lock indicator - #29312
Merged
Merged
Conversation
… indicator The toolbar's sharing indicator rendered only under a declared sharing.type, so a view authored with only lockedBy (the spec defaults type to collaborative, and the served view carries the authored body) showed no lock. The indicator now keys on type or lockedBy, and an absent type reads the spec's ViewSharingSchema default instead of restating it. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jSSoRjvEqsGsZZLPC9
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jSSoRjvEqsGsZZLPC9
Contributor
Author
|
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m 席位核对 · ACCEPT · 2026-11-02T11:54ZHead-sha:
|
This was referenced Nov 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Steedos · project thread
Fixes #29009
Clause-②: no
Metadata-protocol: none
维护者速读
sharing只写了lockedBy、没写type时,工具栏现在会显示锁定标记「Locked by 用户」,旁边的类型标签按 spec 默认值显示为「Shared view」。写了type的视图显示不变;sharing里两个键都没写时什么都不显示。type默认为collaborative,但下发的视图是作者原文、不带默认值,而工具栏只在type存在时才画这个标记,所以「只写 lockedBy」的已锁定视图对其他人看不出被锁。现在锁定标记只看lockedBy,以后 spec: retire the two inert personal declarations — a view marked personal is visible to everyone, and the docs promise personal views that do not exist #29037 退役personal或type也不会再把它藏掉。ViewSharingSchema读取,不在 ui 里重抄。回滚即 revert 本 PR。ui/packages/plugin-list/src/ListView.tsx里hasSharingIndicator和SPEC_DEFAULT_SHARING_TYPE,以及 sharing 标记块与分隔线的hasLeftSideItems;ListView.test.tsx的sharing spec format — additional。pnpm --dir ui exec vitest run packages/plugin-list/src/__tests__/ListView.test.tsx,应 158/158 通过,其中「shows the lock fromsharing.lockedBywith notype」一条。What changes
lockedBy, not ontype. The toolbar's read-only sharing indicator rendered only underschema.sharing?.type, so a view authored assharing: { lockedBy: 'admin@objectos.ai' }showed no lock at all. It now renders whensharingdeclares atypeor alockedBy(hasSharingIndicator), and the lock part depends onlockedByalone. The toolbar separator'shasLeftSideItemsreads the same predicate, so the separator follows the indicator.typeshows the spec's default type label. The served view carries the authored body, and nothing on the render path parses it, sotypearrives absent. The indicator reads the default from the contract,ViewSharingSchema.parse({}).type(todaycollaborative, shown as "Shared view"), once at module load, the same wayListViewalready reads the pagination page size fromPaginationConfigSchema. Why the default and not "no badge": per the spec the view IS collaborative, and a view that writestype: 'collaborative'with the same lock already shows "Shared view · Locked by USER", so the two spellings of one contract value now render the same. If spec: retire the two inert personal declarations — a view marked personal is visible to everyone, and the docs promise personal views that do not exist #29037 later retirestype, this read stops compiling, which points the author at this spot.typeset renders exactly as before; asharingblock with neither key, and a view with nosharing, show nothing; the copy (list.sharingLockedBy,list.sharingPersonal,list.sharingCollaborative) is untouched. No spec edit.Tests
ListView.test.tsx,sharing spec format — additional:sharing: { lockedBy: 'admin@objectos.ai' }with notype, withtype: 'collaborative', and withtype: 'personal'. Each shows "Locked by admin@objectos.ai" and the titleTYPE_LABEL · Locked by admin@objectos.ai.sharing: {}(neither key) shows no indicator and no lock.Acceptance notes
domain:spec): that card retires thepersonalvalue and may retiretypeand the type label. This PR makes the lock independent oftype, so the lock survives either outcome; the type label is the part spec: retire the two inert personal declarations — a view marked personal is visible to everyone, and the docs promise personal views that do not exist #29037 owns.ListView.tsx. Neither had landed when this branch mergedorigin/mainf2bf2938. This diff touches the@objectstack/spec/uiimport line, one module-level block afterDEFAULT_LIST_DISPLAY_PAGE_SIZE, the sharing block and the separator'shasLeftSideItemsline; none of their hunks overlaps those lines.ListView, and the tests render the real component.Verification
Head
57e2c4d1mergesorigin/mainf2bf2938, which does not touchui/packages/plugin-list/orpackages/spec/src/ui/; the delta against main is still exactly the three files of this PR. The runs below were taken onb6269b70(base8a8a03d3).Tests and the ablation
vitest run packages/plugin-list/src/__tests__/ListView.test.tsx: 158/158 passed.scripts/ablation-replace.mjs, replacing the guard{hasSharingIndicator(schema.sharing) && (() => {with the old{schema.sharing?.type && (() => {(anchor 1 to 0, blobccc95a10to9518d23b): 1 failed, 157 passed. The failing case is "shows the lock fromsharing.lockedBywith notype(the spec default)". Restored: blob equals HEAD andgit diff HEADis empty.Package suite, type-check, lint and gates
packages/plugin-list/suite under the verify lock,--maxWorkers=2, two batches: 185 files passed, 1767 tests passed.turbo run type-check --filter=@object-ui/plugin-list: 50/50 tasks, exit 0 (tsc --noEmit && tsc -p tsconfig.test.json, so the test file is compiled).eslinton the two touched files (fromui/): 0 errors.dispatch-gates --commands: 34 derived families, all exit 0, includingnode scripts/check-sdui-manifest.mjsandpnpm --dir ui exec vitest run scripts/(169 files passed, 2 skipped).dispatch-gates --ran: 34 derived, 34 run, 0 NOT-MEASURED.pnpm check:new-line-citations(ui): 0 new citations.check-closing-keyword-parity,check-changeset-no-majorandcheck-adr-0087-registrationwere also run against this body.Generated by Claude Code