Repository navigation
perf(console): write app navigation at page and dashboard create and delete sites - #28783
Merged
Merged
Conversation
…delete sites NavigationSyncEffect read the whole /meta/page and /meta/dashboard lists on every app page to diff their name sets (maintainer ruling A on #28680 retires it). The metadata editor's first Publish and real Delete of a package-less page or dashboard, and Publish all's creates, now write app navigation through useNavigationWrites, which keeps the diff's rules: platform artifacts never write, write-protected apps are skipped, nothing is written in draft preview. A create no longer duplicates an entry an app already holds. NavigationSyncEffect stays exported as an inert, deprecated component. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jUjXYpqdaAkEWBHbqG
…mments naming it a live writer @object-ui/app-shell is private and nothing outside it imported the effect, so the inert export goes: useNavigationSync.ts, both index files, the AppContent test's stale mock and the effect's pins. The comments that named it as a live writer (useNavTargetLabel, CommandPalette, PreviewModeContext, the react package's getTypeStatus doc, two test fixtures) now name the create sites. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jUjXYpqdaAkEWBHbqG
Contributor
Author
|
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu 席位核对 · ACCEPT · 2026-11-01T20:28ZHead-sha:
|
This was referenced Nov 1, 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 #28680
Fixes #28645
Clause-②: no
Metadata-protocol: none
维护者速读
NavigationSyncEffect不再在每个应用页读取整张/meta/page和/meta/dashboard列表做差异比较。_packageId,原本就不经过差异比较。回滚即还原本 PR,无数据或协议变更。ui/packages/app-shell/src/hooks/useNavigationSync.ts(useNavigationWrites)、ui/packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx(doPublish、runReset)、ui/packages/app-shell/src/preview/usePublishAllDrafts.ts。cd ui && pnpm exec vitest run packages/app-shell/src/views/metadata-admin/ResourceEditPage.navigationWrites-28680.test.tsx packages/app-shell/src/hooks/__tests__/useNavigationSync.test.tsx,预期 22 个用例全绿。/meta/dashboard(见 Deviations),可另开卡处理。What changes
NavigationSyncEffectread the whole/meta/pageand/meta/dashboardlists on every app page, after the first paint, only to diff their name sets and add or remove navigation entries. Maintainer ruling A on #28680 retires it. The console's sites now write navigation themselves, through a new door inuseNavigationSync.ts:useNavigationWrites()returnscreated(type, name, item?)anddeleted(type, name, item?). They call the existingsync…CreatedAllApps/sync…DeletedAllAppswriters and keep the diff's rules: only apageor adashboard; never a platform artifact (isPlatformArtifact: asys_name, or_packageId/_provenance: 'package'); nothing in draft preview (ADR-0037, whereappsmay be draft bodies); only into apps that may be written (isNavigationSyncableApp). Entries are written label-less, as before (objectui#9868).ResourceEditPagedoPublish): when the item held no layer before the publish (its draft was its only layer,/layers404) and the editor is not bound to a package, the page or dashboard is created and joins navigation. A later publish of the same item is an update and writes nothing.runResetwith no baseline): an unbound real delete removes the item from navigation. A reset to a packaged baseline writes nothing.usePublishAllDrafts): before publishing each package-less page or dashboard draft, it asks the item's layers. The ones that had none are created and join navigation after the batch. A failed layers read is not taken for a create.syncPageCreated/syncDashboardCreatedskip an app whose navigation already references the target at any depth (navigationReferences).addNavigationItemitself still appends.NavigationSyncEffectstays exported,@deprecated, and renders nothing.AppContentno longer mounts it.No rename site exists in the console today, so the
sync…RenamedAllAppswriters keep no caller.Who relied on the diff (the claim's pre-code check)
Nothing created outside the console. The diff dropped every platform artifact, and package installs and CLI deploys carry
_packageId(checked on the running showcase:showcase_start_here's layers answer_packageId: 'com.example.showcase',_provenance: 'package'). Studio always saves with a package. The diff acted only on package-less pages or dashboards that appeared or vanished in this tab's lists mid-session, and its baseline re-seeded on every load.What no longer reaches navigation: a package-less page or dashboard created or deleted outside this tab (a server-side agent, another tab, a raw REST call). It now reaches navigation only through its own writer. The changeset says the same.
Tests
ResourceEditPage.navigationWrites-28680.test.tsx(5 cases, the real page): the first publish adds the page to the app once and a second publish adds no second entry; publishing an item that already had a layer writes nothing; a package-bound publish writes nothing; a real delete removes the entry; a reset leaves navigation alone.usePublishAllDrafts.navigationWrites-28680.test.tsx(2 cases, realMetadataClient): new package-less page and dashboard join; an updated page, a packaged page and a flow do not; layers are asked before each publish; a failed layers read writes nothing.useNavigationSync.test.tsx: the diff's cases are replaced byuseNavigationWritescases (platform artifacts in both directions, other types, draft preview, locked apps, a second create of a referenced page or dashboard),navigationReferences, and a pin thatNavigationSyncEffectreads neither list and writes nothing.labelInherits-9868,standardEntryLocalizes-11201andchromeReads.afterFirstPaint-12980now drive the new door, or pin that the retired effect reads nothing.Acceptance notes
Measured on a production console build (
pnpm build,pnpm console:build,pnpm dev -- --fresh),showcase_app, admin, API calls of a warm reload, two runs each with the same count:2678600dpage/showcase_start_here/meta/page−1,/meta/dashboard−1dashboard/showcase_ops_dashboard/meta/page−1showcase_task(object list)/meta/page−1,/meta/dashboard−1On the running server, a page saved as a draft answers
/layers404 and its first publish turns it into a layer withresettable: false, which is the editor's create and delete verdict this PR reads. The probe page was deleted afterwards.Deviations:
AppContentwaits for thedashboardlist (routeReads), and the dashboard view reads its definition from it. The effect shared that one request, so removing the effect saves only/meta/pagethere. Reading the dashboard route bundle-first, as PR 1 did for the page route, would remove it. That isAppContent's route gate and the dashboard view, outside this claim's surface, so it is left for a follow-up card.appsmay be draft bodies. The diff wrote nothing there either.AppContent.tsxchanges only to drop the mount.useNavTargetLabel.tskeeps a comment that says the console'sNavigationSyncEffectloads the dashboard list; it is outside the surface and left as it is.Verification
Derived gates (34)
Run at
f31794f6(this PR merged withorigin/mainatcd0ec76b).dispatch-gates --ran: 34 derived, 34 run, 0 NOT-MEASURED.Tests and type-check
useNavigationSync,ResourceEditPage,usePublishAllDrafts,AppContent,DraftPreviewBar,HomePage), 5 locked batches at--maxWorkers=3: 295 passed, 2493 tests. The full app-shell suite is left to CI's Test UI shards.pnpm turbo run type-check --filter=@object-ui/app-shell: 65/65 tasks, exit 0.eslint --quietover the changed files: exit 0.origin/mainatcd0ec76bwith no overlap on touched files and no parallel fix found.Human Minimum
packages/specholds no runtime logic.pnpm lintpasses. (run aseslint --quietover the changed ui files: 0 errors; the whole-workspace lint is left to CI)main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed. (not touched)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01QsR2jUjXYpqdaAkEWBHbqG