@nivaro/react 0.3.41 → 0.3.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/components/LayoutForm.js +100 -98
  2. package/dist/full.css +1 -1
  3. package/dist/hooks/useSessionRecorder.js +1 -1
  4. package/dist/index.d.ts +733 -15
  5. package/dist/index.js +820 -775
  6. package/dist/shared/components/ActivityEntry.js +154 -0
  7. package/dist/shared/components/AudienceConfirmPanel.js +98 -0
  8. package/dist/shared/components/BackgroundRunOffer.js +43 -31
  9. package/dist/shared/components/BroadcastView.js +225 -204
  10. package/dist/shared/components/CollectionBrowserView.js +3924 -3584
  11. package/dist/shared/components/ConfigHistory.js +153 -0
  12. package/dist/shared/components/ConfigReadBack.js +65 -0
  13. package/dist/shared/components/DataTable.js +379 -346
  14. package/dist/shared/components/ForceReloadBanner.js +47 -40
  15. package/dist/shared/components/IdleReloadWatcher.js +69 -0
  16. package/dist/shared/components/ItemEditForm.js +4041 -3853
  17. package/dist/shared/components/MyWorkView.js +278 -213
  18. package/dist/shared/components/NotificationBell.js +130 -121
  19. package/dist/shared/components/ProfileView.js +776 -1003
  20. package/dist/shared/components/RecentRecordsRail.js +34 -16
  21. package/dist/shared/components/RecordReadView.js +500 -477
  22. package/dist/shared/components/Skeletons.js +199 -0
  23. package/dist/shared/components/SlowNotice.js +63 -0
  24. package/dist/shared/components/Term.js +23 -0
  25. package/dist/shared/components/WidgetSlot.js +350 -353
  26. package/dist/shared/components/access/PermissionSummary.js +106 -0
  27. package/dist/shared/components/bulk/BulkActionButtons.js +76 -73
  28. package/dist/shared/components/chat/ChatPanel.js +902 -886
  29. package/dist/shared/components/chat/MemberPaging.js +70 -0
  30. package/dist/shared/components/chat/RoomParts.js +147 -117
  31. package/dist/shared/components/chat/ScreenClip.js +73 -69
  32. package/dist/shared/components/chat/chat-core.js +449 -396
  33. package/dist/shared/components/chat/huddle/huddle-store.js +48 -43
  34. package/dist/shared/components/help-videos/api.js +2 -5
  35. package/dist/shared/components/help-videos/viewer/HelpVideoMatchChip.js +79 -0
  36. package/dist/shared/components/help-videos/viewer/matchChip.js +50 -0
  37. package/dist/shared/components/imports/CollectionImportPanel.js +139 -133
  38. package/dist/shared/components/imports/RunDetailSheet.js +222 -227
  39. package/dist/shared/components/integrations/console/ErrorExplanation.js +121 -0
  40. package/dist/shared/components/integrations/console/PartnerDetail.js +175 -174
  41. package/dist/shared/components/integrations/console/SubmissionRow.js +36 -34
  42. package/dist/shared/components/integrations/console/drill/SubmissionDrill.js +50 -48
  43. package/dist/shared/components/item-edit/FieldComments.js +212 -0
  44. package/dist/shared/components/item-edit/FieldRow.js +340 -336
  45. package/dist/shared/components/item-edit/RecordHeaderActions.js +23 -22
  46. package/dist/shared/components/item-edit/RelationCombobox.js +231 -222
  47. package/dist/shared/components/item-edit/RuleHiddenNotes.js +55 -0
  48. package/dist/shared/components/item-edit/field-comments-context.js +6 -0
  49. package/dist/shared/components/item-edit/field-sources.js +33 -0
  50. package/dist/shared/components/item-edit/rule-hidden.js +30 -0
  51. package/dist/shared/components/layout-editor/HistoryPanel.js +113 -96
  52. package/dist/shared/components/layout-editor/editors/cascade-filters.js +170 -145
  53. package/dist/shared/components/layout-editor/inspector/Breadcrumb.js +22 -18
  54. package/dist/shared/components/layout-editor/inspector/GroupInspector.js +177 -159
  55. package/dist/shared/components/layout-editor/inspector/PickerTab.js +35 -34
  56. package/dist/shared/components/layout-editor/inspector/RulesTab.js +124 -111
  57. package/dist/shared/components/layout-editor/inspector/kit.js +292 -277
  58. package/dist/shared/components/layout-editor/parity-keys.json.js +1 -1
  59. package/dist/shared/components/list/CopyListLinkButton.js +41 -0
  60. package/dist/shared/components/list/InlineEdit.js +363 -0
  61. package/dist/shared/components/notifications/NotificationCenterView.js +213 -181
  62. package/dist/shared/components/notifications/NotificationDetailBits.js +205 -82
  63. package/dist/shared/components/notifications/NotificationRulesEditor.js +515 -0
  64. package/dist/shared/components/notifications/TestMyRules.js +137 -0
  65. package/dist/shared/components/notifications/changes-lines.js +24 -0
  66. package/dist/shared/components/notifications/why-lines.js +64 -0
  67. package/dist/shared/components/panels/CommentPanel.js +316 -281
  68. package/dist/shared/components/panels/LegalHoldBanner.js +38 -0
  69. package/dist/shared/components/panels/PipelinePanel.js +201 -196
  70. package/dist/shared/components/panels/RevisionsPanel.js +496 -479
  71. package/dist/shared/components/pipeline/PipelineEditorView.js +1587 -1560
  72. package/dist/shared/components/pipeline/PipelineStateOwners.js +116 -103
  73. package/dist/shared/components/profile/PersonDidPanel.js +188 -0
  74. package/dist/shared/components/profile/PersonProfile.js +57 -52
  75. package/dist/shared/components/queue/QueueWorklist.js +1526 -1365
  76. package/dist/shared/hooks/useSlowReason.js +39 -0
  77. package/dist/shared/lib/activity-sentence.js +670 -0
  78. package/dist/shared/lib/config-sentences.js +418 -0
  79. package/dist/shared/lib/core-glossary.js +229 -0
  80. package/dist/shared/lib/error-hints.js +159 -0
  81. package/dist/shared/lib/error-message.js +105 -0
  82. package/dist/shared/lib/error-toast.js +22 -0
  83. package/dist/shared/lib/field-comments.js +25 -0
  84. package/dist/shared/lib/filter-sentence.js +261 -0
  85. package/dist/shared/lib/glossary.js +55 -48
  86. package/dist/shared/lib/idle-reload.js +138 -0
  87. package/dist/shared/lib/layout-resolve.js +42 -29
  88. package/dist/shared/lib/list-inline-edit.js +190 -0
  89. package/dist/shared/lib/list-link.js +147 -0
  90. package/dist/shared/lib/nav-trail.js +107 -0
  91. package/dist/shared/lib/prefetch.js +259 -106
  92. package/dist/shared/lib/record-ref.js +72 -0
  93. package/dist/shared/lib/reload-holds.js +25 -0
  94. package/dist/shared/lib/safe-error.js +52 -24
  95. package/dist/shared/lib/skeleton-shapes.js +72 -0
  96. package/dist/shared/lib/slow-reason.js +63 -0
  97. package/package.json +1 -1
@@ -0,0 +1,418 @@
1
+ import { choiceLabel as F, titleCase as y } from "./utils.js";
2
+ import { formulaInputs as P } from "./write-formula.js";
3
+ const R = /* @__PURE__ */ new Set(["integer", "bigInteger", "float", "decimal", "number"]);
4
+ function v(e, n = {}) {
5
+ var t, s, c;
6
+ const o = (t = n.fields) == null ? void 0 : t[e];
7
+ if (o != null && o.trim()) return o.trim();
8
+ if (e.includes(".")) {
9
+ const r = e.split(".");
10
+ return [((c = (s = n.fields) == null ? void 0 : s[r[0]]) == null ? void 0 : c.trim()) || y(r[0]), ...r.slice(1).map((u) => y(u))].join("’s ");
11
+ }
12
+ return y(e);
13
+ }
14
+ function N(e, n = {}) {
15
+ var t;
16
+ const o = (t = n.collections) == null ? void 0 : t[e];
17
+ return o != null && o.trim() ? o.trim() : y(e);
18
+ }
19
+ function w(e, n, o) {
20
+ var s, c;
21
+ const t = (c = (s = o.relatedFields) == null ? void 0 : s[e]) == null ? void 0 : c[n];
22
+ return t != null && t.trim() ? t.trim() : y(n);
23
+ }
24
+ const b = (e) => e == null || e === "" || Array.isArray(e) && e.length === 0;
25
+ function z(e, n) {
26
+ return n === "money" ? `${e < 0 ? "-" : ""}$${Math.abs(e).toLocaleString("en-US", { maximumFractionDigits: 2 })}` : n === "percent" ? `${e.toLocaleString("en-US", { maximumFractionDigits: 2 })}%` : e.toLocaleString("en-US", { maximumFractionDigits: 6 });
27
+ }
28
+ function S(e, n, o = {}) {
29
+ var u, l, h, f, a, d, m;
30
+ if (b(n)) return "empty";
31
+ const t = String(n), s = (l = (u = o.choices) == null ? void 0 : u[e]) == null ? void 0 : l[t];
32
+ if (s != null) return F(s);
33
+ const c = (f = (h = o.records) == null ? void 0 : h[e]) == null ? void 0 : f[t];
34
+ if (c != null) return c;
35
+ if (typeof n == "boolean" || ((a = o.types) == null ? void 0 : a[e]) === "boolean") {
36
+ if (n === !0 || t === "true" || t === "1") return "Yes";
37
+ if (n === !1 || t === "false" || t === "0") return "No";
38
+ }
39
+ const r = (d = o.formats) == null ? void 0 : d[e];
40
+ return (typeof n == "number" || /^\s*-?\d+(\.\d+)?\s*$/.test(t)) && (r || R.has(((m = o.types) == null ? void 0 : m[e]) ?? "")) ? z(Number(t), r) : typeof n == "object" ? JSON.stringify(n) : F(t);
41
+ }
42
+ function _(e) {
43
+ return e.length <= 1 ? e[0] ?? "" : `${e.slice(0, -1).join(", ")} or ${e[e.length - 1]}`;
44
+ }
45
+ function T(e) {
46
+ return e.length <= 1 ? e[0] ?? "" : `${e.slice(0, -1).join(", ")} and ${e[e.length - 1]}`;
47
+ }
48
+ function B(e) {
49
+ if (Array.isArray(e)) return e.map((o) => String(o));
50
+ if (e == null) return null;
51
+ const n = String(e).trim();
52
+ if (!n) return null;
53
+ if (n.startsWith("["))
54
+ try {
55
+ const o = JSON.parse(n);
56
+ return Array.isArray(o) ? o.map((t) => String(t)) : null;
57
+ } catch {
58
+ return null;
59
+ }
60
+ return n.split(",").map((o) => o.trim()).filter(Boolean);
61
+ }
62
+ const C = (e) => e && e[0].toUpperCase() + e.slice(1);
63
+ function A(e, n, o, t = {}) {
64
+ if (!e) return null;
65
+ const s = v(e, t), c = n ?? "eq";
66
+ switch (c) {
67
+ case "null":
68
+ return `${s} is empty`;
69
+ case "nnull":
70
+ return `${s} is set`;
71
+ case "eq":
72
+ return b(o) ? `${s} is empty` : `${s} is ${S(e, o, t)}`;
73
+ case "neq":
74
+ return b(o) ? `${s} is set` : `${s} is not ${S(e, o, t)} (or is empty)`;
75
+ case "gt":
76
+ case "gte":
77
+ case "lt":
78
+ case "lte": {
79
+ if (b(o)) return null;
80
+ const r = { gt: "is over", gte: "is at least", lt: "is under", lte: "is at most" }[c];
81
+ return `${s} ${r} ${S(e, o, t)}`;
82
+ }
83
+ case "contains":
84
+ return b(o) ? null : `${s} contains “${String(o)}”`;
85
+ case "in": {
86
+ const r = B(o);
87
+ return r != null && r.length ? `${s} is ${_(r.map((i) => S(e, i, t)))}` : null;
88
+ }
89
+ default:
90
+ return null;
91
+ }
92
+ }
93
+ function U(e, n = {}) {
94
+ if (!Array.isArray(e) || e.length === 0) return null;
95
+ const o = [];
96
+ for (const t of e) {
97
+ if (!t || typeof t != "object" || !t.field) continue;
98
+ const s = A(t.field, t.op, t.value, n);
99
+ if (!s) return null;
100
+ o.push(s);
101
+ }
102
+ return o.length ? o.join(" and ") : null;
103
+ }
104
+ const I = {
105
+ _eq: "eq",
106
+ _neq: "neq",
107
+ _gt: "gt",
108
+ _gte: "gte",
109
+ _lt: "lt",
110
+ _lte: "lte",
111
+ _in: "in",
112
+ _contains: "contains"
113
+ };
114
+ function O(e, n = {}, o = "") {
115
+ if (!e || typeof e != "object" || Array.isArray(e)) return null;
116
+ const t = [];
117
+ for (const [s, c] of Object.entries(e)) {
118
+ if (s === "_and" || s === "_or") {
119
+ if (!Array.isArray(c) || c.length === 0) return null;
120
+ const l = c.map((h) => O(h, n, o));
121
+ if (l.some((h) => !h)) return null;
122
+ t.push(
123
+ s === "_and" ? l.join(" and ") : `either ${_(l)}`
124
+ );
125
+ continue;
126
+ }
127
+ if (s.startsWith("_")) return null;
128
+ const r = o ? `${o}.${s}` : s;
129
+ if (c === null || typeof c != "object" || Array.isArray(c)) {
130
+ const l = A(r, Array.isArray(c) ? "in" : "eq", c, n);
131
+ if (!l) return null;
132
+ t.push(l);
133
+ continue;
134
+ }
135
+ const i = Object.entries(c);
136
+ if (i.length === 0) return null;
137
+ if (!i.every(([l]) => l.startsWith("_"))) {
138
+ const l = O(c, n, r);
139
+ if (!l) return null;
140
+ t.push(l);
141
+ continue;
142
+ }
143
+ for (const [l, h] of i) {
144
+ let f;
145
+ if (l === "_null" ? f = A(r, h === !1 ? "nnull" : "null", null, n) : l === "_nnull" ? f = A(r, h === !1 ? "null" : "nnull", null, n) : I[l] ? f = A(r, I[l], h, n) : f = null, !f) return null;
146
+ t.push(f);
147
+ }
148
+ }
149
+ return t.length ? t.join(" and ") : null;
150
+ }
151
+ function k(e) {
152
+ if (!e) return null;
153
+ if (typeof e == "object" && !Array.isArray(e)) return e;
154
+ if (typeof e != "string") return null;
155
+ try {
156
+ const n = JSON.parse(e);
157
+ return n && typeof n == "object" && !Array.isArray(n) ? n : null;
158
+ } catch {
159
+ return null;
160
+ }
161
+ }
162
+ function H(e, n, o = {}) {
163
+ var d, m;
164
+ const t = (d = e.parent_field) == null ? void 0 : d.trim(), s = (m = e.filter_column) == null ? void 0 : m.trim();
165
+ if (!t || !s || !n.field) return null;
166
+ const c = v(n.field, o), r = v(t, o), i = n.relatedCollection ?? null, u = i ? N(i, o) : "records", l = i ? s.split(".").map((p, $) => $ === 0 ? w(i, p, o) : y(p)).join("’s ") : y(s), f = e.value_map && Object.keys(e.value_map).length > 0 ? `whose ${l} is mapped from this record’s ${r}` : e.filter_is_m2m ? `whose ${l} is one of this record’s ${r}` : `whose ${l} is this record’s ${r}`, a = [`${c} only offers ${u} ${f}.`];
167
+ return e.clear_on_parent_change !== !1 && a.push(`Changing ${r} clears ${c}.`), e.clear_on_unavailable && a.push(`A ${c} that no longer fits is cleared.`), a.push(
168
+ e.show_all_if_no_parent === !1 ? `${c} stays locked until ${r} is picked.` : `With no ${r} picked, it offers every one.`
169
+ ), e.upstream && a.push(`Picking a ${c} fills ${r} from it.`), a;
170
+ }
171
+ function D(e) {
172
+ return [e.first_name, e.last_name].filter(Boolean).join(" ").trim() || e.email || "someone";
173
+ }
174
+ function j(e) {
175
+ if (e == null || e === "") return [];
176
+ if (Array.isArray(e)) return e;
177
+ try {
178
+ const n = JSON.parse(e);
179
+ return Array.isArray(n) ? n : null;
180
+ } catch {
181
+ return null;
182
+ }
183
+ }
184
+ const M = /* @__PURE__ */ new Set(["eq", "neq", "gt", "gte", "lt", "lte", "in"]);
185
+ function K(e, n, o = {}) {
186
+ const t = j(e.filters);
187
+ if (!t) return null;
188
+ const s = [
189
+ ...(e.users ?? []).map(D),
190
+ ...(e.teams ?? []).map((l) => l.name ? `the ${l.name} team` : "a team")
191
+ ], c = s.length ? s.length > 4 ? `${s.slice(0, 3).join(", ")} and ${s.length - 3} others` : T(s) : "nobody", r = s.length === 1 && !(e.teams ?? []).length ? "owns" : "own", i = n.stateLabel ? `${n.stateLabel}` : "this step";
192
+ if (e.is_default) return `When no other group matches, ${c} ${r} ${i}.`;
193
+ if (t.length === 0 || t.some((l) => !M.has(l.op ?? "eq"))) return null;
194
+ const u = U(
195
+ t.map((l) => ({ field: l.field, op: l.op ?? "eq", value: l.value })),
196
+ o
197
+ );
198
+ return u ? `When ${u}, ${c} ${r} ${i}.` : null;
199
+ }
200
+ function Q(e, n = {}) {
201
+ var a, d, m;
202
+ const o = ((a = e.to_states) != null && a.length ? e.to_states : e.to_state ? [e.to_state] : []).map(
203
+ (p) => {
204
+ var $;
205
+ return (($ = n.states) == null ? void 0 : $[p]) ?? p;
206
+ }
207
+ );
208
+ if (!o.length) return null;
209
+ const t = e.from_state ? ((d = n.states) == null ? void 0 : d[e.from_state]) ?? e.from_state : null, s = j(e.required_roles), c = j(e.condition_rules), r = j(e.requirements);
210
+ if (!s || !c || !r) return null;
211
+ const i = c.length ? U(c, n) : null;
212
+ if (c.length && !i) return null;
213
+ let u;
214
+ if (s.length) {
215
+ const p = s.map(($) => {
216
+ var g;
217
+ return (g = n.roles) == null ? void 0 : g[$];
218
+ }).filter(($) => !!$);
219
+ u = p.length === s.length ? _(p) : `people in ${s.length === 1 ? "one chosen role" : `one of ${s.length} chosen roles`}`;
220
+ } else u = "anyone who can edit the record";
221
+ e.require_owner && (u = e.allow_creator ? `the step’s owner or the record’s creator${s.length ? ` (in ${u})` : ""}` : `the step’s owner${s.length ? ` (in ${u})` : ""}`);
222
+ const l = e.to_previous ? `back to the step it came from (${_(o)} when that is not known)` : `to ${_(o)}`, h = `move it ${t ? `from ${t} ` : "from any step "}${l}`, f = [];
223
+ e.auto_trigger ? f.push(
224
+ C(`${i ? `when ${i}, ` : ""}it moves by itself ${t ? `from ${t} ` : ""}${l}.`)
225
+ ) : f.push(C(`${i ? `when ${i}, ` : ""}${u} can ${h}.`));
226
+ for (const p of r) {
227
+ if ((p == null ? void 0 : p.type) !== "child_fields" || !p.collection || !((m = p.fields) != null && m.length)) return null;
228
+ const $ = p.fields.map(
229
+ (g) => {
230
+ var W;
231
+ return ((W = p.labels) == null ? void 0 : W[g]) ?? w(p.collection, g, n);
232
+ }
233
+ );
234
+ f.push(
235
+ `Before it moves, every ${N(p.collection, n)} line needs ${T($)}.`
236
+ );
237
+ }
238
+ return e.comment_mode === "required" && f.push("A comment is required."), f;
239
+ }
240
+ const q = {
241
+ sum: "Sum of",
242
+ count: "Number of",
243
+ avg: "Average of",
244
+ min: "Smallest",
245
+ max: "Largest",
246
+ median: "Median of",
247
+ distinct_count: "Number of different",
248
+ weighted_avg: "Weighted average of"
249
+ };
250
+ function E(e, n) {
251
+ return e.replace(/\{\{\s*([A-Za-z_][A-Za-z0-9_.]*)\s*\}\}/g, (o, t) => n(t)).replace(/\bitem\.([A-Za-z_][A-Za-z0-9_]*)/g, (o, t) => n(t)).replace(/\s*\*\s*/g, " × ").replace(/\s*\/\s*/g, " ÷ ").replace(/\s+/g, " ").trim();
252
+ }
253
+ function Z(e, n) {
254
+ var f, a;
255
+ const o = typeof e.related_collection == "string" ? e.related_collection : null, t = typeof e.aggregate == "string" ? e.aggregate : null;
256
+ if (!o || !t || !q[t]) return null;
257
+ const s = N(o, n), c = (d) => w(o, d, n), r = [];
258
+ let i;
259
+ if (t === "count")
260
+ i = `${s} records`;
261
+ else {
262
+ const d = typeof e.value_formula == "string" ? e.value_formula.trim() : "", m = typeof e.value_field == "string" ? e.value_field : "";
263
+ if (d)
264
+ i = `(${E(d, c)})`, r.push(...P(d).map(c));
265
+ else if (m)
266
+ i = c(m), r.push(i);
267
+ else return null;
268
+ if (t === "weighted_avg") {
269
+ const p = typeof e.weight_field == "string" ? e.weight_field : "";
270
+ if (!p) return null;
271
+ i = `${i} weighted by ${c(p)}`, r.push(c(p));
272
+ }
273
+ i = `${i} on ${s}`;
274
+ }
275
+ const u = t === "distinct_count" ? `${q[t]} ${i}` : `${q[t]} ${i}`;
276
+ let l = "";
277
+ if (e.filter && typeof e.filter == "object" && Object.keys(e.filter).length > 0) {
278
+ const d = {
279
+ fields: ((f = n.relatedFields) == null ? void 0 : f[o]) ?? {},
280
+ choices: ((a = n.relatedChoices) == null ? void 0 : a[o]) ?? {},
281
+ collections: n.collections,
282
+ relatedFields: n.relatedFields
283
+ }, m = O(e.filter, d);
284
+ if (!m) return null;
285
+ l = ` where ${m}`;
286
+ }
287
+ const h = e.recursive ? ", counting every level below" : "";
288
+ return { text: `${u}${l}${h}`, inputs: r };
289
+ }
290
+ function X(e, n = {}, o = []) {
291
+ var c;
292
+ const t = (r) => v(r, n), s = e.computed_store === !0 || e.computed_store === 1;
293
+ switch (e.computed_type) {
294
+ case "rollup": {
295
+ const r = k(e.computed_formula);
296
+ if (!r) return null;
297
+ const u = (Array.isArray(r.sources) ? r.sources : [r]).map((a) => Z(a, n));
298
+ if (!u.length || u.some((a) => !a)) return null;
299
+ const l = u, h = [];
300
+ l.length > 1 && h.push("The figures above are added together.");
301
+ const f = r.parent_filter;
302
+ if (f && typeof f == "object" && Object.keys(f).length > 0) {
303
+ const a = O(f, n);
304
+ if (!a) return null;
305
+ h.push(`Only for records where ${a}; on other records it is typed in by hand.`);
306
+ }
307
+ return e.computed_store != null && h.push(
308
+ s ? "Saved on the record and recalculated when one of those records changes." : "Worked out each time the record is read."
309
+ ), {
310
+ sentence: `${l.map((a) => a.text).join(", plus ")}.`,
311
+ notes: h,
312
+ inputs: [...new Set(l.flatMap((a) => a.inputs))]
313
+ };
314
+ }
315
+ case "lookup": {
316
+ const r = k(e.computed_formula), i = typeof (r == null ? void 0 : r.fk_field) == "string" ? r.fk_field : null, u = typeof (r == null ? void 0 : r.source_field) == "string" ? r.source_field : null;
317
+ if (!i || !u) return null;
318
+ const l = (c = n.links) == null ? void 0 : c[i], h = l ? w(l, u, n) : y(u);
319
+ return {
320
+ sentence: `Copied from the ${t(i)}’s ${h} when ${t(i)} is set.`,
321
+ notes: [
322
+ `It keeps the value it copied, even if the ${t(i)} changes later; clearing ${t(i)} clears it.`
323
+ ],
324
+ inputs: [t(i)]
325
+ };
326
+ }
327
+ case "read":
328
+ case "write": {
329
+ const r = String(e.computed_formula ?? "").trim();
330
+ if (!r) return null;
331
+ const i = P(r).map(t);
332
+ return {
333
+ sentence: `Worked out as ${E(r, t)}.`,
334
+ notes: [
335
+ e.computed_type === "read" ? "Worked out each time the record is read; it is never saved." : `Saved on the record; worked out again when ${i.length ? _(i) : "an input"} changes.`
336
+ ],
337
+ inputs: i
338
+ };
339
+ }
340
+ }
341
+ for (const { field: r, config: i } of o) {
342
+ const u = k(i), l = k(u == null ? void 0 : u.field_map), h = typeof (u == null ? void 0 : u.source_collection) == "string" ? u.source_collection : null;
343
+ if (!l || !h) continue;
344
+ const f = l[e.field];
345
+ if (typeof f != "string" || !f.trim()) continue;
346
+ const a = typeof (u == null ? void 0 : u.source_fk_field) == "string" ? u.source_fk_field : r, d = f.split("||").map((g) => g.trim()).filter(Boolean), m = d.map(
347
+ (g) => g === "id" ? `the picked ${t(a)} itself` : w(h, g, n)
348
+ ), p = m.length === 1 ? d[0] === "id" ? m[0] : `the ${t(a)}’s ${m[0]}` : `the ${t(a)}’s ${m[0]} (or ${_(m.slice(1))} when that is empty)`, $ = (u == null ? void 0 : u.on_write) === !1 ? "picked on the form" : "set, on the form or through the API";
349
+ return {
350
+ sentence: `Filled from ${p} when ${t(a)} is ${$}.`,
351
+ notes: ["You can change it afterwards; a value someone typed is never overwritten."],
352
+ inputs: [t(a)]
353
+ };
354
+ }
355
+ return null;
356
+ }
357
+ const J = (e, n, o = `${n}s`) => `${e.toLocaleString("en-US")} ${e === 1 ? n : o}`;
358
+ function G(e) {
359
+ if (e.length === 0) return "";
360
+ const n = e.slice(0, 3).map((t) => `“${t}”`), o = e.length - n.length;
361
+ return `${J(e.length, "form")} (${n.join(", ")}${o > 0 ? ` and ${o} more` : ""})`;
362
+ }
363
+ function L(e, n = [], o, t = {}) {
364
+ var c;
365
+ const s = {
366
+ ...t,
367
+ fields: { ...t.fields ?? {} },
368
+ types: { ...t.types ?? {} },
369
+ choices: { ...t.choices ?? {} },
370
+ links: { ...t.links ?? {} }
371
+ };
372
+ for (const r of e) {
373
+ (c = r.label) != null && c.trim() && (s.fields[r.field] = r.label.trim()), r.type && (s.types[r.field] = r.type);
374
+ let i = r.options;
375
+ if (typeof i == "string")
376
+ try {
377
+ i = JSON.parse(i);
378
+ } catch {
379
+ i = null;
380
+ }
381
+ const u = Array.isArray(i) ? i : i && typeof i == "object" ? i.choices : null;
382
+ if (!Array.isArray(u)) continue;
383
+ const l = {};
384
+ for (const h of u) {
385
+ if (!h || typeof h != "object") continue;
386
+ const { value: f, text: a } = h;
387
+ f != null && (l[String(f)] = F(a == null ? String(f) : String(a)));
388
+ }
389
+ Object.keys(l).length && (s.choices[r.field] = l);
390
+ }
391
+ for (const r of n)
392
+ (!o || r.many_collection === o) && r.many_field && r.one_collection && !r.junction_field && (s.links[r.many_field] = r.one_collection);
393
+ return s;
394
+ }
395
+ function x(e) {
396
+ var t;
397
+ const n = [];
398
+ e.forms.length && n.push(`It is on ${G(e.forms)}`);
399
+ const o = ((t = e.records) == null ? void 0 : t.with_value) ?? 0;
400
+ return e.records && o > 0 && n.push(`${J(o, "record")} ${o === 1 ? "has" : "have"} a ${e.fieldLabel}`), n.length ? `${n.join(" and ")}.` : null;
401
+ }
402
+ export {
403
+ T as andList,
404
+ N as collectionLabelOf,
405
+ H as describeCascadeFilter,
406
+ A as describeCondition,
407
+ U as describeConditionList,
408
+ x as describeFieldReach,
409
+ X as describeFieldSource,
410
+ O as describeFilterObject,
411
+ K as describeOwnerGroup,
412
+ Q as describeTransition,
413
+ v as fieldLabelOf,
414
+ E as formulaInWords,
415
+ _ as orList,
416
+ L as sentenceLabelsFromFields,
417
+ S as valueTextOf
418
+ };
@@ -0,0 +1,229 @@
1
+ const d = [
2
+ {
3
+ slug: "collection",
4
+ term: "Collection",
5
+ hint: "A kind of record — one database table, such as Purchase Orders or Vendors.",
6
+ aliases: ["collections"]
7
+ },
8
+ {
9
+ slug: "field",
10
+ term: "Field",
11
+ hint: "One piece of information on a record, such as Status or Amount."
12
+ },
13
+ {
14
+ slug: "relation",
15
+ term: "Relation",
16
+ hint: "A link between two collections, such as a PO pointing at its Vendor.",
17
+ aliases: ["relations"]
18
+ },
19
+ {
20
+ slug: "junction",
21
+ term: "Junction",
22
+ hint: "A hidden table that links many records to many records (M2M)."
23
+ },
24
+ {
25
+ slug: "pipeline",
26
+ term: "Pipeline",
27
+ hint: "The steps a record moves through (states and the moves between them), with who owns each step.",
28
+ aliases: ["pipelines"]
29
+ },
30
+ {
31
+ slug: "state",
32
+ term: "State",
33
+ hint: "One step of a pipeline, such as Draft, Review or Approved.",
34
+ aliases: ["states"]
35
+ },
36
+ {
37
+ slug: "transition",
38
+ term: "Transition",
39
+ hint: "A move from one pipeline state to another, such as Submit or Approve.",
40
+ aliases: ["transitions"]
41
+ },
42
+ {
43
+ slug: "owner-group",
44
+ term: "Owner group",
45
+ hint: "The people who own a pipeline step for records that match its filters.",
46
+ aliases: ["owner groups"]
47
+ },
48
+ {
49
+ slug: "owner-matrix",
50
+ term: "Owner matrix",
51
+ hint: "The grid of owner groups per state and dimension — the most specific match owns the record."
52
+ },
53
+ {
54
+ slug: "dimension",
55
+ term: "Dimension",
56
+ hint: "A field the owner matrix splits ownership by, such as Zone or Category.",
57
+ aliases: ["dimensions"]
58
+ },
59
+ {
60
+ slug: "layout",
61
+ term: "Layout",
62
+ hint: "How a record form is arranged: its sections, fields and rules. Each record gets the best-matching form.",
63
+ aliases: ["layouts", "form layout"]
64
+ },
65
+ {
66
+ slug: "section",
67
+ term: "Section",
68
+ hint: "A titled block of fields on a form layout.",
69
+ aliases: ["sections"]
70
+ },
71
+ {
72
+ slug: "queue",
73
+ term: "Queue",
74
+ hint: "A worklist of records from one or more collections, split into My items, No owners and All items.",
75
+ aliases: ["queues", "worklist"]
76
+ },
77
+ {
78
+ slug: "scope",
79
+ term: "User Scope",
80
+ hint: "A person's own limits, such as their Zones: they only see records that belong to them.",
81
+ aliases: ["user scopes", "scope", "scopes"]
82
+ },
83
+ {
84
+ slug: "row-filter",
85
+ term: "Row filter",
86
+ hint: "A rule on a role that limits which records it can see or change, such as Status is Approved.",
87
+ aliases: ["row filters", "row rule", "row rules", "row-level security"]
88
+ },
89
+ {
90
+ slug: "policy",
91
+ term: "Policy",
92
+ hint: "What a role may do on one collection: see, add, edit or delete, and which fields.",
93
+ aliases: ["policies"]
94
+ },
95
+ {
96
+ slug: "role",
97
+ term: "Role",
98
+ hint: "A set of policies people share. Everyone has exactly one role.",
99
+ aliases: ["roles"]
100
+ },
101
+ {
102
+ slug: "rollup",
103
+ term: "Rollup",
104
+ hint: "A figure worked out from related records, such as the total of all lines on a PO.",
105
+ aliases: ["rollups"]
106
+ },
107
+ {
108
+ slug: "computed-field",
109
+ term: "Computed field",
110
+ hint: "A field whose value is calculated from other fields instead of typed in.",
111
+ aliases: ["computed fields", "formula field"]
112
+ },
113
+ {
114
+ slug: "addendum",
115
+ term: "Addendum",
116
+ hint: "A change request attached to a record, approved on its own before it changes the record.",
117
+ aliases: ["addendums", "amendment"]
118
+ },
119
+ {
120
+ slug: "picker",
121
+ term: "Picker",
122
+ hint: "The dropdown that chooses a related record, such as the Vendor picker on a PO.",
123
+ aliases: ["pickers"]
124
+ },
125
+ {
126
+ slug: "hidden-from-pickers",
127
+ term: "Hidden from pickers",
128
+ hint: "Never offered in any dropdown, but still in lists, search, reports and the API.",
129
+ aliases: ["hide from pickers"]
130
+ },
131
+ {
132
+ slug: "cascade",
133
+ term: "Cascade",
134
+ hint: "A picker narrowed by another field, such as Sites only for the chosen Zone.",
135
+ aliases: ["cascades", "cascading picker"]
136
+ },
137
+ {
138
+ slug: "display-template",
139
+ term: "Display template",
140
+ hint: "How a related record is named in lists and pickers, such as {{number}} — {{vendor}}."
141
+ },
142
+ {
143
+ slug: "flow",
144
+ term: "Flow",
145
+ hint: "An automation: when something happens, run steps such as send mail or update a record.",
146
+ aliases: ["flows"]
147
+ },
148
+ {
149
+ slug: "sla",
150
+ term: "SLA",
151
+ hint: "A deadline for a record in a state; it turns at risk, then breached, as time runs out.",
152
+ aliases: ["deadline", "deadlines"]
153
+ },
154
+ {
155
+ slug: "field-rule",
156
+ term: "Field rule",
157
+ hint: "A rule that fills, shows, hides or locks a field depending on other values.",
158
+ aliases: ["field rules"]
159
+ },
160
+ {
161
+ slug: "edit-lock",
162
+ term: "Edit lock",
163
+ hint: "While someone is editing a record, others can read it but not save over them."
164
+ },
165
+ {
166
+ slug: "workspace",
167
+ term: "Workspace",
168
+ hint: "A separate set of collections and roles inside one instance.",
169
+ aliases: ["workspaces"]
170
+ },
171
+ {
172
+ slug: "custom-query",
173
+ term: "Custom query",
174
+ hint: "Saved SQL that dashboards, reports and pickers can use.",
175
+ aliases: ["custom queries"]
176
+ },
177
+ {
178
+ slug: "record-template",
179
+ term: "Record template",
180
+ hint: "Saved values that pre-fill a new record.",
181
+ aliases: ["record templates"]
182
+ },
183
+ {
184
+ slug: "bulk-action",
185
+ term: "Bulk action",
186
+ hint: "One change applied to many selected records at once.",
187
+ aliases: ["bulk actions"]
188
+ }
189
+ ], c = d.map((e, i) => ({
190
+ id: -(i + 1),
191
+ term: e.term,
192
+ slug: e.slug,
193
+ aliases: e.aliases ?? [],
194
+ definition: e.hint,
195
+ ui_hint: e.hint,
196
+ query_slug: null,
197
+ query_note: null,
198
+ collection: null,
199
+ updated_at: null,
200
+ builtin: !0
201
+ }));
202
+ function u(e) {
203
+ var r, s;
204
+ const i = (r = e.ui_hint) == null ? void 0 : r.trim();
205
+ if (i) return i;
206
+ const o = (e.definition ?? "").trim().replace(/\s+/g, " "), t = ((s = o.match(/^.+?[.!?](?=\s|$)/)) == null ? void 0 : s[0]) ?? o;
207
+ return t.length > 160 ? `${t.slice(0, 157).trimEnd()}…` : t;
208
+ }
209
+ const a = (e) => e.trim().toLowerCase();
210
+ function h(e, i) {
211
+ const o = /* @__PURE__ */ new Map();
212
+ for (const s of e) for (const n of [s.slug, s.term, ...s.aliases]) o.set(a(n), s);
213
+ const t = /* @__PURE__ */ new Map(), r = [];
214
+ for (const s of i) {
215
+ const n = [s.slug, s.term, ...s.aliases ?? []].map((l) => o.get(a(l))).find((l) => !!l);
216
+ n && !t.has(n.slug) ? t.set(n.slug, { ...s, overrides: n.slug }) : r.push(s);
217
+ }
218
+ return [...e.map((s) => t.get(s.slug) ?? s), ...r];
219
+ }
220
+ function m(e, i) {
221
+ const o = a(i);
222
+ return e.find((t) => a(t.slug) === o || t.overrides && a(t.overrides) === o) ?? e.find((t) => a(t.term) === o || t.aliases.some((r) => a(r) === o)) ?? null;
223
+ }
224
+ export {
225
+ c as CORE_GLOSSARY,
226
+ m as findGlossaryTerm,
227
+ h as mergeGlossary,
228
+ u as uiHint
229
+ };