Commit e77bab1
SEP-1845: Report failed UI actions in SEP's own component tree so a refused action is never silent (#1388)
Stacked on #1387 (SEP-1844), which this branch is based on. Retarget to
`main` once that merges.
## Why
SEP-1838 made every state-changing API route refuse a non-admin with a
403 and a JSON reason, turning a rare failure into a routine one. An
audit of the 47 mutation call sites in the frontend found:
* 9 that surface nothing at all on failure
* 2 that keep the server's message only for HTTP 400 and substitute a
generic string otherwise
* 6 that report only through a notistack toast
The toast family depends on a `SnackbarProvider` the host application
mounts. In standalone SEP that is `@sep/shell`; in the PMM-embedded
deployment SEP ships no frontend of its own, so that provider is not
SEP's to guarantee. A toast-only report can therefore be no report at
all, which is the reported symptom: a refused create leaves the form
open with nothing shown.
## What changed
**A shared primitive in `@sep/framework`** (`ActionErrorAlert` /
`useActionError` / `actionErrorMessage`) that derives the server's own
reason and renders it inline, with no notistack dependency.
`useActionError` is for actions fired from a dialog that closes before
the request settles; where the mutation object is in scope at the render
site, its `error` goes straight to the alert.
**The message is the server's own reason.** A string `detail` arrives as
`ApiError.message`. A 422 carries `detail` as a per-field array that the
lift skips, so the field entries are read through `parseFieldErrors` and
joined; a form uses `mapSubmitError` instead, which places them on their
fields. The fallback string is reached only when neither path yields
text.
**One signal per failure.** At every repaired site the error toast is
removed rather than kept alongside the new alert. Success toasts are
unaffected.
**`mapSubmitError` no longer returns an empty state for non-422
errors**, so AppCreatePage, AppTaskEditPage and the SchemaDrivenApp edit
form all show a persistent banner carrying the server's reason. The 422
per-field behaviour is unchanged, and a 422 whose `detail` is a string
keeps that string.
**`TaskHistoryTable` gained `actionError` / `onDismissActionError`.**
The connected variant reports its own stop mutation; a caller owning the
mutation threads its error in. The stop confirmation closes on confirm,
so the alert renders above the rows the user is left looking at. This
covers the stop-task sites on AppDetailPage, SnippetExecutionAccordion,
DipperApp and the tasks detail page.
**`AppDetailPage`'s execute confirmation** now closes in a `finally`
like the adjacent delete, and reports on the page behind it. Reopening
the same execute action keeps the composed chain, so a refused chained
execute can be retried without rebuilding it; opening a different action
still starts empty.
**The two status-narrowed sites** (`SyncControl`, batch approve in
`SnippetsListPage`) report on any status. Batch approve reads the reason
off the hook's `raw` wrapper, since the wrapper's own message says
nothing.
**A guard test** walks every package for `.mutate(` / `.mutateAsync(`
call sites and fails on a file with no in-tree failure path. Sites that
already reported in-tree before the primitive existed are allowlisted
with the mechanism each uses. Granularity is the file, not the
individual call: a file that already reports one action passes even if a
second unwired mutation is added to it. Tightening that would trade a
mechanical check for a heuristic one, and the omissions this guard
exists to catch were whole files with no failure path at all.
## Sites repaired
Previously silent: AppDetailPage (stop task, delete entity from detail
page), TaskHistoryTable (stop), SnippetExecutionAccordion (stop),
DipperApp (stop), tasks TaskDetailPage (stop), SnippetsListPage
(download, remove approval, approve).
Previously toast-only: AppListPage (delete), AppDetailPage (execute,
delete task), ConnectivityControl, InventoryAppNavigation (nested
delete), SyncControl. The three create/edit forms are resolved by the
`mapSubmitError` change.
Status-narrowed: SyncControl, batch approve.
## UX trade-off worth checking in design QA
Removing the error toasts is deliberate: an inline alert is less
attention-grabbing than a toast, so each alert is placed where the user
is actually looking after the dialog closes (above the rows for stop, on
the page behind the confirm for execute/delete, above the table for the
snippet row actions). The snippets page shares one alert across every
row action, so each attempt clears it first.
ConnectivityControl now renders a failed probe inline as well; its
passing case stays a success toast.
## Out of scope
Backend authorization (SEP-1838), hiding write controls from non-admins
(SEP-1844), migrating the ~30 sites that already render an in-tree
signal, and a central runtime mutation-error handler (rejected: it runs
outside the failing component's tree, so a host-provided toast is the
only thing it could render).
## Test plan
* `pnpm -r test` (14 packages, all green), `pnpm typecheck`, `pnpm exec
oxlint` (0 errors), `pnpm format:check`.
* New tests per repaired site cover both halves: the failure renders the
server's message, and the success path is unchanged.
* `ActionErrorAlert.test.tsx` covers the 403 reason, the 422 per-field
join, an array `detail` on a non-422 status keeping its own message,
transport failures, and the fallback.
* The guard was verified against a planted probe file: a new `.mutate(`
call with no failure path fails the test.
---------
Signed-off-by: Ignacio Durand <nachodurand@gmail.com>
Co-authored-by: yyyyyyy <yan.orestes@percona.com>
Co-authored-by: yyyyyyy <contact@yyyyyyyan.tech>1 parent eb17427 commit e77bab1
42 files changed
Lines changed: 2133 additions & 135 deletions
File tree
- changelog.d
- frontend/packages
- api
- src
- tests
- apps
- dipper/src
- inventory/src
- snippets/src
- tasks/src
- framework
- src
- components
- ActionErrorAlert
- SchemaDrivenApp
- SnippetExecutionAccordion
- TaskHistoryTable
- hooks
- tests
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
119 | 165 | | |
120 | 166 | | |
121 | 167 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
| 37 | + | |
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| |||
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
| 28 | + | |
29 | 29 | | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
82 | 83 | | |
83 | 84 | | |
84 | 85 | | |
| 86 | + | |
85 | 87 | | |
86 | 88 | | |
87 | 89 | | |
88 | 90 | | |
| 91 | + | |
89 | 92 | | |
90 | 93 | | |
91 | 94 | | |
| |||
97 | 100 | | |
98 | 101 | | |
99 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
100 | 108 | | |
101 | 109 | | |
102 | 110 | | |
103 | 111 | | |
104 | 112 | | |
105 | | - | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
106 | 121 | | |
107 | 122 | | |
108 | 123 | | |
| |||
119 | 134 | | |
120 | 135 | | |
121 | 136 | | |
| 137 | + | |
122 | 138 | | |
123 | 139 | | |
124 | 140 | | |
| |||
206 | 222 | | |
207 | 223 | | |
208 | 224 | | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
209 | 286 | | |
210 | 287 | | |
211 | 288 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
235 | 235 | | |
236 | 236 | | |
237 | 237 | | |
| 238 | + | |
| 239 | + | |
238 | 240 | | |
239 | 241 | | |
240 | 242 | | |
| |||
Lines changed: 24 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
144 | 144 | | |
145 | 145 | | |
146 | 146 | | |
147 | | - | |
| 147 | + | |
148 | 148 | | |
149 | 149 | | |
150 | 150 | | |
151 | 151 | | |
152 | | - | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
153 | 175 | | |
154 | 176 | | |
155 | 177 | | |
| |||
Lines changed: 33 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
| 18 | + | |
| 19 | + | |
19 | 20 | | |
20 | | - | |
| 21 | + | |
| 22 | + | |
21 | 23 | | |
22 | 24 | | |
23 | 25 | | |
| |||
45 | 47 | | |
46 | 48 | | |
47 | 49 | | |
| 50 | + | |
| 51 | + | |
48 | 52 | | |
49 | 53 | | |
50 | 54 | | |
51 | 55 | | |
52 | 56 | | |
53 | 57 | | |
| 58 | + | |
| 59 | + | |
54 | 60 | | |
55 | 61 | | |
56 | 62 | | |
57 | 63 | | |
58 | 64 | | |
59 | | - | |
60 | | - | |
61 | | - | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
62 | 68 | | |
63 | 69 | | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
71 | 73 | | |
72 | 74 | | |
73 | 75 | | |
| |||
96 | 98 | | |
97 | 99 | | |
98 | 100 | | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
99 | 120 | | |
100 | 121 | | |
101 | 122 | | |
0 commit comments