Repository navigation
Commit 633f641
Load the web console's server state through TanStack Query (#23)
* Add TanStack Query to the web console
Pull in @tanstack/react-query 5.102 and mount a shared client in
main.tsx. The client's defaults live in src/lib/query-client.ts with
their reasons: no retries, since nearly every failure here is a 4xx a
retry cannot fix, and no refetch on window focus, since admin pages
mount several queries at once.
api() now announces successful writes (onSuccessfulWrite), and main.tsx
has the cache drop the queries no screen is using. One write can change
what several cached screens hold; this way none of them reopens onto
data from before it, without each call site knowing what it touched.
@tanstack/eslint-plugin-query joins the lint config: its exhaustive-deps
keeps every value a queryFn reads in its key. Tests get
renderWithQueryClient, which renders inside a fresh cache.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Load server state through TanStack Query
Every load that carried a react-hooks/set-state-in-effect suppression
goes through useQuery now, and writes invalidate what their screen shows
instead of calling a loader again. The loading flags, the abort
controllers, the fetch-token race guard and the 13 loader useCallback
wrappers they needed are gone; query keys follow the endpoint.
Behaviour that changes on purpose:
- Logout, and the cross-tab logout broadcast, clear the cache along
with the user. The signed-in user is one shared query, so signing out
from Profile now signs out the whole UI.
- A reload after a write refreshes in place instead of flashing the
skeleton, and a load error clears on the next successful load.
- RouteEditorDialog maps remote-models entries to ids: the endpoint
returns objects, and the dialog handed them to React as children.
- OutboxBacklogDialog drops onChanged: invalidating the webhook-outbox
prefix also refreshes the parent's backlog counts.
- Polling uses refetchInterval, which pauses while the tab is hidden.
Where cached data can already be there on the first render, local state
follows it through trackers that start empty: BatchImportDialog can
mount open, the Models page's ?import= deeplink opens it during render,
and the pricing form seeds once, from a fetch made after mount.
BatchImportDialog also offers nothing until both lists are fresh, so a
cached copy cannot offer models imported since.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Derive the setup wizard's validation errors during render
adminErrors was state kept in step with the form by an effect that ran
validateAdmin after every change. It is a pure function of the form
values, so it is a useMemo now: an error clears on the keystroke that
fixes it, and the last set-state-in-effect suppression goes with the
effect. It was labelled a hand-rolled load; it never fetched anything.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Document the query layer in the web README
The "Data fetching" section described hand-rolled loads and the two
reasons a suppression of set-state-in-effect could stand. Both are gone,
so the section now describes the query layer — keys, writes, signals,
deriving local state — and keeps the rule against new suppressions.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>1 parent dd4d6b0 commit 633f641
42 files changed
Lines changed: 1550 additions & 1421 deletions
File tree
- web
- src
- components
- limits
- mcp
- wizard
- roles
- hooks
- lib
- routes
- admin
- settings/oidc
- analytics
- gateway
- models
- mcp
- test
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 | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
48 | 57 | | |
49 | 58 | | |
50 | 59 | | |
| |||
58 | 67 | | |
59 | 68 | | |
60 | 69 | | |
| 70 | + | |
61 | 71 | | |
62 | 72 | | |
63 | 73 | | |
| |||
88 | 98 | | |
89 | 99 | | |
90 | 100 | | |
| 101 | + | |
91 | 102 | | |
92 | 103 | | |
93 | 104 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
25 | 30 | | |
26 | 31 | | |
27 | 32 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
44 | 45 | | |
45 | 46 | | |
46 | 47 | | |
| 48 | + | |
47 | 49 | | |
48 | 50 | | |
49 | 51 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
| 2 | + | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
58 | | - | |
| 59 | + | |
59 | 60 | | |
60 | 61 | | |
61 | 62 | | |
| |||
72 | 73 | | |
73 | 74 | | |
74 | 75 | | |
75 | | - | |
| 76 | + | |
76 | 77 | | |
77 | 78 | | |
78 | 79 | | |
| |||
103 | 104 | | |
104 | 105 | | |
105 | 106 | | |
106 | | - | |
| 107 | + | |
107 | 108 | | |
108 | 109 | | |
109 | 110 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
| 34 | + | |
35 | 35 | | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
| |||
174 | 175 | | |
175 | 176 | | |
176 | 177 | | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
181 | 190 | | |
182 | 191 | | |
183 | 192 | | |
| |||
186 | 195 | | |
187 | 196 | | |
188 | 197 | | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
222 | 198 | | |
223 | 199 | | |
224 | 200 | | |
| |||
229 | 205 | | |
230 | 206 | | |
231 | 207 | | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
232 | 224 | | |
233 | 225 | | |
234 | 226 | | |
235 | | - | |
| 227 | + | |
236 | 228 | | |
237 | 229 | | |
238 | 230 | | |
| |||
259 | 251 | | |
260 | 252 | | |
261 | 253 | | |
262 | | - | |
| 254 | + | |
263 | 255 | | |
264 | 256 | | |
265 | 257 | | |
| |||
0 commit comments