@nivaro/react 0.3.41 → 0.3.43

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 (97) hide show
  1. package/dist/components/LayoutForm.js +100 -98
  2. package/dist/full.css +1 -1
  3. package/dist/hooks/useSessionRecorder.js +1 -1
  4. package/dist/index.d.ts +733 -15
  5. package/dist/index.js +820 -775
  6. package/dist/shared/components/ActivityEntry.js +154 -0
  7. package/dist/shared/components/AudienceConfirmPanel.js +98 -0
  8. package/dist/shared/components/BackgroundRunOffer.js +43 -31
  9. package/dist/shared/components/BroadcastView.js +225 -204
  10. package/dist/shared/components/CollectionBrowserView.js +3924 -3584
  11. package/dist/shared/components/ConfigHistory.js +153 -0
  12. package/dist/shared/components/ConfigReadBack.js +65 -0
  13. package/dist/shared/components/DataTable.js +379 -346
  14. package/dist/shared/components/ForceReloadBanner.js +47 -40
  15. package/dist/shared/components/IdleReloadWatcher.js +69 -0
  16. package/dist/shared/components/ItemEditForm.js +4041 -3853
  17. package/dist/shared/components/MyWorkView.js +278 -213
  18. package/dist/shared/components/NotificationBell.js +130 -121
  19. package/dist/shared/components/ProfileView.js +776 -1003
  20. package/dist/shared/components/RecentRecordsRail.js +34 -16
  21. package/dist/shared/components/RecordReadView.js +500 -477
  22. package/dist/shared/components/Skeletons.js +199 -0
  23. package/dist/shared/components/SlowNotice.js +63 -0
  24. package/dist/shared/components/Term.js +23 -0
  25. package/dist/shared/components/WidgetSlot.js +350 -353
  26. package/dist/shared/components/access/PermissionSummary.js +106 -0
  27. package/dist/shared/components/bulk/BulkActionButtons.js +76 -73
  28. package/dist/shared/components/chat/ChatPanel.js +902 -886
  29. package/dist/shared/components/chat/MemberPaging.js +70 -0
  30. package/dist/shared/components/chat/RoomParts.js +147 -117
  31. package/dist/shared/components/chat/ScreenClip.js +73 -69
  32. package/dist/shared/components/chat/chat-core.js +449 -396
  33. package/dist/shared/components/chat/huddle/huddle-store.js +48 -43
  34. package/dist/shared/components/help-videos/api.js +2 -5
  35. package/dist/shared/components/help-videos/viewer/HelpVideoMatchChip.js +79 -0
  36. package/dist/shared/components/help-videos/viewer/matchChip.js +50 -0
  37. package/dist/shared/components/imports/CollectionImportPanel.js +139 -133
  38. package/dist/shared/components/imports/RunDetailSheet.js +222 -227
  39. package/dist/shared/components/integrations/console/ErrorExplanation.js +121 -0
  40. package/dist/shared/components/integrations/console/PartnerDetail.js +175 -174
  41. package/dist/shared/components/integrations/console/SubmissionRow.js +36 -34
  42. package/dist/shared/components/integrations/console/drill/SubmissionDrill.js +50 -48
  43. package/dist/shared/components/item-edit/FieldComments.js +212 -0
  44. package/dist/shared/components/item-edit/FieldRow.js +340 -336
  45. package/dist/shared/components/item-edit/RecordHeaderActions.js +23 -22
  46. package/dist/shared/components/item-edit/RelationCombobox.js +231 -222
  47. package/dist/shared/components/item-edit/RuleHiddenNotes.js +55 -0
  48. package/dist/shared/components/item-edit/field-comments-context.js +6 -0
  49. package/dist/shared/components/item-edit/field-sources.js +33 -0
  50. package/dist/shared/components/item-edit/rule-hidden.js +30 -0
  51. package/dist/shared/components/layout-editor/HistoryPanel.js +113 -96
  52. package/dist/shared/components/layout-editor/editors/cascade-filters.js +170 -145
  53. package/dist/shared/components/layout-editor/inspector/Breadcrumb.js +22 -18
  54. package/dist/shared/components/layout-editor/inspector/GroupInspector.js +177 -159
  55. package/dist/shared/components/layout-editor/inspector/PickerTab.js +35 -34
  56. package/dist/shared/components/layout-editor/inspector/RulesTab.js +124 -111
  57. package/dist/shared/components/layout-editor/inspector/kit.js +292 -277
  58. package/dist/shared/components/layout-editor/parity-keys.json.js +1 -1
  59. package/dist/shared/components/list/CopyListLinkButton.js +41 -0
  60. package/dist/shared/components/list/InlineEdit.js +363 -0
  61. package/dist/shared/components/notifications/NotificationCenterView.js +213 -181
  62. package/dist/shared/components/notifications/NotificationDetailBits.js +205 -82
  63. package/dist/shared/components/notifications/NotificationRulesEditor.js +515 -0
  64. package/dist/shared/components/notifications/TestMyRules.js +137 -0
  65. package/dist/shared/components/notifications/changes-lines.js +24 -0
  66. package/dist/shared/components/notifications/why-lines.js +64 -0
  67. package/dist/shared/components/panels/CommentPanel.js +316 -281
  68. package/dist/shared/components/panels/LegalHoldBanner.js +38 -0
  69. package/dist/shared/components/panels/PipelinePanel.js +201 -196
  70. package/dist/shared/components/panels/RevisionsPanel.js +496 -479
  71. package/dist/shared/components/pipeline/PipelineEditorView.js +1587 -1560
  72. package/dist/shared/components/pipeline/PipelineStateOwners.js +116 -103
  73. package/dist/shared/components/profile/PersonDidPanel.js +188 -0
  74. package/dist/shared/components/profile/PersonProfile.js +57 -52
  75. package/dist/shared/components/queue/QueueWorklist.js +1526 -1365
  76. package/dist/shared/hooks/useSlowReason.js +39 -0
  77. package/dist/shared/lib/activity-sentence.js +670 -0
  78. package/dist/shared/lib/config-sentences.js +418 -0
  79. package/dist/shared/lib/core-glossary.js +229 -0
  80. package/dist/shared/lib/error-hints.js +159 -0
  81. package/dist/shared/lib/error-message.js +105 -0
  82. package/dist/shared/lib/error-toast.js +22 -0
  83. package/dist/shared/lib/field-comments.js +25 -0
  84. package/dist/shared/lib/filter-sentence.js +261 -0
  85. package/dist/shared/lib/glossary.js +55 -48
  86. package/dist/shared/lib/idle-reload.js +138 -0
  87. package/dist/shared/lib/layout-resolve.js +42 -29
  88. package/dist/shared/lib/list-inline-edit.js +190 -0
  89. package/dist/shared/lib/list-link.js +147 -0
  90. package/dist/shared/lib/nav-trail.js +107 -0
  91. package/dist/shared/lib/prefetch.js +259 -106
  92. package/dist/shared/lib/record-ref.js +72 -0
  93. package/dist/shared/lib/reload-holds.js +25 -0
  94. package/dist/shared/lib/safe-error.js +52 -24
  95. package/dist/shared/lib/skeleton-shapes.js +72 -0
  96. package/dist/shared/lib/slow-reason.js +63 -0
  97. package/package.json +1 -1
@@ -0,0 +1,41 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import { Check as d, Link2 as m } from "lucide-react";
3
+ import { useState as u, useRef as p, useEffect as f } from "react";
4
+ import { toast as r } from "sonner";
5
+ import { copyListLink as k } from "../../lib/list-link.js";
6
+ import { cn as h } from "../../lib/utils.js";
7
+ function L({
8
+ listKey: s,
9
+ getState: a,
10
+ className: n
11
+ }) {
12
+ const [l, o] = u(!1), e = p(null);
13
+ f(
14
+ () => () => {
15
+ e.current && clearTimeout(e.current);
16
+ },
17
+ []
18
+ );
19
+ const c = async () => {
20
+ const i = await k(s, a());
21
+ i === "copied" ? (r.success("Link copied"), o(!0), e.current && clearTimeout(e.current), e.current = setTimeout(() => o(!1), 1500)) : i === "too-long" ? r.error("This view is too big for a link — save it as a shared view instead") : r.error("Could not copy the link");
22
+ };
23
+ return /* @__PURE__ */ t(
24
+ "button",
25
+ {
26
+ type: "button",
27
+ onClick: () => void c(),
28
+ "aria-label": "Copy link to this view",
29
+ "data-tip": "Copy link to this view",
30
+ "data-copy-list-link": "",
31
+ className: h(
32
+ "flex h-8 w-8 items-center justify-center rounded-md border border-slate-200 text-slate-500 hover:bg-slate-100 hover:text-slate-700 dark:border-slate-700 dark:text-slate-400 dark:hover:bg-slate-800 dark:hover:text-slate-200",
33
+ n
34
+ ),
35
+ children: l ? /* @__PURE__ */ t(d, { className: "h-4 w-4 text-emerald-500 dark:text-emerald-400" }) : /* @__PURE__ */ t(m, { className: "h-4 w-4" })
36
+ }
37
+ );
38
+ }
39
+ export {
40
+ L as CopyListLinkButton
41
+ };
@@ -0,0 +1,363 @@
1
+ import { jsx as s, jsxs as v } from "react/jsx-runtime";
2
+ import { useQuery as $ } from "@tanstack/react-query";
3
+ import { Loader2 as L, Check as K, Pencil as R } from "lucide-react";
4
+ import { useState as y, useRef as w, useEffect as P, useCallback as C } from "react";
5
+ import { useNivaroClient as O } from "../../context.js";
6
+ import { patch as _, get as j } from "../../lib/commands.js";
7
+ import { inlineValueUnchanged as A, inlineInputValue as F, parseInlineInput as D } from "../../lib/list-inline-edit.js";
8
+ import { userErrorMessage as q } from "../../lib/safe-error.js";
9
+ import { choiceLabel as U, cn as N } from "../../lib/utils.js";
10
+ import { RelationCombobox as M } from "../item-edit/RelationCombobox.js";
11
+ import { Command as V, CommandInput as z, CommandList as B, CommandEmpty as J, CommandItem as I } from "../ui/command.js";
12
+ import { Popover as Q, PopoverAnchor as Y, PopoverContent as G } from "../ui/popover.js";
13
+ function me() {
14
+ const t = O(), [p, o] = y(null), [n, i] = y({}), [l, a] = y({}), [d, h] = y({}), r = w({});
15
+ P(
16
+ () => () => {
17
+ for (const e of Object.values(r.current)) clearTimeout(e);
18
+ },
19
+ []
20
+ );
21
+ const c = C((e) => {
22
+ i((f) => {
23
+ if (!(e in f)) return f;
24
+ const u = { ...f };
25
+ return delete u[e], u;
26
+ });
27
+ }, []), b = C(
28
+ (e) => {
29
+ c(e), o(e);
30
+ },
31
+ [c]
32
+ ), k = C(() => o(null), []), m = C(
33
+ (e) => {
34
+ var u;
35
+ if (o(e.next ?? null), A(e.kind, e.before, e.value)) return;
36
+ const f = ((u = e.optimistic) == null ? void 0 : u.call(e)) ?? (() => {
37
+ });
38
+ a((x) => ({ ...x, [e.cellKey]: !0 })), c(e.cellKey), t.request(
39
+ _(`/items/${encodeURIComponent(e.collection)}/${encodeURIComponent(String(e.id))}`, {
40
+ [e.field]: e.value
41
+ })
42
+ ).then((x) => {
43
+ var g;
44
+ (g = e.onSaved) == null || g.call(e, (x == null ? void 0 : x.data) ?? null), h((E) => ({ ...E, [e.cellKey]: !0 })), clearTimeout(r.current[e.cellKey]), r.current[e.cellKey] = setTimeout(() => {
45
+ h((E) => {
46
+ const S = { ...E };
47
+ return delete S[e.cellKey], S;
48
+ });
49
+ }, 1500);
50
+ }).catch((x) => {
51
+ f(), i((g) => ({
52
+ ...g,
53
+ [e.cellKey]: q(x, "This change was not saved")
54
+ }));
55
+ }).finally(() => {
56
+ a((x) => {
57
+ const g = { ...x };
58
+ return delete g[e.cellKey], g;
59
+ });
60
+ });
61
+ },
62
+ [t, c]
63
+ );
64
+ return {
65
+ editing: p,
66
+ start: b,
67
+ cancel: k,
68
+ commit: m,
69
+ errorOf: (e) => n[e] ?? null,
70
+ savingOf: (e) => !!l[e],
71
+ savedOf: (e) => !!d[e],
72
+ clearError: c
73
+ };
74
+ }
75
+ function H(t) {
76
+ const p = O(), { data: o } = $({
77
+ queryKey: ["cbv-collection-meta", t],
78
+ queryFn: () => p.request(j(`/collections/${t}`)).then((i) => i.data),
79
+ enabled: !!t,
80
+ staleTime: 10 * 6e4,
81
+ retry: !1
82
+ }), n = o == null ? void 0 : o.picker_filter;
83
+ if (n) {
84
+ if (typeof n == "object" && !Array.isArray(n)) return n;
85
+ if (typeof n == "string")
86
+ try {
87
+ const i = JSON.parse(n);
88
+ if (i && typeof i == "object" && !Array.isArray(i))
89
+ return i;
90
+ } catch {
91
+ }
92
+ }
93
+ }
94
+ const T = "h-7 w-full min-w-[120px] rounded border border-nvr-cyan bg-white px-1.5 text-[12px] text-slate-800 shadow-sm outline-none ring-2 ring-nvr-cyan/30 dark:bg-slate-900 dark:text-slate-100";
95
+ function W({
96
+ kind: t,
97
+ value: p,
98
+ label: o,
99
+ onCommit: n,
100
+ onCancel: i
101
+ }) {
102
+ const [l, a] = y(() => F(t, p)), [d, h] = y(null), r = w(!1), c = w(null);
103
+ P(() => {
104
+ var e, f, u;
105
+ (e = c.current) == null || e.focus();
106
+ try {
107
+ (u = (f = c.current) == null ? void 0 : f.select) == null || u.call(f);
108
+ } catch {
109
+ }
110
+ }, []);
111
+ const b = (e) => {
112
+ var u;
113
+ if (r.current) return;
114
+ const f = D(t, l);
115
+ if (!f.ok) {
116
+ h(f.error), (u = c.current) == null || u.focus();
117
+ return;
118
+ }
119
+ r.current = !0, n(f.value, e);
120
+ }, k = (e) => {
121
+ e.stopPropagation(), e.key === "Escape" ? (e.preventDefault(), r.current = !0, i()) : e.key === "Enter" && !(t === "longtext" && e.shiftKey) ? (e.preventDefault(), b(0)) : e.key === "Tab" && (e.preventDefault(), b(e.shiftKey ? -1 : 1));
122
+ }, m = {
123
+ "aria-label": `Edit ${o}`,
124
+ "aria-invalid": d ? !0 : void 0,
125
+ value: l,
126
+ onChange: (e) => {
127
+ a(e.target.value), d && h(null);
128
+ },
129
+ onKeyDown: k,
130
+ // Clicking away keeps what was typed (a spreadsheet's habit); a value that
131
+ // does not parse is dropped (Enter / Tab say why instead).
132
+ onBlur: () => {
133
+ if (!r.current) {
134
+ if (!D(t, l).ok) {
135
+ r.current = !0, i();
136
+ return;
137
+ }
138
+ b(0);
139
+ }
140
+ },
141
+ onClick: (e) => e.stopPropagation(),
142
+ onDoubleClick: (e) => e.stopPropagation()
143
+ };
144
+ return /* @__PURE__ */ v("span", { className: "block min-w-0", "data-inline-editor": t, children: [
145
+ t === "longtext" ? /* @__PURE__ */ s(
146
+ "textarea",
147
+ {
148
+ ref: c,
149
+ rows: 2,
150
+ ...m,
151
+ className: N(T, "h-auto min-h-[28px] resize-y py-1")
152
+ }
153
+ ) : /* @__PURE__ */ s(
154
+ "input",
155
+ {
156
+ ref: c,
157
+ type: t === "date" ? "date" : t === "datetime" ? "datetime-local" : "text",
158
+ inputMode: t === "integer" ? "numeric" : t === "number" ? "decimal" : void 0,
159
+ ...m,
160
+ className: N(
161
+ T,
162
+ (t === "integer" || t === "number") && "text-right tabular-nums"
163
+ )
164
+ }
165
+ ),
166
+ d && /* @__PURE__ */ s("span", { className: "mt-0.5 block text-[10.5px] font-medium text-red-600 dark:text-red-400", children: d })
167
+ ] });
168
+ }
169
+ function X({
170
+ value: t,
171
+ options: p,
172
+ label: o,
173
+ onCommit: n,
174
+ onCancel: i
175
+ }) {
176
+ var h;
177
+ const l = w(!1), a = t == null ? "" : String(t), d = (r, c = 0) => {
178
+ l.current || (l.current = !0, n(r === "" ? null : r, c));
179
+ };
180
+ return /* @__PURE__ */ v(
181
+ Q,
182
+ {
183
+ open: !0,
184
+ onOpenChange: (r) => {
185
+ !r && !l.current && (l.current = !0, i());
186
+ },
187
+ children: [
188
+ /* @__PURE__ */ s(Y, { asChild: !0, children: /* @__PURE__ */ s("span", { className: "block h-7 min-w-[120px] rounded border border-nvr-cyan bg-white px-1.5 py-1 text-[12px] text-slate-700 ring-2 ring-nvr-cyan/30 dark:bg-slate-900 dark:text-slate-200", children: ((h = p.find((r) => r.value === a)) == null ? void 0 : h.label) ?? (a || "—") }) }),
189
+ /* @__PURE__ */ s(
190
+ G,
191
+ {
192
+ align: "start",
193
+ className: "w-[240px] p-0",
194
+ onClick: (r) => r.stopPropagation(),
195
+ onKeyDown: (r) => {
196
+ r.stopPropagation(), r.key === "Tab" && (r.preventDefault(), d(a, r.shiftKey ? -1 : 1));
197
+ },
198
+ children: /* @__PURE__ */ v(V, { children: [
199
+ /* @__PURE__ */ s(z, { placeholder: `Set ${o}…`, className: "h-8 text-[12px]" }),
200
+ /* @__PURE__ */ v(B, { children: [
201
+ /* @__PURE__ */ s(J, { className: "py-3 text-center text-[12px] text-muted-foreground", children: "No matches" }),
202
+ /* @__PURE__ */ v(
203
+ I,
204
+ {
205
+ value: "__clear__ —",
206
+ onSelect: () => d(""),
207
+ className: "text-[12px] text-slate-500 dark:text-slate-400",
208
+ children: [
209
+ /* @__PURE__ */ s("span", { className: "mr-2 inline-block w-3" }),
210
+ "— Clear —"
211
+ ]
212
+ }
213
+ ),
214
+ p.map((r) => /* @__PURE__ */ v(
215
+ I,
216
+ {
217
+ value: `${r.label} ${r.value}`,
218
+ onSelect: () => d(r.value),
219
+ className: "text-[12px]",
220
+ children: [
221
+ /* @__PURE__ */ s(
222
+ K,
223
+ {
224
+ className: N("mr-2 h-3 w-3", r.value === a ? "opacity-100" : "opacity-0")
225
+ }
226
+ ),
227
+ r.label
228
+ ]
229
+ },
230
+ r.value
231
+ ))
232
+ ] })
233
+ ] })
234
+ }
235
+ )
236
+ ]
237
+ }
238
+ );
239
+ }
240
+ function Z({
241
+ target: t,
242
+ value: p,
243
+ onCommit: o,
244
+ onCancel: n
245
+ }) {
246
+ const i = H(t), l = w(!1);
247
+ return P(() => {
248
+ const a = (d) => {
249
+ d.key !== "Escape" || l.current || (l.current = !0, n());
250
+ };
251
+ return document.addEventListener("keydown", a, !0), () => document.removeEventListener("keydown", a, !0);
252
+ }, [n]), // biome-ignore lint/a11y/noStaticElementInteractions: stops the row's open-on-click
253
+ /* @__PURE__ */ s(
254
+ "span",
255
+ {
256
+ className: "block min-w-[180px]",
257
+ onClick: (a) => a.stopPropagation(),
258
+ onKeyDown: (a) => a.stopPropagation(),
259
+ "data-inline-editor": "m2o",
260
+ children: /* @__PURE__ */ s(
261
+ M,
262
+ {
263
+ collection: t,
264
+ value: p,
265
+ defaultOpen: !0,
266
+ extraFilter: i,
267
+ onChange: (a) => {
268
+ l.current || (l.current = !0, o(a ?? null, 0));
269
+ },
270
+ onClose: () => {
271
+ l.current || (l.current = !0, n());
272
+ }
273
+ }
274
+ )
275
+ }
276
+ );
277
+ }
278
+ function de({
279
+ controller: t,
280
+ cellKey: p,
281
+ kind: o,
282
+ value: n,
283
+ label: i,
284
+ choices: l,
285
+ target: a,
286
+ onCommit: d,
287
+ children: h
288
+ }) {
289
+ const r = t.editing === p, c = t.errorOf(p), b = t.savingOf(p), k = t.savedOf(p);
290
+ if (r) {
291
+ const m = t.cancel;
292
+ if (o === "m2o" && a)
293
+ return /* @__PURE__ */ s(Z, { target: a, value: n, onCommit: d, onCancel: m });
294
+ if (o === "choice" || o === "boolean") {
295
+ const e = o === "boolean" ? [
296
+ { value: "true", label: "Yes" },
297
+ { value: "false", label: "No" }
298
+ ] : (l ?? []).map((u) => ({ value: u.value, label: U(u.label) })), f = o === "boolean" && n != null ? n === !0 || n === 1 || n === "1" || n === "true" ? "true" : "false" : n;
299
+ return /* @__PURE__ */ s(
300
+ X,
301
+ {
302
+ value: f,
303
+ options: e,
304
+ label: i,
305
+ onCommit: (u, x) => d(o === "boolean" ? u == null ? null : u === "true" : u, x),
306
+ onCancel: m
307
+ }
308
+ );
309
+ }
310
+ return /* @__PURE__ */ s(
311
+ W,
312
+ {
313
+ kind: o,
314
+ value: n,
315
+ label: i,
316
+ onCommit: d,
317
+ onCancel: m
318
+ }
319
+ );
320
+ }
321
+ return (
322
+ // biome-ignore lint/a11y/useSemanticElements: wraps arbitrary cell content (links, chips)
323
+ /* @__PURE__ */ v(
324
+ "span",
325
+ {
326
+ role: "button",
327
+ tabIndex: 0,
328
+ "data-inline-editable": o,
329
+ "data-inline-error": c ? "" : void 0,
330
+ "aria-label": `${i}: edit`,
331
+ onClick: (m) => {
332
+ m.stopPropagation(), t.start(p);
333
+ },
334
+ onDoubleClick: (m) => m.stopPropagation(),
335
+ onKeyDown: (m) => {
336
+ (m.key === "Enter" || m.key === "F2") && (m.preventDefault(), m.stopPropagation(), t.start(p));
337
+ },
338
+ className: N(
339
+ "group/ie -mx-1 flex min-h-[22px] min-w-[48px] cursor-text items-center gap-1 rounded px-1 outline-none transition-colors hover:bg-slate-100 focus-visible:ring-2 focus-visible:ring-nvr-cyan/50 dark:hover:bg-white/[0.06]",
340
+ c && "ring-1 ring-red-400 dark:ring-red-500/70",
341
+ b && "opacity-60"
342
+ ),
343
+ children: [
344
+ /* @__PURE__ */ s("span", { className: "min-w-0 flex-1 truncate", children: h }),
345
+ b ? /* @__PURE__ */ s(L, { className: "h-3 w-3 shrink-0 animate-spin text-slate-400" }) : k ? /* @__PURE__ */ s(K, { className: "h-3 w-3 shrink-0 text-emerald-500 dark:text-emerald-400" }) : /* @__PURE__ */ s(R, { className: "invisible h-3 w-3 shrink-0 text-slate-400 group-hover/ie:visible group-focus-visible/ie:visible dark:text-slate-500" }),
346
+ c && /* @__PURE__ */ s(
347
+ "span",
348
+ {
349
+ className: "ml-1 max-w-[220px] shrink-0 truncate text-[10.5px] font-medium text-red-600 dark:text-red-400",
350
+ "data-tip": c,
351
+ "data-inline-refusal": "",
352
+ children: c
353
+ }
354
+ )
355
+ ]
356
+ }
357
+ )
358
+ );
359
+ }
360
+ export {
361
+ de as InlineEditCell,
362
+ me as useInlineEdit
363
+ };