Uh oh!
There was an error while loading. Please reload this page.
fix(studio): confirm before header SPA nav discards unsaved pillar edits (#2600) - #2606
Merged
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub. |
xuyushun441-sysforce-pushed
the
claude/reverent-gould-095d7a
branch
from
July 16, 2026 13:25
1dba2a8 to
4982bd3Compare8 tasks
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
…its (#2600) The Studio header's pillar links, Home button and PackageSwitcher are pure react-router client navigation, so the editors' beforeunload guard never fires — a dirty pillar unmounted silently and its unsaved edits were gone (Access permission-matrix cells, Interfaces nav). Pillars now mirror their dirty state up to StudioDesignSurface (the PR #2588 onDirtyChange contract: AccessPillar forwards the matrix editor's report, InterfacesPillar mirrors navDirty ref-stabilized with an unmount reset), and every header-driven departure gates on the same native confirm the Access rail already uses. Same-pillar / same-package re-clicks and modified (new-tab) clicks never prompt — nothing unmounts. A surface-level beforeunload guard also closes the reload/close gap for nav edits, which had none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
xuyushun441-sysforce-pushed
the
claude/reverent-gould-095d7a
branch
from
July 16, 2026 13:37
4982bd3 to
d8b5529CompareContributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Uh oh!
There was an error while loading. Please reload this page.
xuyushun441-sys pushed a commit
that referenced
this pull request
Jul 16, 2026
…d Studio header nav (#2600 follow-up) PackageOwdOverviewPanel tracked its unsaved per-object OWD rows internally (rowState/dirtyCount) but reported them to no one, so both unsaved-edit guards discarded them silently: the Access rail's confirm (confirmDiscardMatrixEdits checked only matrixDirty) and the Studio header's surface-level pillarDirty guard from PR #2606. - PackageOwdOverviewPanel grows onDirtyChange — same contract as PermissionMatrixEditPage (ref-stabilized transitions, false on unmount). - AccessPillar folds it in as owdDirty alongside matrixDirty: the rail confirm gates on the combined bit (the two surfaces never coexist), and the combined bit mirrors up to the surface via an effect (replacing the reportMatrixDirty wrapper). - Re-clicking the open OWD rail entry is now a no-op (nothing remounts, so no confirm), mirroring the set re-click. - The create flow now lands on the new set's matrix even from the OWD overview (setOwdOpen(false) in doCreate), so the up-front gate's discard warning is truthful. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
os-zhuang added a commit
that referenced
this pull request
Jul 16, 2026
…d Studio header nav (#2600 follow-up) (#2610) PackageOwdOverviewPanel tracked its unsaved per-object OWD rows internally (rowState/dirtyCount) but reported them to no one, so both unsaved-edit guards discarded them silently: the Access rail's confirm (confirmDiscardMatrixEdits checked only matrixDirty) and the Studio header's surface-level pillarDirty guard from PR #2606. - PackageOwdOverviewPanel grows onDirtyChange — same contract as PermissionMatrixEditPage (ref-stabilized transitions, false on unmount). - AccessPillar folds it in as owdDirty alongside matrixDirty: the rail confirm gates on the combined bit (the two surfaces never coexist), and the combined bit mirrors up to the surface via an effect (replacing the reportMatrixDirty wrapper). - Re-clicking the open OWD rail entry is now a no-op (nothing remounts, so no confirm), mirroring the set re-click. - The create flow now lands on the new set's matrix even from the OWD overview (setOwdOpen(false) in doCreate), so the up-front gate's discard warning is truthful. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
os-zhuang added a commit
that referenced
this pull request
Jul 18, 2026
…nt capabilities so the matrix hits the first screen (#2600 B1) (#2649) The Access pillar is called "Permission Matrix", but the editor opened with a name/label form plus the capability picker's option chips, pushing the matrix below the fold. Two low-frequency, high-chrome sections now start collapsed: - Identity (name/label) collapses to a one-line summary (label · provenance · default/read-only badges) and expands on click. The api-name already lives in the PageShell breadcrumb, so the summary carries the human label only. - System capabilities: a zero-grant WRITABLE set rendered every option as an outline chip, which read as already-owned. It now shows an explicit "none granted · add" affordance; granted sets and read-only sets keep the inline picker as before. Read-only packages, the dirty/guard contracts (#2588/#2606), the history sheet and breadcrumb (#2599) are all unaffected. Adds PermissionMatrixEditor.basics.test.tsx and updates the settle points of the existing matrix/guard suites (identity is now summary text, not an input). Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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 freeto 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.
Summary
Follow-up to #2600 / PR #2588. The A1 fix guarded rail-driven swaps inside the Access pillar, but the Studio header was still unguarded: the pillar links (Data/Automations/Interfaces/Access) are plain react-router
<Link>s, the Home button callsshellNavigate('/home'), and the PackageSwitcher callsnavigate(...)— all pure SPA client navigation, so the editors'beforeunloadguard never fires and a dirty pillar unmounts silently, discarding its unsaved edits (AccessmatrixDirty, InterfacesnavDirty).AccessPillarandInterfacesPillargrow anonDirtyChangeprop (the PR fix(studio): Access pillar no longer silently discards unsaved permission-matrix edits on rail switch #2588 contract — reportfalseon unmount so a confirmed discard clears the guard by itself). AccessPillar forwards the matrix editor's report alongside its local rail guard; InterfacesPillar mirrorsnavDirtyref-stabilized, same asPermissionMatrixEditPage's own report.window.confirm(t('engine.edit.unsavedLeaveConfirm')): pillar links (e.preventDefault()on decline), Home, PackageSwitcher row clicks, and the post-create jump into a new package.onManageChangedstays unguarded — that navigation is forced.beforeunloadguard keyed on the lifted dirty bit — Interfaces nav edits previously had no reload/close guard at all (the matrix editor has its own; double registration is harmless).Tests
New
StudioDesignSurface.pillarNavGuard.test.tsx(6 cases), rendered through the realStudioDesignSurface+AccessPillar+PermissionMatrixEditPagestack with the same mock seams asStudioDesignSurface.accessGuard.test.tsx: dirty pillar switch (cancel keeps edits / confirm lands + guard resets), clean switch, same-pillar re-click, Home button both ways, package switch both ways, clean package switch.vitest run packages/app-shell/src/views/studio-design/— 17 files / 102 tests passtsc --noEmitinpackages/app-shell— clean (after building workspace deps)Not covered: driving
navDirtyend-to-end (needs a full app + nav-canvas drag setup); its mirror is the same 10-line pattern the matrix path exercises. The OWD overview panel's internaldirtyCountis intentionally out of scope (also not covered by the existing rail guard) — noted on #2600.Merge note (issue #2600 「合并注意」)
Touches
StudioDesignSurface.tsx(AccessPillar mount point + props) — same file as A2 (readOnly) and PR #2599 (A3). Per the issue: serial merge, rebase whichever lands later.🤖 Generated with Claude Code