feat(forms): browser-level unsaved-changes guard for the Company form (MAPPS-292) #293

Merged
YousifShkara merged 1 commit from feat/MAPPS-292-unsaved-changes-guard into main 2026-06-21 07:21:23 +02:00
Owner

Adds a use_unsaved_guard(dirty) hook in src/hooks/unsaved_guard.rs that installs a beforeunload window listener while the supplied signal reads true. The Company form (~10 fields, the QA repro case) wires the hook to a derived dirty memo that compares every editable field to its initial value and suppresses the prompt during a save (the navigate-away triggered by is_submitting). Closing the tab, reloading, or navigating to an external URL on a half-filled Company form now surfaces the browser's "Leave site?" dialog instead of silently discarding the input.

Scope. This hook covers OS-level navigation triggers. Dioxus 0.7's router does not expose a transition-guard API, so client-side <Link> clicks and navigator.push() still bypass the guard; that part of the unsaved-changes story is parked as a follow-up. The browser-level cover is the highest-impact half of the data-loss surface (the QA's specific complaint: ten fields lost on tab close). Other long forms (Contract, Project, Asset, Invoice) can opt in by wiring their own dirty memo to the same hook in a follow-up.

#MAPPS-292

Adds a `use_unsaved_guard(dirty)` hook in `src/hooks/unsaved_guard.rs` that installs a `beforeunload` window listener while the supplied signal reads true. The Company form (~10 fields, the QA repro case) wires the hook to a derived `dirty` memo that compares every editable field to its initial value and suppresses the prompt during a save (the navigate-away triggered by `is_submitting`). Closing the tab, reloading, or navigating to an external URL on a half-filled Company form now surfaces the browser's "Leave site?" dialog instead of silently discarding the input. Scope. This hook covers OS-level navigation triggers. Dioxus 0.7's router does not expose a transition-guard API, so client-side `<Link>` clicks and `navigator.push()` still bypass the guard; that part of the unsaved-changes story is parked as a follow-up. The browser-level cover is the highest-impact half of the data-loss surface (the QA's specific complaint: ten fields lost on tab close). Other long forms (Contract, Project, Asset, Invoice) can opt in by wiring their own `dirty` memo to the same hook in a follow-up. #MAPPS-292
feat(forms): browser-level unsaved-changes guard for the Company form (MAPPS-292)
All checks were successful
Create release / Create release from merged PR (pull_request) Has been skipped
Check / clippy + fmt + tests (pull_request) Successful in 1m33s
0042625f06
Adds a `use_unsaved_guard(dirty)` hook in `src/hooks/unsaved_guard.rs` that installs a `beforeunload` window listener while the supplied signal reads true. The Company form (~10 fields, the QA repro case) wires the hook to a derived `dirty` memo that compares every editable field to its initial value and suppresses the prompt during a save (the navigate-away triggered by `is_submitting`). Closing the tab, reloading, or navigating to an external URL on a half-filled Company form now surfaces the browser's "Leave site?" dialog instead of silently discarding the input.

Scope. This hook covers OS-level navigation triggers. Dioxus 0.7's router does not expose a transition-guard API, so client-side `<Link>` clicks and `navigator.push()` still bypass the guard; that part of the unsaved-changes story is parked as a follow-up. The browser-level cover is the highest-impact half of the data-loss surface (the QA's specific complaint: ten fields lost on tab close). Other long forms (Contract, Project, Asset, Invoice) can opt in by wiring their own `dirty` memo to the same hook in a follow-up.

#MAPPS-292
YousifShkara deleted branch feat/MAPPS-292-unsaved-changes-guard 2026-06-21 07:21:23 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-apps!293
No description provided.