@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
@@ -1,23 +1,26 @@
1
- import { jsxs as d, jsx as o, Fragment as K } from "react/jsx-runtime";
2
- import { useQuery as te } from "@tanstack/react-query";
3
- import { Search as re, LayoutPanelTop as oe, Sigma as ae, Plus as Q, CopyPlus as ie, Check as ne } from "lucide-react";
4
- import { useState as W, useMemo as Y } from "react";
5
- import { useNivaroClient as se } from "../../context.js";
6
- import { get as le } from "../../lib/commands.js";
7
- import { HEADER_GROUP_KEY as R, isCanvasSlot as de } from "../../lib/layout-ops.js";
8
- import { listLayoutSlots as ce } from "../../lib/layout-slots.js";
9
- import { nextDisplayFormulaField as me } from "../../lib/placement-behaviour.js";
10
- import { titleCase as $, cn as X } from "../../lib/utils.js";
11
- import { sectionOp as ue, fieldSpot as j, slotSpot as pe, placeOp as z } from "./add-target.js";
12
- import { MeaningSuggestions as _e } from "./ai-forms/MeaningSuggestions.js";
13
- import { useAddDragSource as fe } from "./dnd/node.js";
14
- import { useFormFields as ge } from "./inspect/inspect-api.js";
15
- import { textMatcher as he } from "./nav/find.js";
16
- import { useOverviewFields as xe } from "./overview/overview-api.js";
17
- import { LibraryRows as ye } from "./reuse/LibraryRows.js";
1
+ import { jsxs as i, jsx as r, Fragment as G } from "react/jsx-runtime";
2
+ import { useQuery as se } from "@tanstack/react-query";
3
+ import { Search as ie, Undo2 as de, LayoutPanelTop as ce, ListPlus as me, Sigma as ue, Plus as Z, CopyPlus as pe, Check as fe } from "lucide-react";
4
+ import { useState as P, useMemo as q } from "react";
5
+ import { toast as ge } from "sonner";
6
+ import { useNivaroClient as he } from "../../context.js";
7
+ import { get as _e } from "../../lib/commands.js";
8
+ import { HEADER_GROUP_KEY as R, isCanvasSlot as xe } from "../../lib/layout-ops.js";
9
+ import { listLayoutSlots as ke } from "../../lib/layout-slots.js";
10
+ import { nextDisplayFormulaField as ye } from "../../lib/placement-behaviour.js";
11
+ import { titleCase as T, cn as ae } from "../../lib/utils.js";
12
+ import { sectionOp as be, fieldSpot as I, slotSpot as Ne, placeOp as ee } from "./add-target.js";
13
+ import { MeaningSuggestions as we } from "./ai-forms/MeaningSuggestions.js";
14
+ import { useAddDragSource as ve } from "./dnd/node.js";
15
+ import { parseFieldList as oe, placeListPlan as Ce } from "./field-list.js";
16
+ import { useFormFields as Pe } from "./inspect/inspect-api.js";
17
+ import { textMatcher as Fe } from "./nav/find.js";
18
+ import { useOverviewFields as De } from "./overview/overview-api.js";
19
+ import { putBackPlan as $e } from "./removed-log.js";
20
+ import { LibraryRows as Le } from "./reuse/LibraryRows.js";
18
21
  import { slotName as O } from "./slot-names.js";
19
- import { useFieldFillRates as ke, fillText as be } from "./usage/usage-api.js";
20
- const we = [
22
+ import { useFieldFillRates as Se, fillText as Ae } from "./usage/usage-api.js";
23
+ const Oe = [
21
24
  "__pipeline__",
22
25
  "__comments__",
23
26
  "__tasks__",
@@ -27,7 +30,7 @@ const we = [
27
30
  "__owners__",
28
31
  "__pdf__",
29
32
  "__subtitle__"
30
- ], J = {
33
+ ], te = {
31
34
  __pipeline__: "State track and actions",
32
35
  __comments__: "Notes and replies",
33
36
  __tasks__: "To-dos on this record",
@@ -37,19 +40,19 @@ const we = [
37
40
  __owners__: "Who owns it at each step",
38
41
  __pdf__: "Generate and download a PDF",
39
42
  __subtitle__: "A line of values under the title"
40
- }, Ne = ["review_list", "rollup"];
41
- function V(a) {
43
+ }, Re = ["review_list", "rollup"];
44
+ function re(o) {
42
45
  return {
43
- widget_id: a.id,
44
- input_bindings: Ne.includes(a.widget_type) ? [{ key: "record_id", binding_type: "item_field", binding_value: "id" }] : []
46
+ widget_id: o.id,
47
+ input_bindings: Re.includes(o.widget_type) ? [{ key: "record_id", binding_type: "item_field", binding_value: "id" }] : []
45
48
  };
46
49
  }
47
- function ve(a) {
48
- const n = a.interface ?? "";
49
- if (n.includes("o2m") || n === "list-o2m" || n === "inline-grid") return "Grid";
50
- if (n.includes("m2m") || n.includes("m2a")) return "Several records";
51
- if (n.includes("m2o")) return "Record";
52
- switch (a.type) {
50
+ function Te(o) {
51
+ const s = o.interface ?? "";
52
+ if (s.includes("o2m") || s === "list-o2m" || s === "inline-grid") return "Grid";
53
+ if (s.includes("m2m") || s.includes("m2a")) return "Several records";
54
+ if (s.includes("m2o")) return "Record";
55
+ switch (o.type) {
53
56
  case "string":
54
57
  case "uuid":
55
58
  return "Text";
@@ -72,132 +75,137 @@ function ve(a) {
72
75
  case "alias":
73
76
  return "Group";
74
77
  default:
75
- return a.type ? $(a.type) : "";
78
+ return o.type ? T(o.type) : "";
76
79
  }
77
80
  }
78
- const Ce = "h-8 w-full rounded-md border border-slate-200 bg-white pl-7 pr-2.5 text-[12.5px] text-slate-800 outline-none placeholder:text-slate-400 focus:border-nvr-cyan dark:border-border dark:bg-background dark:text-foreground dark:placeholder:text-muted-foreground", N = "px-2 pb-1 pt-3 text-[11.5px] font-semibold text-slate-500 dark:text-muted-foreground";
79
- function M({ children: a }) {
80
- return /* @__PURE__ */ d("span", { className: "inline-flex shrink-0 items-center gap-0.5 text-[11px] font-medium text-[#0089ad] dark:text-nvr-cyan", children: [
81
- /* @__PURE__ */ o(ne, { className: "h-3 w-3" }),
82
- a
81
+ const je = "h-8 w-full rounded-md border border-slate-200 bg-white pl-7 pr-2.5 text-[12.5px] text-slate-800 outline-none placeholder:text-slate-400 focus:border-nvr-cyan dark:border-border dark:bg-background dark:text-foreground dark:placeholder:text-muted-foreground", y = "px-2 pb-1 pt-3 text-[11.5px] font-semibold text-slate-500 dark:text-muted-foreground";
82
+ function K({ children: o }) {
83
+ return /* @__PURE__ */ i("span", { className: "inline-flex shrink-0 items-center gap-0.5 text-[11px] font-medium text-[#0089ad] dark:text-nvr-cyan", children: [
84
+ /* @__PURE__ */ r(fe, { className: "h-3 w-3" }),
85
+ o
83
86
  ] });
84
87
  }
85
- function y({
86
- title: a,
87
- sub: n,
88
- aside: c,
88
+ function x({
89
+ title: o,
90
+ sub: s,
91
+ aside: m,
89
92
  onClick: u,
90
- attrs: l,
91
- extra: g,
92
- drag: _ = null
93
+ attrs: d,
94
+ extra: f,
95
+ drag: h = null
93
96
  }) {
94
- const p = fe(_), t = /* @__PURE__ */ d(
97
+ const c = ve(h), t = /* @__PURE__ */ i(
95
98
  "button",
96
99
  {
97
100
  type: "button",
98
- ...p.props,
101
+ ...c.props,
99
102
  onClick: () => {
100
- p.clickBlocked() || u();
103
+ c.clickBlocked() || u();
101
104
  },
102
- ...l,
103
- className: X(
105
+ ...d,
106
+ className: ae(
104
107
  "group flex w-full min-w-0 items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-muted",
105
- p.dragging && "opacity-40"
108
+ c.dragging && "opacity-40"
106
109
  ),
107
110
  children: [
108
- /* @__PURE__ */ d("span", { className: "flex min-w-0 flex-1 flex-col", children: [
109
- /* @__PURE__ */ o("span", { className: "truncate text-[12.5px] font-medium text-slate-900 dark:text-foreground", children: a }),
110
- n && /* @__PURE__ */ o("span", { className: "truncate text-[11.5px] text-slate-500 dark:text-muted-foreground", children: n })
111
+ /* @__PURE__ */ i("span", { className: "flex min-w-0 flex-1 flex-col", children: [
112
+ /* @__PURE__ */ r("span", { className: "truncate text-[12.5px] font-medium text-slate-900 dark:text-foreground", children: o }),
113
+ s && /* @__PURE__ */ r("span", { className: "truncate text-[11.5px] text-slate-500 dark:text-muted-foreground", children: s })
111
114
  ] }),
112
- c
115
+ m
113
116
  ]
114
117
  }
115
118
  );
116
- return g ? /* @__PURE__ */ d("div", { className: "flex items-center gap-0.5", children: [
119
+ return f ? /* @__PURE__ */ i("div", { className: "flex items-center gap-0.5", children: [
117
120
  t,
118
- g
121
+ f
119
122
  ] }) : t;
120
123
  }
121
- function Ye({
122
- bundle: a,
123
- collection: n,
124
- selected: c,
124
+ function dt({
125
+ bundle: o,
126
+ collection: s,
127
+ selected: m,
125
128
  apply: u,
126
- onSelect: l
129
+ onSelect: d,
130
+ removed: f = []
127
131
  }) {
128
- const g = se(), [_, p] = W(""), [t, s] = W("form"), { data: h = [] } = xe(n), { data: D } = ke(n), { data: Z = [], error: T } = te({
132
+ const h = he(), [c, t] = P(""), [l, p] = P("form"), { data: b = [] } = De(s), { data: j } = Se(s), { data: le = [], error: E } = se({
129
133
  queryKey: ["layout-editor", "widgets"],
130
- queryFn: () => g.request(le("/widgets-internal")).then((e) => e.data ?? []),
134
+ queryFn: () => h.request(_e("/widgets-internal")).then((e) => e.data ?? []),
131
135
  staleTime: 6e4,
132
136
  retry: !1
133
- }), [v, L] = W(null), f = he(_), P = Y(() => {
137
+ }), [F, B] = P(null), [W, N] = P(null), [D, H] = P(null), _ = Fe(c), M = q(() => {
134
138
  const e = /* @__PURE__ */ new Map();
135
- for (const r of a.placements) e.set(r.field, [...e.get(r.field) ?? [], r]);
139
+ for (const a of o.placements) e.set(a.field, [...e.get(a.field) ?? [], a]);
136
140
  return e;
137
- }, [a.placements]), C = (e) => (P.get(e) ?? []).find((r) => r.group_key !== R), E = (e) => (P.get(e) ?? []).find((r) => r.group_key === R), S = (e) => e.group_key === R ? { kind: "header", field: e.field } : {
141
+ }, [o.placements]), $ = (e) => (M.get(e) ?? []).find((a) => a.group_key !== R), U = (e) => (M.get(e) ?? []).find((a) => a.group_key === R), L = (e) => e.group_key === R ? { kind: "header", field: e.field } : {
138
142
  kind: e.field.startsWith("__") ? "slot" : "field",
139
143
  field: e.field,
140
144
  group_key: e.group_key
141
- }, B = (e, r, i) => {
142
- const m = t === "header" ? j(a, c, "header") : de({ field: e, group_key: null }) ? pe(a, c) : e === "__subtitle__" ? { group_key: null, index: 0 } : j(a, c);
143
- u([z(e, m, i)], { label: `Add ${r}` }), l(S({ field: e, group_key: m.group_key }));
144
- }, F = (e, r, i, m) => i ? null : {
145
+ }, z = (e, a, n) => {
146
+ const g = l === "header" ? I(o, m, "header") : xe({ field: e, group_key: null }) ? Ne(o, m) : e === "__subtitle__" ? { group_key: null, index: 0 } : I(o, m);
147
+ u([ee(e, g, n)], { label: `Add ${a}` }), d(L({ field: e, group_key: g.group_key }));
148
+ }, S = (e, a, n, g) => n ? null : {
145
149
  field: e,
146
- label: r,
147
- patch: m,
148
- to: t,
149
- onAdded: (w) => {
150
- const x = w[0];
151
- (x == null ? void 0 : x.op) === "place" && l(S({ field: e, group_key: x.group_key }));
150
+ label: a,
151
+ patch: g,
152
+ to: l,
153
+ onAdded: (C) => {
154
+ const k = C[0];
155
+ (k == null ? void 0 : k.op) === "place" && d(L({ field: e, group_key: k.group_key }));
152
156
  }
153
- }, A = (e, r, i) => {
154
- L(null);
155
- const m = t === "header" ? E(e) : C(e);
156
- m ? l(S(m)) : B(e, r, i);
157
- }, ee = (e, r) => {
158
- var m;
159
- const i = j(a, c);
160
- if ((P.get(e) ?? []).some((w) => w.group_key === i.group_key)) {
161
- const w = i.group_key === null ? "Ungrouped" : ((m = a.groups.find((x) => x.key === i.group_key)) == null ? void 0 : m.label) ?? i.group_key;
162
- L({
157
+ }, A = (e, a, n) => {
158
+ B(null);
159
+ const g = l === "header" ? U(e) : $(e);
160
+ g ? d(L(g)) : z(e, a, n);
161
+ }, ne = (e, a) => {
162
+ var g;
163
+ const n = I(o, m);
164
+ if ((M.get(e) ?? []).some((C) => C.group_key === n.group_key)) {
165
+ const C = n.group_key === null ? "Ungrouped" : ((g = o.groups.find((k) => k.key === n.group_key)) == null ? void 0 : g.label) ?? n.group_key;
166
+ B({
163
167
  field: e,
164
- text: `${r} is already in ${w}. Select another section first.`
168
+ text: `${a} is already in ${C}. Select another section first.`
165
169
  });
166
170
  return;
167
171
  }
168
- L(null), u([z(e, i)], { label: `Add another ${r}` }), l(S({ field: e, group_key: i.group_key }));
169
- }, { data: G = [] } = ge(n), I = Y(
170
- () => Se(a, G, h),
171
- [a, G, h]
172
- ).filter((e) => f(e.title, e.field)).slice(0, 8), U = h.filter((e) => e.field && !e.field.startsWith("__")).map((e) => ({ ...e, title: e.label || $(e.field) })).filter((e) => f(e.title, e.field)).sort((e, r) => e.title.localeCompare(r.title)), q = [...we, ...ce().map((e) => `__ext_${e}__`)].filter(
173
- (e) => t === "header" ? e === "__owners__" : !0
174
- ).filter((e) => f(O(e), J[e])), H = Z.filter((e) => f(e.name, e.widget_type)), k = ue(a, c), b = k.op === "group_create" ? k.label.replace(/^New /, "") : "";
175
- return /* @__PURE__ */ d("div", { "data-editor-add": "", className: "flex flex-col px-2 pb-4", children: [
176
- /* @__PURE__ */ d("div", { className: "sticky top-0 z-10 flex flex-col gap-2 bg-white px-1 pb-1 pt-2 dark:bg-card", children: [
177
- /* @__PURE__ */ d("div", { className: "relative", children: [
178
- /* @__PURE__ */ o(re, { className: "pointer-events-none absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-slate-400" }),
179
- /* @__PURE__ */ o(
172
+ B(null), u([ee(e, n)], { label: `Add another ${a}` }), d(L({ field: e, group_key: n.group_key }));
173
+ }, { data: Q = [] } = Pe(s), Y = q(
174
+ () => Ee(o, Q, b),
175
+ [o, Q, b]
176
+ ).filter((e) => _(e.title, e.field)).slice(0, 8), J = b.filter((e) => e.field && !e.field.startsWith("__")).map((e) => ({ ...e, title: e.label || T(e.field) })).filter((e) => _(e.title, e.field)).sort((e, a) => e.title.localeCompare(a.title)), V = [...Oe, ...ke().map((e) => `__ext_${e}__`)].filter(
177
+ (e) => l === "header" ? e === "__owners__" : !0
178
+ ).filter((e) => _(O(e), te[e])), X = le.filter((e) => _(e.name, e.widget_type)), w = be(o, m), v = w.op === "group_create" ? w.label.replace(/^New /, "") : "";
179
+ return /* @__PURE__ */ i("div", { "data-editor-add": "", className: "flex flex-col px-2 pb-4", children: [
180
+ /* @__PURE__ */ i("div", { className: "sticky top-0 z-10 flex flex-col gap-2 bg-white px-1 pb-1 pt-2 dark:bg-card", children: [
181
+ /* @__PURE__ */ i("div", { className: "relative", children: [
182
+ /* @__PURE__ */ r(ie, { className: "pointer-events-none absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-slate-400" }),
183
+ /* @__PURE__ */ r(
180
184
  "input",
181
185
  {
182
- value: _,
183
- onChange: (e) => p(e.target.value),
186
+ value: c,
187
+ onChange: (e) => t(e.target.value),
188
+ onPaste: (e) => {
189
+ const a = e.clipboardData.getData("text/plain");
190
+ /[\n\r,;\t]/.test(a) && oe(a).length > 1 && (e.preventDefault(), N(a));
191
+ },
184
192
  placeholder: "Find a field, panel or widget",
185
193
  "aria-label": "Find something to add",
186
- className: Ce
194
+ className: je
187
195
  }
188
196
  )
189
197
  ] }),
190
- /* @__PURE__ */ d("div", { className: "flex items-center gap-1 text-[12px] text-slate-500 dark:text-muted-foreground", children: [
191
- /* @__PURE__ */ o("span", { className: "mr-1", children: "Add to" }),
192
- ["form", "header"].map((e) => /* @__PURE__ */ o(
198
+ /* @__PURE__ */ i("div", { className: "flex items-center gap-1 text-[12px] text-slate-500 dark:text-muted-foreground", children: [
199
+ /* @__PURE__ */ r("span", { className: "mr-1", children: "Add to" }),
200
+ ["form", "header"].map((e) => /* @__PURE__ */ r(
193
201
  "button",
194
202
  {
195
203
  type: "button",
196
- "aria-pressed": t === e,
197
- onClick: () => s(e),
198
- className: X(
204
+ "aria-pressed": l === e,
205
+ onClick: () => p(e),
206
+ className: ae(
199
207
  "rounded-md px-2 py-0.5 font-medium transition-colors",
200
- t === e ? "bg-accent text-slate-900 dark:text-foreground" : "hover:bg-muted hover:text-slate-800 dark:hover:text-foreground"
208
+ l === e ? "bg-accent text-slate-900 dark:text-foreground" : "hover:bg-muted hover:text-slate-800 dark:hover:text-foreground"
201
209
  ),
202
210
  children: e === "form" ? "Form" : "Header strip"
203
211
  },
@@ -205,30 +213,93 @@ function Ye({
205
213
  ))
206
214
  ] })
207
215
  ] }),
208
- t === "form" && f(b, "section", "tab", "step") && /* @__PURE__ */ d(K, { children: [
209
- /* @__PURE__ */ o("p", { className: N, children: "Layout" }),
210
- /* @__PURE__ */ o(
211
- y,
216
+ f.length > 0 && !c.trim() && /* @__PURE__ */ i(G, { children: [
217
+ /* @__PURE__ */ r("p", { className: y, children: "Recently removed" }),
218
+ f.slice(0, 8).map((e) => {
219
+ var a;
220
+ return /* @__PURE__ */ i("div", { children: [
221
+ /* @__PURE__ */ r(
222
+ x,
223
+ {
224
+ title: e.piece.kind === "field" ? ((a = b.find(
225
+ (n) => e.piece.kind === "field" && n.field === e.piece.field
226
+ )) == null ? void 0 : a.label) ?? e.label : e.label,
227
+ sub: `${e.where} · ${e.how}`,
228
+ attrs: { "data-removed-entry": e.id },
229
+ aside: /* @__PURE__ */ i("span", { className: "inline-flex shrink-0 items-center gap-1 text-[11.5px] font-medium text-slate-500 group-hover:text-slate-800 dark:text-muted-foreground dark:group-hover:text-foreground", children: [
230
+ /* @__PURE__ */ r(de, { className: "h-3.5 w-3.5" }),
231
+ "Put back"
232
+ ] }),
233
+ onClick: () => {
234
+ const n = $e(o, e, m);
235
+ if (!n.ok) {
236
+ H({ id: e.id, text: n.reason });
237
+ return;
238
+ }
239
+ H(null), u(n.ops, { label: n.label }), n.select && d(n.select), n.notes.length && ge.success(n.label, { description: n.notes.join(". ") });
240
+ }
241
+ }
242
+ ),
243
+ (D == null ? void 0 : D.id) === e.id && /* @__PURE__ */ r(
244
+ "p",
245
+ {
246
+ role: "status",
247
+ className: "px-2 pb-1 text-[11.5px] text-amber-700 dark:text-amber-300",
248
+ children: D.text
249
+ }
250
+ )
251
+ ] }, e.id);
252
+ })
253
+ ] }),
254
+ W !== null && /* @__PURE__ */ r(
255
+ Be,
256
+ {
257
+ bundle: o,
258
+ text: W,
259
+ onText: N,
260
+ fields: b,
261
+ selected: m,
262
+ to: l,
263
+ onPlace: (e, a, n) => {
264
+ u(e, { label: a }), n && d(n), N(null);
265
+ },
266
+ onClose: () => N(null)
267
+ }
268
+ ),
269
+ l === "form" && _(v, "section", "tab", "step") && /* @__PURE__ */ i(G, { children: [
270
+ /* @__PURE__ */ r("p", { className: y, children: "Layout" }),
271
+ /* @__PURE__ */ r(
272
+ x,
212
273
  {
213
- title: b.charAt(0).toUpperCase() + b.slice(1),
214
- sub: `A new ${b.toLowerCase()} after the selection`,
274
+ title: v.charAt(0).toUpperCase() + v.slice(1),
275
+ sub: `A new ${v.toLowerCase()} after the selection`,
215
276
  attrs: { "data-add-section": "" },
216
- aside: /* @__PURE__ */ o(oe, { className: "h-3.5 w-3.5 text-slate-400" }),
277
+ aside: /* @__PURE__ */ r(ce, { className: "h-3.5 w-3.5 text-slate-400" }),
217
278
  onClick: () => {
218
- u([k], { label: `Add ${b.toLowerCase()}` }), k.op === "group_create" && l({ kind: "group", key: k.key });
279
+ u([w], { label: `Add ${v.toLowerCase()}` }), w.op === "group_create" && d({ kind: "group", key: w.key });
219
280
  }
220
281
  }
221
282
  )
222
283
  ] }),
223
- t === "form" && !["table", "file"].includes(String(a.layout.layout_type ?? "grouped")) && f("Display formula", "formula calculation remaining total") && /* @__PURE__ */ o(
224
- y,
284
+ W === null && _("Place a list of fields", "paste names list several") && /* @__PURE__ */ r(
285
+ x,
286
+ {
287
+ title: "Place a list of fields",
288
+ sub: "Paste names or keys, one per line or with commas",
289
+ attrs: { "data-add-list-open": "" },
290
+ aside: /* @__PURE__ */ r(me, { className: "h-3.5 w-3.5 text-slate-400" }),
291
+ onClick: () => N("")
292
+ }
293
+ ),
294
+ l === "form" && !["table", "file"].includes(String(o.layout.layout_type ?? "grouped")) && _("Display formula", "formula calculation remaining total") && /* @__PURE__ */ r(
295
+ x,
225
296
  {
226
297
  title: "Display formula",
227
298
  sub: "A read-only figure worked out from fields on the form, never saved",
228
299
  attrs: { "data-add-formula": "" },
229
- aside: /* @__PURE__ */ o(ae, { className: "h-3.5 w-3.5 text-slate-400" }),
230
- onClick: () => B(
231
- me(a.placements.map((e) => e.field)),
300
+ aside: /* @__PURE__ */ r(ue, { className: "h-3.5 w-3.5 text-slate-400" }),
301
+ onClick: () => z(
302
+ ye(o.placements.map((e) => e.field)),
232
303
  "a display formula",
233
304
  {
234
305
  overrides: { label: "Formula", display_formula: { expr: "", format: "" } }
@@ -236,75 +307,75 @@ function Ye({
236
307
  )
237
308
  }
238
309
  ),
239
- t === "form" && !_.trim() && /* @__PURE__ */ o(_e, { bundle: a, collection: n, apply: u }),
240
- t === "form" && I.length > 0 && /* @__PURE__ */ d(K, { children: [
241
- /* @__PURE__ */ o("p", { className: N, children: "On other forms" }),
242
- I.map((e) => /* @__PURE__ */ o(
243
- y,
310
+ l === "form" && !c.trim() && /* @__PURE__ */ r(we, { bundle: o, collection: s, apply: u }),
311
+ l === "form" && Y.length > 0 && /* @__PURE__ */ i(G, { children: [
312
+ /* @__PURE__ */ r("p", { className: y, children: "On other forms" }),
313
+ Y.map((e) => /* @__PURE__ */ r(
314
+ x,
244
315
  {
245
316
  title: e.title,
246
317
  sub: `On ${e.count} of ${e.of} other forms · ${e.names.join(", ")}`,
247
318
  attrs: { "data-add-suggested": e.field },
248
- aside: /* @__PURE__ */ o(Q, { className: "h-3.5 w-3.5 shrink-0 text-slate-400 opacity-0 group-hover:opacity-100" }),
319
+ aside: /* @__PURE__ */ r(Z, { className: "h-3.5 w-3.5 shrink-0 text-slate-400 opacity-0 group-hover:opacity-100" }),
249
320
  onClick: () => A(e.field, e.title),
250
- drag: F(e.field, e.title, null)
321
+ drag: S(e.field, e.title, null)
251
322
  },
252
323
  e.field
253
324
  ))
254
325
  ] }),
255
- t === "form" && /* @__PURE__ */ o(
256
- ye,
326
+ l === "form" && /* @__PURE__ */ r(
327
+ Le,
257
328
  {
258
- bundle: a,
259
- collection: n,
260
- selected: c,
329
+ bundle: o,
330
+ collection: s,
331
+ selected: m,
261
332
  apply: u,
262
- onSelect: l,
263
- matches: f
333
+ onSelect: d,
334
+ matches: _
264
335
  }
265
336
  ),
266
- /* @__PURE__ */ o("p", { className: N, children: "Fields" }),
267
- U.map((e) => {
268
- const r = t === "header" ? E(e.field) : C(e.field);
269
- return /* @__PURE__ */ d("div", { children: [
270
- /* @__PURE__ */ o(
271
- y,
337
+ /* @__PURE__ */ r("p", { className: y, children: "Fields" }),
338
+ J.map((e) => {
339
+ const a = l === "header" ? U(e.field) : $(e.field);
340
+ return /* @__PURE__ */ i("div", { children: [
341
+ /* @__PURE__ */ r(
342
+ x,
272
343
  {
273
344
  title: e.title,
274
- sub: [e.field, ve(e), D ? be(D.pct.get(e.field), D.total) : null].filter(Boolean).join(" · "),
275
- attrs: { "data-add-field": e.field, "data-on-form": r ? "true" : void 0 },
276
- aside: r ? /* @__PURE__ */ o(M, { children: t === "header" ? "in header" : "on this form" }) : /* @__PURE__ */ o(Q, { className: "h-3.5 w-3.5 shrink-0 text-slate-400 opacity-0 group-hover:opacity-100" }),
345
+ sub: [e.field, Te(e), j ? Ae(j.pct.get(e.field), j.total) : null].filter(Boolean).join(" · "),
346
+ attrs: { "data-add-field": e.field, "data-on-form": a ? "true" : void 0 },
347
+ aside: a ? /* @__PURE__ */ r(K, { children: l === "header" ? "in header" : "on this form" }) : /* @__PURE__ */ r(Z, { className: "h-3.5 w-3.5 shrink-0 text-slate-400 opacity-0 group-hover:opacity-100" }),
277
348
  onClick: () => A(e.field, e.title),
278
- drag: F(e.field, e.title, r),
279
- extra: r && t === "form" ? /* @__PURE__ */ o(
349
+ drag: S(e.field, e.title, a),
350
+ extra: a && l === "form" ? /* @__PURE__ */ r(
280
351
  "button",
281
352
  {
282
353
  type: "button",
283
354
  "aria-label": `Add another copy of ${e.title}`,
284
355
  "data-add-copy": e.field,
285
356
  "data-tip": "Add another copy after the selection",
286
- onClick: () => ee(e.field, e.title),
357
+ onClick: () => ne(e.field, e.title),
287
358
  className: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-slate-400 transition-colors hover:bg-muted hover:text-slate-700 dark:hover:text-foreground",
288
- children: /* @__PURE__ */ o(ie, { className: "h-3.5 w-3.5" })
359
+ children: /* @__PURE__ */ r(pe, { className: "h-3.5 w-3.5" })
289
360
  }
290
361
  ) : null
291
362
  }
292
363
  ),
293
- (v == null ? void 0 : v.field) === e.field && /* @__PURE__ */ o(
364
+ (F == null ? void 0 : F.field) === e.field && /* @__PURE__ */ r(
294
365
  "p",
295
366
  {
296
367
  role: "status",
297
368
  "data-add-notice": "",
298
369
  className: "px-2 pb-1 text-[11.5px] text-amber-700 dark:text-amber-300",
299
- children: v.text
370
+ children: F.text
300
371
  }
301
372
  )
302
373
  ] }, e.field);
303
374
  }),
304
- !U.length && /* @__PURE__ */ o("p", { className: "px-2 py-1.5 text-[12px] text-slate-500 dark:text-muted-foreground", children: "No fields match." }),
305
- q.length > 0 && /* @__PURE__ */ o("p", { className: N, children: "Panels" }),
306
- q.map((e) => {
307
- const r = t === "header" ? E(e) : C(e), i = e === "__subtitle__" ? {
375
+ !J.length && /* @__PURE__ */ r("p", { className: "px-2 py-1.5 text-[12px] text-slate-500 dark:text-muted-foreground", children: "No fields match." }),
376
+ V.length > 0 && /* @__PURE__ */ r("p", { className: y, children: "Panels" }),
377
+ V.map((e) => {
378
+ const a = l === "header" ? U(e) : $(e), n = e === "__subtitle__" ? {
308
379
  input_bindings: [
309
380
  {
310
381
  key: "__subtitle_config__",
@@ -313,64 +384,150 @@ function Ye({
313
384
  }
314
385
  ]
315
386
  } : void 0;
316
- return /* @__PURE__ */ o(
317
- y,
387
+ return /* @__PURE__ */ r(
388
+ x,
318
389
  {
319
390
  title: O(e),
320
- sub: J[e] ?? "Extension panel",
321
- attrs: { "data-add-slot": e, "data-on-form": r ? "true" : void 0 },
322
- aside: r ? /* @__PURE__ */ o(M, { children: "on this form" }) : null,
323
- onClick: () => A(e, O(e), i),
324
- drag: e === "__subtitle__" ? null : F(e, O(e), r)
391
+ sub: te[e] ?? "Extension panel",
392
+ attrs: { "data-add-slot": e, "data-on-form": a ? "true" : void 0 },
393
+ aside: a ? /* @__PURE__ */ r(K, { children: "on this form" }) : null,
394
+ onClick: () => A(e, O(e), n),
395
+ drag: e === "__subtitle__" ? null : S(e, O(e), a)
325
396
  },
326
397
  e
327
398
  );
328
399
  }),
329
- t === "form" && (H.length > 0 || T) && /* @__PURE__ */ o("p", { className: N, children: "Widgets" }),
330
- t === "form" && T && /* @__PURE__ */ d("p", { role: "alert", className: "px-2 py-1.5 text-[12px] text-red-700 dark:text-red-300", children: [
400
+ l === "form" && (X.length > 0 || E) && /* @__PURE__ */ r("p", { className: y, children: "Widgets" }),
401
+ l === "form" && E && /* @__PURE__ */ i("p", { role: "alert", className: "px-2 py-1.5 text-[12px] text-red-700 dark:text-red-300", children: [
331
402
  "Widgets could not be loaded: ",
332
- T.message
403
+ E.message
333
404
  ] }),
334
- t === "form" && H.map((e) => {
335
- const r = `__widget_${e.id}__`, i = C(r);
336
- return /* @__PURE__ */ o(
337
- y,
405
+ l === "form" && X.map((e) => {
406
+ const a = `__widget_${e.id}__`, n = $(a);
407
+ return /* @__PURE__ */ r(
408
+ x,
338
409
  {
339
410
  title: e.name,
340
- sub: $(e.widget_type),
341
- attrs: { "data-add-widget": String(e.id), "data-on-form": i ? "true" : void 0 },
342
- aside: i ? /* @__PURE__ */ o(M, { children: "on this form" }) : null,
343
- onClick: () => A(r, e.name, V(e)),
344
- drag: F(r, e.name, i, V(e))
411
+ sub: T(e.widget_type),
412
+ attrs: { "data-add-widget": String(e.id), "data-on-form": n ? "true" : void 0 },
413
+ aside: n ? /* @__PURE__ */ r(K, { children: "on this form" }) : null,
414
+ onClick: () => A(a, e.name, re(e)),
415
+ drag: S(a, e.name, n, re(e))
345
416
  },
346
417
  e.id
347
418
  );
348
419
  })
349
420
  ] });
350
421
  }
351
- function Se(a, n, c) {
352
- const u = String(a.layout.layout_type || "grouped"), l = n.filter(
353
- (t) => Number(t.layout_id) !== Number(a.layout.id) && t.layout_type === u
422
+ function Ee(o, s, m) {
423
+ const u = String(o.layout.layout_type || "grouped"), d = s.filter(
424
+ (t) => Number(t.layout_id) !== Number(o.layout.id) && t.layout_type === u
354
425
  );
355
- if (!l.length) return [];
356
- const g = new Set(
357
- a.placements.filter((t) => t.group_key !== R).map((t) => t.field)
358
- ), _ = new Map(c.map((t) => [t.field, t])), p = /* @__PURE__ */ new Map();
359
- for (const t of l)
360
- for (const s of t.fields)
361
- !g.has(s) && _.has(s) && p.set(s, [...p.get(s) ?? [], t.name]);
362
- return [...p.entries()].map(([t, s]) => {
363
- var h;
426
+ if (!d.length) return [];
427
+ const f = new Set(
428
+ o.placements.filter((t) => t.group_key !== R).map((t) => t.field)
429
+ ), h = new Map(m.map((t) => [t.field, t])), c = /* @__PURE__ */ new Map();
430
+ for (const t of d)
431
+ for (const l of t.fields)
432
+ !f.has(l) && h.has(l) && c.set(l, [...c.get(l) ?? [], t.name]);
433
+ return [...c.entries()].map(([t, l]) => {
434
+ var p;
364
435
  return {
365
436
  field: t,
366
- title: ((h = _.get(t)) == null ? void 0 : h.label) || $(t),
367
- count: s.length,
368
- of: l.length,
369
- names: s.slice(0, 3).concat(s.length > 3 ? [`${s.length - 3} more`] : [])
437
+ title: ((p = h.get(t)) == null ? void 0 : p.label) || T(t),
438
+ count: l.length,
439
+ of: d.length,
440
+ names: l.slice(0, 3).concat(l.length > 3 ? [`${l.length - 3} more`] : [])
370
441
  };
371
- }).sort((t, s) => s.count - t.count || t.title.localeCompare(s.title));
442
+ }).sort((t, l) => l.count - t.count || t.title.localeCompare(l.title));
443
+ }
444
+ function Be({
445
+ bundle: o,
446
+ text: s,
447
+ onText: m,
448
+ fields: u,
449
+ selected: d,
450
+ to: f,
451
+ onPlace: h,
452
+ onClose: c
453
+ }) {
454
+ const t = q(
455
+ () => Ce(o, s, u, d, f),
456
+ [o, s, u, d, f]
457
+ ), l = oe(s).length;
458
+ return /* @__PURE__ */ i(
459
+ "div",
460
+ {
461
+ "data-add-list": "",
462
+ className: "mx-1 mt-2 rounded-lg border border-slate-200 bg-slate-50/60 p-2 dark:border-border dark:bg-muted/30",
463
+ children: [
464
+ /* @__PURE__ */ i("label", { className: "block text-[11.5px] font-semibold text-slate-600 dark:text-muted-foreground", children: [
465
+ "Field names, keys or labels",
466
+ /* @__PURE__ */ r(
467
+ "textarea",
468
+ {
469
+ autoFocus: !0,
470
+ value: s,
471
+ onChange: (p) => m(p.target.value),
472
+ onKeyDown: (p) => {
473
+ p.key === "Escape" && (p.stopPropagation(), c()), p.key === "Enter" && (p.metaKey || p.ctrlKey) && t.ok && (p.preventDefault(), h(t.ops, t.label, t.select));
474
+ },
475
+ rows: 4,
476
+ placeholder: `PO number
477
+ Vendor
478
+ status, due_date`,
479
+ className: "mt-1 block w-full resize-y rounded-md border border-slate-200 bg-white px-2 py-1.5 font-normal text-[12.5px] text-slate-800 outline-none placeholder:text-slate-400 focus:border-nvr-cyan dark:border-border dark:bg-background dark:text-foreground dark:placeholder:text-muted-foreground"
480
+ }
481
+ )
482
+ ] }),
483
+ l > 0 && /* @__PURE__ */ i("div", { role: "status", className: "mt-1.5 space-y-0.5 text-[11.5px] leading-snug", children: [
484
+ /* @__PURE__ */ i("p", { className: "m-0 text-slate-600 dark:text-muted-foreground", children: [
485
+ t.placed.length,
486
+ " of ",
487
+ l,
488
+ " will be placed",
489
+ t.ok ? ` · ${t.label.replace(/^Place \d+ fields? /, "")}` : ""
490
+ ] }),
491
+ t.unmatched.length > 0 && /* @__PURE__ */ i("p", { className: "m-0 text-amber-700 dark:text-amber-300", "data-add-list-unmatched": "", children: [
492
+ "No field matches: ",
493
+ t.unmatched.join(", ")
494
+ ] }),
495
+ t.already.length > 0 && /* @__PURE__ */ i("p", { className: "m-0 text-slate-500 dark:text-muted-foreground", children: [
496
+ "Already there: ",
497
+ t.already.join(", ")
498
+ ] }),
499
+ !t.ok && t.placed.length === 0 && t.unmatched.length === 0 && /* @__PURE__ */ r("p", { className: "m-0 text-slate-500 dark:text-muted-foreground", children: t.reason })
500
+ ] }),
501
+ /* @__PURE__ */ i("div", { className: "mt-2 flex items-center justify-end gap-1.5", children: [
502
+ /* @__PURE__ */ r(
503
+ "button",
504
+ {
505
+ type: "button",
506
+ onClick: c,
507
+ className: "inline-flex h-7 items-center rounded-md px-2.5 text-[12px] font-medium text-slate-600 hover:bg-muted dark:text-muted-foreground dark:hover:text-foreground",
508
+ children: "Cancel"
509
+ }
510
+ ),
511
+ /* @__PURE__ */ r(
512
+ "button",
513
+ {
514
+ type: "button",
515
+ "data-add-list-place": "",
516
+ disabled: !t.ok,
517
+ onClick: () => t.ok && h(t.ops, t.label, t.select),
518
+ className: "inline-flex h-7 items-center rounded-md bg-nvr-cyan px-3 text-[12px] font-medium text-white transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-40",
519
+ children: t.ok ? `Place ${t.placed.length}` : "Place"
520
+ }
521
+ )
522
+ ] })
523
+ ]
524
+ }
525
+ );
372
526
  }
373
527
  export {
374
- Ye as AddPanel,
375
- Se as otherFormSuggestions
528
+ dt as AddPanel,
529
+ Oe as BUILT_IN_SLOTS,
530
+ te as SLOT_HINTS,
531
+ Ee as otherFormSuggestions,
532
+ Te as typeWord
376
533
  };