@nivaro/react 0.3.33 → 0.3.35

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.
Files changed (32) hide show
  1. package/dist/full.css +1 -1
  2. package/dist/hooks/useSessionRecorder.js +1 -1
  3. package/dist/index.d.ts +79 -5
  4. package/dist/index.js +338 -329
  5. package/dist/shared/components/ItemEditForm.js +5274 -5069
  6. package/dist/shared/components/ProfileView.js +46 -44
  7. package/dist/shared/components/ReportView.js +208 -205
  8. package/dist/shared/components/SearchHighlight.js +30 -0
  9. package/dist/shared/components/TipLayer.js +39 -37
  10. package/dist/shared/components/item-edit/CatalogPickerField.js +1484 -1232
  11. package/dist/shared/components/item-edit/FieldAffordances.js +424 -213
  12. package/dist/shared/components/item-edit/FieldRow.js +475 -427
  13. package/dist/shared/components/item-edit/PersonalDefaultControl.js +211 -0
  14. package/dist/shared/components/item-edit/PersonalDefaultPill.js +20 -0
  15. package/dist/shared/components/item-edit/RecordLiveSync.js +115 -110
  16. package/dist/shared/components/item-edit/RelationCombobox.js +42 -41
  17. package/dist/shared/components/item-edit/catalog-search.js +34 -0
  18. package/dist/shared/components/item-edit/entry/useEntryKeyboard.js +43 -43
  19. package/dist/shared/components/item-edit/live-record-marks.js +13 -0
  20. package/dist/shared/components/item-edit/personal-default-checks.js +134 -0
  21. package/dist/shared/components/item-edit/usePersonalDefaults.js +442 -0
  22. package/dist/shared/components/layout-editor/inspector/BehaviourSettings.js +130 -111
  23. package/dist/shared/components/layout-editor/inspector/RulesTab.js +76 -75
  24. package/dist/shared/components/layout-editor/parity-keys.json.js +1 -1
  25. package/dist/shared/components/profile/MyDefaultsCard.js +667 -0
  26. package/dist/shared/components/profile/PersonProfile.js +42 -40
  27. package/dist/shared/components/profile/my-defaults-labels.js +76 -0
  28. package/dist/shared/components/profile/primitives.js +72 -67
  29. package/dist/shared/lib/personal-defaults.js +76 -0
  30. package/dist/shared/lib/request-gate.js +78 -76
  31. package/dist/shared/lib/search-text.js +111 -0
  32. package/package.json +1 -1
@@ -0,0 +1,442 @@
1
+ import { useQueryClient as Qe, useQuery as ze } from "@tanstack/react-query";
2
+ import { useRef as F, useMemo as Ee, useState as ce, useEffect as z, useCallback as a, createContext as He, useContext as Ie } from "react";
3
+ import { useNivaroClient as _e } from "../../context.js";
4
+ import { get as Be, put as oe, del as Je } from "../../lib/commands.js";
5
+ import { isEmptyValue as g, pickDefault as ue, cascadeParents as C, orderTopDown as Ue, captureContext as We } from "../../lib/personal-defaults.js";
6
+ import { titleCase as Ne } from "../../lib/utils.js";
7
+ const Ge = He(null);
8
+ function it() {
9
+ return Ie(Ge);
10
+ }
11
+ function j(o) {
12
+ return ["field-defaults", o];
13
+ }
14
+ function O(o) {
15
+ return Array.isArray(o) ? o.map(O) : o && typeof o == "object" && "id" in o ? o.id : o;
16
+ }
17
+ const Xe = /* @__PURE__ */ new Set(["integer", "bigInteger", "float", "decimal", "number", "double"]), Ze = /* @__PURE__ */ new Set(["date"]), et = /* @__PURE__ */ new Set(["dateTime", "datetime", "timestamp", "time"]);
18
+ function q(o, i, v) {
19
+ if (g(o) && g(i)) return !0;
20
+ if (v && !Array.isArray(o) && !Array.isArray(i) && !g(o) && !g(i)) {
21
+ const S = O(o), b = O(i);
22
+ if (Xe.has(v)) {
23
+ const d = Number(S), p = Number(b);
24
+ if (Number.isFinite(d) && Number.isFinite(p)) return d === p;
25
+ } else if (Ze.has(v)) {
26
+ const d = (A) => {
27
+ var V;
28
+ return (V = /^(\d{4}-\d{2}-\d{2})/.exec(String(A))) == null ? void 0 : V[1];
29
+ }, p = d(S), f = d(b);
30
+ if (p && f) return p === f;
31
+ } else if (et.has(v)) {
32
+ const d = Date.parse(String(S)), p = Date.parse(String(b));
33
+ if (Number.isFinite(d) && Number.isFinite(p)) return d === p;
34
+ }
35
+ }
36
+ const D = (S) => {
37
+ const b = O(S);
38
+ return Array.isArray(b) ? b.map((d) => String(d)).sort() : String(b);
39
+ };
40
+ return JSON.stringify(D(o)) === JSON.stringify(D(i));
41
+ }
42
+ function lt(o, i) {
43
+ let v = 0;
44
+ for (const [D, S] of o) {
45
+ const b = i.get(D);
46
+ for (const d of S) b != null && b.has(String(d)) || v++;
47
+ }
48
+ return v;
49
+ }
50
+ function tt(o) {
51
+ return Array.isArray(o) ? o : g(o) ? [] : [o];
52
+ }
53
+ function ft(o) {
54
+ const { collection: i, isNew: v, disabled: D, enabled: S = !0, ready: b = !0 } = o, d = _e(), p = Qe(), f = F(o);
55
+ f.current = o;
56
+ const { data: A, isError: V } = ze({
57
+ queryKey: j(i),
58
+ queryFn: () => d.request(Be("/field-defaults/mine", { collection: i })).then((e) => e.data ?? []),
59
+ staleTime: 5 * 6e4,
60
+ enabled: !!i && S
61
+ }), H = Ee(() => {
62
+ const e = /* @__PURE__ */ new Map();
63
+ for (const t of A ?? []) {
64
+ const r = e.get(t.field) ?? [];
65
+ r.push(t), e.set(t.field, r);
66
+ }
67
+ return e;
68
+ }, [A]), W = F(H);
69
+ W.current = H;
70
+ const y = F(/* @__PURE__ */ new Map()), [G, Te] = ce(() => /* @__PURE__ */ new Map()), P = F(/* @__PURE__ */ new Map()), [ae, Ce] = ce(() => /* @__PURE__ */ new Map()), E = F(/* @__PURE__ */ new Set()), I = F(!0);
71
+ z(() => (I.current = !0, () => {
72
+ I.current = !1;
73
+ }), []);
74
+ const m = a(() => {
75
+ I.current && (Te((e) => {
76
+ const t = y.current;
77
+ return e.size === t.size && [...t].every(([r, n]) => e.get(r) === n) ? e : new Map(t);
78
+ }), Ce((e) => {
79
+ const t = P.current;
80
+ return e.size === t.size && [...t].every(([r, n]) => e.get(r) === n) ? e : new Map(t);
81
+ }));
82
+ }, []), c = a((e) => {
83
+ var n;
84
+ const t = f.current, r = (n = t.readValue) == null ? void 0 : n.call(t, e);
85
+ return r !== void 0 ? r : t.draftRef.current[e];
86
+ }, []), N = a(
87
+ (e) => {
88
+ const t = {};
89
+ for (const r of e) t[r] = c(r);
90
+ return t;
91
+ },
92
+ [c]
93
+ ), M = a(async (e, t) => {
94
+ const r = f.current, s = (await Promise.all(
95
+ tt(O(t)).map(async (l) => {
96
+ if (!r.valueLabel) return String(l);
97
+ try {
98
+ return await r.valueLabel(e, l) ?? null;
99
+ } catch {
100
+ return null;
101
+ }
102
+ })
103
+ )).filter((l) => !!l);
104
+ return s.length > 0 ? s.join(", ") : null;
105
+ }, []), K = F(0), _ = a(
106
+ async (e, t, r) => {
107
+ const n = await t;
108
+ K.current === r && (P.current.set(e, n), m());
109
+ },
110
+ [m]
111
+ ), X = a(
112
+ async (e, t) => {
113
+ var s, l;
114
+ const r = ((l = (s = f.current).fieldLabel) == null ? void 0 : l.call(s, e)) ?? e, n = await M(e, t);
115
+ return n ? `Your default is for ${r} “${n}”` : `Your saved default is for a different ${r}`;
116
+ },
117
+ [M]
118
+ ), B = a((e, t, r) => {
119
+ const n = f.current;
120
+ if (n.setFieldValue(e, t, r), g(t)) {
121
+ y.current.delete(e);
122
+ return;
123
+ }
124
+ y.current.set(e, t), P.current.delete(e), n.markAutoFilled([e]);
125
+ }, []), ie = a(
126
+ async (e, t) => {
127
+ var Se, Ae, Pe, Me, Re, qe;
128
+ const r = f.current, n = () => K.current !== t, s = W.current.get(e) ?? [];
129
+ if (s.length === 0 || !r.layoutAllows(e)) return [];
130
+ if (E.current.has(e) || !(((Se = r.canFill) == null ? void 0 : Se.call(r, e)) ?? !0)) return [];
131
+ const l = c(e), w = !g(l);
132
+ if (w && !(((Ae = r.replaceable) == null ? void 0 : Ae.call(r, e, l)) ?? !1)) return [];
133
+ const T = new Set(s.flatMap((u) => Object.keys(u.context ?? {}))), U = N(T), { pick: h, fillParents: R, blockedBy: Y } = ue(s, U);
134
+ if (!h) {
135
+ if (Y) {
136
+ const u = (Pe = s.find(
137
+ (k) => k.context && Y in k.context && !q(k.context[Y], U[Y])
138
+ )) == null ? void 0 : Pe.context[Y];
139
+ await _(e, X(Y, u), t);
140
+ }
141
+ return [];
142
+ }
143
+ const ke = C(e, r.rulesFor).reverse(), Le = [
144
+ ...ke.filter((u) => u in R),
145
+ ...Object.keys(R).filter((u) => !ke.includes(u))
146
+ ], se = [], $ = () => {
147
+ for (const [u, k] of se.reverse())
148
+ q(c(u), k) ? B(u, null, k) : y.current.delete(u);
149
+ };
150
+ for (const u of Le) {
151
+ const k = R[u], De = r.layoutAllows(u) && !E.current.has(u) && (((Me = r.canFill) == null ? void 0 : Me.call(r, u)) ?? !0) ? await r.revalidate(u, k) : !1;
152
+ if (n()) return [];
153
+ if (De === null)
154
+ return $(), [];
155
+ if (!De || !g(c(u)))
156
+ return $(), await _(e, X(u, k), t), [];
157
+ B(u, k), se.push([u, k]);
158
+ }
159
+ const Fe = await r.revalidate(e, h.value);
160
+ if (n()) return [];
161
+ if (Fe === null)
162
+ return $(), [];
163
+ if (!Fe)
164
+ return $(), await _(
165
+ e,
166
+ M(e, h.value).then(
167
+ (u) => u ? `Your default "${u}" is no longer available` : "Your saved default is no longer available"
168
+ ),
169
+ t
170
+ ), [];
171
+ if (!q(c(e), l) || !(((Re = r.canFill) == null ? void 0 : Re.call(r, e)) ?? !0))
172
+ return $(), [];
173
+ const xe = ue(s, N(T));
174
+ return ((qe = xe.pick) == null ? void 0 : qe.id) !== h.id || Object.keys(xe.fillParents).length > 0 ? ($(), "stale") : (B(e, h.value, w ? l : void 0), [...se.map(([u]) => u), e]);
175
+ },
176
+ [c, N, _, X, M, B]
177
+ ), le = a(
178
+ async (e, t) => {
179
+ for (let r = 0; r < 3; r++) {
180
+ const n = await ie(e, t);
181
+ if (n !== "stale") return n;
182
+ }
183
+ return [];
184
+ },
185
+ [ie]
186
+ ), Z = a(
187
+ async (e) => {
188
+ var n, s;
189
+ const t = K.current, r = /* @__PURE__ */ new Set();
190
+ for (const l of e) {
191
+ if (!I.current || K.current !== t) return;
192
+ for (const w of await le(l, t)) r.add(w);
193
+ m();
194
+ }
195
+ if (K.current === t) {
196
+ for (const l of r)
197
+ y.current.has(l) && ((s = (n = f.current).afterApply) == null || s.call(n, l, y.current.get(l)));
198
+ m();
199
+ }
200
+ },
201
+ [le, m]
202
+ ), ee = a(() => {
203
+ const e = f.current;
204
+ return Ue(
205
+ [...W.current.keys()].filter((t) => e.layoutAllows(t)),
206
+ e.rulesFor
207
+ );
208
+ }, []), te = F(!1);
209
+ z(() => {
210
+ !v || D || !b || te.current || A === void 0 || (te.current = !0, Z(ee()));
211
+ }, [v, D, b, A, Z, ee]), z(() => {
212
+ let e = !1;
213
+ for (const [t, r] of y.current)
214
+ q(c(t), r) || (y.current.delete(t), e = !0);
215
+ for (const t of P.current.keys())
216
+ g(c(t)) || (P.current.delete(t), e = !0);
217
+ e && m();
218
+ });
219
+ const L = F(/* @__PURE__ */ new Set()), Q = F(/* @__PURE__ */ new Map()), [Oe, Ve] = ce(0), Ke = a(
220
+ (e) => {
221
+ let t = y.current.delete(e);
222
+ if (P.current.delete(e) && (t = !0), E.current.delete(e), Q.current.delete(e), !f.current.isNew) {
223
+ t && m();
224
+ return;
225
+ }
226
+ const r = f.current.rulesFor;
227
+ for (const [n, s] of [...y.current])
228
+ C(n, r).includes(e) && (Q.current.set(n, s), y.current.delete(n), t = !0);
229
+ t && m(), L.current.add(e), Ve((n) => n + 1);
230
+ },
231
+ [m]
232
+ );
233
+ z(() => {
234
+ if (L.current.size === 0 || f.current.disabled) return;
235
+ const e = [...L.current];
236
+ L.current.clear();
237
+ const t = new Map(Q.current);
238
+ Q.current.clear();
239
+ const r = f.current, n = [];
240
+ for (const s of ee()) {
241
+ if (t.has(s)) {
242
+ const w = t.get(s), T = c(s);
243
+ if (q(T, w)) r.setFieldValue(s, null, w);
244
+ else if (!g(T)) continue;
245
+ n.push(s);
246
+ continue;
247
+ }
248
+ const l = C(s, r.rulesFor);
249
+ e.some((w) => l.includes(w)) && P.current.has(s) && g(c(s)) && (P.current.delete(s), n.push(s));
250
+ }
251
+ m(), n.length > 0 && Z(n);
252
+ }, [Oe]);
253
+ const re = a(
254
+ (e) => {
255
+ const t = f.current;
256
+ if (!y.current.has(e)) return;
257
+ const r = [
258
+ e,
259
+ ...[...y.current.keys()].filter(
260
+ (n) => n !== e && C(n, t.rulesFor).includes(e)
261
+ )
262
+ ];
263
+ for (const n of r) {
264
+ const s = y.current.get(n);
265
+ q(c(n), s) && t.setFieldValue(n, null, s), y.current.delete(n);
266
+ }
267
+ E.current.add(e), m();
268
+ },
269
+ [c, m]
270
+ ), Ye = a(
271
+ (e) => {
272
+ if (!y.current.has(e)) return;
273
+ const t = y.current.get(e);
274
+ q(c(e), t) && f.current.setFieldValue(e, null, t), y.current.delete(e), E.current.add(e), m();
275
+ },
276
+ [c, m]
277
+ ), J = `${i}|${v ? "new" : "saved"}|${o.resetKey ?? ""}`, fe = F(J);
278
+ z(() => {
279
+ fe.current !== J && (fe.current = J, y.current.clear(), P.current.clear(), E.current.clear(), Q.current.clear(), L.current.clear(), te.current = !1, K.current += 1, m());
280
+ }, [J, m]);
281
+ const ne = a((e) => ae.get(e) ?? null, [ae]), $e = a(() => y.current, []), x = a(
282
+ (e) => {
283
+ const t = H.get(e) ?? [];
284
+ if (t.length === 0) return null;
285
+ const r = new Set(t.flatMap((n) => Object.keys(n.context ?? {})));
286
+ return ue(t, N(r)).pick;
287
+ },
288
+ [H, N]
289
+ ), de = a(() => {
290
+ p.invalidateQueries({ queryKey: j(i) });
291
+ }, [p, i]), ye = a(
292
+ (e) => !g(c(e)),
293
+ [c]
294
+ ), we = a(
295
+ (e) => {
296
+ var n, s;
297
+ const t = c(e);
298
+ if (g(t)) return !1;
299
+ const r = x(e);
300
+ return !!r && q(r.value, t, (s = (n = f.current).fieldType) == null ? void 0 : s.call(n, e));
301
+ },
302
+ [c, x]
303
+ ), pe = a(
304
+ async (e) => {
305
+ const t = f.current, r = [
306
+ ...[...C(e, t.rulesFor)].reverse().filter((n) => t.layoutAllows(n) && !g(c(n))),
307
+ e
308
+ ];
309
+ return Promise.all(
310
+ // A value with no label says which field it is, never its stored id ("Save 4521 · …").
311
+ r.map(
312
+ async (n) => {
313
+ var s;
314
+ return await M(n, c(n)) ?? ((s = t.fieldLabel) == null ? void 0 : s.call(t, n)) ?? Ne(n);
315
+ }
316
+ )
317
+ );
318
+ },
319
+ [c, M]
320
+ ), me = a(
321
+ async (e) => {
322
+ const t = f.current, r = c(e);
323
+ if (g(r)) throw new Error("Pick a value first");
324
+ const n = C(e, t.rulesFor), s = N([e, ...n]), l = (w) => d.request(
325
+ oe("/field-defaults/mine", {
326
+ collection: i,
327
+ field: w,
328
+ value: O(s[w]),
329
+ context: We(w, s, t.rulesFor)
330
+ })
331
+ );
332
+ try {
333
+ await l(e);
334
+ for (const w of [...n].reverse())
335
+ t.layoutAllows(w) && !g(s[w]) && await l(w);
336
+ } finally {
337
+ await p.invalidateQueries({ queryKey: j(i) });
338
+ }
339
+ },
340
+ [d, p, i, c, N]
341
+ ), he = a(
342
+ async (e) => {
343
+ const t = x(e);
344
+ if (!t) throw new Error("You have no default here to update");
345
+ const r = c(e);
346
+ if (g(r)) throw new Error("Pick a value first");
347
+ try {
348
+ await d.request(
349
+ oe("/field-defaults/mine", {
350
+ collection: i,
351
+ field: e,
352
+ value: O(r),
353
+ context: t.context ?? {}
354
+ })
355
+ );
356
+ } finally {
357
+ await p.invalidateQueries({ queryKey: j(i) });
358
+ }
359
+ },
360
+ [d, p, i, c, x]
361
+ ), ge = a(
362
+ async (e) => {
363
+ const t = f.current, r = x(e), n = (r == null ? void 0 : r.context) ?? {}, s = [...C(e, t.rulesFor)].reverse(), l = [
364
+ ...s.filter((h) => h in n),
365
+ ...Object.keys(n).filter((h) => !s.includes(h))
366
+ ], w = (h) => {
367
+ var R;
368
+ return ((R = t.fieldLabel) == null ? void 0 : R.call(t, h)) ?? Ne(h);
369
+ }, [T, ...U] = await Promise.all([
370
+ M(e, c(e)).then((h) => h ?? w(e)),
371
+ ...l.map((h) => M(h, n[h]).then((R) => R ?? w(h)))
372
+ ]);
373
+ return { value: T, context: U };
374
+ },
375
+ [c, x, M]
376
+ ), be = a(
377
+ async (e) => {
378
+ const t = x(e);
379
+ return t ? (await d.request(Je(`/field-defaults/mine/${t.id}`)), y.current.delete(e) && (E.current.add(e), m()), await p.invalidateQueries({ queryKey: j(i) }), t) : null;
380
+ },
381
+ [d, p, i, x, m]
382
+ ), ve = a(
383
+ async (e) => {
384
+ await d.request(
385
+ oe("/field-defaults/mine", {
386
+ collection: i,
387
+ field: e.field,
388
+ value: e.value,
389
+ context: e.context ?? {}
390
+ })
391
+ ), await p.invalidateQueries({ queryKey: j(i) });
392
+ },
393
+ [d, p, i]
394
+ ), je = Ee(
395
+ () => ({
396
+ allowed: (e) => (f.current.enabled ?? !0) && f.current.layoutAllows(e),
397
+ loaded: A !== void 0 || V,
398
+ failed: A === void 0 && V,
399
+ isNew: v,
400
+ defaultFor: x,
401
+ isDefault: we,
402
+ save: me,
403
+ update: he,
404
+ describeUpdate: ge,
405
+ clear: be,
406
+ restore: ve,
407
+ refresh: de,
408
+ hasValue: ye,
409
+ describeSave: pe,
410
+ applied: (e) => G.has(e),
411
+ hintFor: ne,
412
+ undo: re
413
+ }),
414
+ [
415
+ A,
416
+ V,
417
+ v,
418
+ x,
419
+ we,
420
+ me,
421
+ he,
422
+ ge,
423
+ be,
424
+ ve,
425
+ de,
426
+ ye,
427
+ pe,
428
+ G,
429
+ ne,
430
+ re
431
+ ]
432
+ );
433
+ return { ledger: G, hintFor: ne, undo: re, onPersonChange: Ke, release: Ye, appliedNow: $e, context: je };
434
+ }
435
+ export {
436
+ Ge as PersonalDefaultsContext,
437
+ lt as linksBeyond,
438
+ j as personalDefaultsKey,
439
+ q as sameDefaultValue,
440
+ ft as usePersonalDefaults,
441
+ it as usePersonalDefaultsApi
442
+ };