@nivaro/react 0.3.24 → 0.3.26

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 (27) hide show
  1. package/dist/hooks/useSessionRecorder.js +1 -1
  2. package/dist/index.d.ts +45 -26
  3. package/dist/shared/components/FilePreviewLightbox.js +56 -35
  4. package/dist/shared/components/ItemEditForm.js +4309 -4263
  5. package/dist/shared/components/PageRenderer.js +63 -62
  6. package/dist/shared/components/RecordReadView.js +229 -229
  7. package/dist/shared/components/ReportView.js +123 -120
  8. package/dist/shared/components/ai/AiMarkdown.js +168 -148
  9. package/dist/shared/components/chat/RoomParts.js +120 -119
  10. package/dist/shared/components/chat/chat-core.js +228 -224
  11. package/dist/shared/components/item-edit/FieldRenderer.js +333 -333
  12. package/dist/shared/components/item-edit/FieldRow.js +413 -394
  13. package/dist/shared/components/item-edit/GroupSection.js +637 -635
  14. package/dist/shared/components/item-edit/InlineGridField.js +89 -90
  15. package/dist/shared/components/item-edit/M2MCombobox.js +117 -116
  16. package/dist/shared/components/item-edit/QuickPicker.js +9 -9
  17. package/dist/shared/components/item-edit/RawEditSheet.js +80 -79
  18. package/dist/shared/components/item-edit/RelationCombobox.js +173 -167
  19. package/dist/shared/components/item-edit/RowMatchPanel.js +1 -1
  20. package/dist/shared/components/item-edit/m2m-invalidate.js +19 -0
  21. package/dist/shared/components/item-edit/record-lookups.js +15 -0
  22. package/dist/shared/components/item-edit/render-stability.js +147 -0
  23. package/dist/shared/components/layout-editor/FormMapButton.js +5 -4
  24. package/dist/shared/lib/picker-rank.js +21 -0
  25. package/dist/shared/lib/safe-href.js +10 -0
  26. package/dist/shared/lib/socket-realtime.js +107 -78
  27. package/package.json +6 -6
@@ -7,18 +7,19 @@ import { useDebounced as He } from "../hooks/useDebounced.js";
7
7
  import { get as je, post as Y } from "../lib/commands.js";
8
8
  import { explicitAllUrlParams as Ye, initialFilterSelection as Xe, filterSelectionToSearch as Ze } from "../lib/query-filter-seed.js";
9
9
  import { userErrorMessage as Re } from "../lib/safe-error.js";
10
- import { resolveSheetDef as et } from "../lib/sheet-def.js";
11
- import { uniqueByValue as tt } from "../lib/unique-options.js";
12
- import { useMyScopes as rt, matchScopeDimension as Se, effectiveScopeSeedIds as nt, translateScopeValues as at } from "../lib/use-my-scopes.js";
13
- import { titleCase as L, formatRelative as lt, formatNumber as st } from "../lib/utils.js";
14
- import { CacheStamp as it } from "./CacheStamp.js";
15
- import { RelationCombobox as ot } from "./item-edit/RelationCombobox.js";
10
+ import { safeLinkKind as et } from "../lib/safe-href.js";
11
+ import { resolveSheetDef as tt } from "../lib/sheet-def.js";
12
+ import { uniqueByValue as rt } from "../lib/unique-options.js";
13
+ import { useMyScopes as nt, matchScopeDimension as Se, effectiveScopeSeedIds as at, translateScopeValues as lt } from "../lib/use-my-scopes.js";
14
+ import { titleCase as L, formatRelative as st, formatNumber as it } from "../lib/utils.js";
15
+ import { CacheStamp as ot } from "./CacheStamp.js";
16
+ import { RelationCombobox as dt } from "./item-edit/RelationCombobox.js";
16
17
  import { MatrixEditor as se } from "./MatrixEditor.js";
17
- import { QueryStatStrip as dt } from "./QueryStatStrip.js";
18
- import { QueryTable as ct } from "./QueryTable.js";
19
- import { RecordDrilldownSheet as ut } from "./RecordDrilldownSheet.js";
18
+ import { QueryStatStrip as ct } from "./QueryStatStrip.js";
19
+ import { QueryTable as ut } from "./QueryTable.js";
20
+ import { RecordDrilldownSheet as mt } from "./RecordDrilldownSheet.js";
20
21
  import { RecordGridEditor as $e } from "./RecordGridEditor.js";
21
- import { SheetHeaderBody as mt } from "./SheetHeaderBody.js";
22
+ import { SheetHeaderBody as pt } from "./SheetHeaderBody.js";
22
23
  const ae = 76;
23
24
  function X() {
24
25
  return /* @__PURE__ */ t("div", { className: "space-y-1.5 p-3", children: [1, 2, 3].map((e) => /* @__PURE__ */ t(
@@ -33,7 +34,7 @@ function Z({ error: e }) {
33
34
  const r = Re(e, "Failed to load widget data");
34
35
  return /* @__PURE__ */ t("div", { className: "flex h-full items-center justify-center p-3 text-[12px] text-amber-600 dark:text-amber-500", children: r });
35
36
  }
36
- function pt(e) {
37
+ function ht(e) {
37
38
  if (e == null) return "—";
38
39
  if (typeof e == "boolean") return e ? "true" : "false";
39
40
  const r = String(e);
@@ -61,13 +62,13 @@ function le(e, r) {
61
62
  );
62
63
  else {
63
64
  const a = o.match(/^\[([^\]]+)\]\(([^)]+)\)$/);
64
- a && (/^https?:\/\//i.test(a[2]) || a[2].startsWith("/")) ? n.push(
65
+ a && et(a[2]) !== null ? n.push(
65
66
  /* @__PURE__ */ t("a", { href: a[2], className: "text-nvr-cyan underline-offset-2 hover:underline", children: a[1] }, d)
66
67
  ) : n.push(o);
67
68
  }
68
69
  }), n;
69
70
  }
70
- function ht({ content: e }) {
71
+ function xt({ content: e }) {
71
72
  const r = [];
72
73
  let n = [], l = [], o = !1;
73
74
  const m = (a) => {
@@ -107,7 +108,7 @@ function ie(e, r, n) {
107
108
  staleTime: 3e4
108
109
  });
109
110
  }
110
- function xt({ slug: e, widget: r }) {
111
+ function ft({ slug: e, widget: r }) {
111
112
  var u;
112
113
  const n = r.config ?? {}, { data: l, isLoading: o, error: m } = ie(e, r, !!n.collection), d = Ue();
113
114
  if (!n.collection)
@@ -138,7 +139,7 @@ function xt({ slug: e, widget: r }) {
138
139
  "td",
139
140
  {
140
141
  className: "whitespace-nowrap px-3 py-1.5 text-slate-700 dark:text-slate-300",
141
- children: pt(f[$])
142
+ children: ht(f[$])
142
143
  },
143
144
  $
144
145
  ))
@@ -147,14 +148,14 @@ function xt({ slug: e, widget: r }) {
147
148
  )) })
148
149
  ] }) });
149
150
  }
150
- function ft({ slug: e, widget: r }) {
151
+ function bt({ slug: e, widget: r }) {
151
152
  const n = r.config ?? {}, { data: l, isLoading: o, error: m } = ie(e, r, !!n.collection);
152
153
  return n.collection ? m ? /* @__PURE__ */ t(Z, { error: m }) : /* @__PURE__ */ p("div", { className: "flex h-full flex-col items-start justify-center px-4", children: [
153
- o ? /* @__PURE__ */ t("div", { className: "h-9 w-24 animate-pulse rounded bg-slate-100 dark:bg-[hsl(var(--nvr-skeleton))]" }) : /* @__PURE__ */ t("span", { className: "text-[32px] font-semibold leading-none tracking-tight text-slate-900 dark:text-slate-100", children: (l == null ? void 0 : l.value) != null ? st(Number(l.value)) : "—" }),
154
+ o ? /* @__PURE__ */ t("div", { className: "h-9 w-24 animate-pulse rounded bg-slate-100 dark:bg-[hsl(var(--nvr-skeleton))]" }) : /* @__PURE__ */ t("span", { className: "text-[32px] font-semibold leading-none tracking-tight text-slate-900 dark:text-slate-100", children: (l == null ? void 0 : l.value) != null ? it(Number(l.value)) : "—" }),
154
155
  /* @__PURE__ */ t("span", { className: "mt-1.5 text-[12px] text-slate-400", children: n.label || `${n.aggregate ?? "count"} of ${n.collection}` })
155
156
  ] }) : /* @__PURE__ */ t("div", { className: "p-3 text-[12px] text-slate-400", children: "Select a collection" });
156
157
  }
157
- function bt({ slug: e, widget: r }) {
158
+ function gt({ slug: e, widget: r }) {
158
159
  const { data: n, isLoading: l, error: o } = ie(e, r, !0);
159
160
  if (l) return /* @__PURE__ */ t(X, {});
160
161
  if (o) return /* @__PURE__ */ t(Z, { error: o });
@@ -169,13 +170,13 @@ function bt({ slug: e, widget: r }) {
169
170
  d.collection,
170
171
  d.item ? ` · ${d.item}` : ""
171
172
  ] }),
172
- /* @__PURE__ */ t("span", { className: "ml-auto shrink-0 text-[11px] text-slate-400", children: lt(d.timestamp) })
173
+ /* @__PURE__ */ t("span", { className: "ml-auto shrink-0 text-[11px] text-slate-400", children: st(d.timestamp) })
173
174
  ]
174
175
  },
175
176
  d.id
176
177
  )) }) : /* @__PURE__ */ t("div", { className: "p-3 text-[12px] text-slate-400", children: "No activity" });
177
178
  }
178
- function gt({ widget: e }) {
179
+ function yt({ widget: e }) {
179
180
  var n;
180
181
  const r = String(((n = e.config) == null ? void 0 : n.url) ?? "");
181
182
  return r ? /^https?:\/\//i.test(r) ? /* @__PURE__ */ t(
@@ -220,7 +221,7 @@ function Te({
220
221
  }
221
222
  ) });
222
223
  }
223
- function yt({ widget: e }) {
224
+ function vt({ widget: e }) {
224
225
  const r = e.config ?? {}, [n, l] = q(!1);
225
226
  return !r.target_collection || !r.option_collection || !r.key_field || !r.value_field ? /* @__PURE__ */ t("div", { className: "p-3 text-[12px] text-slate-400", children: "Matrix editor not configured" }) : r.display === "drawer" ? /* @__PURE__ */ p("div", { className: "flex h-full items-center", children: [
226
227
  /* @__PURE__ */ t(
@@ -242,7 +243,7 @@ function yt({ widget: e }) {
242
243
  )
243
244
  ] }) : /* @__PURE__ */ t(se, { config: r });
244
245
  }
245
- function vt(e) {
246
+ function kt(e) {
246
247
  return Xe(
247
248
  e,
248
249
  typeof window > "u" ? "" : window.location.search
@@ -262,7 +263,7 @@ function We(e, r, n, l, o, m) {
262
263
  }
263
264
  return e;
264
265
  }
265
- function kt(e, r, n, l, o, m) {
266
+ function wt(e, r, n, l, o, m) {
266
267
  const d = {};
267
268
  for (const [a, c] of Object.entries(e.params ?? {})) {
268
269
  const u = We(c, r, n, l, o, m);
@@ -270,7 +271,7 @@ function kt(e, r, n, l, o, m) {
270
271
  }
271
272
  return { ...e, params: d };
272
273
  }
273
- function wt({
274
+ function Nt({
274
275
  config: e,
275
276
  stats: r,
276
277
  asOf: n,
@@ -290,7 +291,7 @@ function wt({
290
291
  className: "shrink-0 border-b border-slate-200 bg-white px-4 py-3 dark:border-border dark:bg-card",
291
292
  "data-sheet-header": !0,
292
293
  children: /* @__PURE__ */ t(
293
- mt,
294
+ pt,
294
295
  {
295
296
  stats: r,
296
297
  rows: (d == null ? void 0 : d.data) ?? [],
@@ -304,7 +305,7 @@ function wt({
304
305
  }
305
306
  );
306
307
  }
307
- function Nt({
308
+ function St({
308
309
  def: e,
309
310
  row: r,
310
311
  onClose: n
@@ -345,7 +346,7 @@ function Nt({
345
346
  )
346
347
  ] }),
347
348
  e.header && /* @__PURE__ */ t(
348
- wt,
349
+ Nt,
349
350
  {
350
351
  config: e.header.config,
351
352
  stats: e.header.stats,
@@ -376,7 +377,7 @@ function Nt({
376
377
  }
377
378
  ) });
378
379
  }
379
- function St(e, r, n, l) {
380
+ function $t(e, r, n, l) {
380
381
  if (!e) return;
381
382
  const o = (c) => {
382
383
  const u = /^\$filters\.(\w+)(?:\.(\w+))?$/.exec(c);
@@ -390,11 +391,11 @@ function St(e, r, n, l) {
390
391
  ) : c, d = (c) => c === void 0 ? !0 : Array.isArray(c) ? c.some(d) : c && typeof c == "object" ? Object.values(c).some(d) : !1, a = m(e);
391
392
  return Array.isArray(a._and) && (a._and = a._and.filter((c) => !d(c))), d(a) ? void 0 : a;
392
393
  }
393
- const $t = 400, _t = 2500;
394
+ const _t = 400, Ct = 2500;
394
395
  function _e(e, r) {
395
396
  return e.map((n) => String(n[r] ?? "")).sort().join("\0");
396
397
  }
397
- function Ct({
398
+ function qt({
398
399
  filter: e,
399
400
  selected: r,
400
401
  onChange: n,
@@ -425,7 +426,7 @@ function Ct({
425
426
  };
426
427
  return window.addEventListener("mousedown", v), () => window.removeEventListener("mousedown", v);
427
428
  }, [a]);
428
- const j = e.label ?? L(e.param), O = tt(
429
+ const j = e.label ?? L(e.param), O = rt(
429
430
  l != null && l.length ? _.filter((v) => l.some((s) => String(s) === String(v.id))) : _,
430
431
  (v) => String(v[w] ?? "")
431
432
  ).filter(
@@ -510,10 +511,10 @@ function Ct({
510
511
  ] })
511
512
  ] });
512
513
  }
513
- function qt({ widget: e }) {
514
+ function jt({ widget: e }) {
514
515
  return /* @__PURE__ */ t(Me, { config: e.config ?? {} });
515
516
  }
516
- function jt({ widget: e }) {
517
+ function Rt({ widget: e }) {
517
518
  const r = e.config ?? {}, [n, l] = q(!1);
518
519
  return r.collection ? r.display === "drawer" ? /* @__PURE__ */ p("div", { className: "flex h-full items-center", children: [
519
520
  /* @__PURE__ */ t(
@@ -560,7 +561,7 @@ function jt({ widget: e }) {
560
561
  )
561
562
  ] }) : /* @__PURE__ */ t($e, { config: r }) : /* @__PURE__ */ t("div", { className: "p-3 text-[12px] text-slate-400", children: "Configure the record grid (collection)" });
562
563
  }
563
- function Rt({
564
+ function Tt({
564
565
  cfg: e
565
566
  }) {
566
567
  const [r, n] = q(!1), l = { ...e };
@@ -610,12 +611,12 @@ function Rt({
610
611
  ] });
611
612
  }
612
613
  function Me({ config: e }) {
613
- return e.display === "drawer" ? /* @__PURE__ */ t(Rt, { cfg: e }) : /* @__PURE__ */ t(Oe, { config: e });
614
+ return e.display === "drawer" ? /* @__PURE__ */ t(Tt, { cfg: e }) : /* @__PURE__ */ t(Oe, { config: e });
614
615
  }
615
616
  function Oe({ config: e }) {
616
617
  var fe, be, ge, ye, ve, ke, we;
617
618
  const r = z(), n = qe(), [l, o] = q(null), [m, d] = q(null), [a, c] = q(null), [u, f] = q(
618
- () => vt(e.filters)
619
+ () => kt(e.filters)
619
620
  ), [S] = q(
620
621
  () => Ye(e.filters, typeof window > "u" ? "" : window.location.search)
621
622
  ), $ = (i, h) => {
@@ -637,7 +638,7 @@ function Oe({ config: e }) {
637
638
  }, 250);
638
639
  return () => window.clearInterval(i);
639
640
  }, [_ == null ? void 0 : _.phase]);
640
- const { scopes: C, ready: v } = rt(), s = D(!1), [y, M] = q(!1), [B, K] = q(/* @__PURE__ */ new Map());
641
+ const { scopes: C, ready: v } = nt(), s = D(!1), [y, M] = q(!1), [B, K] = q(/* @__PURE__ */ new Map());
641
642
  H(() => {
642
643
  if (s.current || !v) return;
643
644
  s.current = !0;
@@ -654,9 +655,9 @@ function Oe({ config: e }) {
654
655
  for (const b of i) {
655
656
  const x = Se(C, { key: b.param, collection: b.collection });
656
657
  if (!x) continue;
657
- const g = nt(C, x.name);
658
+ const g = at(C, x.name);
658
659
  if (!g.length) continue;
659
- const N = b.value_field ?? "id", T = await at(
660
+ const N = b.value_field ?? "id", T = await lt(
660
661
  r,
661
662
  x,
662
663
  g,
@@ -695,7 +696,7 @@ function Oe({ config: e }) {
695
696
  return i;
696
697
  }, [e.params, e.filters, u]), [V, Fe] = q(/* @__PURE__ */ new Set()), ee = D(!1), oe = JSON.stringify(J), Pe = He(
697
698
  oe,
698
- ee.current ? V.size > 0 ? _t : $t : 0
699
+ ee.current ? V.size > 0 ? Ct : _t : 0
699
700
  ), te = ee.current ? Pe : oe, A = Ne(
700
701
  () => JSON.parse(te),
701
702
  [te]
@@ -767,7 +768,7 @@ function Oe({ config: e }) {
767
768
  ), R(`${i.action.label} failed: ${x}`);
768
769
  }
769
770
  }, Be = /* @__PURE__ */ t(
770
- it,
771
+ ot,
771
772
  {
772
773
  envelope: F,
773
774
  onRefresh: Ee,
@@ -778,7 +779,7 @@ function Oe({ config: e }) {
778
779
  (e.filters ?? []).map((i) => {
779
780
  const h = Se(C, { key: i.param, collection: i.collection }), b = h ? (C == null ? void 0 : C.restricted[h.name]) ?? [] : [];
780
781
  return /* @__PURE__ */ t(
781
- Ct,
782
+ qt,
782
783
  {
783
784
  filter: i,
784
785
  selected: u[i.param] ?? [],
@@ -810,7 +811,7 @@ function Oe({ config: e }) {
810
811
  w && /* @__PURE__ */ t("span", { className: "text-[12px] text-slate-500", children: w }),
811
812
  Be
812
813
  ] }) : null, he = (be = e.stats) != null && be.length ? /* @__PURE__ */ t(
813
- dt,
814
+ ct,
814
815
  {
815
816
  stats: e.stats,
816
817
  rows: G ?? [],
@@ -830,7 +831,7 @@ function Oe({ config: e }) {
830
831
  /* @__PURE__ */ t(Z, { error: ce })
831
832
  ] });
832
833
  const k = e.row_click, xe = (i, h) => {
833
- const x = et(i, (N) => kt(
834
+ const x = tt(i, (N) => wt(
834
835
  N,
835
836
  h,
836
837
  G ?? [],
@@ -886,7 +887,7 @@ function Oe({ config: e }) {
886
887
  ne,
887
888
  he,
888
889
  /* @__PURE__ */ t(
889
- ct,
890
+ ut,
890
891
  {
891
892
  rows: G ?? [],
892
893
  config: (
@@ -915,7 +916,7 @@ function Oe({ config: e }) {
915
916
  children: [
916
917
  /* @__PURE__ */ t("p", { className: "mb-2 text-[13px] font-semibold text-slate-700 dark:text-slate-200", children: k.picker.title ?? "Choose a record" }),
917
918
  /* @__PURE__ */ t(
918
- ot,
919
+ dt,
919
920
  {
920
921
  collection: k.picker.collection,
921
922
  value: null,
@@ -934,7 +935,7 @@ function Oe({ config: e }) {
934
935
  });
935
936
  }
936
937
  },
937
- extraFilter: St(k.picker.filter, l, u, e.filters),
938
+ extraFilter: $t(k.picker.filter, l, u, e.filters),
938
939
  placeholder: "Search…"
939
940
  }
940
941
  ),
@@ -962,9 +963,9 @@ function Oe({ config: e }) {
962
963
  onClose: () => d(null)
963
964
  }
964
965
  ),
965
- a && /* @__PURE__ */ t(Nt, { def: a.def, row: a.row, onClose: () => c(null) }),
966
+ a && /* @__PURE__ */ t(St, { def: a.def, row: a.row, onClose: () => c(null) }),
966
967
  _ && /* @__PURE__ */ t(
967
- Tt,
968
+ Wt,
968
969
  {
969
970
  run: _,
970
971
  onConfirm: () => void pe(_),
@@ -978,7 +979,7 @@ function Oe({ config: e }) {
978
979
  );
979
980
  }
980
981
  const U = (e) => e < 6e4 ? `${(e / 1e3).toFixed(e < 1e4 ? 1 : 0)}s` : `${Math.floor(e / 6e4)}m ${Math.round(e % 6e4 / 1e3)}s`;
981
- function Tt({
982
+ function Wt({
982
983
  run: e,
983
984
  onConfirm: r,
984
985
  onClose: n
@@ -1101,26 +1102,26 @@ function Ce({ slug: e, widget: r }) {
1101
1102
  var n;
1102
1103
  switch (r.type) {
1103
1104
  case "table":
1104
- return /* @__PURE__ */ t(xt, { slug: e, widget: r });
1105
- case "kpi":
1106
1105
  return /* @__PURE__ */ t(ft, { slug: e, widget: r });
1106
+ case "kpi":
1107
+ return /* @__PURE__ */ t(bt, { slug: e, widget: r });
1107
1108
  case "markdown":
1108
- return /* @__PURE__ */ t(ht, { content: String(((n = r.config) == null ? void 0 : n.content) ?? "") });
1109
+ return /* @__PURE__ */ t(xt, { content: String(((n = r.config) == null ? void 0 : n.content) ?? "") });
1109
1110
  case "iframe":
1110
- return /* @__PURE__ */ t(gt, { widget: r });
1111
+ return /* @__PURE__ */ t(yt, { widget: r });
1111
1112
  case "query":
1112
- return /* @__PURE__ */ t(qt, { widget: r });
1113
+ return /* @__PURE__ */ t(jt, { widget: r });
1113
1114
  case "matrix":
1114
- return /* @__PURE__ */ t(yt, { widget: r });
1115
+ return /* @__PURE__ */ t(vt, { widget: r });
1115
1116
  case "record-grid":
1116
- return /* @__PURE__ */ t(jt, { widget: r });
1117
+ return /* @__PURE__ */ t(Rt, { widget: r });
1117
1118
  case "recent-activity":
1118
- return /* @__PURE__ */ t(bt, { slug: e, widget: r });
1119
+ return /* @__PURE__ */ t(gt, { slug: e, widget: r });
1119
1120
  default:
1120
1121
  return /* @__PURE__ */ t("div", { className: "p-3 text-[12px] text-slate-400", children: "Unknown widget" });
1121
1122
  }
1122
1123
  }
1123
- function Zt({ slug: e, hideHeader: r, className: n }) {
1124
+ function tr({ slug: e, hideHeader: r, className: n }) {
1124
1125
  var C, v;
1125
1126
  const l = z(), o = qe(), m = Ve("drill.page"), d = m.value, {
1126
1127
  data: a,
@@ -1197,7 +1198,7 @@ function Zt({ slug: e, hideHeader: r, className: n }) {
1197
1198
  ] });
1198
1199
  return o ? O : /* @__PURE__ */ p(Ge.Provider, { value: { open: (s) => m.push([s]) }, children: [
1199
1200
  d != null && d.length ? /* @__PURE__ */ t(
1200
- ut,
1201
+ mt,
1201
1202
  {
1202
1203
  collection: d[0].collection,
1203
1204
  itemId: d[0].itemId,
@@ -1214,8 +1215,8 @@ function Zt({ slug: e, hideHeader: r, className: n }) {
1214
1215
  ] });
1215
1216
  }
1216
1217
  export {
1217
- Zt as PageRenderer,
1218
+ tr as PageRenderer,
1218
1219
  Me as QueryWidgetView,
1219
- jt as RecordGridWidgetBody,
1220
+ Rt as RecordGridWidgetBody,
1220
1221
  _e as selectionSignature
1221
1222
  };