You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0420fee
Browse filesBrowse the repository at this point in the historyBrowse files
chore(data-drains): remove settings callout and unused InfoNote component (#5235)
* chore(data-drains): remove settings callout and unused InfoNote component
* improvement(data-retention): convert policy editor from modal to full-surface page
Mirror the access-control group-detail pattern: clicking a retention policy
now drills into a full-surface PolicyDetail page (back chip + dirty-gated
header Save/Discard + Remove) instead of an xl modal. Form fields use
SettingsSection (Workspaces / Retention / PII redaction) and the page chrome
matches group-detail exactly. The unsaved-changes confirm stays a small modal.
* improvement(settings): shared save/discard + unsaved-changes guard
Consolidate every editable settings surface onto one stack instead of
per-page custom logic:
- SaveDiscardActions: the canonical dirty-gated Discard+Save chip pair
- useSettingsUnsavedGuard: syncs local dirty into useSettingsDirtyStore (so the
sidebar section-switch confirm applies) + provides guardBack/UnsavedChangesModal
for detail sub-views' back chip
- useSettingsBeforeUnload: a single beforeunload in the settings shell
Migrate whitelabeling, sso, access-control group-detail, data-retention, and
secrets-manager (drops its duplicate beforeunload). Deletes the hand-rolled
'Unsaved changes' modals; the leave-confirm standardizes on Keep editing /
Discard. Documents the pattern in the settings rule + add-settings-page skill.
* fix(sso): reset originalFormData on discard/save so dirty state clears
handleDiscard and the post-save cleanup reset formData to DEFAULT but left
originalFormData on the edit snapshot, so hasChanges stayed true after leaving
the form — leaking a stuck-dirty state into the shared settings guard. Reset
originalFormData alongside formData in both leave paths (handleEdit re-seeds
both on re-entry).
* fix(settings): auto-dismiss unsaved-changes modal when page goes clean
useSettingsUnsavedGuard stashed a deferred leave + opened UnsavedChangesModal
when back was pressed while dirty, but never cleared them if isDirty later
became false. Confirming Discard could then run a stale leave with no unsaved
edits. Clear the pending leave and close the modal in the dirty-sync effect
whenever isDirty is false.
(from `@/app/workspace/[workspaceId]/components/credential-detail`). The
129
+
in-view header **Discard** chip (via `SaveDiscardActions onDiscard`) is a
130
+
*reset to original* — distinct from the back-confirm's discard, which leaves.
131
+
-**`useSettingsBeforeUnload`** is mounted **once** in the settings shell
132
+
(`settings/[section]/settings.tsx`) — never add a per-page `beforeunload`.
133
+
-**Dirty *computation* stays local** (shapes differ: field-compare vs
134
+
normalize+stringify) — only how dirty is *consumed* is shared. Derive it (a
135
+
`const`/`useMemo`), never store it in `useState`.
136
+
-**CRITICAL — rules of hooks:** call `useSettingsUnsavedGuard(...)`
137
+
**unconditionally, before every early-return gate** (entitlement / loading /
138
+
not-entitled `return <SettingsEmptyState>`). A hook placed after a gate is
139
+
skipped on gated renders and crashes.
140
+
- The route-based credential detail keeps its own `useUnsavedChangesGuard` (it
141
+
guards real `router.push` navigation + browser Back via a history sentinel);
142
+
it already shares `UnsavedChangesModal`, so copy stays unified.
143
+
104
144
## Detail sub-views (the one exception)
105
145
106
146
A drill-down view reached from a list row (selected MCP server, workflow MCP
@@ -119,5 +159,6 @@ A settings page is design-system-clean when:
119
159
-[ ] Header chips are in `actions`; a standalone search is in the `search` prop.
120
160
-[ ] Its `NavigationItem` has an accurate, consistent-length `description`.
121
161
-[ ] Detail sub-views and entitlement/loading gates keep their own chrome (intentional).
162
+
-[ ] If it has editable state: Save/Discard go through `SaveDiscardActions`, dirty is wired via `useSettingsUnsavedGuard` (called before any early-return gate), and there is **no** hand-rolled Save button / `beforeunload` / "Unsaved changes" modal.
122
163
-[ ] No business logic, handlers, or conditional rendering changed by the migration.
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/settings/components/secrets/components/secrets-manager/secrets-manager.tsx
-10Lines changed: 0 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -501,16 +501,6 @@ export function SecretsManager() {
0 commit comments