@nivaro/react 0.3.36 → 0.3.37

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 +11 -10
  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,123 +1,154 @@
1
- import { jsxs as i, Fragment as w, jsx as o } from "react/jsx-runtime";
2
- import { BookMarked as C, X as R } from "lucide-react";
3
- import { useState as u } from "react";
4
- import { toast as p } from "sonner";
5
- import { useNivaroClient as $ } from "../../../context.js";
6
- import { cn as j } from "../../../lib/utils.js";
7
- import { sectionOp as F } from "../add-target.js";
1
+ import { jsxs as r, Fragment as j, jsx as o } from "react/jsx-runtime";
2
+ import { BookMarked as L, Link2 as F, X as M } from "lucide-react";
3
+ import { useState as y } from "react";
4
+ import { toast as f } from "sonner";
5
+ import { useNivaroClient as S } from "../../../context.js";
6
+ import { cn as B } from "../../../lib/utils.js";
7
+ import { sectionOp as I } from "../add-target.js";
8
8
  import { apiFailure as v } from "../overview/overview-api.js";
9
- import { useFieldMapping as M, FieldMapStep as B } from "./FieldMapStep.js";
10
- import { useTemplates as S, useRefreshTemplates as A, planBlock as T, leftOutWords as L, deleteTemplate as O } from "./reuse-api.js";
11
- import { reusePrimary as E } from "./SectionReuseActions.js";
12
- const I = "px-2 pb-1 pt-3 text-[11.5px] font-semibold text-slate-500 dark:text-muted-foreground";
13
- function K(e, t) {
14
- const r = F(e, t);
15
- return r.op === "group_create" && r.parent_key === null ? r.index : void 0;
9
+ import { useFieldMapping as T, FieldMapStep as O } from "./FieldMapStep.js";
10
+ import { useLinkedSectionsContext as E, createLink as K } from "./linked-sections.js";
11
+ import { useTemplates as P, useRefreshTemplates as W, planBlock as X, leftOutWords as q, deleteTemplate as z } from "./reuse-api.js";
12
+ import { reusePrimary as D } from "./SectionReuseActions.js";
13
+ const G = "px-2 pb-1 pt-3 text-[11.5px] font-semibold text-slate-500 dark:text-muted-foreground";
14
+ function H(e, t) {
15
+ const n = I(e, t);
16
+ return n.op === "group_create" && n.parent_key === null ? n.index : void 0;
16
17
  }
17
- function P({ t: e, ...t }) {
18
- const r = $(), n = A(), [f, c] = u(!1), [y, h] = u(!1), [s, x] = u(!1), m = !!e.source_collection && e.source_collection !== t.collection, a = M(m ? e.fields : [], e.source_collection, t.collection), b = async () => {
19
- if (!s) {
20
- if (m && !f && a.needed.length) {
21
- c(!0);
22
- return;
23
- }
24
- x(!0);
25
- try {
26
- const l = await T(r, {
27
- source: { template_id: e.id },
28
- target_collection: t.collection,
29
- target_bundle: t.bundle,
30
- field_map: m ? a.map : void 0,
31
- index: K(t.bundle, t.selected)
32
- });
33
- if (!l.ops.length) throw new Error("Nothing to add");
34
- t.apply(l.ops, { label: `Add ${e.name}` });
35
- const d = l.ops.find((_) => _.op === "group_create");
36
- (d == null ? void 0 : d.op) === "group_create" && t.onSelect({ kind: "group", key: d.key });
37
- const g = L(l);
38
- g && p(`${e.name} added: ${g}`), c(!1);
39
- } catch (l) {
40
- p.error(v(l, "Could not add the section").message);
41
- } finally {
42
- x(!1);
43
- }
18
+ function J({ t: e, ...t }) {
19
+ const n = S(), i = W(), c = E(), [m, h] = y(null), [C, N] = y(!1), [d, _] = y(!1), u = !!e.source_collection && e.source_collection !== t.collection, l = T(u ? e.fields : [], e.source_collection, t.collection), b = Number(t.bundle.layout.id), $ = !!c && Number.isInteger(b) && b > 0, k = async (s) => {
20
+ if (d) return;
21
+ if (u && m !== s && l.needed.length) {
22
+ h(s);
23
+ return;
24
+ }
25
+ const x = s === "linked";
26
+ _(!0);
27
+ try {
28
+ const a = await X(n, {
29
+ source: { template_id: e.id },
30
+ target_collection: t.collection,
31
+ target_bundle: t.bundle,
32
+ field_map: u ? l.map : void 0,
33
+ index: H(t.bundle, t.selected),
34
+ linked: x
35
+ });
36
+ if (!a.ops.length) throw new Error("Nothing to add");
37
+ t.apply(a.ops, { label: x ? `Add ${e.name} (linked)` : `Add ${e.name}` });
38
+ const p = a.ops.find((g) => g.op === "group_create");
39
+ if ((p == null ? void 0 : p.op) === "group_create" && t.onSelect({ kind: "group", key: p.key }), x && a.linked_key)
40
+ try {
41
+ await K(n, b, {
42
+ template_id: e.id,
43
+ group_key: a.linked_key,
44
+ field_map: u ? l.map : void 0
45
+ }), c == null || c.refresh();
46
+ } catch (g) {
47
+ f.error(
48
+ `${e.name} was added as an ordinary copy: ${v(g, "it could not be linked").message}`
49
+ );
50
+ }
51
+ const w = q(a);
52
+ w && f(`${e.name} added: ${w}`), h(null);
53
+ } catch (a) {
54
+ f.error(v(a, "Could not add the section").message);
55
+ } finally {
56
+ _(!1);
44
57
  }
45
- }, k = async () => {
58
+ }, A = async () => {
46
59
  try {
47
- await O(r, e.id), n("section");
48
- } catch (l) {
49
- p.error(v(l, "Could not remove it").message);
60
+ await z(n, e.id), i("section");
61
+ } catch (s) {
62
+ f.error(v(s, "Could not remove it").message);
50
63
  }
51
- }, N = [
64
+ }, R = [
52
65
  `${e.fields.length} ${e.fields.length === 1 ? "field" : "fields"}`,
66
+ e.linked_forms ? `linked on ${e.linked_forms} ${e.linked_forms === 1 ? "form" : "forms"}` : null,
53
67
  e.source_collection && e.source_collection !== t.collection ? `from ${e.source_collection}` : null,
54
68
  e.description
55
69
  ].filter(Boolean).join(" · ");
56
- return /* @__PURE__ */ i("div", { "data-library-section": e.id, children: [
57
- /* @__PURE__ */ i("div", { className: "group flex items-center gap-0.5", children: [
58
- /* @__PURE__ */ i(
70
+ return /* @__PURE__ */ r("div", { "data-library-section": e.id, children: [
71
+ /* @__PURE__ */ r("div", { className: "group flex items-center gap-0.5", children: [
72
+ /* @__PURE__ */ r(
59
73
  "button",
60
74
  {
61
75
  type: "button",
62
- disabled: s || a.loading,
63
- onClick: () => void b(),
76
+ disabled: d || l.loading,
77
+ onClick: () => void k("copy"),
64
78
  className: "flex w-full min-w-0 items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-muted disabled:opacity-60",
65
79
  children: [
66
- /* @__PURE__ */ i("span", { className: "flex min-w-0 flex-1 flex-col", children: [
80
+ /* @__PURE__ */ r("span", { className: "flex min-w-0 flex-1 flex-col", children: [
67
81
  /* @__PURE__ */ o("span", { className: "truncate text-[12.5px] font-medium text-slate-900 dark:text-foreground", children: e.name }),
68
- /* @__PURE__ */ o("span", { className: "truncate text-[11.5px] text-slate-500 dark:text-muted-foreground", children: N })
82
+ /* @__PURE__ */ o("span", { className: "truncate text-[11.5px] text-slate-500 dark:text-muted-foreground", children: R })
69
83
  ] }),
70
- /* @__PURE__ */ o(C, { className: "h-3.5 w-3.5 shrink-0 text-slate-400" })
84
+ /* @__PURE__ */ o(L, { className: "h-3.5 w-3.5 shrink-0 text-slate-400" })
71
85
  ]
72
86
  }
73
87
  ),
88
+ $ && /* @__PURE__ */ o(
89
+ "button",
90
+ {
91
+ type: "button",
92
+ "aria-label": `Add ${e.name} linked`,
93
+ "data-tip": "Add linked: it follows the library, so a change there updates this form too",
94
+ "data-library-linked": e.id,
95
+ disabled: d || l.loading,
96
+ onClick: () => void k("linked"),
97
+ className: "invisible 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 group-hover:visible focus-visible:visible disabled:opacity-50 dark:hover:text-foreground",
98
+ children: /* @__PURE__ */ o(F, { className: "h-3.5 w-3.5" })
99
+ }
100
+ ),
74
101
  /* @__PURE__ */ o(
75
102
  "button",
76
103
  {
77
104
  type: "button",
78
105
  "aria-label": `Remove ${e.name} from the library`,
79
106
  "data-tip": "Remove from the library",
80
- onClick: () => h(!0),
107
+ onClick: () => N(!0),
81
108
  className: "invisible 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 group-hover:visible focus-visible:visible dark:hover:text-foreground",
82
- children: /* @__PURE__ */ o(R, { className: "h-3.5 w-3.5" })
109
+ children: /* @__PURE__ */ o(M, { className: "h-3.5 w-3.5" })
83
110
  }
84
111
  )
85
112
  ] }),
86
- y && /* @__PURE__ */ i("div", { className: "mx-2 mb-1 flex items-center gap-2 text-[12px] text-slate-600 dark:text-muted-foreground", children: [
87
- /* @__PURE__ */ o("span", { className: "flex-1", children: "Remove from the library? Forms keep their copies." }),
113
+ C && /* @__PURE__ */ r("div", { className: "mx-2 mb-1 flex items-center gap-2 text-[12px] text-slate-600 dark:text-muted-foreground", children: [
114
+ /* @__PURE__ */ r("span", { className: "flex-1", children: [
115
+ "Remove from the library? Forms keep their copies",
116
+ e.linked_forms ? "; linked ones become ordinary sections" : "",
117
+ "."
118
+ ] }),
88
119
  /* @__PURE__ */ o(
89
120
  "button",
90
121
  {
91
122
  type: "button",
92
- onClick: () => void k(),
123
+ onClick: () => void A(),
93
124
  className: "font-medium text-red-600 hover:underline dark:text-red-400",
94
125
  children: "Remove"
95
126
  }
96
127
  ),
97
- /* @__PURE__ */ o("button", { type: "button", onClick: () => h(!1), className: "hover:underline", children: "Keep" })
128
+ /* @__PURE__ */ o("button", { type: "button", onClick: () => N(!1), className: "hover:underline", children: "Keep" })
98
129
  ] }),
99
- f && /* @__PURE__ */ i(
130
+ m && /* @__PURE__ */ r(
100
131
  "div",
101
132
  {
102
- className: j(
133
+ className: B(
103
134
  "mx-1 mb-2 rounded-md border border-slate-200 bg-slate-50 p-2 dark:border-border dark:bg-muted/40"
104
135
  ),
105
136
  children: [
106
137
  /* @__PURE__ */ o(
107
- B,
138
+ O,
108
139
  {
109
- needed: a.needed,
110
- map: a.map,
111
- onChange: a.setMap,
140
+ needed: l.needed,
141
+ map: l.map,
142
+ onChange: l.setMap,
112
143
  targetCollection: t.collection
113
144
  }
114
145
  ),
115
- /* @__PURE__ */ i("div", { className: "mt-2 flex justify-end gap-2", children: [
146
+ /* @__PURE__ */ r("div", { className: "mt-2 flex justify-end gap-2", children: [
116
147
  /* @__PURE__ */ o(
117
148
  "button",
118
149
  {
119
150
  type: "button",
120
- onClick: () => c(!1),
151
+ onClick: () => h(null),
121
152
  className: "text-[12px] text-slate-500 hover:underline dark:text-muted-foreground",
122
153
  children: "Cancel"
123
154
  }
@@ -126,10 +157,10 @@ function P({ t: e, ...t }) {
126
157
  "button",
127
158
  {
128
159
  type: "button",
129
- className: E,
130
- disabled: s,
131
- onClick: () => void b(),
132
- children: s ? "Adding…" : "Add section"
160
+ className: D,
161
+ disabled: d,
162
+ onClick: () => void k(m ?? "copy"),
163
+ children: d ? "Adding…" : m === "linked" ? "Add linked" : "Add section"
133
164
  }
134
165
  )
135
166
  ] })
@@ -138,13 +169,13 @@ function P({ t: e, ...t }) {
138
169
  )
139
170
  ] });
140
171
  }
141
- function Y(e) {
142
- const { data: t = [] } = S("section"), r = t.filter((n) => e.matches(n.name, n.description, ...n.fields));
143
- return r.length ? /* @__PURE__ */ i(w, { children: [
144
- /* @__PURE__ */ o("p", { className: I, children: "Section library" }),
145
- r.map((n) => /* @__PURE__ */ o(P, { t: n, ...e }, n.id))
172
+ function ae(e) {
173
+ const { data: t = [] } = P("section"), n = t.filter((i) => e.matches(i.name, i.description, ...i.fields));
174
+ return n.length ? /* @__PURE__ */ r(j, { children: [
175
+ /* @__PURE__ */ o("p", { className: G, children: "Section library" }),
176
+ n.map((i) => /* @__PURE__ */ o(J, { t: i, ...e }, i.id))
146
177
  ] }) : null;
147
178
  }
148
179
  export {
149
- Y as LibraryRows
180
+ ae as LibraryRows
150
181
  };
@@ -0,0 +1,373 @@
1
+ import { jsxs as c, jsx as a } from "react/jsx-runtime";
2
+ import { useQueryClient as G, useQuery as O } from "@tanstack/react-query";
3
+ import { Link2 as W, Unlink as E } from "lucide-react";
4
+ import { useState as w, useEffect as L, useMemo as $, useCallback as C, useContext as D, createContext as X } from "react";
5
+ import { toast as b } from "sonner";
6
+ import { useNivaroClient as K } from "../../../context.js";
7
+ import { get as Y, post as j, put as H, del as J } from "../../../lib/commands.js";
8
+ import { cn as T } from "../../../lib/utils.js";
9
+ import { apiFailure as V } from "../overview/overview-api.js";
10
+ import { effectText as Z, amberStrip as I, tintCard as ee } from "../panel-style.js";
11
+ import { useRefreshTemplates as te, reuseKeys as ne } from "./reuse-api.js";
12
+ import { reuseBtn as g, reusePrimary as q } from "./SectionReuseActions.js";
13
+ const S = { byGroup: /* @__PURE__ */ new Map(), roots: /* @__PURE__ */ new Set() };
14
+ function oe(e, t) {
15
+ if (!e || t.length === 0) return S;
16
+ const o = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Set(), r = new Set(e.groups.map((n) => n.key));
17
+ for (const n of t)
18
+ r.has(n.group_key) && (i.add(n.group_key), o.set(n.group_key, n));
19
+ if (!i.size) return S;
20
+ for (let n = !0; n; ) {
21
+ n = !1;
22
+ for (const s of e.groups) {
23
+ const l = s.parent_key ? o.get(s.parent_key) : void 0;
24
+ l && !o.has(s.key) && (o.set(s.key, l), n = !0);
25
+ }
26
+ }
27
+ return { byGroup: o, roots: i };
28
+ }
29
+ function z(e, t) {
30
+ return !t || e.roots.size === 0 ? null : t.kind === "group" ? e.byGroup.get(t.key) ?? null : (t.kind === "field" || t.kind === "slot") && t.group_key ? e.byGroup.get(t.group_key) ?? null : null;
31
+ }
32
+ function ie(e, t, o) {
33
+ const i = z(e, t);
34
+ return !i || i.group_key === o ? !1 : !(t.kind === "group" && e.roots.has(t.key));
35
+ }
36
+ function re(e, t, o) {
37
+ if (t.roots.size === 0) return null;
38
+ const i = (r) => {
39
+ if (!r) return null;
40
+ const n = t.byGroup.get(r);
41
+ return n && n.group_key !== o ? n : null;
42
+ };
43
+ for (const r of e) {
44
+ let n = null;
45
+ switch (r.op) {
46
+ case "place":
47
+ n = i(r.group_key);
48
+ break;
49
+ case "move":
50
+ n = i(r.from.group_key) ?? i(r.to_group_key);
51
+ break;
52
+ case "update_placement":
53
+ case "remove":
54
+ n = i(r.at.group_key);
55
+ break;
56
+ case "group_create":
57
+ n = i(r.parent_key);
58
+ break;
59
+ case "group_update":
60
+ n = i(r.key);
61
+ break;
62
+ case "group_move":
63
+ n = (t.roots.has(r.key) ? null : i(r.key)) ?? i(r.parent_key);
64
+ break;
65
+ case "group_remove":
66
+ n = t.roots.has(r.key) ? null : i(r.key);
67
+ break;
68
+ }
69
+ if (n) return n;
70
+ }
71
+ return null;
72
+ }
73
+ const _ = (e) => `${e} ${e === 1 ? "form" : "forms"}`;
74
+ function se(e) {
75
+ const t = [`${_(e.updated.length)} updated`];
76
+ e.unchanged && t.push(`${e.unchanged} already matched`);
77
+ const o = e.skipped.length ? `Not updated: ${e.skipped.slice(0, 4).map((i) => `${i.name}${i.reason ? ` (${i.reason})` : ""}`).join(
78
+ ", "
79
+ )}${e.skipped.length > 4 ? ` and ${e.skipped.length - 4} more` : ""}. Update them from their editors.` : null;
80
+ return { text: t.join(", "), skipped: o };
81
+ }
82
+ const A = {
83
+ layout: (e) => ["layout-editor", "section-links", e]
84
+ };
85
+ function ae(e) {
86
+ const t = K();
87
+ return O({
88
+ queryKey: A.layout(e ?? 0),
89
+ queryFn: () => t.request(Y(`/collection-layouts/${e}/section-links`)).then((o) => Array.isArray(o == null ? void 0 : o.data) ? o.data : []),
90
+ enabled: e != null && e > 0,
91
+ staleTime: 15e3
92
+ });
93
+ }
94
+ function $e(e, t, o) {
95
+ return e.request(j(`/collection-layouts/${t}/section-links`, o));
96
+ }
97
+ function le(e, t, o) {
98
+ return e.request(
99
+ J(`/collection-layouts/${t}/section-links/${encodeURIComponent(o)}`)
100
+ );
101
+ }
102
+ function ce(e, t, o, i) {
103
+ return e.request(
104
+ j(`/collection-layouts/${t}/section-links/${encodeURIComponent(o)}/plan`, {
105
+ bundle: { groups: i.groups, placements: i.placements }
106
+ })
107
+ );
108
+ }
109
+ function ue(e, t, o) {
110
+ return e.request(
111
+ H(`/collection-layouts/templates/${t}/content`, o)
112
+ ).then((i) => i.data);
113
+ }
114
+ const Q = X(null);
115
+ function Ne({
116
+ value: e,
117
+ children: t
118
+ }) {
119
+ return /* @__PURE__ */ a(Q.Provider, { value: e, children: t });
120
+ }
121
+ function U() {
122
+ return D(Q);
123
+ }
124
+ function Le(e, t) {
125
+ const o = G(), { data: i = [] } = ae(e), [r, n] = w(null);
126
+ L(() => n(null), [e]);
127
+ const s = t.bundle, l = $(() => oe(s, i), [s, i]), m = C(
128
+ () => void o.invalidateQueries({ queryKey: A.layout(e) }),
129
+ [o, e]
130
+ );
131
+ L(() => {
132
+ i.length && m();
133
+ }, [t.baseRev]), L(() => {
134
+ r && !l.roots.has(r) && n(null);
135
+ }, [r, l]);
136
+ const h = t.apply, y = C(
137
+ (f, N) => {
138
+ const x = re(f, l, r);
139
+ if (x) {
140
+ b(`${x.template_name} is a linked library section`, {
141
+ id: "linked-section-refused",
142
+ description: "Select it and choose Edit the shared section to change it on every form, or Unlink to change it here only."
143
+ });
144
+ return;
145
+ }
146
+ h(f, N);
147
+ },
148
+ [l, r, h]
149
+ ), d = C(async () => (await t.save(), t.unsavedOps().length === 0), [t]), p = $(() => ({ ...t, apply: y }), [t, y]), v = $(
150
+ () => ({ layoutId: e, bundle: s, links: i, index: l, editing: r, setEditing: n, rawApply: h, save: d, refresh: m }),
151
+ [e, s, i, l, r, h, d, m]
152
+ );
153
+ return { draft: p, value: v };
154
+ }
155
+ function Ce(e) {
156
+ const t = U(), o = (t == null ? void 0 : t.index) ?? S, i = (t == null ? void 0 : t.editing) ?? null;
157
+ return $(() => o.roots.size === 0 ? { marks: e, locked: void 0 } : {
158
+ marks: (r) => {
159
+ const n = (e == null ? void 0 : e(r)) ?? [];
160
+ if (r.kind !== "group" || !o.roots.has(r.key)) return n;
161
+ const s = o.byGroup.get(r.key);
162
+ return [...n, de(s, s.group_key === i)];
163
+ },
164
+ locked: (r) => ie(o, r, i)
165
+ }, [o, i, e]);
166
+ }
167
+ function de(e, t) {
168
+ return t ? {
169
+ text: "Editing shared section",
170
+ tone: "violet",
171
+ icon: "link",
172
+ highlight: !0,
173
+ tip: `Changes here go to the library section ${e.template_name} and ${_(e.linked_forms)} when you publish.`
174
+ } : e.in_sync === !1 ? {
175
+ text: "Linked · differs",
176
+ tone: "amber",
177
+ icon: "link",
178
+ tip: `Linked to ${e.template_name} in the section library, but this copy differs from it. Select it to update it.`
179
+ } : {
180
+ text: "Linked",
181
+ tone: "slate",
182
+ icon: "link",
183
+ tip: `Linked to ${e.template_name} in the section library: it changes there, on every form that uses it.`
184
+ };
185
+ }
186
+ function Se(e) {
187
+ const t = U();
188
+ if (!t) return null;
189
+ const o = z(t.index, e);
190
+ return o ? { link: o, editing: t.editing === o.group_key } : null;
191
+ }
192
+ const P = Z, M = "font-medium text-slate-800 dark:text-foreground";
193
+ function Ue({ link: e }) {
194
+ const t = U(), o = K(), i = G(), r = te(), [n, s] = w(null), [l, m] = w(!1), [h, y] = w(null);
195
+ if (!t) return null;
196
+ const d = t.editing === e.group_key, p = Math.max(0, e.linked_forms - 1), v = async (k) => {
197
+ if (!t.bundle) return !1;
198
+ const u = await ce(o, t.layoutId, e.group_key, t.bundle);
199
+ return u.ops.length && !u.in_sync && t.rawApply(u.ops, { label: k }), !0;
200
+ }, f = async (k, u) => {
201
+ if (!n) {
202
+ s(k), y(null);
203
+ try {
204
+ await u();
205
+ } catch (F) {
206
+ y(V(F, "That did not work").message);
207
+ } finally {
208
+ s(null);
209
+ }
210
+ }
211
+ }, N = () => f("update", async () => {
212
+ await v(`Update ${e.template_name} from the library`), b.success(`${e.template_name} matches the library again. Save to keep it.`);
213
+ }), x = () => f("cancel", async () => {
214
+ await v(`Undo edits to ${e.template_name}`), t.setEditing(null);
215
+ }), R = () => f("publish", async () => {
216
+ if (!await t.save()) {
217
+ y("Save the form first (it may ask for a reason), then publish.");
218
+ return;
219
+ }
220
+ const k = await ue(o, e.template_id, {
221
+ layout_id: t.layoutId,
222
+ group_key: e.group_key
223
+ });
224
+ t.setEditing(null), t.refresh(), r("section"), i.invalidateQueries({ queryKey: ne.templates("section") });
225
+ const u = se(k);
226
+ b.success(`Published ${e.template_name}: ${u.text}`), u.skipped && b.warning(u.skipped, { duration: 1e4 });
227
+ }), B = () => f("unlink", async () => {
228
+ await le(o, t.layoutId, e.group_key), t.setEditing(null), t.refresh(), r("section"), b.success(`${e.template_name} is an ordinary section on this form now`);
229
+ });
230
+ return /* @__PURE__ */ c(
231
+ "div",
232
+ {
233
+ "data-linked-section": e.group_key,
234
+ "data-linked-editing": d ? "" : void 0,
235
+ className: T(ee, "mb-4 space-y-2.5 p-3"),
236
+ children: [
237
+ /* @__PURE__ */ c("p", { className: "flex items-start gap-2 text-[12.5px] leading-snug text-slate-700 dark:text-foreground", children: [
238
+ /* @__PURE__ */ a(
239
+ W,
240
+ {
241
+ "aria-hidden": !0,
242
+ className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-[#0089ad] dark:text-nvr-cyan"
243
+ }
244
+ ),
245
+ d ? /* @__PURE__ */ c("span", { children: [
246
+ "Editing the shared section ",
247
+ /* @__PURE__ */ a("span", { className: M, children: e.template_name }),
248
+ ". Publish saves this form and sends the section to the library",
249
+ p ? ` and ${_(p)} that use it` : "",
250
+ "."
251
+ ] }) : /* @__PURE__ */ c("span", { children: [
252
+ "Linked to ",
253
+ /* @__PURE__ */ a("span", { className: M, children: e.template_name }),
254
+ " in the section library",
255
+ p ? `, also on ${_(p)}` : "",
256
+ ". It changes there, for every form at once."
257
+ ] })
258
+ ] }),
259
+ !d && !e.confirmed && /* @__PURE__ */ a("p", { className: P, children: "The link is kept when you save this form." }),
260
+ !d && e.in_sync === !1 && /* @__PURE__ */ a(
261
+ "p",
262
+ {
263
+ "data-linked-differs": "",
264
+ className: T("rounded-md border px-2.5 py-1.5 text-[12px] leading-snug", I),
265
+ children: "This copy differs from the library (changed here, or the library changed while the form could not be updated)."
266
+ }
267
+ ),
268
+ l ? /* @__PURE__ */ c("div", { className: "space-y-2", children: [
269
+ /* @__PURE__ */ a("p", { className: P, children: "The section stays on this form as an ordinary copy you can change. Library changes stop reaching it." }),
270
+ /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1.5", children: [
271
+ /* @__PURE__ */ c(
272
+ "button",
273
+ {
274
+ type: "button",
275
+ "data-linked-unlink-confirm": "",
276
+ disabled: !!n,
277
+ onClick: () => void B(),
278
+ className: g,
279
+ children: [
280
+ /* @__PURE__ */ a(E, { className: "h-3.5 w-3.5" }),
281
+ n === "unlink" ? "Unlinking…" : "Unlink"
282
+ ]
283
+ }
284
+ ),
285
+ /* @__PURE__ */ a("button", { type: "button", className: g, onClick: () => m(!1), children: "Keep linked" })
286
+ ] })
287
+ ] }) : d ? /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1.5", children: [
288
+ /* @__PURE__ */ a(
289
+ "button",
290
+ {
291
+ type: "button",
292
+ "data-linked-publish": "",
293
+ disabled: !!n,
294
+ onClick: () => void R(),
295
+ className: q,
296
+ children: n === "publish" ? "Publishing…" : p ? `Publish to ${_(p + 1)}` : "Publish to the library"
297
+ }
298
+ ),
299
+ /* @__PURE__ */ a(
300
+ "button",
301
+ {
302
+ type: "button",
303
+ "data-linked-cancel": "",
304
+ disabled: !!n,
305
+ onClick: () => void x(),
306
+ className: g,
307
+ children: n === "cancel" ? "Putting it back…" : "Cancel"
308
+ }
309
+ )
310
+ ] }) : /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-1.5", children: [
311
+ /* @__PURE__ */ a(
312
+ "button",
313
+ {
314
+ type: "button",
315
+ "data-linked-edit": "",
316
+ disabled: !!n,
317
+ onClick: () => t.setEditing(e.group_key),
318
+ className: q,
319
+ children: "Edit the shared section"
320
+ }
321
+ ),
322
+ e.in_sync === !1 && /* @__PURE__ */ a(
323
+ "button",
324
+ {
325
+ type: "button",
326
+ "data-linked-update": "",
327
+ disabled: !!n,
328
+ onClick: () => void N(),
329
+ className: g,
330
+ children: n === "update" ? "Updating…" : "Update from the library"
331
+ }
332
+ ),
333
+ /* @__PURE__ */ c(
334
+ "button",
335
+ {
336
+ type: "button",
337
+ "data-linked-unlink": "",
338
+ disabled: !!n,
339
+ onClick: () => m(!0),
340
+ className: g,
341
+ children: [
342
+ /* @__PURE__ */ a(E, { className: "h-3.5 w-3.5" }),
343
+ "Unlink"
344
+ ]
345
+ }
346
+ )
347
+ ] }),
348
+ h && /* @__PURE__ */ a("p", { role: "alert", className: "text-[12px] leading-snug text-red-700 dark:text-red-300", children: h })
349
+ ]
350
+ }
351
+ );
352
+ }
353
+ export {
354
+ S as EMPTY_INDEX,
355
+ Ue as LinkedSectionNotice,
356
+ Ne as LinkedSectionsProvider,
357
+ re as blockedLink,
358
+ $e as createLink,
359
+ oe as indexLinks,
360
+ ie as isLockedTarget,
361
+ A as linkKeys,
362
+ z as linkOfTarget,
363
+ de as linkedMark,
364
+ ce as planLinkUpdate,
365
+ ue as publishSection,
366
+ se as publishWords,
367
+ le as unlinkSection,
368
+ Ce as useLinkedSectionMarks,
369
+ Le as useLinkedSections,
370
+ U as useLinkedSectionsContext,
371
+ Se as useLinkedTarget,
372
+ ae as useSectionLinks
373
+ };