@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
@@ -8,16 +8,17 @@ import { get as j, post as He } from "../../lib/commands.js";
8
8
  import { compareByMatch as Ye } from "../../lib/picker-rank.js";
9
9
  import { useRecordReader as $e } from "../../lib/record-loader.js";
10
10
  import { useOnlineUsers as We } from "../../lib/use-online-users.js";
11
- import { UserAvatar as Xe } from "../UserAvatar.js";
12
- import { userOptionFilter as Ge, cn as D } from "../../lib/utils.js";
11
+ import { SearchHighlight as Xe } from "../SearchHighlight.js";
12
+ import { UserAvatar as Ge } from "../UserAvatar.js";
13
+ import { userOptionFilter as Ve, cn as D } from "../../lib/utils.js";
13
14
  import { applyDisplayTemplate as k } from "./helpers.js";
14
- import { collidingIds as Ve, disambiguators as Ze } from "./option-disambiguate.js";
15
- import { usePickerMissReport as Qe } from "./picker-miss.js";
16
- import { useLatestSearch as Be, narrowLocally as et } from "./picker-search.js";
17
- function tt(s) {
15
+ import { collidingIds as Ze, disambiguators as Qe } from "./option-disambiguate.js";
16
+ import { usePickerMissReport as Be } from "./picker-miss.js";
17
+ import { useLatestSearch as et, narrowLocally as tt } from "./picker-search.js";
18
+ function rt(s) {
18
19
  return s.replace(/\(.*$/, "").trim().split(/\s+/).map((r) => r[0]).filter(Boolean).slice(0, 2).join("").toUpperCase() || "?";
19
20
  }
20
- function rt(s) {
21
+ function nt(s) {
21
22
  const [r, d] = $(null), x = {
22
23
  onMouseEnter: (h) => {
23
24
  if (!s) return;
@@ -38,7 +39,7 @@ function rt(s) {
38
39
  ) : null;
39
40
  return { bind: x, tip: q };
40
41
  }
41
- function nt({
42
+ function st({
42
43
  collection: s,
43
44
  value: r,
44
45
  onChange: d,
@@ -54,7 +55,7 @@ function nt({
54
55
  pinned: p,
55
56
  missPlacement: _
56
57
  }) {
57
- const F = ie(), ae = $e(), [y, K] = $(!1), [N, le] = $(""), [Ce, Le] = $(!1), L = Be(N, Ce), de = Z(null), J = Z(null);
58
+ const F = ie(), ae = $e(), [y, K] = $(!1), [v, le] = $(""), [Ce, Le] = $(!1), L = et(v, Ce), de = Z(null), J = Z(null);
58
59
  O(() => {
59
60
  y ? setTimeout(() => {
60
61
  var e;
@@ -124,7 +125,7 @@ function nt({
124
125
  return e;
125
126
  }, [i, me, s]), T = s === "nivaro_users", Ee = We(T), pe = Je().isAdmin, re = I(() => {
126
127
  const e = [];
127
- T && e.push(Ge(pe)), h && e.push(h);
128
+ T && e.push(Ve(pe)), h && e.push(h);
128
129
  for (const [o, t] of Object.entries(te))
129
130
  t != null && t !== "" && e.push({ [o]: { _eq: t } });
130
131
  if (e.length !== 0)
@@ -134,7 +135,7 @@ function nt({
134
135
  const e = [...z.matchAll(/\{\{([\w.]+)\}\}/g)].map((o) => o[1]);
135
136
  if (e.length)
136
137
  return ["id", ...e].join(",");
137
- }, [z]), v = re ? JSON.stringify(re) : void 0, P = u && !/^-?label$/.test(u) ? u : void 0, {
138
+ }, [z]), N = re ? JSON.stringify(re) : void 0, P = u && !/^-?label$/.test(u) ? u : void 0, {
138
139
  data: f,
139
140
  isFetching: E,
140
141
  isPlaceholderData: fe
@@ -143,7 +144,7 @@ function nt({
143
144
  "relation-opts",
144
145
  s,
145
146
  L,
146
- v,
147
+ N,
147
148
  g,
148
149
  P ?? ""
149
150
  ],
@@ -152,7 +153,7 @@ function nt({
152
153
  limit: 200,
153
154
  picker: "1",
154
155
  ...L ? { search: L } : {},
155
- ...v ? { filter: v } : {},
156
+ ...N ? { filter: N } : {},
156
157
  ...g ? { fields: g } : {},
157
158
  ...P ? { sort: P } : {}
158
159
  })
@@ -160,17 +161,17 @@ function nt({
160
161
  // Wait for the display template: it decides `fields`, and starting before
161
162
  // it lands sent the whole first page twice.
162
163
  enabled: y && !Re,
163
- staleTime: v ? 0 : 3e4,
164
+ staleTime: N ? 0 : 3e4,
164
165
  // A new SEARCH keeps the previous answer on screen (narrowed locally below)
165
166
  // instead of blanking the list behind a spinner. A changed filter, sort or
166
167
  // template never does — those rows may no longer be allowed.
167
168
  placeholderData: (e, o) => {
168
169
  const t = o == null ? void 0 : o.queryKey;
169
170
  if (!(!e || !t))
170
- return t[1] === s && t[3] === v && t[4] === g && t[5] === (P ?? "") ? e : void 0;
171
+ return t[1] === s && t[3] === N && t[4] === g && t[5] === (P ?? "") ? e : void 0;
171
172
  }
172
173
  });
173
- O(() => Le(E), [E]), Qe({
174
+ O(() => Le(E), [E]), Be({
174
175
  placement: _,
175
176
  open: y,
176
177
  search: L,
@@ -190,7 +191,7 @@ function nt({
190
191
  enabled: !!b && y,
191
192
  staleTime: 6e4
192
193
  }), Ie = JSON.stringify(h ? { _and: [{ id: { _eq: r } }, h] } : { id: { _eq: r } }), { data: Y } = S({
193
- queryKey: ["relation-avail", s, String(r), v],
194
+ queryKey: ["relation-avail", s, String(r), N],
194
195
  queryFn: () => F.request(
195
196
  j(`/items/${s}`, {
196
197
  filter: Ie,
@@ -204,7 +205,7 @@ function nt({
204
205
  // the pin is available by construction — never probe it, never flag it.
205
206
  enabled: !!r && !!H && String(r) !== b,
206
207
  staleTime: 3e4
207
- }), A = !!r && String(r) !== b && Y !== void 0 && Y.length === 0, W = Z(null), ne = Z(!1), he = `${s}|${v ?? ""}`, Ke = () => {
208
+ }), A = !!r && String(r) !== b && Y !== void 0 && Y.length === 0, W = Z(null), ne = Z(!1), he = `${s}|${N ?? ""}`, Ke = () => {
208
209
  ne.current = !0, W.current = he, d(null);
209
210
  }, X = r == null || r === "";
210
211
  O(() => {
@@ -217,7 +218,7 @@ function nt({
217
218
  limit: 2,
218
219
  picker: "1",
219
220
  fields: "id",
220
- ...v ? { filter: v } : {}
221
+ ...N ? { filter: N } : {}
221
222
  })
222
223
  ).then((o) => {
223
224
  var a;
@@ -226,17 +227,17 @@ function nt({
226
227
  }).catch(() => {
227
228
  W.current = null;
228
229
  }));
229
- }, [m, x, X, s, v]);
230
- const w = z, ge = r && H ? k(w, H) : null, se = !fe && N === L, G = I(
231
- () => et(
230
+ }, [m, x, X, s, N]);
231
+ const w = z, ge = r && H ? k(w, H) : null, se = !fe && v === L, G = I(
232
+ () => tt(
232
233
  f ?? [],
233
234
  (e) => k(w, e) || `#${e.id}`,
234
- N,
235
+ v,
235
236
  se
236
237
  ),
237
- [f, w, N, se]
238
+ [f, w, v, se]
238
239
  ), V = I(
239
- () => Ve(f ?? [], (e) => k(w, e) || `#${e.id}`),
240
+ () => Ze(f ?? [], (e) => k(w, e) || `#${e.id}`),
240
241
  [f, w]
241
242
  ), { data: M } = S({
242
243
  queryKey: ["relation-opts-dups", s, V.join(",")],
@@ -262,11 +263,11 @@ function nt({
262
263
  const a = e.get(String(t.id));
263
264
  a !== void 0 && o.set(a, [...o.get(a) ?? [], t]);
264
265
  }
265
- return Ze(
266
+ return Qe(
266
267
  [...o.values()],
267
268
  ((g == null ? void 0 : g.split(",")) ?? []).map((t) => t.split(".")[0])
268
269
  );
269
- }, [M, f, w, g]), Pe = !!r && Oe && !H, xe = rt(A), oe = ze();
270
+ }, [M, f, w, g]), Pe = !!r && Oe && !H, xe = nt(A), oe = ze();
270
271
  return O(() => {
271
272
  !oe || !C || Y === void 0 || oe(C, A);
272
273
  }, [oe, C, A, Y]), R ? /* @__PURE__ */ c(
@@ -333,7 +334,7 @@ function nt({
333
334
  return o ? /* @__PURE__ */ c("div", { children: [
334
335
  /* @__PURE__ */ n("p", { className: "mb-0.5 text-[10px] font-medium uppercase tracking-wide text-slate-400", children: e.label ?? e.field }),
335
336
  /* @__PURE__ */ n(
336
- nt,
337
+ st,
337
338
  {
338
339
  collection: o,
339
340
  value: te[e.field] ?? null,
@@ -351,7 +352,7 @@ function nt({
351
352
  "input",
352
353
  {
353
354
  ref: de,
354
- value: N,
355
+ value: v,
355
356
  onChange: (e) => le(e.target.value),
356
357
  placeholder: "Search…",
357
358
  className: "flex h-9 w-full bg-transparent py-3 text-[13px] outline-none placeholder:text-muted-foreground"
@@ -405,7 +406,7 @@ function nt({
405
406
  ]
406
407
  }
407
408
  ),
408
- f === void 0 && E ? /* @__PURE__ */ n("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ n(Q, { className: "h-4 w-4 animate-spin text-muted-foreground" }) }) : G.length === 0 && !se ? /* @__PURE__ */ n("p", { className: "px-3 py-2 text-[13px] text-muted-foreground", children: "Searching…" }) : G.length === 0 ? l && l.labels.length > 0 && !N.trim() ? /* @__PURE__ */ c("div", { className: "px-3 py-2 text-[12px] leading-5 text-muted-foreground", children: [
409
+ f === void 0 && E ? /* @__PURE__ */ n("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ n(Q, { className: "h-4 w-4 animate-spin text-muted-foreground" }) }) : G.length === 0 && !se ? /* @__PURE__ */ n("p", { className: "px-3 py-2 text-[13px] text-muted-foreground", children: "Searching…" }) : G.length === 0 ? l && l.labels.length > 0 && !v.trim() ? /* @__PURE__ */ c("div", { className: "px-3 py-2 text-[12px] leading-5 text-muted-foreground", children: [
409
410
  /* @__PURE__ */ c("p", { children: [
410
411
  "No options for",
411
412
  " ",
@@ -428,11 +429,11 @@ function nt({
428
429
  },
429
430
  e
430
431
  )) })
431
- ] }) : /* @__PURE__ */ n("p", { className: "px-3 py-2 text-[13px] text-muted-foreground", children: N.trim() ? `No results for “${N.trim()}”` : "No results" }) : (P ? [...G] : [...G].sort(
432
+ ] }) : /* @__PURE__ */ n("p", { className: "px-3 py-2 text-[13px] text-muted-foreground", children: v.trim() ? `No results for “${v.trim()}”` : "No results" }) : (P ? [...G] : [...G].sort(
432
433
  (e, o) => Ye(
433
434
  k(w, e),
434
435
  k(w, o),
435
- N,
436
+ v,
436
437
  u === "-label"
437
438
  )
438
439
  )).filter((e) => !b || String(e.id) !== b).map((e) => {
@@ -457,11 +458,11 @@ function nt({
457
458
  }
458
459
  ),
459
460
  T && /* @__PURE__ */ n(
460
- Xe,
461
+ Ge,
461
462
  {
462
463
  userId: e.id,
463
464
  className: "h-4 w-4",
464
- fallback: /* @__PURE__ */ n("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-nvr-cyan/20 text-[8px] font-bold text-nvr-navy dark:text-nvr-cyan", children: tt(o) })
465
+ fallback: /* @__PURE__ */ n("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-nvr-cyan/20 text-[8px] font-bold text-nvr-navy dark:text-nvr-cyan", children: rt(o) })
465
466
  }
466
467
  ),
467
468
  T && Ee.has(String(e.id).toUpperCase()) && /* @__PURE__ */ n(
@@ -471,7 +472,7 @@ function nt({
471
472
  "data-tip": "Online now"
472
473
  }
473
474
  ),
474
- o,
475
+ /* @__PURE__ */ n(Xe, { text: o, query: v }),
475
476
  be.has(String(e.id)) && /* @__PURE__ */ n(
476
477
  "span",
477
478
  {
@@ -487,7 +488,7 @@ function nt({
487
488
  })
488
489
  ] }),
489
490
  !E && /* @__PURE__ */ n(
490
- st,
491
+ ot,
491
492
  {
492
493
  collection: s,
493
494
  search: L,
@@ -504,7 +505,7 @@ function nt({
504
505
  ] })
505
506
  );
506
507
  }
507
- function st({
508
+ function ot({
508
509
  collection: s,
509
510
  search: r,
510
511
  filter: d,
@@ -554,7 +555,7 @@ function st({
554
555
  }
555
556
  );
556
557
  }
557
- function vt({
558
+ function kt({
558
559
  collection: s,
559
560
  id: r,
560
561
  displayTemplate: d
@@ -585,7 +586,7 @@ function vt({
585
586
  return /* @__PURE__ */ n("span", { children: k(d, u) });
586
587
  }
587
588
  export {
588
- vt as RelatedItemLabel,
589
- nt as RelationCombobox,
590
- rt as useStaleTip
589
+ kt as RelatedItemLabel,
590
+ st as RelationCombobox,
591
+ nt as useStaleTip
591
592
  };
@@ -0,0 +1,34 @@
1
+ import { matchesSearch as m, searchRankTier as x } from "../../lib/search-text.js";
2
+ const g = (o) => o == null || typeof o == "object" ? "" : String(o);
3
+ function l(o, r, e) {
4
+ return r.length === 0 ? !1 : m(r.map((c) => g(o[c])).join(""), e);
5
+ }
6
+ function k(o, r, e) {
7
+ return l(o, r, e) ? x(
8
+ r.map((c) => o[c]),
9
+ e
10
+ ) : 6;
11
+ }
12
+ function S({
13
+ shown: o,
14
+ other: r,
15
+ recent: e,
16
+ shownFields: c,
17
+ q: p
18
+ }) {
19
+ const a = (t) => t.map((n, f) => ({ r: n, i: f, t: k(n, c, p) })).sort((n, f) => n.t - f.t || n.i - f.i), i = a(o), u = a(e), d = [], h = /* @__PURE__ */ new Set(), s = (t) => {
20
+ const n = String(t.id);
21
+ h.has(n) || (h.add(n), d.push(t));
22
+ };
23
+ for (const t of i) t.t === 0 && s(t.r);
24
+ for (const t of u) t.t === 0 && s(t.r);
25
+ for (const t of u) s(t.r);
26
+ for (const t of i) s(t.r);
27
+ for (const t of r) s(t);
28
+ return d;
29
+ }
30
+ export {
31
+ k as catalogRowTier,
32
+ S as orderCatalogMatches,
33
+ l as rowMatchesFields
34
+ };
@@ -1,70 +1,70 @@
1
- import { useRef as _, useEffect as k } from "react";
2
- import { firstEmptyRequired as F, entrySequence as L, enterIsTaken as R, stepField as q, FOCUSABLE as S } from "./entry-keys.js";
3
- const O = (o) => Array.from(document.querySelectorAll("[data-field]")).filter(
1
+ import { useRef as k, useEffect as _ } from "react";
2
+ import { firstEmptyRequired as R, entrySequence as F, enterIsTaken as L, stepField as q, FOCUSABLE as S } from "./entry-keys.js";
3
+ const O = (a) => Array.from(document.querySelectorAll("[data-field]")).filter(
4
4
  (t) => {
5
5
  var n;
6
- return t.getAttribute("data-field-collection") === o && // Fields of a nested form (a record shown inside a field) are not this form's.
6
+ return t.getAttribute("data-field-collection") === a && // Fields of a nested form (a record shown inside a field) are not this form's.
7
7
  ((n = t.parentElement) == null ? void 0 : n.closest("[data-field]")) == null && t.getClientRects().length > 0;
8
8
  }
9
- ), C = (o) => Array.from(o.querySelectorAll(S)).filter(
10
- (t) => t.getClientRects().length > 0 && t.tabIndex !== -1
9
+ ), D = "[data-field-menu-trigger], [data-personal-default-make], [data-personal-default-update], [data-personal-default-undo], [data-personal-default-clear], [data-repeat-last], [data-ai-fill]", C = (a) => Array.from(a.querySelectorAll(S)).filter(
10
+ (t) => t.getClientRects().length > 0 && t.tabIndex !== -1 && !t.matches(D)
11
11
  );
12
- function v(o, t = !1) {
13
- var d;
14
- if (!o) return !1;
15
- const n = C(o), r = t ? n[n.length - 1] : n[0];
16
- return r ? (r.focus(), r instanceof HTMLInputElement && r.type === "text" && ((d = r.select) == null || d.call(r)), !0) : !1;
12
+ function v(a, t = !1) {
13
+ var u;
14
+ if (!a) return !1;
15
+ const n = C(a), r = t ? n[n.length - 1] : n[0];
16
+ return r ? (r.focus(), r instanceof HTMLInputElement && r.type === "text" && ((u = r.select) == null || u.call(r)), !0) : !1;
17
17
  }
18
- function B(o) {
19
- var E;
20
- const { collection: t, config: n, enabled: r, ready: d, recordKey: g } = o, m = _(o);
21
- m.current = o;
22
- const b = _(null);
23
- k(() => {
24
- if (!r || !d || !n.focus_first || b.current === g) return;
18
+ function M(a) {
19
+ var x;
20
+ const { collection: t, config: n, enabled: r, ready: u, recordKey: g } = a, m = k(a);
21
+ m.current = a;
22
+ const E = k(null);
23
+ _(() => {
24
+ if (!r || !u || !n.focus_first || E.current === g) return;
25
25
  let y = 0;
26
26
  const e = window.setInterval(() => {
27
27
  y++;
28
- const i = m.current, c = O(t);
29
- if (c.length > 0) {
30
- window.clearInterval(e), b.current = g;
31
- const s = document.activeElement;
32
- if (s && s !== document.body && s.closest("input, textarea, select")) return;
33
- const f = c.map((p) => p.getAttribute("data-field")), a = F(f, i.required, i.draft);
34
- a && v(c[f.indexOf(a)]);
28
+ const o = m.current, l = O(t);
29
+ if (l.length > 0) {
30
+ window.clearInterval(e), E.current = g;
31
+ const i = document.activeElement;
32
+ if (i && i !== document.body && i.closest("input, textarea, select")) return;
33
+ const c = l.map((p) => p.getAttribute("data-field")), f = R(c, o.required, o.draft);
34
+ f && v(l[c.indexOf(f)]);
35
35
  } else y > 12 && window.clearInterval(e);
36
36
  }, 150);
37
37
  return () => window.clearInterval(e);
38
- }, [r, d, n.focus_first, g, t]);
39
- const x = r && (n.enter_next === !0 || !!((E = n.tab_order) != null && E.length));
40
- k(() => {
41
- if (!x) return;
38
+ }, [r, u, n.focus_first, g, t]);
39
+ const b = r && (n.enter_next === !0 || !!((x = n.tab_order) != null && x.length));
40
+ _(() => {
41
+ if (!b) return;
42
42
  const y = (e) => {
43
- var w, h;
43
+ var h, w;
44
44
  if (e.defaultPrevented || e.isComposing) return;
45
- const i = e.target, c = i == null ? void 0 : i.closest("[data-field]");
46
- if (!i || !c || c.getAttribute("data-field-collection") !== t || (w = c.parentElement) != null && w.closest("[data-field]")) return;
47
- const s = m.current.config, f = O(t), a = f.map((l) => l.getAttribute("data-field")), p = L(a, s.tab_order), K = c.getAttribute("data-field");
48
- if (e.key === "Enter" && s.enter_next) {
45
+ const o = e.target, l = o == null ? void 0 : o.closest("[data-field]");
46
+ if (!o || !l || l.getAttribute("data-field-collection") !== t || (h = l.parentElement) != null && h.closest("[data-field]")) return;
47
+ const i = m.current.config, c = O(t), f = c.map((s) => s.getAttribute("data-field")), p = F(f, i.tab_order), K = l.getAttribute("data-field");
48
+ if (e.key === "Enter" && i.enter_next) {
49
49
  if (e.ctrlKey || e.metaKey) {
50
50
  e.preventDefault(), m.current.save();
51
51
  return;
52
52
  }
53
- if (e.shiftKey || e.altKey || R(i)) return;
54
- const l = q(p, K, 1), u = l ? f[a.indexOf(l)] : void 0;
55
- u && v(u) && e.preventDefault();
53
+ if (e.shiftKey || e.altKey || L(o)) return;
54
+ const s = q(p, K, 1), d = s ? c[f.indexOf(s)] : void 0;
55
+ d && v(d) && e.preventDefault();
56
56
  return;
57
57
  }
58
- if (e.key === "Tab" && ((h = s.tab_order) != null && h.length) && !e.ctrlKey && !e.metaKey && !e.altKey) {
59
- const l = C(c), u = l.indexOf(i);
60
- if (u >= 0 && (e.shiftKey ? u > 0 : u < l.length - 1)) return;
61
- const A = q(p, K, e.shiftKey ? -1 : 1), I = A ? f[a.indexOf(A)] : void 0;
58
+ if (e.key === "Tab" && ((w = i.tab_order) != null && w.length) && !e.ctrlKey && !e.metaKey && !e.altKey) {
59
+ const s = C(l), d = s.indexOf(o);
60
+ if (d >= 0 && (e.shiftKey ? d > 0 : d < s.length - 1)) return;
61
+ const A = q(p, K, e.shiftKey ? -1 : 1), I = A ? c[f.indexOf(A)] : void 0;
62
62
  I && v(I, e.shiftKey) && e.preventDefault();
63
63
  }
64
64
  };
65
65
  return document.addEventListener("keydown", y), () => document.removeEventListener("keydown", y);
66
- }, [x, t]);
66
+ }, [b, t]);
67
67
  }
68
68
  export {
69
- B as useEntryKeyboard
69
+ M as useEntryKeyboard
70
70
  };
@@ -0,0 +1,13 @@
1
+ const s = /* @__PURE__ */ new Map(), a = (n, o) => `${n}:${o}`;
2
+ function i(n, o, r) {
3
+ const e = a(n, o), t = s.get(e), c = Date.now(), W = !r || t && t.fields === null && c - t.at < 15e3 ? null : [.../* @__PURE__ */ new Set([...t && c - t.at < 15e3 ? t.fields ?? [] : [], ...r])];
4
+ s.set(e, { at: c, fields: W });
5
+ }
6
+ function l(n, o, r = Date.now()) {
7
+ const e = s.get(a(n, o));
8
+ return !e || r - e.at > 15e3 ? null : e;
9
+ }
10
+ export {
11
+ l as liveRecordWrite,
12
+ i as markLiveRecordWrite
13
+ };
@@ -0,0 +1,134 @@
1
+ import { get as N } from "../../lib/commands.js";
2
+ import { resolveOptionFilterTokens as F } from "../../lib/option-filter-tokens.js";
3
+ import { isEmptyValue as x } from "../../lib/personal-defaults.js";
4
+ import { choiceLabel as V } from "../../lib/utils.js";
5
+ import { USER_SYSTEM_COLS as Y, userDisplayLabel as B, renderDisplayTemplate as I } from "../pipeline/relations.js";
6
+ import { parseJson as C, buildCascadeFilter as R, getCascadeFilters as U } from "./helpers.js";
7
+ function L(t) {
8
+ return t && typeof t == "object" && !Array.isArray(t) && "id" in t ? t.id : t;
9
+ }
10
+ function P(t) {
11
+ return (Array.isArray(t) ? t : x(t) ? [] : [t]).map((n) => String(L(n)));
12
+ }
13
+ function D(t, e, n) {
14
+ const s = t.find(
15
+ (r) => r.many_collection === e && r.many_field === n && !r.junction_field
16
+ );
17
+ if (s != null && s.one_collection) return { target: s.one_collection, kind: "m2o" };
18
+ const f = t.find((r) => r.one_collection === e && r.one_field === n);
19
+ if (!(f != null && f.many_collection) || f.many_field == null) return null;
20
+ const h = t.find(
21
+ (r) => r.many_collection === f.many_collection && f.junction_field != null && r.many_field === f.junction_field
22
+ ) ?? t.find((r) => r.many_collection === f.many_collection && r.id !== f.id);
23
+ return h != null && h.one_collection ? { target: h.one_collection, kind: "m2m" } : null;
24
+ }
25
+ function E(t) {
26
+ var n;
27
+ if ((t.interface ?? "") === "tags") return null;
28
+ const e = (n = C(t.options)) == null ? void 0 : n.choices;
29
+ return !Array.isArray(e) || e.length === 0 ? null : e.map(
30
+ (s) => s && typeof s == "object" ? s : { value: s, text: String(s) }
31
+ );
32
+ }
33
+ function W(t, e) {
34
+ const n = (t.type ?? "").toLowerCase();
35
+ return typeof e == "object" ? n === "json" || n === "csv" : n === "integer" || n === "biginteger" ? typeof e != "boolean" && e !== "" && Number.isInteger(Number(e)) : n === "float" || n === "decimal" ? typeof e != "boolean" && e !== "" && Number.isFinite(Number(e)) : n === "boolean" ? typeof e == "boolean" : n === "date" || n === "datetime" || n === "timestamp" ? !Number.isNaN(Date.parse(String(e))) : n === "time" ? /^\d{1,2}:\d{2}/.test(String(e)) : !(typeof e == "boolean" || t.max_length != null && String(e).length > t.max_length);
36
+ }
37
+ function Z(t) {
38
+ const { client: e, collection: n, fields: s, relations: f, readValue: h } = t, r = new Map(s.map((m) => [m.field, m])), J = () => {
39
+ const m = {};
40
+ for (const u of s) {
41
+ const o = h(u.field);
42
+ o !== void 0 && (m[u.field] = o);
43
+ }
44
+ return m;
45
+ };
46
+ async function M(m, u) {
47
+ const o = r.get(m);
48
+ if (!o || x(u) || (o.interface ?? "").startsWith("file")) return !1;
49
+ const g = D(f, n, m);
50
+ if (g) {
51
+ const d = P(u);
52
+ if (d.length === 0 || g.kind === "m2o" && d.length > 1) return !1;
53
+ const i = C(
54
+ o.options
55
+ );
56
+ if (g.kind === "m2m" && (i == null ? void 0 : i.max_values) != null && d.length > i.max_values)
57
+ return !1;
58
+ const _ = J(), S = R({
59
+ rules: U(o.dependency_config),
60
+ parentValue: (a) => {
61
+ const c = h(a);
62
+ if (x(c)) return null;
63
+ if (!Array.isArray(c)) return L(c);
64
+ const l = P(c);
65
+ return l.length === 1 ? l[0] : l;
66
+ },
67
+ parentOptionFilter: (a) => {
68
+ var l, b;
69
+ const c = (b = C(
70
+ ((l = r.get(a)) == null ? void 0 : l.options) ?? null
71
+ )) == null ? void 0 : b.option_filter;
72
+ return c && typeof c == "object" ? F(c, _, "new") : void 0;
73
+ }
74
+ }).filter, k = g.kind === "m2o" && (i != null && i.option_filter) && typeof i.option_filter == "object" ? F(i.option_filter, _, "new") : void 0, y = { _and: [{ id: { _in: d } }, k, S].filter(Boolean) };
75
+ try {
76
+ const a = await e.request(
77
+ N(`/items/${g.target}`, {
78
+ filter: JSON.stringify(y),
79
+ picker: "1",
80
+ fields: "id",
81
+ limit: d.length
82
+ })
83
+ ), c = new Set(((a == null ? void 0 : a.data) ?? []).map((l) => String(l.id)));
84
+ return d.every((l) => c.has(l));
85
+ } catch {
86
+ return null;
87
+ }
88
+ }
89
+ const p = E(o);
90
+ if (p) {
91
+ const d = new Set(p.map((_) => String(_.value)));
92
+ return (Array.isArray(u) ? u : [u]).every((_) => d.has(String(_)));
93
+ }
94
+ return Array.isArray(u) ? (o.type ?? "").toLowerCase() === "json" || o.type === "csv" : W(o, u);
95
+ }
96
+ const O = /* @__PURE__ */ new Map();
97
+ function T(m, u) {
98
+ const o = r.get(m), g = L(u), p = String(g ?? "");
99
+ if (!o) return Promise.resolve(null);
100
+ const d = E(o);
101
+ if (d) {
102
+ const y = d.find((a) => String(a.value) === p);
103
+ return Promise.resolve(y != null && y.text ? V(y.text) : null);
104
+ }
105
+ if (typeof g == "boolean") return Promise.resolve(g ? "Yes" : "No");
106
+ const i = D(f, n, m);
107
+ if (!i) return Promise.resolve(p || null);
108
+ const _ = `${i.target}:${p}`, S = O.get(_);
109
+ if (S) return S;
110
+ const k = (async () => {
111
+ var $, q;
112
+ if (Y.has(i.target)) {
113
+ const w = await e.request(N(`/users/${p}`)).catch(() => null), j = w != null && w.data ? B(w.data).trim() : "";
114
+ return j && j !== p ? j : null;
115
+ }
116
+ const y = await e.request(N(`/collections/${i.target}`)).catch(() => null), a = (($ = y == null ? void 0 : y.data) == null ? void 0 : $.display_template) ?? null, c = a ? [...a.matchAll(/\{\{([\w.]+)\}\}/g)].map((w) => w[1]) : [], l = await e.request(
117
+ N(`/items/${i.target}`, {
118
+ filter: JSON.stringify({ id: { _eq: p } }),
119
+ limit: 1,
120
+ ...c.length ? { fields: ["id", ...c].join(",") } : {}
121
+ })
122
+ ).catch(() => null), b = (q = l == null ? void 0 : l.data) == null ? void 0 : q[0];
123
+ if (!b) return null;
124
+ const A = I(a, b).trim();
125
+ return !/[\p{L}\p{N}]/u.test(A) || A === String(b.id) || A === p ? null : A;
126
+ })();
127
+ return O.set(_, k), k;
128
+ }
129
+ return { revalidate: M, valueLabel: T };
130
+ }
131
+ export {
132
+ Z as makePersonalDefaultChecks,
133
+ D as pickedCollection
134
+ };