@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,4 +1,4 @@
1
- import { jsxs as r, jsx as t, Fragment as I } from "react/jsx-runtime";
1
+ import { jsxs as s, jsx as t, Fragment as I } from "react/jsx-runtime";
2
2
  import { useState as U, useEffect as ae } from "react";
3
3
  import { readGroupStructure as ne } from "../../../lib/form-structure.js";
4
4
  import { lazySectionsOf as oe, lazySectionPatch as ie } from "../../../lib/layout-resolve.js";
@@ -10,10 +10,10 @@ import { SwapConfigEditor as de } from "../editors/swap-config.js";
10
10
  import { IconPicker as ce } from "../pickers/icon-picker.js";
11
11
  import { SectionReuseActions as he } from "../reuse/SectionReuseActions.js";
12
12
  import { emptyTextOp as pe, stickyPlan as fe, rowUpdatePlan as X } from "../section-structure.js";
13
- import { useCollectionMeta as ue } from "./field-context.js";
14
- import { useInspectorEnv as me, Setting as d, TextInput as S, Choice as F, Segmented as y, Toggle as g, TextArea as Y, Section as $, FieldMultiPicker as be, ConditionBuilder as ye } from "./kit.js";
15
- import { groupFields as ge, asArray as k, describeField as Z, relKindOf as ke, relatedCollectionOf as _e } from "./model.js";
16
- import { GroupTranslations as ve } from "./Translations.js";
13
+ import { useCollectionMeta as me } from "./field-context.js";
14
+ import { useInspectorEnv as ue, Setting as d, TextInput as S, Choice as F, Segmented as g, Toggle as k, TextArea as Y, Section as $, FieldMultiPicker as be, ConditionBuilder as ye } from "./kit.js";
15
+ import { groupFields as ge, asArray as v, describeField as Z, relKindOf as ke, relatedCollectionOf as ve } from "./model.js";
16
+ import { GroupTranslations as _e } from "./Translations.js";
17
17
  const T = {
18
18
  section: "Section",
19
19
  tab: "Tab or step",
@@ -25,30 +25,30 @@ function we(l) {
25
25
  return typeof l == "string" ? { field: l } : l && typeof l == "object" && typeof l.field == "string" ? l : null;
26
26
  }
27
27
  function xe(l) {
28
- const { field: u, label: o, agg: p, agg_field: m, field_options: f } = l;
29
- return !o && !p ? u : {
30
- field: u,
28
+ const { field: m, label: o, agg: p, agg_field: u, field_options: f } = l;
29
+ return !o && !p ? m : {
30
+ field: m,
31
31
  ...o ? { label: o } : {},
32
- ...p ? { agg: p, agg_field: m, ...f ? { field_options: f } : {} } : {}
32
+ ...p ? { agg: p, agg_field: u, ...f ? { field_options: f } : {} } : {}
33
33
  };
34
34
  }
35
35
  const _ = (l) => l.length ? JSON.stringify(l) : null;
36
- function je({ group: l, readOnly: u }) {
36
+ function je({ group: l, readOnly: m }) {
37
37
  var B, H;
38
- const o = me(), { data: p } = ue(o.collection), m = (p == null ? void 0 : p.fields) ?? [], f = (p == null ? void 0 : p.relations) ?? [], n = l.label || W(l.key), i = l.type, s = (e, a, c) => o.apply([{ op: "group_update", key: l.key, patch: e }], { label: a, text: c }), L = o.bundle.groups.filter((e) => e.parent_key === l.key), Q = o.bundle.groups.filter((e) => e.type === "container" && e.key !== l.key), P = o.bundle.placements.some((e) => e.group_key === l.key), V = (l.parent_key ? ["tab"] : Object.keys(T)).filter((e) => e === i || !(P && (e === "container" || e === "content"))).map((e) => ({ value: e, label: T[e] })), v = i === "section" || i === "metadata" || i === "tab", R = oe(o.bundle.layout.conditions).includes(l.key), M = !!o.bundle.layout.accordion_mode, w = ne(l.swap_config), D = m.filter((e) => !e.field.startsWith("__") && e.type !== "alias").map((e) => ({ value: e.field, label: e.label || W(e.field) })).sort((e, a) => e.label.localeCompare(a.label)), j = ge(o.bundle, l.key), x = k(l.summary_fields).map(we).filter((e) => !!e), G = (e, a, c) => s({ summary_fields: _(e.map(xe)) }, a, c), J = k(l.visible_when), C = JSON.stringify(J), [ee, K] = U(J);
38
+ const o = ue(), { data: p } = me(o.collection), u = (p == null ? void 0 : p.fields) ?? [], f = (p == null ? void 0 : p.relations) ?? [], n = l.label || W(l.key), i = l.type, r = (e, a, c) => o.apply([{ op: "group_update", key: l.key, patch: e }], { label: a, text: c }), L = o.bundle.groups.filter((e) => e.parent_key === l.key), Q = o.bundle.groups.filter((e) => e.type === "container" && e.key !== l.key), P = o.bundle.placements.some((e) => e.group_key === l.key), V = (l.parent_key ? ["tab"] : Object.keys(T)).filter((e) => e === i || !(P && (e === "container" || e === "content"))).map((e) => ({ value: e, label: T[e] })), w = i === "section" || i === "metadata" || i === "tab", R = oe(o.bundle.layout.conditions).includes(l.key), M = !!o.bundle.layout.accordion_mode, x = ne(l.swap_config), D = u.filter((e) => !e.field.startsWith("__") && e.type !== "alias").map((e) => ({ value: e.field, label: e.label || W(e.field) })).sort((e, a) => e.label.localeCompare(a.label)), j = ge(o.bundle, l.key), b = v(l.summary_fields).map(we).filter((e) => !!e), G = (e, a, c) => r({ summary_fields: _(e.map(xe)) }, a, c), J = v(l.visible_when), C = JSON.stringify(J), [ee, K] = U(J);
39
39
  ae(() => {
40
40
  K(
41
41
  (e) => JSON.stringify(e.filter((a) => a.field)) === C ? e : JSON.parse(C)
42
42
  );
43
43
  }, [C]);
44
44
  const [te, z] = U(!1);
45
- return /* @__PURE__ */ r("fieldset", { disabled: u, className: "min-w-0 space-y-5", children: [
45
+ return /* @__PURE__ */ s("fieldset", { disabled: m, className: "min-w-0 space-y-5", children: [
46
46
  /* @__PURE__ */ t(d, { k: "group.label", label: "Name", effect: "The heading people see.", children: /* @__PURE__ */ t(
47
47
  S,
48
48
  {
49
49
  ariaLabel: "Name",
50
50
  value: l.label,
51
- onChange: (e) => s({ label: e }, `Rename ${n}`, !0)
51
+ onChange: (e) => r({ label: e }, `Rename ${n}`, !0)
52
52
  }
53
53
  ) }),
54
54
  /* @__PURE__ */ t(d, { k: "group.icon", label: "Icon", effect: "Shown before the section title.", children: /* @__PURE__ */ t(
@@ -56,7 +56,7 @@ function je({ group: l, readOnly: u }) {
56
56
  {
57
57
  className: "h-8 rounded-md border-slate-200 bg-white px-2.5 text-[13px] hover:bg-white dark:border-border dark:bg-background dark:hover:bg-background",
58
58
  value: l.icon ?? "",
59
- onChange: (e) => s({ icon: e || null }, `Change the icon of ${n}`)
59
+ onChange: (e) => r({ icon: e || null }, `Change the icon of ${n}`)
60
60
  }
61
61
  ) }),
62
62
  /* @__PURE__ */ t(
@@ -74,7 +74,7 @@ function je({ group: l, readOnly: u }) {
74
74
  options: V,
75
75
  onChange: (e) => {
76
76
  var a;
77
- return s(
77
+ return r(
78
78
  e === "container" ? { type: e, tab_mode: l.tab_mode ?? "tabs" } : { type: e },
79
79
  `Make ${n} a ${(a = T[e]) == null ? void 0 : a.toLowerCase()}`
80
80
  );
@@ -90,14 +90,14 @@ function je({ group: l, readOnly: u }) {
90
90
  label: "Show its tabs as",
91
91
  effect: "Steps walk people through in order.",
92
92
  children: /* @__PURE__ */ t(
93
- y,
93
+ g,
94
94
  {
95
95
  value: l.tab_mode === "steps" ? "steps" : "tabs",
96
96
  options: [
97
97
  { value: "tabs", label: "Tabs" },
98
98
  { value: "steps", label: "Steps" }
99
99
  ],
100
- onChange: (e) => s({ tab_mode: e }, `Show ${n} as ${e}`)
100
+ onChange: (e) => r({ tab_mode: e }, `Show ${n} as ${e}`)
101
101
  }
102
102
  )
103
103
  }
@@ -133,17 +133,17 @@ function je({ group: l, readOnly: u }) {
133
133
  }
134
134
  ),
135
135
  (i === "section" || i === "metadata") && /* @__PURE__ */ t(
136
- g,
136
+ k,
137
137
  {
138
138
  k: "group.is_collapsed",
139
139
  label: "Starts collapsed",
140
140
  effect: "The section opens folded; people unfold it.",
141
141
  checked: l.is_collapsed,
142
- onChange: (e) => s({ is_collapsed: e }, e ? `Collapse ${n}` : `Expand ${n}`)
142
+ onChange: (e) => r({ is_collapsed: e }, e ? `Collapse ${n}` : `Expand ${n}`)
143
143
  }
144
144
  ),
145
145
  (i === "section" || i === "metadata") && /* @__PURE__ */ t(
146
- g,
146
+ k,
147
147
  {
148
148
  k: "group.load_on_open",
149
149
  label: "Load when opened",
@@ -161,7 +161,7 @@ function je({ group: l, readOnly: u }) {
161
161
  )
162
162
  }
163
163
  ),
164
- i === "content" && /* @__PURE__ */ r(I, { children: [
164
+ i === "content" && /* @__PURE__ */ s(I, { children: [
165
165
  /* @__PURE__ */ t(
166
166
  d,
167
167
  {
@@ -169,7 +169,7 @@ function je({ group: l, readOnly: u }) {
169
169
  label: "Style",
170
170
  effect: "Note and Warning are coloured boxes; Divider is a line with the text.",
171
171
  children: /* @__PURE__ */ t(
172
- y,
172
+ g,
173
173
  {
174
174
  value: l.content_tone ?? "info",
175
175
  options: [
@@ -177,7 +177,7 @@ function je({ group: l, readOnly: u }) {
177
177
  { value: "warn", label: "Warning" },
178
178
  { value: "divider", label: "Divider" }
179
179
  ],
180
- onChange: (e) => s({ content_tone: e }, `Change the style of ${n}`)
180
+ onChange: (e) => r({ content_tone: e }, `Change the style of ${n}`)
181
181
  }
182
182
  )
183
183
  }
@@ -187,11 +187,11 @@ function je({ group: l, readOnly: u }) {
187
187
  {
188
188
  ariaLabel: "Text",
189
189
  value: l.content ?? "",
190
- onChange: (e) => s({ content: e || null }, `Edit the text of ${n}`, !0)
190
+ onChange: (e) => r({ content: e || null }, `Edit the text of ${n}`, !0)
191
191
  }
192
192
  ) })
193
193
  ] }),
194
- (i === "section" || i === "tab") && /* @__PURE__ */ r(I, { children: [
194
+ (i === "section" || i === "tab") && /* @__PURE__ */ s(I, { children: [
195
195
  /* @__PURE__ */ t(
196
196
  d,
197
197
  {
@@ -203,7 +203,7 @@ function je({ group: l, readOnly: u }) {
203
203
  {
204
204
  ariaLabel: "Intro",
205
205
  value: l.content ?? "",
206
- onChange: (e) => s({ content: e || null }, `Edit the intro of ${n}`, !0)
206
+ onChange: (e) => r({ content: e || null }, `Edit the intro of ${n}`, !0)
207
207
  }
208
208
  )
209
209
  }
@@ -215,20 +215,20 @@ function je({ group: l, readOnly: u }) {
215
215
  label: "Intro style",
216
216
  effect: "Note is a quiet box; Warning is amber.",
217
217
  children: /* @__PURE__ */ t(
218
- y,
218
+ g,
219
219
  {
220
220
  value: l.content_tone === "warn" ? "warn" : "info",
221
221
  options: [
222
222
  { value: "info", label: "Note" },
223
223
  { value: "warn", label: "Warning" }
224
224
  ],
225
- onChange: (e) => s({ content_tone: e }, `Change the intro style of ${n}`)
225
+ onChange: (e) => r({ content_tone: e }, `Change the intro style of ${n}`)
226
226
  }
227
227
  )
228
228
  }
229
229
  )
230
230
  ] }),
231
- v && /* @__PURE__ */ r(I, { children: [
231
+ w && /* @__PURE__ */ s(I, { children: [
232
232
  /* @__PURE__ */ t(
233
233
  d,
234
234
  {
@@ -236,7 +236,7 @@ function je({ group: l, readOnly: u }) {
236
236
  label: "Show",
237
237
  effect: "On new records, existing ones or both.",
238
238
  children: /* @__PURE__ */ t(
239
- y,
239
+ g,
240
240
  {
241
241
  value: l.visibility_mode ?? "always",
242
242
  options: [
@@ -244,19 +244,19 @@ function je({ group: l, readOnly: u }) {
244
244
  { value: "new_only", label: "New records" },
245
245
  { value: "existing_only", label: "Existing" }
246
246
  ],
247
- onChange: (e) => s({ visibility_mode: e }, `Change when ${n} shows`)
247
+ onChange: (e) => r({ visibility_mode: e }, `Change when ${n} shows`)
248
248
  }
249
249
  )
250
250
  }
251
251
  ),
252
252
  /* @__PURE__ */ t(
253
- g,
253
+ k,
254
254
  {
255
255
  k: "group.hide_when_empty",
256
256
  label: "Hide when all its fields are empty",
257
257
  effect: "The section disappears while none of its fields has a value.",
258
258
  checked: l.hide_when_empty,
259
- onChange: (e) => s({ hide_when_empty: e }, `Change when ${n} hides`)
259
+ onChange: (e) => r({ hide_when_empty: e }, `Change when ${n} hides`)
260
260
  }
261
261
  ),
262
262
  /* @__PURE__ */ t(
@@ -266,7 +266,7 @@ function je({ group: l, readOnly: u }) {
266
266
  label: "Width when reading",
267
267
  effect: "On the read view, summary and detail panels. Automatic: half for a short list, full for grids.",
268
268
  children: /* @__PURE__ */ t(
269
- y,
269
+ g,
270
270
  {
271
271
  value: l.read_width ?? "",
272
272
  options: [
@@ -275,7 +275,7 @@ function je({ group: l, readOnly: u }) {
275
275
  { value: "half", label: "½" },
276
276
  { value: "third", label: "⅓" }
277
277
  ],
278
- onChange: (e) => s({ read_width: e || null }, `Change the read width of ${n}`)
278
+ onChange: (e) => r({ read_width: e || null }, `Change the read width of ${n}`)
279
279
  }
280
280
  )
281
281
  }
@@ -290,7 +290,7 @@ function je({ group: l, readOnly: u }) {
290
290
  S,
291
291
  {
292
292
  ariaLabel: "When nothing is filled",
293
- value: w.emptyText ?? "",
293
+ value: x.emptyText ?? "",
294
294
  placeholder: "No details yet",
295
295
  onChange: (e) => o.apply([pe(l, e)], {
296
296
  label: `Change the empty text of ${n}`,
@@ -301,12 +301,12 @@ function je({ group: l, readOnly: u }) {
301
301
  }
302
302
  ),
303
303
  i === "section" && !l.parent_key && /* @__PURE__ */ t(
304
- g,
304
+ k,
305
305
  {
306
306
  k: "group.sticky",
307
307
  label: "Stick to the top",
308
308
  effect: "Stays at the top of the form while people scroll the rest, for totals or status. One section per form; not on phones.",
309
- checked: w.sticky,
309
+ checked: x.sticky,
310
310
  onChange: (e) => {
311
311
  const a = fe(o.bundle, l.key, e);
312
312
  a.ok && o.apply(a.ops, { label: a.label });
@@ -320,8 +320,8 @@ function je({ group: l, readOnly: u }) {
320
320
  k: "group.row_groups",
321
321
  label: "Rows of fields",
322
322
  effect: "Short fields that share one row under one label, like Street / City / Zip. To add one, select the fields on the form, right-click and pick Put side by side.",
323
- children: w.rows.length === 0 ? /* @__PURE__ */ t("p", { className: "text-[12px] leading-snug text-slate-500 dark:text-muted-foreground", children: "No rows yet." }) : /* @__PURE__ */ t("div", { className: "space-y-2", children: w.rows.map((e) => /* @__PURE__ */ r("div", { className: "space-y-1", "data-row-group-setting": e.key, children: [
324
- /* @__PURE__ */ r("div", { className: "flex items-center gap-1.5", children: [
323
+ children: x.rows.length === 0 ? /* @__PURE__ */ t("p", { className: "text-[12px] leading-snug text-slate-500 dark:text-muted-foreground", children: "No rows yet." }) : /* @__PURE__ */ t("div", { className: "space-y-2", children: x.rows.map((e) => /* @__PURE__ */ s("div", { className: "space-y-1", "data-row-group-setting": e.key, children: [
324
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-1.5", children: [
325
325
  /* @__PURE__ */ t("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ t(
326
326
  S,
327
327
  {
@@ -350,12 +350,12 @@ function je({ group: l, readOnly: u }) {
350
350
  const c = o.bundle.placements.find(
351
351
  (N) => N.field === a && N.group_key === l.key
352
352
  ) ?? null;
353
- return Z(a, m, f, c).label;
353
+ return Z(a, u, f, c).label;
354
354
  }).join(" · ") })
355
355
  ] }, e.key)) })
356
356
  }
357
357
  ) }),
358
- i === "tab" && /* @__PURE__ */ r($, { title: "As a step", children: [
358
+ i === "tab" && /* @__PURE__ */ s($, { title: "As a step", children: [
359
359
  /* @__PURE__ */ t(
360
360
  d,
361
361
  {
@@ -366,14 +366,14 @@ function je({ group: l, readOnly: u }) {
366
366
  be,
367
367
  {
368
368
  ariaLabel: "Skip as the first step when filled",
369
- value: k(l.skip_if_filled),
369
+ value: v(l.skip_if_filled),
370
370
  options: D,
371
- onChange: (e) => s({ skip_if_filled: _(e) }, `Change when ${n} is skipped`)
371
+ onChange: (e) => r({ skip_if_filled: _(e) }, `Change when ${n} is skipped`)
372
372
  }
373
373
  )
374
374
  }
375
375
  ),
376
- /* @__PURE__ */ r(
376
+ /* @__PURE__ */ s(
377
377
  d,
378
378
  {
379
379
  k: "group.visible_when",
@@ -388,7 +388,7 @@ function je({ group: l, readOnly: u }) {
388
388
  onChange: (e) => {
389
389
  K(e);
390
390
  const a = e.filter((c) => c.field);
391
- JSON.stringify(a) !== C && s({ visible_when: _(a) }, `Change when ${n} shows`, !0);
391
+ JSON.stringify(a) !== C && r({ visible_when: _(a) }, `Change when ${n} shows`, !0);
392
392
  }
393
393
  }
394
394
  ),
@@ -399,14 +399,14 @@ function je({ group: l, readOnly: u }) {
399
399
  target: { kind: "step", group: l.key },
400
400
  bundle: o.bundle,
401
401
  apply: (e, a) => o.apply(e, a),
402
- disabled: u
402
+ disabled: m
403
403
  }
404
404
  )
405
405
  ]
406
406
  }
407
407
  )
408
408
  ] }),
409
- v && /* @__PURE__ */ r($, { title: "Who", children: [
409
+ w && /* @__PURE__ */ s($, { title: "Who", children: [
410
410
  /* @__PURE__ */ t(
411
411
  d,
412
412
  {
@@ -416,8 +416,8 @@ function je({ group: l, readOnly: u }) {
416
416
  children: /* @__PURE__ */ t(
417
417
  q,
418
418
  {
419
- roleIds: k(l.hidden_for_roles),
420
- onRoleIdsChange: (e) => s({ hidden_for_roles: _(e) }, `Change who sees ${n}`)
419
+ roleIds: v(l.hidden_for_roles),
420
+ onRoleIdsChange: (e) => r({ hidden_for_roles: _(e) }, `Change who sees ${n}`)
421
421
  }
422
422
  )
423
423
  }
@@ -431,139 +431,152 @@ function je({ group: l, readOnly: u }) {
431
431
  children: /* @__PURE__ */ t(
432
432
  q,
433
433
  {
434
- roleIds: k(l.locked_for_roles),
435
- onRoleIdsChange: (e) => s({ locked_for_roles: _(e) }, `Change who can edit ${n}`)
434
+ roleIds: v(l.locked_for_roles),
435
+ onRoleIdsChange: (e) => r({ locked_for_roles: _(e) }, `Change who can edit ${n}`)
436
436
  }
437
437
  )
438
438
  }
439
439
  )
440
440
  ] }),
441
- v && /* @__PURE__ */ r($, { title: "When collapsed", children: [
442
- /* @__PURE__ */ t(
441
+ w && /* @__PURE__ */ s($, { title: "When collapsed", children: [
442
+ /* @__PURE__ */ s(
443
443
  d,
444
444
  {
445
445
  k: "group.summary_fields",
446
446
  label: "Show these values in the heading",
447
- effect: "A short summary while the section is closed.",
448
- children: j.length === 0 ? /* @__PURE__ */ r("p", { className: "text-[12px] leading-snug text-slate-500 dark:text-muted-foreground", children: [
449
- "Place fields in ",
450
- n,
451
- " first."
452
- ] }) : /* @__PURE__ */ t("div", { className: "space-y-1.5", children: j.map((e) => {
453
- const a = x.find((h) => h.field === e), c = ke(e, f) === "O2M", N = o.bundle.placements.find((h) => h.field === e) ?? null, O = Z(e, m, f, N).label, E = (h, b, le) => G(
454
- x.map((A) => A.field === e ? { ...A, ...h } : A),
455
- b,
456
- le
457
- );
458
- return /* @__PURE__ */ r("div", { className: "space-y-1", children: [
459
- /* @__PURE__ */ r("label", { className: "flex items-center gap-2 text-[12px]", children: [
460
- /* @__PURE__ */ t(
461
- "input",
462
- {
463
- type: "checkbox",
464
- checked: !!a,
465
- onChange: (h) => G(
466
- h.target.checked ? [...x, c ? { field: e, agg: "count" } : { field: e }] : x.filter((b) => b.field !== e),
467
- `Change the summary of ${n}`
468
- ),
469
- className: "h-3.5 w-3.5 accent-nvr-cyan"
470
- }
471
- ),
472
- /* @__PURE__ */ t("span", { className: "flex-1 truncate", children: O }),
473
- c && /* @__PURE__ */ t("span", { className: "text-[12px] leading-snug text-slate-500 dark:text-muted-foreground", children: "list" })
474
- ] }),
475
- a && /* @__PURE__ */ r("div", { className: "space-y-1 pl-5", children: [
476
- /* @__PURE__ */ t("div", { "data-setting": "group.summary_fields.label", children: /* @__PURE__ */ t(
477
- S,
478
- {
479
- ariaLabel: `Label for ${O}`,
480
- value: a.label ?? "",
481
- placeholder: `Label (${O})`,
482
- onChange: (h) => E(
483
- { label: h || null },
484
- `Change the summary of ${n}`,
485
- !0
486
- )
487
- }
488
- ) }),
489
- c && /* @__PURE__ */ r("div", { className: "flex gap-1", children: [
490
- /* @__PURE__ */ t("div", { className: "flex-1", "data-setting": "group.summary_fields.agg", children: /* @__PURE__ */ t(
491
- F,
447
+ effect: "A short summary while the section is closed, in edit and summary view. Two or three values read best; the summary heading shows the first three.",
448
+ children: [
449
+ j.length === 0 ? /* @__PURE__ */ s("p", { className: "text-[12px] leading-snug text-slate-500 dark:text-muted-foreground", children: [
450
+ "Place fields in ",
451
+ n,
452
+ " first."
453
+ ] }) : /* @__PURE__ */ t("div", { className: "space-y-1.5", children: j.map((e) => {
454
+ const a = b.find((h) => h.field === e), c = ke(e, f) === "O2M", N = o.bundle.placements.find((h) => h.field === e) ?? null, O = Z(e, u, f, N).label, E = (h, y, le) => G(
455
+ b.map((A) => A.field === e ? { ...A, ...h } : A),
456
+ y,
457
+ le
458
+ );
459
+ return /* @__PURE__ */ s("div", { className: "space-y-1", children: [
460
+ /* @__PURE__ */ s("label", { className: "flex items-center gap-2 text-[12px]", children: [
461
+ /* @__PURE__ */ t(
462
+ "input",
492
463
  {
493
- ariaLabel: "Show",
494
- value: a.agg ?? "count",
495
- options: [
496
- { value: "count", label: "Count" },
497
- { value: "sum", label: "Sum" },
498
- { value: "avg", label: "Average" },
499
- { value: "min", label: "Smallest" },
500
- { value: "max", label: "Largest" }
501
- ],
502
- onChange: (h) => E(
503
- h === "count" ? { agg: h, agg_field: void 0, field_options: void 0 } : { agg: h },
464
+ type: "checkbox",
465
+ checked: !!a,
466
+ onChange: (h) => G(
467
+ h.target.checked ? [...b, c ? { field: e, agg: "count" } : { field: e }] : b.filter((y) => y.field !== e),
504
468
  `Change the summary of ${n}`
505
- )
469
+ ),
470
+ className: "h-3.5 w-3.5 accent-nvr-cyan"
506
471
  }
507
- ) }),
508
- (a.agg ?? "count") !== "count" && /* @__PURE__ */ t(
509
- "div",
472
+ ),
473
+ /* @__PURE__ */ t("span", { className: "flex-1 truncate", children: O }),
474
+ c && /* @__PURE__ */ t("span", { className: "text-[12px] leading-snug text-slate-500 dark:text-muted-foreground", children: "list" })
475
+ ] }),
476
+ a && /* @__PURE__ */ s("div", { className: "space-y-1 pl-5", children: [
477
+ /* @__PURE__ */ t("div", { "data-setting": "group.summary_fields.label", children: /* @__PURE__ */ t(
478
+ S,
510
479
  {
511
- className: "flex-1",
512
- "data-setting": "group.summary_fields.agg_field",
513
- children: /* @__PURE__ */ t(
514
- re,
515
- {
516
- relatedCollection: _e(e, f),
517
- value: a.agg_field ?? "",
518
- onChange: (h, b) => E(
519
- { agg_field: h, field_options: b },
520
- `Change the summary of ${n}`
521
- )
522
- }
480
+ ariaLabel: `Label for ${O}`,
481
+ value: a.label ?? "",
482
+ placeholder: `Label (${O})`,
483
+ onChange: (h) => E(
484
+ { label: h || null },
485
+ `Change the summary of ${n}`,
486
+ !0
523
487
  )
524
488
  }
525
- )
489
+ ) }),
490
+ c && /* @__PURE__ */ s("div", { className: "flex gap-1", children: [
491
+ /* @__PURE__ */ t("div", { className: "flex-1", "data-setting": "group.summary_fields.agg", children: /* @__PURE__ */ t(
492
+ F,
493
+ {
494
+ ariaLabel: "Show",
495
+ value: a.agg ?? "count",
496
+ options: [
497
+ { value: "count", label: "Count" },
498
+ { value: "sum", label: "Sum" },
499
+ { value: "avg", label: "Average" },
500
+ { value: "min", label: "Smallest" },
501
+ { value: "max", label: "Largest" }
502
+ ],
503
+ onChange: (h) => E(
504
+ h === "count" ? { agg: h, agg_field: void 0, field_options: void 0 } : { agg: h },
505
+ `Change the summary of ${n}`
506
+ )
507
+ }
508
+ ) }),
509
+ (a.agg ?? "count") !== "count" && /* @__PURE__ */ t(
510
+ "div",
511
+ {
512
+ className: "flex-1",
513
+ "data-setting": "group.summary_fields.agg_field",
514
+ children: /* @__PURE__ */ t(
515
+ re,
516
+ {
517
+ relatedCollection: ve(e, f),
518
+ value: a.agg_field ?? "",
519
+ onChange: (h, y) => E(
520
+ { agg_field: h, field_options: y },
521
+ `Change the summary of ${n}`
522
+ )
523
+ }
524
+ )
525
+ }
526
+ )
527
+ ] })
526
528
  ] })
527
- ] })
528
- ] }, e);
529
- }) })
529
+ ] }, e);
530
+ }) }),
531
+ b.length > 3 && /* @__PURE__ */ s(
532
+ "p",
533
+ {
534
+ "data-summary-crowded": "",
535
+ className: "mt-1.5 text-[12px] leading-snug text-amber-700 dark:text-amber-300",
536
+ children: [
537
+ b.length,
538
+ " values crowd the heading; the summary view shows the first three."
539
+ ]
540
+ }
541
+ )
542
+ ]
530
543
  }
531
544
  ),
532
545
  /* @__PURE__ */ t(
533
- g,
546
+ k,
534
547
  {
535
548
  k: "group.summary_hide_empty",
536
549
  label: "Leave out empty values",
537
550
  effect: "Fields without a value are left out of the summary line.",
538
551
  checked: l.summary_hide_empty,
539
- onChange: (e) => s({ summary_hide_empty: e }, `Change the summary of ${n}`)
552
+ onChange: (e) => r({ summary_hide_empty: e }, `Change the summary of ${n}`)
540
553
  }
541
554
  )
542
555
  ] }),
543
- v && /* @__PURE__ */ t(
556
+ w && /* @__PURE__ */ t(
544
557
  de,
545
558
  {
546
559
  group: { id: l.id ?? 0, swap_config: l.swap_config },
547
- allFields: m.map((e) => ({ field: e.field, type: e.type ?? void 0 })),
548
- onGroupSettings: (e, a) => s(a, `Change the field swap of ${n}`)
560
+ allFields: u.map((e) => ({ field: e.field, type: e.type ?? void 0 })),
561
+ onGroupSettings: (e, a) => r(a, `Change the field swap of ${n}`)
549
562
  }
550
563
  ),
551
- !u && /* @__PURE__ */ t(he, { bundle: o.bundle, collection: o.collection, group: l }),
552
- /* @__PURE__ */ t(ve, { group: l }),
564
+ !m && /* @__PURE__ */ t(he, { bundle: o.bundle, collection: o.collection, group: l }),
565
+ /* @__PURE__ */ t(_e, { group: l }),
553
566
  /* @__PURE__ */ t(
554
567
  "div",
555
568
  {
556
569
  "data-setting": "group.delete",
557
570
  className: "border-t border-slate-200 pt-3 dark:border-border",
558
- children: te ? /* @__PURE__ */ r("div", { className: "space-y-2 rounded-md border border-red-200 bg-red-50 p-2.5 text-[12px] text-red-900 dark:border-red-800/60 dark:bg-red-950/30 dark:text-red-100", children: [
559
- /* @__PURE__ */ r("p", { children: [
571
+ children: te ? /* @__PURE__ */ s("div", { className: "space-y-2 rounded-md border border-red-200 bg-red-50 p-2.5 text-[12px] text-red-900 dark:border-red-800/60 dark:bg-red-950/30 dark:text-red-100", children: [
572
+ /* @__PURE__ */ s("p", { children: [
560
573
  "Delete ",
561
574
  n,
562
575
  "? Its fields move to the top of the form",
563
576
  L.length ? " and its tabs move out" : "",
564
577
  ". Undo brings it back."
565
578
  ] }),
566
- /* @__PURE__ */ r("div", { className: "flex gap-2", children: [
579
+ /* @__PURE__ */ s("div", { className: "flex gap-2", children: [
567
580
  /* @__PURE__ */ t(
568
581
  "button",
569
582
  {
@@ -585,7 +598,7 @@ function je({ group: l, readOnly: u }) {
585
598
  }
586
599
  )
587
600
  ] })
588
- ] }) : /* @__PURE__ */ r(
601
+ ] }) : /* @__PURE__ */ s(
589
602
  "button",
590
603
  {
591
604
  type: "button",