@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,159 @@
1
+ const h = {
2
+ // ── Signing in / access ────────────────────────────────────────────────────
3
+ NOT_SIGNED_IN: "Sign in again, then try once more.",
4
+ UNAUTHENTICATED: "Sign in again, then try once more.",
5
+ SESSION_EXPIRED: "Your session ended. Sign in again, then try once more.",
6
+ SESSION_ENDED: "Your session ended. Sign in again, then try once more.",
7
+ SESSION_REQUIRED: "Sign in with your own account (not an API key) to do this.",
8
+ SIGN_IN_DISABLED: "Ask an administrator to turn sign-in back on for your role.",
9
+ TOO_MANY_ATTEMPTS: "Wait a few minutes before trying to sign in again.",
10
+ FORBIDDEN: "Ask an administrator for access if you need it.",
11
+ ADMIN_ONLY: "Only administrators can do this. Ask one to do it for you.",
12
+ FIELD_FORBIDDEN: "Leave that field out, or ask an administrator for access to it.",
13
+ FIELD_NOT_READABLE: "Leave that field out, or ask an administrator for access to it.",
14
+ FILE_NOT_READABLE: "Ask the person who shared it to share it with you, or attach your own copy.",
15
+ NOT_WHILE_MASQUERADING: "Stop viewing as someone else first, then try again.",
16
+ API_KEY_SCOPE_MISSING: "Use a key that has this scope, or ask an administrator to add it.",
17
+ API_KEY_EXPIRED: "Create a new key under API keys and use it instead.",
18
+ API_KEY_INVALID: "Check the key, or create a new one under API keys.",
19
+ SANDBOX_KEY_READ_ONLY: "Use a regular key to store changes, or rehearse the write with dry_run.",
20
+ SANDBOX_KEY_DRY_RUN_ONLY: "Use a regular key to store changes, or rehearse the write with dry_run.",
21
+ OAUTH_TOKEN_AUDIENCE: "Make this change in Nivaro itself. Connected apps cannot make it.",
22
+ CREDENTIAL_MINT_REFUSED: "Make this change in Nivaro itself. Connected apps cannot make it.",
23
+ MCP_TOOL_NOT_ALLOWED: "Ask an administrator to allow this tool for the connection.",
24
+ MCP_SCOPE_LOCKED: "Ask an administrator to change what this connection may do.",
25
+ SYSTEM_COLLECTION: "System tables change only through their own admin pages.",
26
+ CLOUD_EXTENSIONS_LOCKED: "Extensions are managed by your hosting plan.",
27
+ // ── Records and forms ──────────────────────────────────────────────────────
28
+ OUT_OF_SCOPE: "Pick a value inside your own scope, or ask someone who covers that one to create the record.",
29
+ EDIT_LOCKED: "This record is locked at its current stage. Ask its owner or an administrator to change it.",
30
+ RECORD_LOCKED: "Someone else is editing this record. Wait until they finish, then reload.",
31
+ ITEM_LOCKED: "Someone else is editing this record. Wait until they finish, then reload.",
32
+ MIDAIR_COLLISION: "Someone saved this record while you were editing. Reload to see their changes, then make yours again.",
33
+ VALIDATION_RULE_FAILED: "Correct the highlighted field, then save again.",
34
+ VALIDATION_FAILED: "Correct the highlighted fields, then save again.",
35
+ REQUIRED_VALUE_MISSING: "Fill in the highlighted field, then save again.",
36
+ CHANGE_REASON_REQUIRED: "Give a reason for the change, then save again.",
37
+ REASON_REQUIRED: "Give a reason, then try again.",
38
+ CHANGE_NOTE_REQUIRED: "Add a note that says what changed, then try again.",
39
+ PICKER_RULE_VIOLATED: "Pick one of the values the list offers for that field, then save again.",
40
+ LINKED_RECORD_MISSING: "The linked record you picked no longer exists. Pick it again from the list, then save.",
41
+ RECORD_IN_USE: "Remove or re-link the records that point to this one first, then delete it.",
42
+ DUPLICATE_RECORD: "Change the value so it is unique, or open the existing record instead.",
43
+ VALUE_TOO_LONG: "Shorten the value, then save again.",
44
+ VALUE_TYPE_MISMATCH: "Check each value fits its field (a number, a date, yes or no), then save.",
45
+ VALUE_OUT_OF_RANGE: "Use a smaller number, then save again.",
46
+ DELETE_GUARDED: "This record is protected from deletion. Sort out what the message names first.",
47
+ TRANSITION_DUPLICATE: "This move was already made. Reload the record to see where it is now.",
48
+ NESTED_ROW_REFUSED: "Fix the line the message names, then save again.",
49
+ NESTED_ROW_NOT_OWNED: "That line belongs to another record. Reload, then try again.",
50
+ NESTED_ROWS_LIMIT: "Save fewer lines at once, then add the rest in another save.",
51
+ UNKNOWN_FIELD: "That field does not exist on this collection. Check its name.",
52
+ NOT_EDITABLE: "This value cannot be changed here.",
53
+ NOT_A_SINGLETON: "Open the collection as a list instead.",
54
+ CLONE_SAME_KEY: "Give the copy a different key.",
55
+ STATE_IN_USE: "Move the records out of this state first, then try again.",
56
+ STATE_IN_HISTORY: "Records have passed through this state. Hide it instead of deleting it.",
57
+ SLA_OVERRIDE_FORBIDDEN: "Ask an administrator to change the deadline.",
58
+ DELEGATE_CANNOT_SEE: "Pick a delegate who can see these records.",
59
+ NUDGE_TOO_SOON: "A reminder was just sent. Wait a while before sending another.",
60
+ // ── Not found ──────────────────────────────────────────────────────────────
61
+ NOT_FOUND: "It may have been deleted or moved. Reload, or search for it again.",
62
+ COLLECTION_NOT_FOUND: "Check the collection name, or reload. It may have been renamed.",
63
+ COLLECTION_TABLE_MISSING: "Ask an administrator to check this collection in the data model.",
64
+ USER_NOT_FOUND: "Pick the person again from the list.",
65
+ HELP_VIDEO_NOT_FOUND: "The video may have been archived. Search the video library.",
66
+ // ── Changed while you worked ───────────────────────────────────────────────
67
+ STALE: "This changed since you previewed it. Preview again, then apply.",
68
+ PROC_STALE: "Someone changed this procedure after you opened it. Reload to see their version, then make your change again.",
69
+ PROC_DRIFTED: "The database copy was changed outside Nivaro. Compare the two, then keep one of them.",
70
+ PROC_EXISTS: "Pick another name, or adopt the existing procedure.",
71
+ APP_MANAGED: "Change it on the Procedures page, which keeps its history.",
72
+ MANAGED_PROCEDURE: "Change it on the Procedures page, which keeps its history.",
73
+ SQL_CHECK_FIX_STALE: "The procedure changed since the preview. Propose the fix again.",
74
+ TUNING_STALE: "Prove the proposal again, then apply it.",
75
+ HELP_VIDEO_EDITS_CONFLICT: "Someone else edited this video. Reload to see their edits, then make yours again.",
76
+ IDEMPOTENCY_IN_PROGRESS: "The same request is still running. Wait a moment, then check the result.",
77
+ IDEMPOTENCY_KEY_REUSED: "Send a new Idempotency-Key with a different request.",
78
+ DUPLICATE_REQUEST: "It was already sent. There is no need to send it again.",
79
+ // ── Limits ─────────────────────────────────────────────────────────────────
80
+ RATE_LIMITED: "Too many requests in a short time. Wait a minute, then try again.",
81
+ API_KEY_RATE_LIMITED: "This key sent too many requests. Wait a minute, then try again.",
82
+ MCP_CONNECTION_RATE_LIMITED: "This connection sent too many requests. Wait a minute.",
83
+ AI_RATE_LIMITED: "Too many AI requests in a short time. Wait a minute, then try again.",
84
+ AI_DAILY_TOKENS: "You have used today's AI allowance. Try again tomorrow, or ask an administrator to raise it.",
85
+ BATCH_LIMIT: "Select fewer records, then run it again in smaller batches.",
86
+ BULK_ROWS_LIMIT: "Select fewer records, then run it again in smaller batches.",
87
+ BATCH_READ_LIMIT: "Ask for fewer records at once.",
88
+ TOO_MANY_IDS: "Ask for fewer records at once.",
89
+ FST_ERR_CTP_BODY_TOO_LARGE: "Send less at once: split the upload or the change into parts.",
90
+ QUERY_TOO_COSTLY: "Ask for fewer fields or fewer nested records at once.",
91
+ LIST_TIMEOUT: "Try again, or narrow the filters.",
92
+ HUDDLE_SCHEDULE_OPEN_LIMIT: "Cancel or finish a scheduled huddle first.",
93
+ // ── Filters ────────────────────────────────────────────────────────────────
94
+ FIELD_NOT_FILTERABLE: "Filter on a different field, or remove that filter.",
95
+ FILTER_VALUE_TYPE: "Check the filter value fits the field (a number, a date, yes or no).",
96
+ FILTER_OPERATOR_TYPE: "Pick a comparison that works for this kind of field.",
97
+ FILTER_VALUE_NOT_A_CHOICE: "Pick one of the field’s own choices in the filter.",
98
+ FILTER_VALUE_IS_LABEL: "Filter on the choice itself, not its label.",
99
+ FILTER_VALUE_SHAPE: "Check the filter value, then try again.",
100
+ FILTER_VALUE_EMPTY: "Give the filter a value, or remove it.",
101
+ FILTER_NOT_AN_OBJECT: "Check the filter, then try again.",
102
+ CURSOR_SORT_UNSUPPORTED: "Sort by a different field, or page without a cursor.",
103
+ // ── The platform ───────────────────────────────────────────────────────────
104
+ MAINTENANCE: "Wait until maintenance ends, then try again.",
105
+ SERVER_BUSY: "Try again in a few seconds.",
106
+ DB_UNAVAILABLE: "The database cannot be reached right now. Try again in a minute.",
107
+ MIGRATION_PENDING: "An update is still being applied. Try again in a few minutes.",
108
+ NOT_CONFIGURED: "Ask an administrator to set this up first.",
109
+ NOT_READY: "This is still being set up. Try again in a few minutes.",
110
+ AI_NOT_CONFIGURED: "Ask an administrator to set up AI under Settings → AI Features.",
111
+ AI_UNAVAILABLE: "The AI service is not answering. Try again in a minute.",
112
+ AI_BUSY: "The AI service is busy. Try again in a minute.",
113
+ RENDER_UNAVAILABLE: "Rendering is not available right now. Try again in a minute.",
114
+ RENDER_BUSY: "Rendering is busy. Try again in a minute.",
115
+ HELP_VIDEO_PROCESSING: "The video is still being prepared. Try again in a few minutes.",
116
+ HELP_VIDEO_AUTHOR_ONLY: "Only video authors can do this. Ask an administrator to add you.",
117
+ CHAOS_GATE: "Fault drills are turned off on this instance."
118
+ }, i = {
119
+ 400: "Check what was entered, then try again.",
120
+ 401: "Sign in again, then try once more.",
121
+ 403: "Ask an administrator for access if you need it.",
122
+ 404: "It may have been deleted or moved. Reload, or search for it again.",
123
+ 409: "Something changed while you were working. Reload, then try again.",
124
+ 413: "Send less at once: split the upload or the change into parts.",
125
+ 422: "Correct the highlighted values, then try again.",
126
+ 423: "Someone else is working on this. Wait a moment, then reload.",
127
+ 429: "Too many requests in a short time. Wait a minute, then try again.",
128
+ 500: "Try again. If it keeps happening, copy the details and send them to your administrator.",
129
+ 502: "The server could not reach a service it needs. Try again in a minute.",
130
+ 503: "The server is busy or restarting. Try again in a minute.",
131
+ 504: "The server took too long to answer. Try again in a minute."
132
+ };
133
+ function d(e, t) {
134
+ if (typeof e == "string" && h[e]) return h[e];
135
+ if (i[t]) return i[t];
136
+ if (t >= 500) return i[500];
137
+ if (t >= 400) return i[400];
138
+ }
139
+ const n = (e) => typeof e == "string" && /^[A-Za-z_][\w.$]{0,199}$/.test(e);
140
+ function _(e) {
141
+ const t = /* @__PURE__ */ new Set(), o = e.fields;
142
+ if (Array.isArray(o))
143
+ for (const a of o) n(a) && t.add(a);
144
+ if (Array.isArray(e.violations))
145
+ for (const a of e.violations) {
146
+ const s = a == null ? void 0 : a.field;
147
+ n(s) && t.add(s);
148
+ }
149
+ if (n(e.field) && t.add(e.field), Array.isArray(e.missing))
150
+ for (const a of e.missing) n(a) && t.add(a);
151
+ const E = typeof e.error == "string" ? e.error : "", r = /^([A-Za-z_]\w{0,99})\[[^\]]{1,40}\]: /.exec(E);
152
+ return r && t.add(r[1]), [...t];
153
+ }
154
+ export {
155
+ h as ERROR_HINTS,
156
+ i as STATUS_HINTS,
157
+ _ as fieldsFromBody,
158
+ d as hintFor
159
+ };
@@ -0,0 +1,105 @@
1
+ import { fieldsFromBody as w, hintFor as T } from "./error-hints.js";
2
+ import { isCodeError as O, SOMETHING_WENT_WRONG as R, userErrorMessage as v, isBareStatusText as h, statusTitle as I, errorStatusOf as S } from "./safe-error.js";
3
+ const d = "x-nivaro-request-id", $ = /^[A-Z][A-Z0-9_]{2,}$/, A = /^(ERR_|E[A-Z]+$)/, q = /failed to fetch|load failed|networkerror|network request failed|network error/i, r = (t) => !!t && typeof t == "object" && !Array.isArray(t);
4
+ function N(t) {
5
+ if (!r(t)) return null;
6
+ const n = t.response;
7
+ return r(n) ? r(n.data) ? n.data : "data" in n && typeof n.data == "string" ? null : n : r(t.extensions) || !(t instanceof Error) && ("error" in t || "message" in t || "code" in t) ? t : null;
8
+ }
9
+ function u(t) {
10
+ return typeof t == "string" && t.trim() ? t.trim() : void 0;
11
+ }
12
+ function x(t, n) {
13
+ const e = r(n == null ? void 0 : n.extensions) ? n.extensions : null;
14
+ for (const i of [n == null ? void 0 : n.code, e == null ? void 0 : e.code, r(t) ? t.code : void 0])
15
+ if (typeof i == "string" && $.test(i) && !A.test(i)) return i;
16
+ }
17
+ function C(t, n) {
18
+ const e = u(n == null ? void 0 : n.request_id) ?? u(n == null ? void 0 : n.requestId);
19
+ if (e) return e;
20
+ if (!r(t)) return;
21
+ const i = u(t.requestId) ?? u(t.request_id);
22
+ if (i) return i;
23
+ const s = r(t.response) ? t.response.headers : void 0;
24
+ if (r(s)) return u(s[d]);
25
+ const a = s == null ? void 0 : s.get;
26
+ if (typeof a == "function") return u(a.call(s, d));
27
+ }
28
+ function D(t, n) {
29
+ const e = S(t) ?? (n == null ? void 0 : n.statusCode) ?? (n == null ? void 0 : n.status), i = r(n == null ? void 0 : n.extensions) ? n.extensions.status : void 0, s = typeof e == "number" ? e : typeof i == "number" ? i : void 0;
30
+ return s && s >= 100 && s < 600 ? s : void 0;
31
+ }
32
+ function _(t) {
33
+ for (const n of ["error", "message"]) {
34
+ const e = u(t[n]);
35
+ if (e && !h(e)) return e;
36
+ }
37
+ }
38
+ function k(t) {
39
+ return r(t) ? t.name === "TimeoutError" || t.code === "ECONNABORTED" || t.code === "ETIMEDOUT" || /timed out|timeout of \d+ms exceeded/i.test(String(t.message ?? "")) : !1;
40
+ }
41
+ function p(t, n = "Something went wrong") {
42
+ const e = N(t), i = D(t, e), s = x(t, e), a = C(t, e), o = { title: n };
43
+ if (i && (o.status = i), s && (o.code = s), a && (o.requestId = a), O(t))
44
+ return o.title = R, o;
45
+ const g = r(t) ? String(t.message ?? "") : typeof t == "string" ? t : "";
46
+ if (!i && !e && q.test(g))
47
+ return o.title = "Cannot reach the server", o.hint = "Check your connection, then try again.", o;
48
+ if (!i && k(t))
49
+ return o.title = "The server took too long to answer", o.hint = "Try again in a minute. Narrow the request if it keeps happening.", o;
50
+ const c = (e ? _(e) : void 0) ?? v(t, "");
51
+ o.title = c && !h(c) ? c : I(i) ?? (c || n), o.title || (o.title = n);
52
+ const m = u(e == null ? void 0 : e.hint) ?? u(e == null ? void 0 : e.explanation), E = i || s ? T(s, i ?? 400) : void 0, f = m ?? E;
53
+ f && f !== o.title && (o.hint = f);
54
+ const l = e ? w(e) : [];
55
+ return l.length && (o.fields = l), o;
56
+ }
57
+ function F(t, n = {}) {
58
+ var a;
59
+ const e = U(t) ? t : p(t), i = n.page ?? (typeof window < "u" && window.location ? window.location.pathname : void 0);
60
+ return [
61
+ n.action ? `Action: ${n.action}` : null,
62
+ `What happened: ${e.title}`,
63
+ e.hint ? `What to do: ${e.hint}` : null,
64
+ e.code || e.status ? `Code: ${[e.code, e.status ? `HTTP ${e.status}` : null].filter(Boolean).join(" · ")}` : null,
65
+ (a = e.fields) != null && a.length ? `Fields: ${e.fields.join(", ")}` : null,
66
+ e.requestId ? `Request id: ${e.requestId}` : null,
67
+ i ? `Page: ${i}` : null,
68
+ `When: ${(n.now ?? /* @__PURE__ */ new Date()).toISOString()}`
69
+ ].filter((o) => !!o).join(`
70
+ `);
71
+ }
72
+ function U(t) {
73
+ return r(t) && typeof t.title == "string" && !("response" in t) && !("stack" in t);
74
+ }
75
+ async function H(t, n) {
76
+ try {
77
+ const e = F(t, n);
78
+ return typeof navigator > "u" || !navigator.clipboard ? !1 : (await navigator.clipboard.writeText(e), !0);
79
+ } catch {
80
+ return !1;
81
+ }
82
+ }
83
+ function P(t) {
84
+ const n = typeof t == "string" ? t.trim() : String(t ?? "").trim();
85
+ if (!n) return "This row was not imported";
86
+ let e = n;
87
+ const i = n.lastIndexOf(" - ");
88
+ if (i > 0 && /^(insert|update|delete|merge|select|exec)\s/i.test(n) && (e = n.slice(i + 3)), /conflicted with the (FOREIGN KEY|REFERENCE)/i.test(e))
89
+ return "A linked value in this row does not exist — check the spelling or add that record first";
90
+ if (/Violation of (UNIQUE KEY|PRIMARY KEY)|Cannot insert duplicate key/i.test(e))
91
+ return "Another record already has a value from this row — change it in the file, or import with Overwrite";
92
+ const s = /Cannot insert the value NULL into column '([^']+)'/i.exec(e);
93
+ return s ? `${s[1].replace(/_/g, " ")} is empty — fill it in the file or map a column to it` : e.replace(/,? table '[^']*'/gi, "").replace(/\s*(INSERT|UPDATE) fails\./gi, "").trim();
94
+ }
95
+ function j(t, n) {
96
+ const e = p(t, n);
97
+ return e.hint ? `${e.title.replace(/[.!?]\s*$/, "")}. ${e.hint}` : e.title;
98
+ }
99
+ export {
100
+ H as copyErrorDetails,
101
+ p as describeError,
102
+ F as errorDetailsText,
103
+ j as errorSentence,
104
+ P as rowErrorSentence
105
+ };
@@ -0,0 +1,22 @@
1
+ import { toast as t } from "sonner";
2
+ import { describeError as s, copyErrorDetails as n } from "./error-message.js";
3
+ function d(o, e = {}) {
4
+ const r = c(o) ? o : s(o);
5
+ return {
6
+ ...r.hint ? { description: r.hint } : {},
7
+ action: {
8
+ label: "Copy details",
9
+ onClick: () => {
10
+ n(r, e).then(
11
+ (i) => i ? t.success("Details copied") : t.error("Could not copy the details")
12
+ );
13
+ }
14
+ }
15
+ };
16
+ }
17
+ function c(o) {
18
+ return !!o && typeof o == "object" && typeof o.title == "string" && !(o instanceof Error) && !("response" in o);
19
+ }
20
+ export {
21
+ d as errorToastOptions
22
+ };
@@ -0,0 +1,25 @@
1
+ const l = /^[A-Za-z_][A-Za-z0-9_]{0,254}$/;
2
+ function d(n) {
3
+ if (!n) return null;
4
+ const i = new URLSearchParams(n.startsWith("?") ? n.slice(1) : n).get("field"), e = (i == null ? void 0 : i.trim()) ?? "";
5
+ return l.test(e) && !e.startsWith("__") ? e : null;
6
+ }
7
+ function f(n) {
8
+ return `field=${encodeURIComponent(n)}`;
9
+ }
10
+ function s(n) {
11
+ const i = {};
12
+ for (const e of n)
13
+ !e.field || e.resolved_at || e.deleted || (i[e.field] = (i[e.field] ?? 0) + 1);
14
+ return i;
15
+ }
16
+ function u(n, i) {
17
+ const e = n.filter((t) => t.field === i && !t.deleted), o = (t) => t.created_at ? new Date(t.created_at).getTime() : 0;
18
+ return e.sort((t, r) => o(t) - o(r)), { open: e.filter((t) => !t.resolved_at), resolved: e.filter((t) => !!t.resolved_at) };
19
+ }
20
+ export {
21
+ f as fieldDeepLinkQuery,
22
+ u as fieldThread,
23
+ s as openFieldCommentCounts,
24
+ d as parseFieldDeepLink
25
+ };
@@ -0,0 +1,261 @@
1
+ const y = (e) => e.toLocaleString("en-US");
2
+ function w(e) {
3
+ return e.toLocaleString("en-US", {
4
+ style: "currency",
5
+ currency: "USD",
6
+ maximumFractionDigits: Number.isInteger(e) ? 0 : 2
7
+ });
8
+ }
9
+ function _(e, t = "or", i = 3) {
10
+ const r = e.filter((s) => s !== "");
11
+ return r.length === 0 ? "" : r.length === 1 ? r[0] : r.length <= i ? `${r.slice(0, -1).join(", ")} ${t} ${r[r.length - 1]}` : `${r.slice(0, i).join(", ")} ${t} ${r.length - i} more`;
12
+ }
13
+ function h(e) {
14
+ const t = /^(\d{4})-(\d{2})-(\d{2})/.exec(e);
15
+ return t ? new Date(Date.UTC(Number(t[1]), Number(t[2]) - 1, Number(t[3]))).toLocaleDateString("en-US", {
16
+ month: "short",
17
+ day: "numeric",
18
+ year: "numeric",
19
+ timeZone: "UTC"
20
+ }) : e;
21
+ }
22
+ function N(e) {
23
+ switch (e.kind) {
24
+ case "phrase":
25
+ return e.text.trim();
26
+ case "is": {
27
+ const t = _(e.values), i = e.count ?? e.values.length;
28
+ return t ? `${e.field} is ${e.not ? "not " : ""}${t}` : i ? i === 1 ? `${e.field} is ${e.not ? "not " : ""}the one picked` : `${e.field} is ${e.not ? "none" : "one"} of ${y(i)} picked` : "";
29
+ }
30
+ case "text": {
31
+ const t = e.text.trim();
32
+ if (!t) return "";
33
+ const i = `“${t}”`;
34
+ switch (e.mode ?? "contains") {
35
+ case "equals":
36
+ return `${e.field} is${e.not ? " not" : ""} ${i}`;
37
+ case "starts":
38
+ return `${e.field} ${e.not ? "does not start" : "starts"} with ${i}`;
39
+ case "ends":
40
+ return `${e.field} ${e.not ? "does not end" : "ends"} with ${i}`;
41
+ default:
42
+ return `${e.field} ${e.not ? "does not contain" : "contains"} ${i}`;
43
+ }
44
+ }
45
+ case "compare": {
46
+ const t = (i) => e.currency ? w(i) : `${y(i)}${e.unit ?? ""}`;
47
+ switch (e.op) {
48
+ case "eq":
49
+ return `${e.field} is ${t(e.a)}`;
50
+ case "neq":
51
+ return `${e.field} is not ${t(e.a)}`;
52
+ case "gt":
53
+ return `${e.field} is over ${t(e.a)}`;
54
+ case "gte":
55
+ return `${e.field} is at least ${t(e.a)}`;
56
+ case "lt":
57
+ return `${e.field} is under ${t(e.a)}`;
58
+ case "lte":
59
+ return `${e.field} is at most ${t(e.a)}`;
60
+ case "between":
61
+ return `${e.field} is between ${t(e.a)} and ${t(e.b ?? e.a)}`;
62
+ }
63
+ return "";
64
+ }
65
+ case "date": {
66
+ const t = e.not ? "not " : "";
67
+ switch (e.op) {
68
+ case "today":
69
+ return `${e.field} is ${t}today`;
70
+ case "this_year":
71
+ return `${e.field} is ${t}this year`;
72
+ case "last_days":
73
+ return e.days ? `${e.field} is ${t}in the last ${y(e.days)} days` : "";
74
+ case "on":
75
+ return e.from ? `${e.field} is ${t}${h(e.from)}` : "";
76
+ case "before":
77
+ return e.from ? `${e.field} is ${t}before ${h(e.from)}` : "";
78
+ case "after":
79
+ return e.from ? `${e.field} is ${t}after ${h(e.from)}` : "";
80
+ case "onbefore":
81
+ return e.from ? `${e.field} is ${t}on or before ${h(e.from)}` : "";
82
+ case "onafter":
83
+ return e.from ? `${e.field} is ${t}on or after ${h(e.from)}` : "";
84
+ case "between":
85
+ return e.from && e.to && e.from !== e.to ? `${e.field} is ${t}between ${h(e.from)} and ${h(e.to)}` : e.from ? `${e.field} is ${t}${h(e.from)}` : e.to ? `${e.field} is ${t}on or before ${h(e.to)}` : "";
86
+ }
87
+ return "";
88
+ }
89
+ case "empty":
90
+ return `${e.field} is ${e.empty ? "empty" : "not empty"}`;
91
+ }
92
+ }
93
+ function x(e) {
94
+ var c, m, b;
95
+ const t = [], i = [];
96
+ for (const $ of e.clauses) {
97
+ const o = N($);
98
+ o && ($.kind === "phrase" ? t.push(o) : i.push(o));
99
+ }
100
+ const r = ((c = e.scope) == null ? void 0 : c.trim()) || "", s = ((m = e.viewName) == null ? void 0 : m.trim()) || "", d = ((b = e.search) == null ? void 0 : b.trim()) || "";
101
+ if (!r && !s && !d && t.length === 0 && i.length === 0) return null;
102
+ const n = [`Showing ${e.noun.trim() || "records"}${r ? ` ${r}` : ""}`];
103
+ s && n.push(`in the “${s}” view`), n.push(...t), i.length > 0 && n.push(`where ${_(i, "and", Number.POSITIVE_INFINITY)}`), d && n.push(`matching “${d}”`);
104
+ let a = n.length > 1 ? `${n[0]} ${n[1]}${n.length > 2 ? `, ${n.slice(2).join(", ")}` : ""}` : n[0];
105
+ const f = e.shown;
106
+ if (typeof f == "number" && Number.isFinite(f) && f >= 0) {
107
+ const $ = e.approx ? "about " : "", o = e.of;
108
+ a += typeof o == "number" && Number.isFinite(o) && o > f ? ` — ${$}${y(f)} of ${y(o)}` : ` — ${$}${y(f)}`;
109
+ }
110
+ return `${a}.`;
111
+ }
112
+ const p = /^\d{4}-\d{2}-\d{2}/;
113
+ function q(e) {
114
+ const { field: t, valueLabels: i } = e;
115
+ let r = e.op, s = e.value, d = !1;
116
+ if (r.includes(":")) {
117
+ const [o, l] = r.split(":");
118
+ r = o, s = l, d = l === "true" || l === "false";
119
+ }
120
+ const u = !!e.not;
121
+ if (r === "_null" || r === "_nnull")
122
+ return { kind: "empty", field: t, empty: r === "_null" !== u };
123
+ if (Array.isArray(s)) {
124
+ const o = (i == null ? void 0 : i.length) === s.length ? i : void 0, l = r === "_nin" !== u;
125
+ return o ? { kind: "is", field: t, values: o, not: l } : { kind: "is", field: t, values: [], count: s.length, not: l };
126
+ }
127
+ if (e.kind === "boolean" || d || s === !0 || s === !1) {
128
+ const o = String(s) === "true";
129
+ return { kind: "is", field: t, values: [(r === "_neq" !== u ? !o : o) ? "yes" : "no"] };
130
+ }
131
+ if (r === "_preset") {
132
+ const o = String(s ?? "");
133
+ if (o === "today") return { kind: "date", field: t, op: "today", not: u };
134
+ if (o === "year") return { kind: "date", field: t, op: "this_year", not: u };
135
+ const l = /^(\d+)d$/.exec(o);
136
+ return l ? { kind: "date", field: t, op: "last_days", days: Number(l[1]), not: u } : null;
137
+ }
138
+ const n = s == null ? "" : String(s), a = e.kind === "date" || p.test(n) && e.kind !== "text", f = e.kind === "number" || e.kind === "currency";
139
+ if (r === "_between") {
140
+ const [o, l] = n.split("..");
141
+ if (a)
142
+ return { kind: "date", field: t, op: "between", from: o || void 0, to: l || void 0, not: u };
143
+ const k = Number(o), g = Number(l);
144
+ return Number.isFinite(k) && Number.isFinite(g) && o !== "" && l !== "" ? {
145
+ kind: "compare",
146
+ field: t,
147
+ op: "between",
148
+ a: k,
149
+ b: g,
150
+ currency: e.kind === "currency"
151
+ } : null;
152
+ }
153
+ if (a && p.test(n)) {
154
+ const o = n.slice(0, 10), l = {
155
+ _eq: "on",
156
+ _lt: "before",
157
+ _gt: "after",
158
+ _lte: "onbefore",
159
+ _gte: "onafter"
160
+ }, k = {
161
+ _eq: "on",
162
+ _lt: "onafter",
163
+ _gt: "onbefore",
164
+ _lte: "after",
165
+ _gte: "before"
166
+ };
167
+ if (r === "_neq") return { kind: "date", field: t, op: "on", from: o, not: !u };
168
+ const g = (u ? k : l)[r];
169
+ if (g) return { kind: "date", field: t, op: g, from: o, not: u && r === "_eq" };
170
+ }
171
+ const c = {
172
+ _eq: "eq",
173
+ _neq: "neq",
174
+ _gt: "gt",
175
+ _gte: "gte",
176
+ _lt: "lt",
177
+ _lte: "lte"
178
+ }, m = {
179
+ eq: "neq",
180
+ neq: "eq",
181
+ gt: "lte",
182
+ gte: "lt",
183
+ lt: "gte",
184
+ lte: "gt",
185
+ between: "between"
186
+ }, b = Number(n);
187
+ if (c[r] && n !== "" && Number.isFinite(b) && (f || r !== "_eq")) {
188
+ const o = c[r];
189
+ return {
190
+ kind: "compare",
191
+ field: t,
192
+ op: u ? m[o] : o,
193
+ a: b,
194
+ currency: e.kind === "currency"
195
+ };
196
+ }
197
+ if (!n) return null;
198
+ const $ = (i == null ? void 0 : i[0]) ?? n;
199
+ switch (r) {
200
+ case "_eq":
201
+ return i != null && i.length ? { kind: "is", field: t, values: [$], not: u } : { kind: "text", field: t, text: n, mode: "equals", not: u };
202
+ case "_neq":
203
+ return { kind: "text", field: t, text: n, mode: "equals", not: !u };
204
+ case "_contains":
205
+ return { kind: "text", field: t, text: n, not: u };
206
+ case "_ncontains":
207
+ return { kind: "text", field: t, text: n, not: !u };
208
+ case "_starts_with":
209
+ return { kind: "text", field: t, text: n, mode: "starts", not: u };
210
+ case "_ends_with":
211
+ return { kind: "text", field: t, text: n, mode: "ends", not: u };
212
+ }
213
+ return { kind: "text", field: t, text: n, mode: "equals", not: u };
214
+ }
215
+ function v(e) {
216
+ const { field: t, value: i, optionLabel: r } = e;
217
+ if (Array.isArray(i)) {
218
+ if (i.length === 0) return null;
219
+ const n = i.map((a) => (r == null ? void 0 : r(a)) ?? a);
220
+ return { kind: "is", field: t, values: n };
221
+ }
222
+ const s = String(i ?? "").trim();
223
+ if (!s) return null;
224
+ if (s.startsWith("num:")) {
225
+ const n = s.slice(4), a = n.indexOf(":"), f = n.slice(0, a), c = n.slice(a + 1);
226
+ if (f === "between") {
227
+ const [b, $] = c.split("..").map(Number);
228
+ return Number.isFinite(b) && Number.isFinite($) ? {
229
+ kind: "compare",
230
+ field: t,
231
+ op: f,
232
+ a: Math.min(b, $),
233
+ b: Math.max(b, $),
234
+ currency: e.currency
235
+ } : null;
236
+ }
237
+ const m = Number(c);
238
+ return a > 0 && Number.isFinite(m) ? { kind: "compare", field: t, op: f, a: m, currency: e.currency } : null;
239
+ }
240
+ const d = /^(on|before|after|onbefore|onafter|between|r):(.+)$/.exec(s);
241
+ if (d && (e.type === "date" || p.test(d[2]))) {
242
+ const n = d[1] === "r" ? "between" : d[1];
243
+ if (n === "between") {
244
+ const [a, f] = d[2].split("..");
245
+ return { kind: "date", field: t, op: n, from: a, to: f || a };
246
+ }
247
+ return { kind: "date", field: t, op: n, from: d[2] };
248
+ }
249
+ if (e.type === "range") {
250
+ const [n, a] = s.split(":"), f = Number(n), c = Number(a), m = e.rangeUnit || void 0;
251
+ return n && a && Number.isFinite(f) && Number.isFinite(c) ? { kind: "compare", field: t, op: "between", a: f, b: c, unit: m } : n && Number.isFinite(f) ? { kind: "compare", field: t, op: "gte", a: f, unit: m } : a && Number.isFinite(c) ? { kind: "compare", field: t, op: "lte", a: c, unit: m } : null;
252
+ }
253
+ const u = r == null ? void 0 : r(s);
254
+ return e.type === "select" || e.type === "combobox" || u ? { kind: "is", field: t, values: [u ?? s.replace(/^bool:/, "")] } : { kind: "text", field: t, text: s };
255
+ }
256
+ export {
257
+ q as clauseFromCondition,
258
+ v as clauseFromControlValue,
259
+ N as clauseWords,
260
+ x as filterSentence
261
+ };