@nivaro/react 0.3.36 → 0.3.38

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 (102) hide show
  1. package/dist/components/slots/CommentsSlot.js +44 -36
  2. package/dist/full.css +1 -1
  3. package/dist/hooks/useSessionRecorder.js +1 -1
  4. package/dist/index.d.ts +9 -1
  5. package/dist/shared/components/AgentBadge.js +26 -0
  6. package/dist/shared/components/AgentQuestionsCard.js +198 -0
  7. package/dist/shared/components/ItemEditForm.js +3329 -3263
  8. package/dist/shared/components/McpConnectionScope.js +480 -0
  9. package/dist/shared/components/MyWorkView.js +223 -208
  10. package/dist/shared/components/RecordReadView.js +620 -575
  11. package/dist/shared/components/chat/ChatPanel.js +683 -671
  12. package/dist/shared/components/imports/DownloadSampleButton.js +69 -0
  13. package/dist/shared/components/imports/ImportConsole.js +106 -104
  14. package/dist/shared/components/imports/RunDetailSheet.js +34 -32
  15. package/dist/shared/components/item-edit/FieldAffordances.js +32 -32
  16. package/dist/shared/components/item-edit/FormTour.js +279 -0
  17. package/dist/shared/components/item-edit/GroupSection.js +377 -360
  18. package/dist/shared/components/item-edit/PersonalDefaultControl.js +28 -28
  19. package/dist/shared/components/item-edit/entry/EntryStrip.js +30 -26
  20. package/dist/shared/components/item-edit/form-density.js +36 -0
  21. package/dist/shared/components/item-edit/useFormUsageBeacon.js +59 -46
  22. package/dist/shared/components/item-edit/usePersonalDefaults.js +312 -296
  23. package/dist/shared/components/layout-editor/AddPanel.js +349 -192
  24. package/dist/shared/components/layout-editor/DesignNode.js +126 -112
  25. package/dist/shared/components/layout-editor/EditorTopBar.js +123 -103
  26. package/dist/shared/components/layout-editor/LayoutEditor.js +829 -751
  27. package/dist/shared/components/layout-editor/PlaceTools.js +334 -0
  28. package/dist/shared/components/layout-editor/SlashInsert.js +252 -0
  29. package/dist/shared/components/layout-editor/StructureMenu.js +285 -242
  30. package/dist/shared/components/layout-editor/add-target.js +54 -43
  31. package/dist/shared/components/layout-editor/ai-forms/AiComposer.js +238 -155
  32. package/dist/shared/components/layout-editor/ai-forms/AiFormsButton.js +1 -1
  33. package/dist/shared/components/layout-editor/ai-forms/ai-forms-api.js +15 -12
  34. package/dist/shared/components/layout-editor/dnd/LayoutDndProvider.js +347 -189
  35. package/dist/shared/components/layout-editor/dnd/TrashZone.js +60 -32
  36. package/dist/shared/components/layout-editor/dnd/UndoChip.js +76 -0
  37. package/dist/shared/components/layout-editor/dnd/merge-drop.js +33 -0
  38. package/dist/shared/components/layout-editor/dnd/multi-drop.js +87 -0
  39. package/dist/shared/components/layout-editor/dnd/node.js +115 -105
  40. package/dist/shared/components/layout-editor/dnd/sensors.js +23 -0
  41. package/dist/shared/components/layout-editor/dnd/trash-drop.js +34 -28
  42. package/dist/shared/components/layout-editor/dnd/trash-links.js +97 -0
  43. package/dist/shared/components/layout-editor/even-row.js +86 -0
  44. package/dist/shared/components/layout-editor/field-list.js +99 -0
  45. package/dist/shared/components/layout-editor/format-painter.js +102 -0
  46. package/dist/shared/components/layout-editor/grid-guides.js +15 -13
  47. package/dist/shared/components/layout-editor/inspector/BehaviourSettings.js +150 -132
  48. package/dist/shared/components/layout-editor/inspector/BulkInspector.js +57 -53
  49. package/dist/shared/components/layout-editor/inspector/EvenRowAction.js +31 -0
  50. package/dist/shared/components/layout-editor/inspector/GroupInspector.js +154 -141
  51. package/dist/shared/components/layout-editor/inspector/Inspector.js +209 -178
  52. package/dist/shared/components/layout-editor/inspector/LookTab.js +106 -98
  53. package/dist/shared/components/layout-editor/inspector/RulesTab.js +38 -37
  54. package/dist/shared/components/layout-editor/inspector/kit.js +280 -223
  55. package/dist/shared/components/layout-editor/keyboard-move.js +15 -15
  56. package/dist/shared/components/layout-editor/lint/LabelStyle.js +201 -0
  57. package/dist/shared/components/layout-editor/lint/LintPanel.js +132 -84
  58. package/dist/shared/components/layout-editor/lint/lint-api.js +65 -28
  59. package/dist/shared/components/layout-editor/nav/NavTools.js +14 -12
  60. package/dist/shared/components/layout-editor/nav/ZoomControls.js +145 -0
  61. package/dist/shared/components/layout-editor/nav/useEditorNav.js +34 -32
  62. package/dist/shared/components/layout-editor/nav/view-prefs.js +100 -15
  63. package/dist/shared/components/layout-editor/outputs/LayoutFile.js +89 -0
  64. package/dist/shared/components/layout-editor/outputs/OutputsButton.js +272 -195
  65. package/dist/shared/components/layout-editor/outputs/layout-file-plan.js +176 -0
  66. package/dist/shared/components/layout-editor/outputs/output-api.js +71 -37
  67. package/dist/shared/components/layout-editor/overview/describe-conditions.js +16 -11
  68. package/dist/shared/components/layout-editor/overview/purpose.js +5 -5
  69. package/dist/shared/components/layout-editor/parity-keys.json.js +1 -1
  70. package/dist/shared/components/layout-editor/pin.js +37 -19
  71. package/dist/shared/components/layout-editor/place-clip.js +257 -0
  72. package/dist/shared/components/layout-editor/preview/PreviewModes.js +27 -26
  73. package/dist/shared/components/layout-editor/preview/PreviewPanes.js +148 -117
  74. package/dist/shared/components/layout-editor/preview/SampleRecord.js +113 -0
  75. package/dist/shared/components/layout-editor/preview/preview-model.js +79 -60
  76. package/dist/shared/components/layout-editor/preview/sample-record.js +105 -0
  77. package/dist/shared/components/layout-editor/removed-log.js +151 -0
  78. package/dist/shared/components/layout-editor/reuse/LibraryRows.js +109 -78
  79. package/dist/shared/components/layout-editor/reuse/linked-sections.js +373 -0
  80. package/dist/shared/components/layout-editor/revert-element.js +140 -0
  81. package/dist/shared/components/layout-editor/section-structure.js +193 -170
  82. package/dist/shared/components/layout-editor/settings/EntrySection.js +63 -45
  83. package/dist/shared/components/layout-editor/settings/LayoutSection.js +63 -32
  84. package/dist/shared/components/layout-editor/settings/ResolveSettings.js +179 -137
  85. package/dist/shared/components/layout-editor/settings/WhoSection.js +18 -17
  86. package/dist/shared/components/layout-editor/settings/settings-registry.js +24 -0
  87. package/dist/shared/components/layout-editor/shortcuts.js +21 -16
  88. package/dist/shared/components/layout-editor/structure-ops.js +221 -195
  89. package/dist/shared/components/layout-editor/usage/UsagePanel.js +133 -85
  90. package/dist/shared/components/layout-editor/usage/refusal-lens.js +130 -0
  91. package/dist/shared/components/layout-editor/usage/usage-api.js +12 -11
  92. package/dist/shared/components/panels/CommentPanel.js +47 -45
  93. package/dist/shared/components/panels/RevisionsPanel.js +66 -64
  94. package/dist/shared/components/panels/TaskPanel.js +395 -332
  95. package/dist/shared/components/profile/AgentsPanel.js +196 -147
  96. package/dist/shared/components/profile/ConnectionRollback.js +329 -0
  97. package/dist/shared/components/profile/MyDefaultsCard.js +526 -520
  98. package/dist/shared/lib/entry-config.js +22 -22
  99. package/dist/shared/lib/form-usage-beacon.js +91 -55
  100. package/dist/shared/lib/layout-lint.js +530 -284
  101. package/dist/shared/lib/layout-resolve.js +58 -44
  102. package/package.json +1 -1
@@ -9,7 +9,7 @@ import { noteReplayEvent as _e, createReplayCheckoutState as De } from "../share
9
9
  import { emitReplayTap as Te, setReplayRecorderMode as N, registerReplayCapture as qe, clipEndOffset as Le, withClipKind as Pe } from "../shared/lib/replay-capture.js";
10
10
  import { instrumentConsole as Ne, instrumentRequests as Fe, redactSecrets as Me } from "../shared/lib/replay-context.js";
11
11
  import { instrumentSocket as Oe } from "../shared/lib/replay-socket.js";
12
- const Ue = "nivaro-react@0.3.36", j = 1e4, We = 150, He = 3e3, Ke = 600, $e = (n) => `nvr_replay_resume${n ? `:${n}` : ""}`, G = () => typeof navigator > "u" || navigator.onLine !== !1;
12
+ const Ue = "nivaro-react@0.3.38", j = 1e4, We = 150, He = 3e3, Ke = 600, $e = (n) => `nvr_replay_resume${n ? `:${n}` : ""}`, G = () => typeof navigator > "u" || navigator.onLine !== !1;
13
13
  function Be(n) {
14
14
  return typeof n.url != "string" || typeof fetch != "function" ? null : (f, a) => {
15
15
  const u = typeof n.getToken == "function" ? n.getToken() : void 0, d = { "Content-Type": "application/json" };
package/dist/index.d.ts CHANGED
@@ -2375,7 +2375,7 @@ declare interface DesignMark {
2375
2375
  tip?: string;
2376
2376
  highlight?: boolean;
2377
2377
  /** A small icon before the text (a pinned section's pin, #2628; a personal-default field's person). */
2378
- icon?: 'pin' | 'person';
2378
+ icon?: 'pin' | 'person' | 'link';
2379
2379
  /**
2380
2380
  * Where the tag ranks when a node has more than fit (DesignNode shows two,
2381
2381
  * then "+n"): `preview` (a preview mode's own tag) ranks with the role
@@ -5350,6 +5350,8 @@ declare interface LayoutDesign {
5350
5350
  ghost?(field: string): string | null;
5351
5351
  /** #2701: the width handle on a selected field set its width (12, 6, 4 or 3 columns). */
5352
5352
  resizeWidth?(t: DesignTarget, span: number): void;
5353
+ /** #3194: nodes inside a linked library section never drag (they change in the library). */
5354
+ locked?(t: DesignTarget): boolean;
5353
5355
  }
5354
5356
 
5355
5357
  /**
@@ -5443,6 +5445,12 @@ declare interface LayoutGroup {
5443
5445
  * (lib/visible-when.ts) and "hide this section while everything in it is empty". */
5444
5446
  visible_when?: string | null;
5445
5447
  hide_when_empty?: boolean | number | null;
5448
+ /** #3195: values a collapsed section shows in its heading (the edit form's summary strip). */
5449
+ summary_fields?: string | string[] | Array<string | {
5450
+ field?: string;
5451
+ label?: string | null;
5452
+ }> | null;
5453
+ summary_hide_empty?: boolean | number | null;
5446
5454
  }
5447
5455
 
5448
5456
  export declare type LayoutItem = FormGroupDescriptor | '__ungrouped__';
@@ -0,0 +1,26 @@
1
+ import { jsxs as r, jsx as e } from "react/jsx-runtime";
2
+ import { Bot as n } from "lucide-react";
3
+ import { cn as s } from "../lib/utils.js";
4
+ function o({
5
+ label: t,
6
+ className: a
7
+ }) {
8
+ return t ? /* @__PURE__ */ r(
9
+ "span",
10
+ {
11
+ "data-nvr-agent-badge": !0,
12
+ "data-tip": "Made by an AI assistant acting as this person, through Nivaro’s MCP server",
13
+ className: s(
14
+ "inline-flex shrink-0 items-center gap-1 rounded bg-slate-100 px-1.5 py-px text-[10.5px] font-medium leading-4 text-slate-600 dark:bg-muted dark:text-slate-300",
15
+ a
16
+ ),
17
+ children: [
18
+ /* @__PURE__ */ e(n, { className: "h-3 w-3", "aria-hidden": !0 }),
19
+ /* @__PURE__ */ e("span", { className: "max-w-[16ch] truncate", children: t })
20
+ ]
21
+ }
22
+ ) : null;
23
+ }
24
+ export {
25
+ o as AgentBadge
26
+ };
@@ -0,0 +1,198 @@
1
+ import { jsxs as s, jsx as n } from "react/jsx-runtime";
2
+ import { useQueryClient as E } from "@tanstack/react-query";
3
+ import { Bot as S } from "lucide-react";
4
+ import { useRef as N, useState as f, useEffect as _ } from "react";
5
+ import { useApiFetchConfig as I, useItemNavigation as j } from "../context.js";
6
+ import { userErrorMessage as Q } from "../lib/safe-error.js";
7
+ import { formatRelative as D, cn as L } from "../lib/utils.js";
8
+ import { Textarea as M } from "./ui/textarea.js";
9
+ function O() {
10
+ try {
11
+ const e = new URLSearchParams(window.location.search).get("focus") ?? "", o = /^question:([0-9a-f-]{36})/i.exec(e);
12
+ return o ? o[1].toLowerCase() : null;
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+ function A(e) {
18
+ const o = new Date(e).getTime() - Date.now();
19
+ if (o <= 0) return "Expired";
20
+ const a = Math.round(o / 6e4);
21
+ if (a < 60) return `Expires in ${a} min`;
22
+ const d = Math.round(a / 60);
23
+ return d < 48 ? `Expires in ${d} h` : `Expires in ${Math.round(d / 24)} days`;
24
+ }
25
+ function V({ questions: e }) {
26
+ const o = N(O()).current, [a, d] = f({});
27
+ if (e.length === 0 && Object.keys(a).length === 0) return null;
28
+ const l = e.filter((r) => !a[r.id]).length;
29
+ return /* @__PURE__ */ s(
30
+ "section",
31
+ {
32
+ className: "rounded-lg border border-nvr-cyan/30 bg-white dark:border-nvr-cyan/25 dark:bg-card",
33
+ "data-my-work-questions": !0,
34
+ "aria-labelledby": "my-work-questions-title",
35
+ children: [
36
+ /* @__PURE__ */ s("div", { className: "border-b border-slate-200 px-4 py-2.5 dark:border-border", children: [
37
+ /* @__PURE__ */ s(
38
+ "h2",
39
+ {
40
+ id: "my-work-questions-title",
41
+ className: "flex items-center gap-1.5 text-[13px] font-medium",
42
+ children: [
43
+ /* @__PURE__ */ n(S, { className: "h-3.5 w-3.5 text-[#0e7490] dark:text-[#67e8f9]", "aria-hidden": !0 }),
44
+ "Questions from assistants",
45
+ l > 0 && /* @__PURE__ */ n("span", { className: "rounded-full bg-nvr-cyan/10 px-1.5 text-[10.5px] font-semibold tabular-nums text-[#0e7490] dark:text-[#67e8f9]", children: l })
46
+ ]
47
+ }
48
+ ),
49
+ /* @__PURE__ */ n("p", { className: "text-[11px] text-muted-foreground", children: "An assistant is waiting for your answer before it carries on." })
50
+ ] }),
51
+ /* @__PURE__ */ s("ul", { className: "divide-y divide-slate-100 dark:divide-border/60", children: [
52
+ e.filter((r) => !a[r.id]).map((r) => {
53
+ var c, u;
54
+ return /* @__PURE__ */ n(
55
+ K,
56
+ {
57
+ q: r,
58
+ focused: o === r.id.toLowerCase(),
59
+ forMe: ((c = r.asked_for) == null ? void 0 : c.toLowerCase()) === ((u = r.recipient) == null ? void 0 : u.toLowerCase()),
60
+ onAnswered: (m) => d((i) => ({ ...i, [r.id]: m }))
61
+ },
62
+ r.id
63
+ );
64
+ }),
65
+ Object.entries(a).map(([r, c]) => /* @__PURE__ */ n(
66
+ "li",
67
+ {
68
+ className: "px-4 py-2 text-[12px] text-muted-foreground",
69
+ role: "status",
70
+ "data-my-work-question-done": r,
71
+ children: c
72
+ },
73
+ r
74
+ ))
75
+ ] })
76
+ ]
77
+ }
78
+ );
79
+ }
80
+ function K({
81
+ q: e,
82
+ focused: o,
83
+ forMe: a,
84
+ onAnswered: d
85
+ }) {
86
+ const { apiBase: l, authHeaders: r, credentials: c } = I(), { open: u } = j(), m = E(), [i, C] = f(""), [p, g] = f(null), [k, v] = f(null), b = N(null);
87
+ _(() => {
88
+ var x;
89
+ if (!o || !b.current) return;
90
+ const t = (x = window.matchMedia) == null ? void 0 : x.call(window, "(prefers-reduced-motion: reduce)").matches;
91
+ b.current.scrollIntoView({ block: "center", behavior: t ? "auto" : "smooth" });
92
+ }, [o]);
93
+ const y = async (t, x) => {
94
+ g(x), v(null);
95
+ try {
96
+ const h = await fetch(`${l}/agent-questions/${encodeURIComponent(e.id)}/answer`, {
97
+ method: "POST",
98
+ headers: { ...r, "content-type": "application/json" },
99
+ credentials: c,
100
+ body: JSON.stringify(t)
101
+ }), $ = await h.json().catch(() => ({}));
102
+ if (!h.ok) throw new Error($.error ?? "Could not send the answer");
103
+ d(`Sent to ${e.asked_by}: ${t.choice ?? t.answer}`), m.invalidateQueries({ queryKey: ["my-work"] }), m.invalidateQueries({ queryKey: ["notifications"] });
104
+ } catch (h) {
105
+ v(Q(h, "Could not send the answer"));
106
+ } finally {
107
+ g(null);
108
+ }
109
+ }, w = e.choices.length > 0;
110
+ return /* @__PURE__ */ s(
111
+ "li",
112
+ {
113
+ ref: b,
114
+ className: L(
115
+ "space-y-2 px-4 py-3 transition-colors duration-700",
116
+ o && "bg-nvr-cyan/5 dark:bg-nvr-cyan/10"
117
+ ),
118
+ "data-my-work-question": e.id,
119
+ children: [
120
+ /* @__PURE__ */ s("div", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-0.5", children: [
121
+ /* @__PURE__ */ n("span", { className: "text-[12px] font-medium text-slate-900 dark:text-foreground", children: e.asked_by }),
122
+ /* @__PURE__ */ s("span", { className: "text-[11px] text-muted-foreground", children: [
123
+ a ? "your assistant" : `for ${e.asked_for_name ?? "a colleague"}`,
124
+ " · asked",
125
+ " ",
126
+ D(e.created_at),
127
+ " · ",
128
+ A(e.expires_at)
129
+ ] }),
130
+ e.collection && e.item && /* @__PURE__ */ n(
131
+ "button",
132
+ {
133
+ type: "button",
134
+ onClick: () => u({ collection: e.collection, itemId: e.item }),
135
+ className: "text-[11px] text-[#0e7490] hover:underline dark:text-[#67e8f9]",
136
+ children: "Open the record"
137
+ }
138
+ )
139
+ ] }),
140
+ /* @__PURE__ */ n("p", { className: "whitespace-pre-wrap break-words text-[13px] text-slate-800 dark:text-slate-100", children: e.question }),
141
+ w && /* @__PURE__ */ s("fieldset", { className: "m-0 min-w-0 border-0 p-0", children: [
142
+ /* @__PURE__ */ n("legend", { className: "sr-only", children: "Choices" }),
143
+ /* @__PURE__ */ n("div", { className: "flex flex-wrap gap-1.5", children: e.choices.map((t) => /* @__PURE__ */ n(
144
+ "button",
145
+ {
146
+ type: "button",
147
+ disabled: p != null,
148
+ onClick: () => void y({ choice: t }, `c:${t}`),
149
+ className: "rounded-md border border-slate-200 bg-white px-2.5 py-1 text-[12px] font-medium text-slate-800 hover:border-nvr-cyan hover:bg-nvr-cyan/10 disabled:opacity-50 dark:border-border dark:bg-background dark:text-foreground",
150
+ "data-my-work-question-choice": t,
151
+ children: p === `c:${t}` ? "Sending…" : t
152
+ },
153
+ t
154
+ )) })
155
+ ] }),
156
+ (e.allow_text || !w) && /* @__PURE__ */ s(
157
+ "form",
158
+ {
159
+ className: "flex flex-col gap-1.5 sm:flex-row sm:items-end",
160
+ onSubmit: (t) => {
161
+ t.preventDefault(), i.trim() && y({ answer: i.trim() }, "text");
162
+ },
163
+ children: [
164
+ /* @__PURE__ */ n(
165
+ M,
166
+ {
167
+ value: i,
168
+ onChange: (t) => C(t.target.value),
169
+ placeholder: w ? "Or write your own answer…" : "Your answer…",
170
+ rows: 2,
171
+ maxLength: 4e3,
172
+ className: "min-h-[52px] flex-1 bg-white text-[12.5px] dark:bg-background",
173
+ "aria-label": `Answer to ${e.asked_by}`,
174
+ onKeyDown: (t) => {
175
+ t.key === "Enter" && (t.metaKey || t.ctrlKey) && i.trim() && (t.preventDefault(), y({ answer: i.trim() }, "text"));
176
+ }
177
+ }
178
+ ),
179
+ /* @__PURE__ */ n(
180
+ "button",
181
+ {
182
+ type: "submit",
183
+ disabled: !i.trim() || p != null,
184
+ className: "h-8 shrink-0 rounded-md bg-nvr-cyan px-3 text-[12px] font-medium text-white hover:bg-nvr-cyan/90 disabled:opacity-50",
185
+ children: p === "text" ? "Sending…" : "Send answer"
186
+ }
187
+ )
188
+ ]
189
+ }
190
+ ),
191
+ k && /* @__PURE__ */ n("p", { className: "text-[11.5px] text-red-600 dark:text-red-400", role: "alert", children: k })
192
+ ]
193
+ }
194
+ );
195
+ }
196
+ export {
197
+ V as AgentQuestionsCard
198
+ };