@tristan2828/ui-foundation 4.9.0 → 4.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -178,7 +178,12 @@ is a filled-in example while the Widgets demo is still here).
|
|
|
178
178
|
a toast naming the row and the server's reason; the lists refetch
|
|
179
179
|
after). Its specs cover a flip that saves, the keyboard, and a failed
|
|
180
180
|
save putting the switch back. Copy `useSaveWidgetField` whenever the
|
|
181
|
-
plan has a `toggle` or any quick action, and only then.
|
|
181
|
+
plan has a `toggle` or any quick action, and only then. It finds the
|
|
182
|
+
record under the entity's own detail and list keys: on a screen that
|
|
183
|
+
holds it in a query of its own, a plain change (`{ field: value }`) is
|
|
184
|
+
still sent but only shows once that query refetches, and a change
|
|
185
|
+
built from the record (`(record) => …`) is refused, with a console
|
|
186
|
+
warning naming the keys searched.
|
|
182
187
|
- `src/routes/widgets/use-widgets.ts`, `use-widget-categories.ts` →
|
|
183
188
|
`src/routes/<entity>/use-<entity>.ts` (TanStack Query hooks over the
|
|
184
189
|
new gateway module)
|
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
// or the AppError's).
|
|
22
22
|
// - **The lists refetch once the last save settles**, so a filter on the
|
|
23
23
|
// field drops the row once the server agrees.
|
|
24
|
+
// - **A record in neither cache** (the screen holds it in a query of its
|
|
25
|
+
// own) still saves an object change, shown once that query refetches; a
|
|
26
|
+
// function change has nothing to build on and is refused like any other
|
|
27
|
+
// refusal. Both warn in the console, naming the keys searched.
|
|
24
28
|
//
|
|
25
29
|
// Editing in place uses the same save with `optimistic: false` and
|
|
26
30
|
// `toastOnError: false`: nothing changes on screen until the server
|
|
@@ -35,6 +39,11 @@ function recordStates(queryClient) {
|
|
|
35
39
|
states.set(queryClient, (map = new Map()));
|
|
36
40
|
return map;
|
|
37
41
|
}
|
|
42
|
+
// A function change with no record in either cache to build it from.
|
|
43
|
+
const notLoaded = {
|
|
44
|
+
kind: 'server',
|
|
45
|
+
message: "It isn't loaded on this page. Reload and try again",
|
|
46
|
+
};
|
|
38
47
|
function resolve(change, record) {
|
|
39
48
|
return typeof change === 'function' ? change(record) : change;
|
|
40
49
|
}
|
|
@@ -94,9 +103,19 @@ export function recordUpdateMutationOptions(queryClient, { id, detailKey, listsK
|
|
|
94
103
|
scope: { id: `record-update:${key}` },
|
|
95
104
|
mutationFn: (change) => {
|
|
96
105
|
const confirmed = map.get(key)?.confirmed ?? cached();
|
|
97
|
-
if (
|
|
98
|
-
return
|
|
99
|
-
|
|
106
|
+
if (confirmed)
|
|
107
|
+
return update(id, resolve(change, confirmed));
|
|
108
|
+
// The screen holds the record somewhere these keys don't reach (a
|
|
109
|
+
// query gathering a related list's records, say). An object change
|
|
110
|
+
// needs no current record, so it's still sent; a function change
|
|
111
|
+
// can't be built, and says so rather than doing nothing. Warned in
|
|
112
|
+
// every build: the package has no dev flag every app's bundler sets.
|
|
113
|
+
console.warn(`useRecordUpdate: record ${String(id)} isn't cached under ${JSON.stringify(detailKey)} ` +
|
|
114
|
+
`or any list under ${JSON.stringify(listsKey)}, so the change isn't shown until the server answers` +
|
|
115
|
+
(typeof change === 'function' ? ', and a change built from the record can\'t be sent' : ''));
|
|
116
|
+
if (typeof change === 'function')
|
|
117
|
+
return Promise.reject(notLoaded);
|
|
118
|
+
return update(id, change);
|
|
100
119
|
},
|
|
101
120
|
onMutate: async (change) => {
|
|
102
121
|
let state = map.get(key);
|
|
@@ -120,7 +139,8 @@ export function recordUpdateMutationOptions(queryClient, { id, detailKey, listsK
|
|
|
120
139
|
return;
|
|
121
140
|
// What was sent: the change built on the record it was sent against.
|
|
122
141
|
const record = state.confirmed;
|
|
123
|
-
const
|
|
142
|
+
const { change } = context.entry;
|
|
143
|
+
const sent = record ? resolve(change, record) : typeof change === 'function' ? undefined : change;
|
|
124
144
|
settle(state, context.entry);
|
|
125
145
|
if (toastOnError)
|
|
126
146
|
toast.error(`Couldn't update ${record ? name(record) : 'this record'}: ${refusalReason(error, sent)}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tristan2828/ui-foundation",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.1",
|
|
4
4
|
"description": "Shared UI foundation for contract-first, database-backed React apps: shadcn primitives, DataTable/EntityForm composites, auth, the gateway error seam, design tokens, lint rules and the AI playbook.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|