@ai-matrx/records-ui 0.93.146 → 0.95.2
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.
- package/CHANGELOG.md +142 -0
- package/dist/index.cjs +22160 -17446
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +555 -61
- package/dist/index.d.ts +555 -61
- package/dist/index.js +12610 -7849
- package/dist/index.js.map +1 -1
- package/dist/object-actions.cjs +34 -1
- package/dist/object-actions.cjs.map +1 -1
- package/dist/object-actions.d.cts +1 -1
- package/dist/object-actions.d.ts +1 -1
- package/dist/object-actions.js +34 -1
- package/dist/object-actions.js.map +1 -1
- package/dist/{objectActions-Dgdr0E4b.d.cts → objectActions-DozKWxks.d.cts} +27 -1
- package/dist/{objectActions-Dgdr0E4b.d.ts → objectActions-DozKWxks.d.ts} +27 -1
- package/dist/pickers.cjs +826 -593
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.d.cts +4 -1
- package/dist/pickers.d.ts +4 -1
- package/dist/pickers.js +714 -479
- package/dist/pickers.js.map +1 -1
- package/package.json +4 -4
package/dist/pickers.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/TablePickers.tsx
|
|
4
|
-
import { useEffect as useEffect12, useMemo as useMemo7, useState as
|
|
4
|
+
import { useEffect as useEffect12, useMemo as useMemo7, useState as useState16 } from "react";
|
|
5
5
|
import { RecordsProvider as RecordsProvider2, useFields, useRecords, useTable } from "@ai-matrx/records/react";
|
|
6
6
|
import { Button as Button9, CreatablePicker } from "@ai-matrx/design-system";
|
|
7
7
|
|
|
8
8
|
// src/editors.tsx
|
|
9
|
-
import { useCallback as useCallback4, useEffect as useEffect10, useRef as useRef9, useState as
|
|
9
|
+
import { useCallback as useCallback4, useEffect as useEffect10, useRef as useRef9, useState as useState14 } from "react";
|
|
10
10
|
import { allowsOtherValues, choiceValuesOf, coerceTypedAnswer, newerKindOf as newerKindOf4, decideTypedChoice, isTheChosen, optionKey as optionKey2, rankTypedMatches as rankTypedMatches3, readTypedTime as readTypedTime2, typedDateText as typedDateText2, typedTimeText as typedTimeText2 } from "@ai-matrx/records";
|
|
11
|
-
import { useOptionalRecordsClient as
|
|
11
|
+
import { useOptionalRecordsClient as useOptionalRecordsClient7 } from "@ai-matrx/records/react";
|
|
12
12
|
import {
|
|
13
13
|
BasicInput as BasicInput6,
|
|
14
14
|
BasicTextarea as BasicTextarea2,
|
|
@@ -19,12 +19,12 @@ import {
|
|
|
19
19
|
Popover as Popover4,
|
|
20
20
|
PopoverContent as PopoverContent4,
|
|
21
21
|
PopoverTrigger as PopoverTrigger4,
|
|
22
|
-
Select,
|
|
23
|
-
SelectContent,
|
|
24
|
-
SelectItem,
|
|
25
|
-
SelectTrigger,
|
|
26
|
-
SelectValue,
|
|
27
|
-
cn as
|
|
22
|
+
Select as Select2,
|
|
23
|
+
SelectContent as SelectContent2,
|
|
24
|
+
SelectItem as SelectItem2,
|
|
25
|
+
SelectTrigger as SelectTrigger2,
|
|
26
|
+
SelectValue as SelectValue2,
|
|
27
|
+
cn as cn12
|
|
28
28
|
} from "@ai-matrx/design-system";
|
|
29
29
|
|
|
30
30
|
// src/dates.ts
|
|
@@ -82,7 +82,9 @@ import {
|
|
|
82
82
|
isAddressValue,
|
|
83
83
|
isPersonStamp,
|
|
84
84
|
newerKindOf,
|
|
85
|
+
personStampText,
|
|
85
86
|
readTypedDuration,
|
|
87
|
+
safeLinkHref,
|
|
86
88
|
statusGroupOf
|
|
87
89
|
} from "@ai-matrx/records";
|
|
88
90
|
import { BasicInput, cn } from "@ai-matrx/design-system";
|
|
@@ -96,7 +98,7 @@ function newerKindValue(field, value, opts = {}) {
|
|
|
96
98
|
}
|
|
97
99
|
case "created_by":
|
|
98
100
|
case "modified_by":
|
|
99
|
-
return isPersonStamp(value) ? /* @__PURE__ */ jsx(PersonStampChip, {
|
|
101
|
+
return isPersonStamp(value) ? /* @__PURE__ */ jsx(PersonStampChip, { stamp: value }) : void 0;
|
|
100
102
|
case "address":
|
|
101
103
|
return isAddressValue(value) || typeof value === "string" ? /* @__PURE__ */ jsx(AddressLink, { value }) : void 0;
|
|
102
104
|
case "barcode":
|
|
@@ -112,10 +114,12 @@ function newerKindValue(field, value, opts = {}) {
|
|
|
112
114
|
return void 0;
|
|
113
115
|
}
|
|
114
116
|
}
|
|
115
|
-
function PersonStampChip({
|
|
116
|
-
const words =
|
|
117
|
-
const
|
|
118
|
-
|
|
117
|
+
function PersonStampChip({ stamp }) {
|
|
118
|
+
const words = personStampText(stamp) ?? NOT_A_MEMBER_WORDS;
|
|
119
|
+
const tier = stamp.actor ?? "user";
|
|
120
|
+
const name = tier === "user" ? stamp.name : null;
|
|
121
|
+
const initial = tier === "system" ? "\u2699" : tier === "agent" ? "\u2726" : name && name.trim() !== "" ? name.trim()[0].toUpperCase() : "?";
|
|
122
|
+
return /* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-0 items-center gap-1.5", "data-records-person-stamp": tier, children: [
|
|
119
123
|
/* @__PURE__ */ jsx(
|
|
120
124
|
"span",
|
|
121
125
|
{
|
|
@@ -124,7 +128,7 @@ function PersonStampChip({ name }) {
|
|
|
124
128
|
children: initial
|
|
125
129
|
}
|
|
126
130
|
),
|
|
127
|
-
/* @__PURE__ */ jsx("span", { className: cn("truncate",
|
|
131
|
+
/* @__PURE__ */ jsx("span", { className: cn("truncate", tier === "user" && !name ? "italic text-muted-foreground" : ""), children: words })
|
|
128
132
|
] });
|
|
129
133
|
}
|
|
130
134
|
function AddressLink({ value }) {
|
|
@@ -149,12 +153,13 @@ function AddressLink({ value }) {
|
|
|
149
153
|
);
|
|
150
154
|
}
|
|
151
155
|
var STATUS_GROUP_MARK = { todo: "\u25CB", in_progress: "\u25D0", done: "\u25CF" };
|
|
152
|
-
function statusMarkOf(field, value) {
|
|
156
|
+
function statusMarkOf(field, value, document2) {
|
|
153
157
|
if (newerKindOf(field) !== "status" || typeof value !== "string") return null;
|
|
154
|
-
const
|
|
158
|
+
const chosen = document2?.["_choices"]?.[field.key];
|
|
159
|
+
const key = chosen && typeof chosen === "object" && typeof chosen.key === "string" ? chosen.key : value;
|
|
160
|
+
const group = statusGroupOf(field, key);
|
|
155
161
|
return { mark: STATUS_GROUP_MARK[group], group, words: STATUS_GROUP_WORDS[group] };
|
|
156
162
|
}
|
|
157
|
-
var SAFE_HREF = /^(https?:\/\/|mailto:)/i;
|
|
158
163
|
function inline(text, key) {
|
|
159
164
|
const out = [];
|
|
160
165
|
let at = 0;
|
|
@@ -181,9 +186,9 @@ function marks(text, key) {
|
|
|
181
186
|
if (tok.startsWith("**") || tok.startsWith("__")) out.push(/* @__PURE__ */ jsx("strong", { children: tok.slice(2, -2) }, k));
|
|
182
187
|
else if (tok.startsWith("[")) {
|
|
183
188
|
const link = /^\[([^\]]+)\]\(([^)\s]+)\)$/.exec(tok);
|
|
184
|
-
const href = link?.[2] ?? "";
|
|
189
|
+
const href = safeLinkHref(link?.[2] ?? "");
|
|
185
190
|
out.push(
|
|
186
|
-
|
|
191
|
+
href ? /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline-offset-2 hover:underline", onClick: own, children: link?.[1] }, k) : link?.[1] ?? tok
|
|
187
192
|
);
|
|
188
193
|
} else out.push(/* @__PURE__ */ jsx("em", { children: tok.slice(1, -1) }, k));
|
|
189
194
|
last = at + tok.length;
|
|
@@ -393,6 +398,63 @@ function BarcodeControl({ value, onChange, disabled, id }) {
|
|
|
393
398
|
] });
|
|
394
399
|
}
|
|
395
400
|
|
|
401
|
+
// src/choiceLooks.ts
|
|
402
|
+
import {
|
|
403
|
+
CHOICE_CHIP_CLASS,
|
|
404
|
+
NEUTRAL_CHIP_CLASS,
|
|
405
|
+
STYLE_COLORS
|
|
406
|
+
} from "@ai-matrx/design-system/data-table";
|
|
407
|
+
function displayFormatOf(field) {
|
|
408
|
+
const raw = field.display_format;
|
|
409
|
+
if (!raw || typeof raw !== "object") return null;
|
|
410
|
+
const id = raw.id;
|
|
411
|
+
if (typeof id !== "string" || id === "") return null;
|
|
412
|
+
const options = raw.options;
|
|
413
|
+
return { id, options: options && typeof options === "object" ? options : {} };
|
|
414
|
+
}
|
|
415
|
+
function isStyleColor(v) {
|
|
416
|
+
return typeof v === "string" && STYLE_COLORS.includes(v);
|
|
417
|
+
}
|
|
418
|
+
function choiceLooksOf(field) {
|
|
419
|
+
const display = displayFormatOf(field);
|
|
420
|
+
const choices = display?.options["choices"];
|
|
421
|
+
if (!Array.isArray(choices)) return [];
|
|
422
|
+
const out = [];
|
|
423
|
+
for (const c of choices) {
|
|
424
|
+
if (!c || typeof c !== "object") continue;
|
|
425
|
+
const value = c.value;
|
|
426
|
+
if (typeof value !== "string" || value.trim() === "") continue;
|
|
427
|
+
const color = c.color;
|
|
428
|
+
const label = c.label;
|
|
429
|
+
out.push({
|
|
430
|
+
value: value.trim(),
|
|
431
|
+
...typeof label === "string" && label.trim() !== "" ? { label: label.trim() } : {},
|
|
432
|
+
...isStyleColor(color) ? { color } : {}
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
return out;
|
|
436
|
+
}
|
|
437
|
+
function choiceWord(value) {
|
|
438
|
+
return String(value ?? "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
439
|
+
}
|
|
440
|
+
function storedChoiceColor(field, value) {
|
|
441
|
+
if (value === null || value === void 0 || value === "") return void 0;
|
|
442
|
+
const word = choiceWord(value);
|
|
443
|
+
if (word === "") return void 0;
|
|
444
|
+
for (const look of choiceLooksOf(field)) {
|
|
445
|
+
if (!look.color) continue;
|
|
446
|
+
if (choiceWord(look.value) === word || look.label && choiceWord(look.label) === word) return look.color;
|
|
447
|
+
}
|
|
448
|
+
return void 0;
|
|
449
|
+
}
|
|
450
|
+
function choiceChipLookOf(field, ...words) {
|
|
451
|
+
for (const word of words) {
|
|
452
|
+
const color = storedChoiceColor(field, word);
|
|
453
|
+
if (color) return { className: CHOICE_CHIP_CLASS[color], color };
|
|
454
|
+
}
|
|
455
|
+
return { className: NEUTRAL_CHIP_CLASS, color: null };
|
|
456
|
+
}
|
|
457
|
+
|
|
396
458
|
// src/parity.ts
|
|
397
459
|
import {
|
|
398
460
|
KERNEL_TABLES,
|
|
@@ -622,7 +684,12 @@ var TITLE = {
|
|
|
622
684
|
already_exists: "That already exists",
|
|
623
685
|
not_supported: "That cannot be done here",
|
|
624
686
|
store_limit: "This has got as big as it can",
|
|
625
|
-
|
|
687
|
+
// 🚨 NOT "THE SWITCH IS OFF" (lane 7 W1 fix round 1). PGRST202 / PGRST205 land here, and the
|
|
688
|
+
// commonest cause is a door this screen asks for that the database it talks to does not serve
|
|
689
|
+
// YET — a release in flight. Telling the person her organization has its store switched off was
|
|
690
|
+
// false (the switch is answered by its own door, `platform.unified_data_store_on`). Honest:
|
|
691
|
+
// nothing happened, and it is ours, and it passes.
|
|
692
|
+
store_not_served: "This isn't available right now",
|
|
626
693
|
unreachable: "We could not reach your data",
|
|
627
694
|
needs_approval: "This is waiting on someone's approval",
|
|
628
695
|
stale_read: "Your view of this is a moment behind",
|
|
@@ -640,7 +707,7 @@ var REMEDY = {
|
|
|
640
707
|
already_exists: "Use a different name.",
|
|
641
708
|
not_supported: "There is another way to do this \u2014 ask, and we will point you at it.",
|
|
642
709
|
store_limit: "Split it up, or ask us to raise the ceiling for your organization.",
|
|
643
|
-
store_not_served: "
|
|
710
|
+
store_not_served: "Nothing was changed. Try again in a few minutes.",
|
|
644
711
|
// 🚨 NOTHING WAS WRITTEN AND NOTHING WAS REFUSED (lane TAILS-6). The call
|
|
645
712
|
// never arrived, so "try again" is the honest instruction rather than a
|
|
646
713
|
// consolation — and saying nothing changed is the half a person actually
|
|
@@ -1140,7 +1207,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
|
|
|
1140
1207
|
|
|
1141
1208
|
// src/gridAttachments.tsx
|
|
1142
1209
|
import { useEffect as useEffect6, useRef as useRef5, useState as useState7 } from "react";
|
|
1143
|
-
import { useOptionalRecordsClient as
|
|
1210
|
+
import { useOptionalRecordsClient as useOptionalRecordsClient3 } from "@ai-matrx/records/react";
|
|
1144
1211
|
import { Badge, Button as Button5 } from "@ai-matrx/design-system";
|
|
1145
1212
|
|
|
1146
1213
|
// src/host.tsx
|
|
@@ -1226,6 +1293,7 @@ import { isUuidShape as isUuidShape2 } from "@ai-matrx/kit/uuid";
|
|
|
1226
1293
|
// src/signature.tsx
|
|
1227
1294
|
import { useEffect as useEffect4, useRef as useRef2, useState as useState4 } from "react";
|
|
1228
1295
|
import { Button as Button3, ErrorBox as ErrorBox2, cn as cn5 } from "@ai-matrx/design-system";
|
|
1296
|
+
import { useOptionalRecordsClient as useOptionalRecordsClient2 } from "@ai-matrx/records/react";
|
|
1229
1297
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1230
1298
|
var DRAWN = /^data:image\/(png|jpeg);base64,[A-Za-z0-9+/=]{64,}$/;
|
|
1231
1299
|
function drawnSignatureOf(value) {
|
|
@@ -1236,18 +1304,105 @@ function signatureWords(value) {
|
|
|
1236
1304
|
if (value === null || value === void 0 || value === "") return null;
|
|
1237
1305
|
return drawnSignatureOf(value) ? SIGNED_WORD : String(value);
|
|
1238
1306
|
}
|
|
1239
|
-
function
|
|
1307
|
+
function signatureFileOf(source) {
|
|
1308
|
+
if (!source || typeof source !== "object") return null;
|
|
1309
|
+
const src = source;
|
|
1310
|
+
const id = src["signature_file_id"];
|
|
1311
|
+
return src["kind"] === "signature" && typeof id === "string" && id !== "" ? id : null;
|
|
1312
|
+
}
|
|
1313
|
+
function signatureFileIn(document2, key) {
|
|
1314
|
+
const values = document2?.["_values"];
|
|
1315
|
+
const src = values?.[key]?.src;
|
|
1316
|
+
if (typeof src === "string") {
|
|
1317
|
+
const sources = document2?.["_sources"];
|
|
1318
|
+
return signatureFileOf(sources?.[src]);
|
|
1319
|
+
}
|
|
1320
|
+
return signatureFileOf(src);
|
|
1321
|
+
}
|
|
1322
|
+
var SOURCES = /* @__PURE__ */ new WeakMap();
|
|
1323
|
+
var FILES = /* @__PURE__ */ new WeakMap();
|
|
1324
|
+
function signatureFilesOf(client, recordId) {
|
|
1325
|
+
let held = SOURCES.get(client);
|
|
1326
|
+
if (!held) SOURCES.set(client, held = /* @__PURE__ */ new Map());
|
|
1327
|
+
let asked2 = held.get(recordId);
|
|
1328
|
+
if (!asked2) {
|
|
1329
|
+
asked2 = client.recordValuesVersioned({ record_id: recordId }).then((answered) => {
|
|
1330
|
+
if (!answered.ok) return {};
|
|
1331
|
+
return Object.fromEntries(answered.data.map((v) => [v.field_key, signatureFileOf(v.source)]));
|
|
1332
|
+
});
|
|
1333
|
+
held.set(recordId, asked2);
|
|
1334
|
+
}
|
|
1335
|
+
return asked2;
|
|
1336
|
+
}
|
|
1337
|
+
function drawingOf(client, fileId) {
|
|
1338
|
+
let held = FILES.get(client);
|
|
1339
|
+
if (!held) FILES.set(client, held = /* @__PURE__ */ new Map());
|
|
1340
|
+
let asked2 = held.get(fileId);
|
|
1341
|
+
if (!asked2) {
|
|
1342
|
+
asked2 = client.recordRead({ record_id: fileId }).then((answered) => {
|
|
1343
|
+
if (!answered.ok) return { src: null, hostFileId: null };
|
|
1344
|
+
const doc = answered.data.document ?? {};
|
|
1345
|
+
const content = drawnSignatureOf(doc["content"]);
|
|
1346
|
+
const hostFileId = typeof doc["file_id"] === "string" && doc["file_id"] !== "" ? doc["file_id"] : null;
|
|
1347
|
+
return { src: content, hostFileId };
|
|
1348
|
+
});
|
|
1349
|
+
held.set(fileId, asked2);
|
|
1350
|
+
}
|
|
1351
|
+
return asked2;
|
|
1352
|
+
}
|
|
1353
|
+
function DrawnImage({ src, inCell }) {
|
|
1354
|
+
return /* @__PURE__ */ jsx6(
|
|
1355
|
+
"img",
|
|
1356
|
+
{
|
|
1357
|
+
src,
|
|
1358
|
+
alt: SIGNED_WORD,
|
|
1359
|
+
"data-records-signature": "",
|
|
1360
|
+
className: cn5("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
|
|
1361
|
+
}
|
|
1362
|
+
);
|
|
1363
|
+
}
|
|
1364
|
+
function SignatureDrawing({
|
|
1365
|
+
recordId,
|
|
1366
|
+
fieldKey,
|
|
1367
|
+
fileId: knownFile,
|
|
1368
|
+
value,
|
|
1369
|
+
inCell
|
|
1370
|
+
}) {
|
|
1371
|
+
const client = useOptionalRecordsClient2();
|
|
1372
|
+
const host = useRecordsUi();
|
|
1373
|
+
const [drawing, setDrawing] = useState4(null);
|
|
1374
|
+
useEffect4(() => {
|
|
1375
|
+
let cancelled = false;
|
|
1376
|
+
setDrawing(null);
|
|
1377
|
+
if (!client) return;
|
|
1378
|
+
void (async () => {
|
|
1379
|
+
const fileId = knownFile ?? (recordId && fieldKey ? (await signatureFilesOf(client, recordId))[fieldKey] ?? null : null);
|
|
1380
|
+
if (!fileId || cancelled) return;
|
|
1381
|
+
const read = await drawingOf(client, fileId);
|
|
1382
|
+
if (!cancelled) setDrawing(read);
|
|
1383
|
+
})();
|
|
1384
|
+
return () => {
|
|
1385
|
+
cancelled = true;
|
|
1386
|
+
};
|
|
1387
|
+
}, [client, recordId, fieldKey, knownFile]);
|
|
1388
|
+
if (drawing?.src) return /* @__PURE__ */ jsx6(DrawnImage, { src: drawing.src, inCell });
|
|
1389
|
+
if (drawing?.hostFileId && host.fileImage) {
|
|
1390
|
+
return /* @__PURE__ */ jsx6("span", { className: cn5("inline-block max-w-[12rem] dark:invert", inCell ? "h-7" : "h-12"), "data-records-signature": "", children: host.fileImage({ fileId: drawing.hostFileId, alt: SIGNED_WORD }) });
|
|
1391
|
+
}
|
|
1392
|
+
return /* @__PURE__ */ jsx6("span", { className: "font-serif italic", children: String(value) });
|
|
1393
|
+
}
|
|
1394
|
+
function SignatureValue({
|
|
1395
|
+
value,
|
|
1396
|
+
inCell,
|
|
1397
|
+
recordId,
|
|
1398
|
+
fieldKey,
|
|
1399
|
+
document: document2
|
|
1400
|
+
}) {
|
|
1240
1401
|
const drawn = drawnSignatureOf(value);
|
|
1241
|
-
if (drawn) {
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
src: drawn,
|
|
1246
|
-
alt: SIGNED_WORD,
|
|
1247
|
-
"data-records-signature": "",
|
|
1248
|
-
className: cn5("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
|
|
1249
|
-
}
|
|
1250
|
-
);
|
|
1402
|
+
if (drawn) return /* @__PURE__ */ jsx6(DrawnImage, { src: drawn, inCell });
|
|
1403
|
+
const fileId = fieldKey ? signatureFileIn(document2, fieldKey) : null;
|
|
1404
|
+
if (value === SIGNED_WORD && (fileId || recordId && fieldKey)) {
|
|
1405
|
+
return /* @__PURE__ */ jsx6(SignatureDrawing, { recordId: recordId ?? null, fieldKey: fieldKey ?? null, fileId, value, inCell });
|
|
1251
1406
|
}
|
|
1252
1407
|
return /* @__PURE__ */ jsx6("span", { className: "font-serif italic", children: String(value) });
|
|
1253
1408
|
}
|
|
@@ -1717,7 +1872,7 @@ function rememberHostFileIds(ids) {
|
|
|
1717
1872
|
var FILE_CHIP_UNREAD = "File";
|
|
1718
1873
|
var FILE_CHIP_NO_PAGE = "This screen has no way to open files yet.";
|
|
1719
1874
|
function AttachmentChip({ id, onRemove }) {
|
|
1720
|
-
const client =
|
|
1875
|
+
const client = useOptionalRecordsClient3();
|
|
1721
1876
|
const host = useRecordsUi();
|
|
1722
1877
|
const [read, setRead] = useState7(null);
|
|
1723
1878
|
useEffect6(() => {
|
|
@@ -1862,11 +2017,99 @@ function AttachmentControl({
|
|
|
1862
2017
|
}
|
|
1863
2018
|
|
|
1864
2019
|
// src/EntityReferenceControl.tsx
|
|
1865
|
-
import { useMemo as useMemo4, useState as
|
|
2020
|
+
import { useMemo as useMemo4, useState as useState9 } from "react";
|
|
1866
2021
|
import { entityRefsOf, entityRefsToWrite } from "@ai-matrx/records";
|
|
1867
|
-
import { useEntityReferenceKinds, useEntityReferenceSearch, useEntityReferenceWords, useOptionalRecordsClient as
|
|
1868
|
-
import { Badge as Badge2, Button as Button6, cn as
|
|
1869
|
-
|
|
2022
|
+
import { useEntityReferenceKinds, useEntityReferenceSearch, useEntityReferenceWords, useOptionalRecordsClient as useOptionalRecordsClient4 } from "@ai-matrx/records/react";
|
|
2023
|
+
import { Badge as Badge2, Button as Button6, cn as cn8 } from "@ai-matrx/design-system";
|
|
2024
|
+
|
|
2025
|
+
// src/PickOne.tsx
|
|
2026
|
+
import { useState as useState8 } from "react";
|
|
2027
|
+
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, cn as cn7 } from "@ai-matrx/design-system";
|
|
2028
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2029
|
+
var PICK_ONE_SEARCH_AFTER = 7;
|
|
2030
|
+
var EMPTY = "__records_pick_one_empty__";
|
|
2031
|
+
var inner = (v) => v === "" ? EMPTY : v;
|
|
2032
|
+
var outer = (v) => v === EMPTY ? "" : v;
|
|
2033
|
+
function PickOne({
|
|
2034
|
+
value,
|
|
2035
|
+
onChange,
|
|
2036
|
+
options,
|
|
2037
|
+
label,
|
|
2038
|
+
placeholder,
|
|
2039
|
+
id,
|
|
2040
|
+
className,
|
|
2041
|
+
disabled,
|
|
2042
|
+
attrs
|
|
2043
|
+
}) {
|
|
2044
|
+
const [open, setOpen] = useState8(false);
|
|
2045
|
+
const [search, setSearch] = useState8("");
|
|
2046
|
+
const current = options.find((o) => o.value === value);
|
|
2047
|
+
if (options.length > PICK_ONE_SEARCH_AFTER) {
|
|
2048
|
+
const q = search.trim().toLowerCase();
|
|
2049
|
+
const shown2 = q === "" ? options : options.filter((o) => o.label.toLowerCase().includes(q));
|
|
2050
|
+
return /* @__PURE__ */ jsx10("span", { className: cn7("inline-flex min-w-0", className), "data-records-pick-one": "search", "data-pick-value": value, ...attrs ?? {}, children: /* @__PURE__ */ jsx10(
|
|
2051
|
+
PickOrAdd,
|
|
2052
|
+
{
|
|
2053
|
+
triggerLabel: label,
|
|
2054
|
+
triggerText: current?.label ?? placeholder ?? "",
|
|
2055
|
+
triggerId: id,
|
|
2056
|
+
open: open && !disabled,
|
|
2057
|
+
onOpenChange: (next) => {
|
|
2058
|
+
setOpen(next);
|
|
2059
|
+
if (!next) setSearch("");
|
|
2060
|
+
},
|
|
2061
|
+
search,
|
|
2062
|
+
onSearch: setSearch,
|
|
2063
|
+
items: shown2.map((o) => ({
|
|
2064
|
+
id: inner(o.value),
|
|
2065
|
+
label: o.label,
|
|
2066
|
+
detail: o.group,
|
|
2067
|
+
picked: o.value === value,
|
|
2068
|
+
attrs: { "data-pick-value": o.value, ...o.group ? { "data-pick-group": o.group } : {} }
|
|
2069
|
+
})),
|
|
2070
|
+
onPick: (picked) => {
|
|
2071
|
+
onChange(outer(picked));
|
|
2072
|
+
setOpen(false);
|
|
2073
|
+
setSearch("");
|
|
2074
|
+
},
|
|
2075
|
+
empty: /* @__PURE__ */ jsx10("p", { className: "p-2 text-xs text-muted-foreground", children: "No match" })
|
|
2076
|
+
}
|
|
2077
|
+
) });
|
|
2078
|
+
}
|
|
2079
|
+
return /* @__PURE__ */ jsxs8(Select, { value: current ? inner(current.value) : "", onValueChange: (v) => onChange(outer(v)), disabled: disabled ?? false, children: [
|
|
2080
|
+
/* @__PURE__ */ jsx10(
|
|
2081
|
+
SelectTrigger,
|
|
2082
|
+
{
|
|
2083
|
+
id,
|
|
2084
|
+
size: "sm",
|
|
2085
|
+
"aria-label": label,
|
|
2086
|
+
className: cn7("h-7 w-auto min-w-[7rem] text-xs", className),
|
|
2087
|
+
"data-records-pick-one": "list",
|
|
2088
|
+
"data-pick-value": value,
|
|
2089
|
+
...attrs ?? {},
|
|
2090
|
+
children: /* @__PURE__ */ jsx10(SelectValue, { placeholder })
|
|
2091
|
+
}
|
|
2092
|
+
),
|
|
2093
|
+
/* @__PURE__ */ jsx10(SelectContent, { children: groupsOf(options).map(
|
|
2094
|
+
([group, items]) => group ? /* @__PURE__ */ jsxs8(SelectGroup, { children: [
|
|
2095
|
+
/* @__PURE__ */ jsx10(SelectLabel, { children: group }),
|
|
2096
|
+
items.map((o) => /* @__PURE__ */ jsx10(SelectItem, { value: inner(o.value), "data-pick-value": o.value, "data-pick-group": group, children: o.label }, inner(o.value)))
|
|
2097
|
+
] }, group) : items.map((o) => /* @__PURE__ */ jsx10(SelectItem, { value: inner(o.value), "data-pick-value": o.value, children: o.label }, inner(o.value)))
|
|
2098
|
+
) })
|
|
2099
|
+
] });
|
|
2100
|
+
}
|
|
2101
|
+
function groupsOf(options) {
|
|
2102
|
+
const out = [];
|
|
2103
|
+
for (const o of options) {
|
|
2104
|
+
const last = out[out.length - 1];
|
|
2105
|
+
if (last && last[0] === o.group) last[1].push(o);
|
|
2106
|
+
else out.push([o.group, [o]]);
|
|
2107
|
+
}
|
|
2108
|
+
return out;
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
// src/EntityReferenceControl.tsx
|
|
2112
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1870
2113
|
var WITHHELD_ENTITY_LABEL = "Something you have not been given access to";
|
|
1871
2114
|
var ENTITY_REFERENCE_EMPTY = "Nothing is pointed at yet.";
|
|
1872
2115
|
function entityReferenceText(value) {
|
|
@@ -1880,12 +2123,12 @@ function allowedKindsOf(field) {
|
|
|
1880
2123
|
return kinds.map((k) => String(k).trim().toLowerCase()).filter(Boolean);
|
|
1881
2124
|
}
|
|
1882
2125
|
function EntityReferenceControl(props) {
|
|
1883
|
-
const client =
|
|
1884
|
-
return client ? /* @__PURE__ */
|
|
2126
|
+
const client = useOptionalRecordsClient4();
|
|
2127
|
+
return client ? /* @__PURE__ */ jsx11(WithWords, { ...props }) : /* @__PURE__ */ jsx11(Chips, { ...props, words: null, picker: null });
|
|
1885
2128
|
}
|
|
1886
2129
|
function WithWords(props) {
|
|
1887
2130
|
const refs = useMemo4(() => entityRefsOf(props.value), [props.value]);
|
|
1888
|
-
const [known, setKnown] =
|
|
2131
|
+
const [known, setKnown] = useState9([]);
|
|
1889
2132
|
const withKnown = refs.map((r) => r.label === null ? known.find((k) => k.token === r.token && k.id === r.id) ?? r : r);
|
|
1890
2133
|
const unlabelled = useMemo4(
|
|
1891
2134
|
() => withKnown.filter((r) => r.label === null).map((r) => ({ token: r.token, id: r.id })),
|
|
@@ -1893,7 +2136,7 @@ function WithWords(props) {
|
|
|
1893
2136
|
[JSON.stringify(withKnown)]
|
|
1894
2137
|
);
|
|
1895
2138
|
const words = useEntityReferenceWords(unlabelled);
|
|
1896
|
-
const picker = props.disabled ? null : /* @__PURE__ */
|
|
2139
|
+
const picker = props.disabled ? null : /* @__PURE__ */ jsx11(
|
|
1897
2140
|
EntityReferencePicker,
|
|
1898
2141
|
{
|
|
1899
2142
|
field: props.field,
|
|
@@ -1906,7 +2149,7 @@ function WithWords(props) {
|
|
|
1906
2149
|
}
|
|
1907
2150
|
}
|
|
1908
2151
|
);
|
|
1909
|
-
return /* @__PURE__ */
|
|
2152
|
+
return /* @__PURE__ */ jsx11(Chips, { ...props, value: withKnown, words, picker });
|
|
1910
2153
|
}
|
|
1911
2154
|
function EntityReferencePicker({
|
|
1912
2155
|
field,
|
|
@@ -1916,9 +2159,9 @@ function EntityReferencePicker({
|
|
|
1916
2159
|
const allowed = allowedKindsOf(field);
|
|
1917
2160
|
const kinds = useEntityReferenceKinds();
|
|
1918
2161
|
const labelOfKind = (token) => kinds.data?.find((k) => k.token === token)?.label ?? token.replace(/_/g, " ");
|
|
1919
|
-
const [open, setOpen] =
|
|
1920
|
-
const [search, setSearch] =
|
|
1921
|
-
const [only, setOnly] =
|
|
2162
|
+
const [open, setOpen] = useState9(false);
|
|
2163
|
+
const [search, setSearch] = useState9("");
|
|
2164
|
+
const [only, setOnly] = useState9(null);
|
|
1922
2165
|
const tokens = only ? [only] : allowed;
|
|
1923
2166
|
const found = useEntityReferenceSearch(tokens, search, open);
|
|
1924
2167
|
const multi = Boolean(field.multi);
|
|
@@ -1929,7 +2172,7 @@ function EntityReferencePicker({
|
|
|
1929
2172
|
picked: refs.some((x) => x.token === r.token && x.id === r.id),
|
|
1930
2173
|
attrs: { "data-entity-reference-candidate": `${r.token}:${r.id}` }
|
|
1931
2174
|
}));
|
|
1932
|
-
const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */
|
|
2175
|
+
const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ jsx11("div", { className: "mb-1 flex flex-wrap gap-1", role: "group", "aria-label": `Which kind \u2014 ${field.label}`, children: [null, ...allowed].map((token) => /* @__PURE__ */ jsx11(
|
|
1933
2176
|
Button6,
|
|
1934
2177
|
{
|
|
1935
2178
|
type: "button",
|
|
@@ -1941,26 +2184,23 @@ function EntityReferencePicker({
|
|
|
1941
2184
|
children: token ? labelOfKind(token) : "Any"
|
|
1942
2185
|
},
|
|
1943
2186
|
token ?? "any"
|
|
1944
|
-
)) }) : /* @__PURE__ */
|
|
1945
|
-
|
|
2187
|
+
)) }) : /* @__PURE__ */ jsx11(
|
|
2188
|
+
PickOne,
|
|
1946
2189
|
{
|
|
1947
|
-
|
|
1948
|
-
"
|
|
2190
|
+
label: `Which kind \u2014 ${field.label}`,
|
|
2191
|
+
className: "mb-1 w-full",
|
|
1949
2192
|
value: only ?? "",
|
|
1950
|
-
onChange: (
|
|
1951
|
-
|
|
1952
|
-
/* @__PURE__ */ jsx10("option", { value: "", children: "Any kind" }),
|
|
1953
|
-
allowed.map((token) => /* @__PURE__ */ jsx10("option", { value: token, children: labelOfKind(token) }, token))
|
|
1954
|
-
]
|
|
2193
|
+
onChange: (picked) => setOnly(picked || null),
|
|
2194
|
+
options: [{ value: "", label: "Any kind" }, ...allowed.map((token) => ({ value: token, label: labelOfKind(token) }))]
|
|
1955
2195
|
}
|
|
1956
2196
|
) : null;
|
|
1957
|
-
const notice = /* @__PURE__ */
|
|
2197
|
+
const notice = /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
1958
2198
|
kindChoice,
|
|
1959
|
-
found.error ? /* @__PURE__ */
|
|
1960
|
-
found.loading && !found.data ? /* @__PURE__ */
|
|
2199
|
+
found.error ? /* @__PURE__ */ jsx11(RefusalLine, { error: found.error, className: "px-2 py-1 text-[11px]" }) : null,
|
|
2200
|
+
found.loading && !found.data ? /* @__PURE__ */ jsx11("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: "Searching\u2026" }) : null
|
|
1961
2201
|
] });
|
|
1962
2202
|
const kindWords = allowed.length === 1 ? labelOfKind(allowed[0]).toLowerCase() : "thing";
|
|
1963
|
-
return /* @__PURE__ */
|
|
2203
|
+
return /* @__PURE__ */ jsx11(
|
|
1964
2204
|
PickOrAdd,
|
|
1965
2205
|
{
|
|
1966
2206
|
triggerLabel: `Pick for ${field.label}`,
|
|
@@ -1974,7 +2214,7 @@ function EntityReferencePicker({
|
|
|
1974
2214
|
onSearch: setSearch,
|
|
1975
2215
|
items,
|
|
1976
2216
|
notice,
|
|
1977
|
-
empty: found.loading ? null : /* @__PURE__ */
|
|
2217
|
+
empty: found.loading ? null : /* @__PURE__ */ jsx11("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: search.trim() ? `No ${kindWords} you can open is called \u201C${search.trim()}\u201D.` : `There is no ${kindWords} you can open yet.` }),
|
|
1978
2218
|
onPick: (key) => {
|
|
1979
2219
|
const r = (found.data ?? []).find((x) => `${x.token}:${x.id}` === key);
|
|
1980
2220
|
if (!r) return;
|
|
@@ -2004,13 +2244,13 @@ function Chips({
|
|
|
2004
2244
|
return WITHHELD_ENTITY_LABEL;
|
|
2005
2245
|
};
|
|
2006
2246
|
const multi = Boolean(field.multi);
|
|
2007
|
-
return /* @__PURE__ */
|
|
2008
|
-
refs.length === 0 && !picker ? /* @__PURE__ */
|
|
2247
|
+
return /* @__PURE__ */ jsxs9("div", { id, className: cn8("flex flex-wrap items-center gap-1", className), "aria-label": `What ${field.label} points at`, children: [
|
|
2248
|
+
refs.length === 0 && !picker ? /* @__PURE__ */ jsx11("span", { className: "text-[11px] text-muted-foreground", children: ENTITY_REFERENCE_EMPTY }) : null,
|
|
2009
2249
|
refs.map((r) => {
|
|
2010
2250
|
const label = labelOf(r.token, r.id, r.label);
|
|
2011
|
-
return /* @__PURE__ */
|
|
2251
|
+
return /* @__PURE__ */ jsxs9(Badge2, { variant: "secondary", className: "gap-1 text-[11px]", "data-entity-reference-chip": `${r.token}:${r.id}`, children: [
|
|
2012
2252
|
label,
|
|
2013
|
-
disabled ? null : /* @__PURE__ */
|
|
2253
|
+
disabled ? null : /* @__PURE__ */ jsx11(
|
|
2014
2254
|
"button",
|
|
2015
2255
|
{
|
|
2016
2256
|
type: "button",
|
|
@@ -2030,9 +2270,9 @@ function Chips({
|
|
|
2030
2270
|
}
|
|
2031
2271
|
|
|
2032
2272
|
// src/PersonPicker.tsx
|
|
2033
|
-
import { useCallback as useCallback3, useEffect as useEffect7, useMemo as useMemo5, useRef as useRef6, useState as
|
|
2273
|
+
import { useCallback as useCallback3, useEffect as useEffect7, useMemo as useMemo5, useRef as useRef6, useState as useState10 } from "react";
|
|
2034
2274
|
import { rankTypedMatches as rankTypedMatches2 } from "@ai-matrx/records";
|
|
2035
|
-
import { useOptionalRecordsClient as
|
|
2275
|
+
import { useOptionalRecordsClient as useOptionalRecordsClient5 } from "@ai-matrx/records/react";
|
|
2036
2276
|
import {
|
|
2037
2277
|
BasicInput as BasicInput4,
|
|
2038
2278
|
Button as Button7,
|
|
@@ -2040,9 +2280,9 @@ import {
|
|
|
2040
2280
|
PopoverContent as PopoverContent2,
|
|
2041
2281
|
PopoverTrigger as PopoverTrigger2,
|
|
2042
2282
|
ScrollArea as ScrollArea2,
|
|
2043
|
-
cn as
|
|
2283
|
+
cn as cn9
|
|
2044
2284
|
} from "@ai-matrx/design-system";
|
|
2045
|
-
import { jsx as
|
|
2285
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2046
2286
|
function personFromRow(row) {
|
|
2047
2287
|
const data = row.document ?? {};
|
|
2048
2288
|
const userId = data["user_id"];
|
|
@@ -2073,20 +2313,20 @@ async function personRecordForMember(client, personTableId, people, member) {
|
|
|
2073
2313
|
return written;
|
|
2074
2314
|
}
|
|
2075
2315
|
function PersonPicker({ field, value, onChange, disabled, id, className, autoOpen, onClose, initialSearch }) {
|
|
2076
|
-
const client =
|
|
2316
|
+
const client = useOptionalRecordsClient5();
|
|
2077
2317
|
const host = useRecordsUi();
|
|
2078
|
-
const [members, setMembers] =
|
|
2079
|
-
const [people, setPeople] =
|
|
2080
|
-
const [error, setError] =
|
|
2081
|
-
const [search, setSearch] =
|
|
2082
|
-
const [open, setOpenState] =
|
|
2318
|
+
const [members, setMembers] = useState10(null);
|
|
2319
|
+
const [people, setPeople] = useState10([]);
|
|
2320
|
+
const [error, setError] = useState10(null);
|
|
2321
|
+
const [search, setSearch] = useState10(initialSearch ?? "");
|
|
2322
|
+
const [open, setOpenState] = useState10(autoOpen === true);
|
|
2083
2323
|
const onCloseRef = useRef6(onClose);
|
|
2084
2324
|
onCloseRef.current = onClose;
|
|
2085
2325
|
const setOpen = useCallback3((next) => {
|
|
2086
2326
|
setOpenState(next);
|
|
2087
2327
|
if (!next) onCloseRef.current?.();
|
|
2088
2328
|
}, []);
|
|
2089
|
-
const [busy, setBusy] =
|
|
2329
|
+
const [busy, setBusy] = useState10(false);
|
|
2090
2330
|
const membersPort = host.members;
|
|
2091
2331
|
const personTable = field.relation_target;
|
|
2092
2332
|
const picked = useMemo5(
|
|
@@ -2133,10 +2373,10 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2133
2373
|
});
|
|
2134
2374
|
const pickRef = useRef6(null);
|
|
2135
2375
|
if (!membersPort || !client) {
|
|
2136
|
-
return /* @__PURE__ */
|
|
2376
|
+
return /* @__PURE__ */ jsx12("p", { className: cn9("text-xs text-muted-foreground", className), children: NO_MEMBERS_REASON });
|
|
2137
2377
|
}
|
|
2138
2378
|
if (!personTable) {
|
|
2139
|
-
return /* @__PURE__ */
|
|
2379
|
+
return /* @__PURE__ */ jsxs10("p", { className: cn9("text-xs text-muted-foreground", className), children: [
|
|
2140
2380
|
fieldName(field),
|
|
2141
2381
|
" is a person field, but it does not say which Table the people are records of yet, so there is nothing to pick from. A table admin sets its target in the field editor."
|
|
2142
2382
|
] });
|
|
@@ -2179,8 +2419,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2179
2419
|
const pickedUserIds = new Set(
|
|
2180
2420
|
picked.map((recordId) => people.find((p) => p.id === recordId)?.userId).filter(Boolean)
|
|
2181
2421
|
);
|
|
2182
|
-
return /* @__PURE__ */
|
|
2183
|
-
picked.map((recordId) => /* @__PURE__ */
|
|
2422
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn9("flex flex-wrap items-center gap-1", className), children: [
|
|
2423
|
+
picked.map((recordId) => /* @__PURE__ */ jsx12(
|
|
2184
2424
|
RecordChip,
|
|
2185
2425
|
{
|
|
2186
2426
|
title: nameOfRecord(recordId),
|
|
@@ -2188,8 +2428,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2188
2428
|
},
|
|
2189
2429
|
recordId
|
|
2190
2430
|
)),
|
|
2191
|
-
disabled ? null : /* @__PURE__ */
|
|
2192
|
-
/* @__PURE__ */
|
|
2431
|
+
disabled ? null : /* @__PURE__ */ jsxs10(Popover2, { open, onOpenChange: setOpen, children: [
|
|
2432
|
+
/* @__PURE__ */ jsx12(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx12(
|
|
2193
2433
|
Button7,
|
|
2194
2434
|
{
|
|
2195
2435
|
id,
|
|
@@ -2200,7 +2440,7 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2200
2440
|
children: picked.length === 0 ? "Pick a person" : "Change"
|
|
2201
2441
|
}
|
|
2202
2442
|
) }),
|
|
2203
|
-
/* @__PURE__ */
|
|
2443
|
+
/* @__PURE__ */ jsxs10(
|
|
2204
2444
|
PopoverContent2,
|
|
2205
2445
|
{
|
|
2206
2446
|
sizing: "content",
|
|
@@ -2209,7 +2449,7 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2209
2449
|
"data-matrx-cell-editor": "",
|
|
2210
2450
|
onKeyDown: (event) => event.stopPropagation(),
|
|
2211
2451
|
children: [
|
|
2212
|
-
/* @__PURE__ */
|
|
2452
|
+
/* @__PURE__ */ jsx12(
|
|
2213
2453
|
BasicInput4,
|
|
2214
2454
|
{
|
|
2215
2455
|
value: search,
|
|
@@ -2222,31 +2462,31 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2222
2462
|
className: "mb-1 h-7 text-xs"
|
|
2223
2463
|
}
|
|
2224
2464
|
),
|
|
2225
|
-
error ? /* @__PURE__ */
|
|
2226
|
-
members === null ? /* @__PURE__ */
|
|
2227
|
-
/* @__PURE__ */
|
|
2228
|
-
/* @__PURE__ */
|
|
2465
|
+
error ? /* @__PURE__ */ jsx12(RefusalLine, { error, className: "p-2" }) : null,
|
|
2466
|
+
members === null ? /* @__PURE__ */ jsx12("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading the members\u2026" }) : null,
|
|
2467
|
+
/* @__PURE__ */ jsxs10(ScrollArea2, { className: "max-h-56", children: [
|
|
2468
|
+
/* @__PURE__ */ jsx12("ul", { role: "listbox", "aria-label": `People for ${fieldName(field)}`, children: visible.map((member, index) => /* @__PURE__ */ jsx12("li", { children: /* @__PURE__ */ jsxs10(
|
|
2229
2469
|
"button",
|
|
2230
2470
|
{
|
|
2231
2471
|
type: "button",
|
|
2232
2472
|
disabled: busy,
|
|
2233
2473
|
"data-pick-highlighted": index === keys.highlight ? "" : void 0,
|
|
2234
2474
|
onClick: () => void pick(member),
|
|
2235
|
-
className:
|
|
2475
|
+
className: cn9(
|
|
2236
2476
|
"w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-muted",
|
|
2237
2477
|
pickedUserIds.has(member.userId) ? "bg-accent text-accent-foreground" : "",
|
|
2238
2478
|
index === keys.highlight ? "ring-1 ring-ring" : ""
|
|
2239
2479
|
),
|
|
2240
2480
|
children: [
|
|
2241
|
-
/* @__PURE__ */
|
|
2242
|
-
member.email && member.email !== memberName(member) ? /* @__PURE__ */
|
|
2481
|
+
/* @__PURE__ */ jsx12("span", { children: memberName(member) }),
|
|
2482
|
+
member.email && member.email !== memberName(member) ? /* @__PURE__ */ jsxs10("span", { className: "ml-1.5 opacity-60", children: [
|
|
2243
2483
|
"\xB7 ",
|
|
2244
2484
|
member.email
|
|
2245
2485
|
] }) : null
|
|
2246
2486
|
]
|
|
2247
2487
|
}
|
|
2248
2488
|
) }, member.userId)) }),
|
|
2249
|
-
members !== null && visible.length === 0 ? /* @__PURE__ */
|
|
2489
|
+
members !== null && visible.length === 0 ? /* @__PURE__ */ jsx12("p", { className: "p-2 text-xs text-muted-foreground", children: members.length === 0 ? "This organization has no other members yet, so there is nobody to assign." : "Nobody in this organization matches." }) : null
|
|
2250
2490
|
] })
|
|
2251
2491
|
]
|
|
2252
2492
|
}
|
|
@@ -2257,7 +2497,7 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2257
2497
|
|
|
2258
2498
|
// src/presentation.ts
|
|
2259
2499
|
import {
|
|
2260
|
-
STYLE_COLORS,
|
|
2500
|
+
STYLE_COLORS as STYLE_COLORS2,
|
|
2261
2501
|
parseTableStyle,
|
|
2262
2502
|
tableStyleIsEmpty
|
|
2263
2503
|
} from "@ai-matrx/design-system/data-table";
|
|
@@ -2322,16 +2562,16 @@ function currencyCodeFor(unit) {
|
|
|
2322
2562
|
}
|
|
2323
2563
|
|
|
2324
2564
|
// src/formatControls.tsx
|
|
2325
|
-
import { useEffect as useEffect8, useRef as useRef8, useState as
|
|
2565
|
+
import { useEffect as useEffect8, useRef as useRef8, useState as useState11 } from "react";
|
|
2326
2566
|
import { BasicInput as BasicInput5, BasicTextarea } from "@ai-matrx/design-system";
|
|
2327
2567
|
import { getFieldFormat as getFieldFormat3, parseFieldInput } from "@ai-matrx/design-system/field-formats";
|
|
2328
2568
|
|
|
2329
2569
|
// src/formattedValue.tsx
|
|
2330
2570
|
import { useRef as useRef7 } from "react";
|
|
2331
2571
|
import { FormattedCell } from "@ai-matrx/design-system/data-table";
|
|
2332
|
-
import { formatFieldValue as formatFieldValue2, getFieldFormat as getFieldFormat2 } from "@ai-matrx/design-system/field-formats";
|
|
2333
|
-
import { cn as
|
|
2334
|
-
import { jsx as
|
|
2572
|
+
import { formatFieldValue as formatFieldValue2, formatPhone, getFieldFormat as getFieldFormat2 } from "@ai-matrx/design-system/field-formats";
|
|
2573
|
+
import { cn as cn10 } from "@ai-matrx/design-system";
|
|
2574
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2335
2575
|
var LINK = "inline-flex min-w-0 items-center gap-1 text-primary hover:underline";
|
|
2336
2576
|
var own2 = (event) => event.stopPropagation();
|
|
2337
2577
|
function numberOf(value) {
|
|
@@ -2353,7 +2593,7 @@ function RatingStars({
|
|
|
2353
2593
|
const score = numberOf(value) ?? 0;
|
|
2354
2594
|
const shown2 = Math.round(score);
|
|
2355
2595
|
const said = `${shown2} out of ${max}`;
|
|
2356
|
-
return /* @__PURE__ */
|
|
2596
|
+
return /* @__PURE__ */ jsx13(
|
|
2357
2597
|
"span",
|
|
2358
2598
|
{
|
|
2359
2599
|
"data-records-rating": "",
|
|
@@ -2365,8 +2605,8 @@ function RatingStars({
|
|
|
2365
2605
|
children: Array.from({ length: max }, (_, i) => {
|
|
2366
2606
|
const n = i + 1;
|
|
2367
2607
|
const lit = n <= shown2;
|
|
2368
|
-
const star = /* @__PURE__ */
|
|
2369
|
-
return onRate ? /* @__PURE__ */
|
|
2608
|
+
const star = /* @__PURE__ */ jsx13("span", { "aria-hidden": true, className: cn10("text-sm leading-none", lit ? "text-amber-400" : "text-muted-foreground/40"), children: "\u2605" });
|
|
2609
|
+
return onRate ? /* @__PURE__ */ jsx13(
|
|
2370
2610
|
"button",
|
|
2371
2611
|
{
|
|
2372
2612
|
type: "button",
|
|
@@ -2391,7 +2631,7 @@ function RatingStars({
|
|
|
2391
2631
|
children: star
|
|
2392
2632
|
},
|
|
2393
2633
|
n
|
|
2394
|
-
) : /* @__PURE__ */
|
|
2634
|
+
) : /* @__PURE__ */ jsx13("span", { children: star }, n);
|
|
2395
2635
|
})
|
|
2396
2636
|
}
|
|
2397
2637
|
);
|
|
@@ -2399,13 +2639,13 @@ function RatingStars({
|
|
|
2399
2639
|
function rich(id, text, raw, format) {
|
|
2400
2640
|
switch (id) {
|
|
2401
2641
|
case "email":
|
|
2402
|
-
return /* @__PURE__ */
|
|
2642
|
+
return /* @__PURE__ */ jsx13("a", { href: `mailto:${text}`, className: LINK, onClick: own2, children: /* @__PURE__ */ jsx13("span", { className: "truncate", children: text }) });
|
|
2403
2643
|
case "url":
|
|
2404
|
-
return /* @__PURE__ */
|
|
2644
|
+
return /* @__PURE__ */ jsx13("a", { href: text.includes("://") ? text : `https://${text}`, target: "_blank", rel: "noopener noreferrer", className: LINK, onClick: own2, children: /* @__PURE__ */ jsx13("span", { className: "truncate", children: text }) });
|
|
2405
2645
|
case "phone":
|
|
2406
|
-
return /* @__PURE__ */
|
|
2646
|
+
return /* @__PURE__ */ jsx13("a", { href: `tel:${text.replace(/[^\d+]/g, "")}`, className: LINK, onClick: own2, title: text, children: /* @__PURE__ */ jsx13("span", { className: "truncate tabular-nums", children: formatPhone(text) }) });
|
|
2407
2647
|
case "address":
|
|
2408
|
-
return /* @__PURE__ */
|
|
2648
|
+
return /* @__PURE__ */ jsx13(
|
|
2409
2649
|
"a",
|
|
2410
2650
|
{
|
|
2411
2651
|
href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(text)}`,
|
|
@@ -2414,7 +2654,7 @@ function rich(id, text, raw, format) {
|
|
|
2414
2654
|
className: LINK,
|
|
2415
2655
|
title: "Open in maps",
|
|
2416
2656
|
onClick: own2,
|
|
2417
|
-
children: /* @__PURE__ */
|
|
2657
|
+
children: /* @__PURE__ */ jsx13("span", { className: "truncate", children: text })
|
|
2418
2658
|
}
|
|
2419
2659
|
);
|
|
2420
2660
|
case "progress": {
|
|
@@ -2422,8 +2662,8 @@ function rich(id, text, raw, format) {
|
|
|
2422
2662
|
if (n === null) return void 0;
|
|
2423
2663
|
const pct = format.options?.percentScale === "fraction" ? n * 100 : n;
|
|
2424
2664
|
const clamped = Math.max(0, Math.min(100, pct));
|
|
2425
|
-
return /* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
2665
|
+
return /* @__PURE__ */ jsxs11("span", { className: "inline-flex w-full min-w-0 items-center gap-2", title: text, children: [
|
|
2666
|
+
/* @__PURE__ */ jsx13(
|
|
2427
2667
|
"span",
|
|
2428
2668
|
{
|
|
2429
2669
|
role: "progressbar",
|
|
@@ -2431,24 +2671,24 @@ function rich(id, text, raw, format) {
|
|
|
2431
2671
|
"aria-valuemax": 100,
|
|
2432
2672
|
"aria-valuenow": Math.round(clamped),
|
|
2433
2673
|
className: "h-1.5 min-w-8 flex-1 overflow-hidden rounded-full bg-muted",
|
|
2434
|
-
children: /* @__PURE__ */
|
|
2674
|
+
children: /* @__PURE__ */ jsx13("span", { className: cn10("block h-full rounded-full", pct >= 100 ? "bg-emerald-500" : "bg-primary"), style: { width: `${clamped}%` } })
|
|
2435
2675
|
}
|
|
2436
2676
|
),
|
|
2437
|
-
/* @__PURE__ */
|
|
2677
|
+
/* @__PURE__ */ jsx13("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: text })
|
|
2438
2678
|
] });
|
|
2439
2679
|
}
|
|
2440
2680
|
case "color":
|
|
2441
|
-
return /* @__PURE__ */
|
|
2442
|
-
/* @__PURE__ */
|
|
2443
|
-
/* @__PURE__ */
|
|
2681
|
+
return /* @__PURE__ */ jsxs11("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
2682
|
+
/* @__PURE__ */ jsx13("span", { className: "h-4 w-4 shrink-0 rounded border border-border", style: { backgroundColor: text } }),
|
|
2683
|
+
/* @__PURE__ */ jsx13("code", { className: "font-mono text-xs", children: text })
|
|
2444
2684
|
] });
|
|
2445
2685
|
case "tags": {
|
|
2446
2686
|
const items = Array.isArray(raw) ? raw.map(String) : text.split(",").map((s) => s.trim()).filter(Boolean);
|
|
2447
2687
|
if (items.length === 0) return void 0;
|
|
2448
|
-
return /* @__PURE__ */
|
|
2688
|
+
return /* @__PURE__ */ jsx13("span", { className: "flex flex-wrap items-center gap-1", children: items.map((item, i) => /* @__PURE__ */ jsx13("span", { className: "inline-flex items-center rounded-md border border-border bg-muted px-1.5 py-0.5 text-xs", children: item }, `${item}-${i}`)) });
|
|
2449
2689
|
}
|
|
2450
2690
|
case "rating":
|
|
2451
|
-
return numberOf(raw) === null ? void 0 : /* @__PURE__ */
|
|
2691
|
+
return numberOf(raw) === null ? void 0 : /* @__PURE__ */ jsx13(RatingStars, { value: raw, max: format.options?.ratingMax ?? 5 });
|
|
2452
2692
|
default:
|
|
2453
2693
|
return void 0;
|
|
2454
2694
|
}
|
|
@@ -2463,21 +2703,11 @@ function FormattedValue({
|
|
|
2463
2703
|
const score = numberOf(value);
|
|
2464
2704
|
const max = format.options?.ratingMax ?? 5;
|
|
2465
2705
|
if (def?.id === "rating" && onRate && (value === null || value === void 0 || value === "" || score !== null && score >= 0 && score <= max)) {
|
|
2466
|
-
return /* @__PURE__ */
|
|
2706
|
+
return /* @__PURE__ */ jsx13(RatingStars, { value, max: format.options?.ratingMax ?? 5, onRate, selectFirst });
|
|
2467
2707
|
}
|
|
2468
2708
|
const result = formatFieldValue2(value, format);
|
|
2469
|
-
if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */
|
|
2470
|
-
return rich(def.id, result.text, value, format) ?? /* @__PURE__ */
|
|
2471
|
-
}
|
|
2472
|
-
function formatPhone(raw) {
|
|
2473
|
-
const text = raw.trim();
|
|
2474
|
-
const digits = text.replace(/\D/g, "");
|
|
2475
|
-
if (/[a-z]/i.test(text.replace(/ext\.?|x/gi, ""))) return text;
|
|
2476
|
-
if (digits.length === 10 && !text.startsWith("+")) return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
|
|
2477
|
-
if (digits.length === 11 && digits.startsWith("1") && (text.startsWith("+1") || text.startsWith("1") || !text.startsWith("+"))) {
|
|
2478
|
-
return `+1 (${digits.slice(1, 4)}) ${digits.slice(4, 7)}-${digits.slice(7)}`;
|
|
2479
|
-
}
|
|
2480
|
-
return text;
|
|
2709
|
+
if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ jsx13(FormattedCell, { result });
|
|
2710
|
+
return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ jsx13(FormattedCell, { result });
|
|
2481
2711
|
}
|
|
2482
2712
|
function linkChipText(raw) {
|
|
2483
2713
|
try {
|
|
@@ -2491,7 +2721,7 @@ function linkChipText(raw) {
|
|
|
2491
2721
|
}
|
|
2492
2722
|
|
|
2493
2723
|
// src/formatControls.tsx
|
|
2494
|
-
import { jsx as
|
|
2724
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2495
2725
|
var TYPED_NUMBERS = /* @__PURE__ */ new Set(["currency", "percent", "progress", "decimal", "duration", "file_size", "integer"]);
|
|
2496
2726
|
function scaled(format) {
|
|
2497
2727
|
return (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction";
|
|
@@ -2508,13 +2738,13 @@ function keptValue(format, raw) {
|
|
|
2508
2738
|
return parsed;
|
|
2509
2739
|
}
|
|
2510
2740
|
function NumberInFormat({ format, value, onChange, disabled, id }) {
|
|
2511
|
-
const [text, setText] =
|
|
2741
|
+
const [text, setText] = useState11(() => typedText(format, value));
|
|
2512
2742
|
const lastSent = useRef8(void 0);
|
|
2513
2743
|
useEffect8(() => {
|
|
2514
2744
|
if (value === lastSent.current) return;
|
|
2515
2745
|
setText(typedText(format, value));
|
|
2516
2746
|
}, [value, format]);
|
|
2517
|
-
return /* @__PURE__ */
|
|
2747
|
+
return /* @__PURE__ */ jsx14(
|
|
2518
2748
|
BasicInput5,
|
|
2519
2749
|
{
|
|
2520
2750
|
id,
|
|
@@ -2539,16 +2769,16 @@ function formatControl(args) {
|
|
|
2539
2769
|
const text = value === null || value === void 0 ? "" : String(value);
|
|
2540
2770
|
const commit = (raw) => onChange(raw === "" ? null : parseFieldInput(raw, format));
|
|
2541
2771
|
if (def.id === "rating") {
|
|
2542
|
-
return disabled ? /* @__PURE__ */
|
|
2772
|
+
return disabled ? /* @__PURE__ */ jsx14(RatingStars, { value, max: format.options?.ratingMax ?? 5, label }) : /* @__PURE__ */ jsx14("span", { id, className: "inline-flex", children: /* @__PURE__ */ jsx14(RatingStars, { value, max: format.options?.ratingMax ?? 5, label, onRate: (n) => onChange(n) }) });
|
|
2543
2773
|
}
|
|
2544
|
-
if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */
|
|
2774
|
+
if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ jsx14(NumberInFormat, { ...args });
|
|
2545
2775
|
switch (def.editor) {
|
|
2546
2776
|
// A TIME OF DAY is not this file's: `FieldControl` draws the typed box and its helper
|
|
2547
2777
|
// (`TypedWordsControl`), never the browser's time control (grids review 3, 2026-09-30).
|
|
2548
2778
|
case "email":
|
|
2549
2779
|
case "url":
|
|
2550
2780
|
case "tel":
|
|
2551
|
-
return /* @__PURE__ */
|
|
2781
|
+
return /* @__PURE__ */ jsx14(
|
|
2552
2782
|
BasicInput5,
|
|
2553
2783
|
{
|
|
2554
2784
|
id,
|
|
@@ -2560,8 +2790,8 @@ function formatControl(args) {
|
|
|
2560
2790
|
}
|
|
2561
2791
|
);
|
|
2562
2792
|
case "color":
|
|
2563
|
-
return /* @__PURE__ */
|
|
2564
|
-
/* @__PURE__ */
|
|
2793
|
+
return /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-2", children: [
|
|
2794
|
+
/* @__PURE__ */ jsx14(
|
|
2565
2795
|
BasicInput5,
|
|
2566
2796
|
{
|
|
2567
2797
|
id: `${id}-swatch`,
|
|
@@ -2573,20 +2803,20 @@ function formatControl(args) {
|
|
|
2573
2803
|
onChange: (e) => commit(e.target.value)
|
|
2574
2804
|
}
|
|
2575
2805
|
),
|
|
2576
|
-
/* @__PURE__ */
|
|
2806
|
+
/* @__PURE__ */ jsx14(BasicInput5, { id, value: text, placeholder: "#3b82f6", disabled, onChange: (e) => commit(e.target.value) })
|
|
2577
2807
|
] });
|
|
2578
2808
|
case "textarea":
|
|
2579
|
-
return /* @__PURE__ */
|
|
2809
|
+
return /* @__PURE__ */ jsx14(BasicTextarea, { id, rows: 4, value: text, disabled, onChange: (e) => commit(e.target.value) });
|
|
2580
2810
|
default:
|
|
2581
2811
|
return null;
|
|
2582
2812
|
}
|
|
2583
2813
|
}
|
|
2584
2814
|
|
|
2585
2815
|
// src/typedDateHelper.tsx
|
|
2586
|
-
import { useState as
|
|
2587
|
-
import { Popover as Popover3, PopoverContent as PopoverContent3, PopoverTrigger as PopoverTrigger3, cn as
|
|
2816
|
+
import { useState as useState12 } from "react";
|
|
2817
|
+
import { Popover as Popover3, PopoverContent as PopoverContent3, PopoverTrigger as PopoverTrigger3, cn as cn11 } from "@ai-matrx/design-system";
|
|
2588
2818
|
import { readTypedDate, readTypedTime, typedDateText, typedTimeText } from "@ai-matrx/records";
|
|
2589
|
-
import { jsx as
|
|
2819
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2590
2820
|
var WEEK = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
2591
2821
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
2592
2822
|
function pad(n) {
|
|
@@ -2615,23 +2845,23 @@ function wordsFor(kind, day, time) {
|
|
|
2615
2845
|
}
|
|
2616
2846
|
var keepFocus = { onMouseDown: (e) => e.preventDefault(), tabIndex: -1 };
|
|
2617
2847
|
function CalendarGlyph() {
|
|
2618
|
-
return /* @__PURE__ */
|
|
2619
|
-
/* @__PURE__ */
|
|
2620
|
-
/* @__PURE__ */
|
|
2848
|
+
return /* @__PURE__ */ jsxs13("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2849
|
+
/* @__PURE__ */ jsx15("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
|
|
2850
|
+
/* @__PURE__ */ jsx15("path", { d: "M16 2v4M8 2v4M3 10h18" })
|
|
2621
2851
|
] });
|
|
2622
2852
|
}
|
|
2623
2853
|
function ClockGlyph() {
|
|
2624
|
-
return /* @__PURE__ */
|
|
2625
|
-
/* @__PURE__ */
|
|
2626
|
-
/* @__PURE__ */
|
|
2854
|
+
return /* @__PURE__ */ jsxs13("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2855
|
+
/* @__PURE__ */ jsx15("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2856
|
+
/* @__PURE__ */ jsx15("path", { d: "M12 6v6l4 2" })
|
|
2627
2857
|
] });
|
|
2628
2858
|
}
|
|
2629
2859
|
function TypedDateHelper({ kind, text, onText, label }) {
|
|
2630
|
-
const [open, setOpen] =
|
|
2860
|
+
const [open, setOpen] = useState12(false);
|
|
2631
2861
|
const held = readBox(text, kind);
|
|
2632
2862
|
const today = /* @__PURE__ */ new Date();
|
|
2633
2863
|
const start = held.day ? new Date(Number(held.day.slice(0, 4)), Number(held.day.slice(5, 7)) - 1, 1) : new Date(today.getFullYear(), today.getMonth(), 1);
|
|
2634
|
-
const [month, setMonth] =
|
|
2864
|
+
const [month, setMonth] = useState12(null);
|
|
2635
2865
|
const shown2 = month ?? { y: start.getFullYear(), m: start.getMonth() };
|
|
2636
2866
|
const first = new Date(shown2.y, shown2.m, 1).getDay();
|
|
2637
2867
|
const days = new Date(shown2.y, shown2.m + 1, 0).getDate();
|
|
@@ -2652,8 +2882,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2652
2882
|
const at = new Date(shown2.y, shown2.m + by, 1);
|
|
2653
2883
|
setMonth({ y: at.getFullYear(), m: at.getMonth() });
|
|
2654
2884
|
};
|
|
2655
|
-
return /* @__PURE__ */
|
|
2656
|
-
/* @__PURE__ */
|
|
2885
|
+
return /* @__PURE__ */ jsxs13(Popover3, { open, onOpenChange: setOpen, children: [
|
|
2886
|
+
/* @__PURE__ */ jsx15(PopoverTrigger3, { asChild: true, children: /* @__PURE__ */ jsx15(
|
|
2657
2887
|
"button",
|
|
2658
2888
|
{
|
|
2659
2889
|
type: "button",
|
|
@@ -2662,10 +2892,10 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2662
2892
|
"aria-label": kind === "time" ? `Pick a time for ${label}` : `Pick a date for ${label}`,
|
|
2663
2893
|
title: kind === "time" ? "Pick a time" : "Pick a date",
|
|
2664
2894
|
className: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
2665
|
-
children: kind === "time" ? /* @__PURE__ */
|
|
2895
|
+
children: kind === "time" ? /* @__PURE__ */ jsx15(ClockGlyph, {}) : /* @__PURE__ */ jsx15(CalendarGlyph, {})
|
|
2666
2896
|
}
|
|
2667
2897
|
) }),
|
|
2668
|
-
/* @__PURE__ */
|
|
2898
|
+
/* @__PURE__ */ jsx15(
|
|
2669
2899
|
PopoverContent3,
|
|
2670
2900
|
{
|
|
2671
2901
|
sizing: "content",
|
|
@@ -2675,29 +2905,29 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2675
2905
|
"data-records-date-helper-panel": "",
|
|
2676
2906
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
2677
2907
|
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
2678
|
-
children: /* @__PURE__ */
|
|
2679
|
-
kind === "time" ? null : /* @__PURE__ */
|
|
2680
|
-
/* @__PURE__ */
|
|
2681
|
-
/* @__PURE__ */
|
|
2682
|
-
/* @__PURE__ */
|
|
2908
|
+
children: /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
|
|
2909
|
+
kind === "time" ? null : /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1", role: "grid", "aria-label": `${MONTHS[shown2.m]} ${shown2.y}`, children: [
|
|
2910
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between text-xs font-medium", children: [
|
|
2911
|
+
/* @__PURE__ */ jsx15("button", { type: "button", ...keepFocus, "aria-label": "Previous month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(-1), children: "\u2039" }),
|
|
2912
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
2683
2913
|
MONTHS[shown2.m],
|
|
2684
2914
|
" ",
|
|
2685
2915
|
shown2.y
|
|
2686
2916
|
] }),
|
|
2687
|
-
/* @__PURE__ */
|
|
2917
|
+
/* @__PURE__ */ jsx15("button", { type: "button", ...keepFocus, "aria-label": "Next month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(1), children: "\u203A" })
|
|
2688
2918
|
] }),
|
|
2689
|
-
/* @__PURE__ */
|
|
2690
|
-
WEEK.map((w) => /* @__PURE__ */
|
|
2919
|
+
/* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-7 gap-0.5 text-center text-[11px]", children: [
|
|
2920
|
+
WEEK.map((w) => /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: w }, w)),
|
|
2691
2921
|
cells.map((d, i) => {
|
|
2692
|
-
if (d === null) return /* @__PURE__ */
|
|
2922
|
+
if (d === null) return /* @__PURE__ */ jsx15("span", {}, `blank-${i}`);
|
|
2693
2923
|
const key = `${shown2.y}-${pad(shown2.m + 1)}-${pad(d)}`;
|
|
2694
|
-
return /* @__PURE__ */
|
|
2924
|
+
return /* @__PURE__ */ jsx15(
|
|
2695
2925
|
"button",
|
|
2696
2926
|
{
|
|
2697
2927
|
type: "button",
|
|
2698
2928
|
...keepFocus,
|
|
2699
2929
|
"data-records-date-helper-day": key,
|
|
2700
|
-
className:
|
|
2930
|
+
className: cn11(
|
|
2701
2931
|
"h-6 w-6 rounded tabular-nums hover:bg-muted",
|
|
2702
2932
|
key === held.day ? "bg-primary text-primary-foreground hover:bg-primary" : "",
|
|
2703
2933
|
key === todayKey && key !== held.day ? "ring-1 ring-ring" : ""
|
|
@@ -2710,13 +2940,13 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2710
2940
|
})
|
|
2711
2941
|
] })
|
|
2712
2942
|
] }),
|
|
2713
|
-
kind === "date" ? null : /* @__PURE__ */
|
|
2943
|
+
kind === "date" ? null : /* @__PURE__ */ jsx15("div", { className: "flex max-h-48 flex-col overflow-y-auto pr-1 text-[11px]", "aria-label": "Times", children: times.map((t) => /* @__PURE__ */ jsx15(
|
|
2714
2944
|
"button",
|
|
2715
2945
|
{
|
|
2716
2946
|
type: "button",
|
|
2717
2947
|
...keepFocus,
|
|
2718
2948
|
"data-records-date-helper-time": `${pad(t.h)}:${pad(t.m)}`,
|
|
2719
|
-
className:
|
|
2949
|
+
className: cn11(
|
|
2720
2950
|
"whitespace-nowrap rounded px-2 py-0.5 text-left tabular-nums hover:bg-muted",
|
|
2721
2951
|
held.time && held.time.h === t.h && held.time.m === t.m ? "bg-primary text-primary-foreground" : ""
|
|
2722
2952
|
),
|
|
@@ -2732,8 +2962,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2732
2962
|
}
|
|
2733
2963
|
|
|
2734
2964
|
// src/choiceNudge.ts
|
|
2735
|
-
import { useEffect as useEffect9, useState as
|
|
2736
|
-
import { useOptionalRecordsClient as
|
|
2965
|
+
import { useEffect as useEffect9, useState as useState13 } from "react";
|
|
2966
|
+
import { useOptionalRecordsClient as useOptionalRecordsClient6 } from "@ai-matrx/records/react";
|
|
2737
2967
|
var asked = /* @__PURE__ */ new WeakMap();
|
|
2738
2968
|
function choiceNudgeOf(client) {
|
|
2739
2969
|
let answer = asked.get(client);
|
|
@@ -2747,8 +2977,8 @@ function choiceNudgeOf(client) {
|
|
|
2747
2977
|
return answer;
|
|
2748
2978
|
}
|
|
2749
2979
|
function useChoiceNudge(enabled = true) {
|
|
2750
|
-
const client =
|
|
2751
|
-
const [nudge, setNudge] =
|
|
2980
|
+
const client = useOptionalRecordsClient6();
|
|
2981
|
+
const [nudge, setNudge] = useState13(null);
|
|
2752
2982
|
useEffect9(() => {
|
|
2753
2983
|
if (!enabled || !client) return;
|
|
2754
2984
|
let live = true;
|
|
@@ -2763,65 +2993,8 @@ function useChoiceNudge(enabled = true) {
|
|
|
2763
2993
|
return nudge;
|
|
2764
2994
|
}
|
|
2765
2995
|
|
|
2766
|
-
// src/choiceLooks.ts
|
|
2767
|
-
import {
|
|
2768
|
-
CHOICE_CHIP_CLASS,
|
|
2769
|
-
NEUTRAL_CHIP_CLASS,
|
|
2770
|
-
STYLE_COLORS as STYLE_COLORS2
|
|
2771
|
-
} from "@ai-matrx/design-system/data-table";
|
|
2772
|
-
function displayFormatOf(field) {
|
|
2773
|
-
const raw = field.display_format;
|
|
2774
|
-
if (!raw || typeof raw !== "object") return null;
|
|
2775
|
-
const id = raw.id;
|
|
2776
|
-
if (typeof id !== "string" || id === "") return null;
|
|
2777
|
-
const options = raw.options;
|
|
2778
|
-
return { id, options: options && typeof options === "object" ? options : {} };
|
|
2779
|
-
}
|
|
2780
|
-
function isStyleColor(v) {
|
|
2781
|
-
return typeof v === "string" && STYLE_COLORS2.includes(v);
|
|
2782
|
-
}
|
|
2783
|
-
function choiceLooksOf(field) {
|
|
2784
|
-
const display = displayFormatOf(field);
|
|
2785
|
-
const choices = display?.options["choices"];
|
|
2786
|
-
if (!Array.isArray(choices)) return [];
|
|
2787
|
-
const out = [];
|
|
2788
|
-
for (const c of choices) {
|
|
2789
|
-
if (!c || typeof c !== "object") continue;
|
|
2790
|
-
const value = c.value;
|
|
2791
|
-
if (typeof value !== "string" || value.trim() === "") continue;
|
|
2792
|
-
const color = c.color;
|
|
2793
|
-
const label = c.label;
|
|
2794
|
-
out.push({
|
|
2795
|
-
value: value.trim(),
|
|
2796
|
-
...typeof label === "string" && label.trim() !== "" ? { label: label.trim() } : {},
|
|
2797
|
-
...isStyleColor(color) ? { color } : {}
|
|
2798
|
-
});
|
|
2799
|
-
}
|
|
2800
|
-
return out;
|
|
2801
|
-
}
|
|
2802
|
-
function choiceWord(value) {
|
|
2803
|
-
return String(value ?? "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
2804
|
-
}
|
|
2805
|
-
function storedChoiceColor(field, value) {
|
|
2806
|
-
if (value === null || value === void 0 || value === "") return void 0;
|
|
2807
|
-
const word = choiceWord(value);
|
|
2808
|
-
if (word === "") return void 0;
|
|
2809
|
-
for (const look of choiceLooksOf(field)) {
|
|
2810
|
-
if (!look.color) continue;
|
|
2811
|
-
if (choiceWord(look.value) === word || look.label && choiceWord(look.label) === word) return look.color;
|
|
2812
|
-
}
|
|
2813
|
-
return void 0;
|
|
2814
|
-
}
|
|
2815
|
-
function choiceChipLookOf(field, ...words) {
|
|
2816
|
-
for (const word of words) {
|
|
2817
|
-
const color = storedChoiceColor(field, word);
|
|
2818
|
-
if (color) return { className: CHOICE_CHIP_CLASS[color], color };
|
|
2819
|
-
}
|
|
2820
|
-
return { className: NEUTRAL_CHIP_CLASS, color: null };
|
|
2821
|
-
}
|
|
2822
|
-
|
|
2823
2996
|
// src/editors.tsx
|
|
2824
|
-
import { Fragment as Fragment4, jsx as
|
|
2997
|
+
import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2825
2998
|
var CHOICE_EDITOR_ADDS_WHAT_IS_TYPED = true;
|
|
2826
2999
|
function isChoiceAddition(value) {
|
|
2827
3000
|
return typeof value === "object" && value !== null && value.addingChoices === true;
|
|
@@ -2851,12 +3024,12 @@ function ChoiceAskButtons({
|
|
|
2851
3024
|
onCancel,
|
|
2852
3025
|
busy
|
|
2853
3026
|
}) {
|
|
2854
|
-
return /* @__PURE__ */
|
|
2855
|
-
/* @__PURE__ */
|
|
2856
|
-
/* @__PURE__ */
|
|
2857
|
-
/* @__PURE__ */
|
|
2858
|
-
keepOffered ? /* @__PURE__ */
|
|
2859
|
-
/* @__PURE__ */
|
|
3027
|
+
return /* @__PURE__ */ jsxs14("span", { "data-records-choice-ask": "", role: "group", "aria-label": choiceAskSentence(field, words), className: "flex flex-col gap-1", children: [
|
|
3028
|
+
/* @__PURE__ */ jsx16("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field, words) }),
|
|
3029
|
+
/* @__PURE__ */ jsxs14("span", { className: "flex flex-wrap items-center gap-1", children: [
|
|
3030
|
+
/* @__PURE__ */ jsx16(Button8, { type: "button", size: "sm", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onAdd, children: "Add" }),
|
|
3031
|
+
keepOffered ? /* @__PURE__ */ jsx16(Button8, { type: "button", size: "sm", variant: "outline", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onKeep, children: "Keep as typed" }) : null,
|
|
3032
|
+
/* @__PURE__ */ jsx16(Button8, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onCancel, children: "Cancel" })
|
|
2860
3033
|
] })
|
|
2861
3034
|
] });
|
|
2862
3035
|
}
|
|
@@ -2939,11 +3112,11 @@ function openingText(field, value) {
|
|
|
2939
3112
|
return format ? typedText(format, value) : String(value);
|
|
2940
3113
|
}
|
|
2941
3114
|
function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCancel }) {
|
|
2942
|
-
const client =
|
|
3115
|
+
const client = useOptionalRecordsClient7();
|
|
2943
3116
|
const kind = String(editorKindFor(field));
|
|
2944
3117
|
const needsChoices = kind === "select" || kind === "multi_select";
|
|
2945
3118
|
const nudge = useChoiceNudge(needsChoices);
|
|
2946
|
-
const [choices, setChoices] =
|
|
3119
|
+
const [choices, setChoices] = useState14(null);
|
|
2947
3120
|
useEffect10(() => {
|
|
2948
3121
|
if (!needsChoices || !client) return;
|
|
2949
3122
|
let cancelled = false;
|
|
@@ -2966,7 +3139,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2966
3139
|
judged: judgeTyped(field, text, needsChoices ? choices : void 0, needsChoices ? nudge : void 0),
|
|
2967
3140
|
...value.openedAs !== void 0 ? { openedAs: value.openedAs } : {}
|
|
2968
3141
|
});
|
|
2969
|
-
const box = /* @__PURE__ */
|
|
3142
|
+
const box = /* @__PURE__ */ jsx16(
|
|
2970
3143
|
BasicInput6,
|
|
2971
3144
|
{
|
|
2972
3145
|
id,
|
|
@@ -2978,16 +3151,16 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2978
3151
|
onChange: (e) => retype(e.target.value)
|
|
2979
3152
|
}
|
|
2980
3153
|
);
|
|
2981
|
-
return /* @__PURE__ */
|
|
2982
|
-
helper && !disabled ? /* @__PURE__ */
|
|
3154
|
+
return /* @__PURE__ */ jsxs14("span", { className: "flex flex-col gap-0.5", children: [
|
|
3155
|
+
helper && !disabled ? /* @__PURE__ */ jsxs14("span", { className: "flex min-w-0 items-center gap-0.5", children: [
|
|
2983
3156
|
box,
|
|
2984
|
-
/* @__PURE__ */
|
|
3157
|
+
/* @__PURE__ */ jsx16(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field) })
|
|
2985
3158
|
] }) : box,
|
|
2986
|
-
judged === null ? /* @__PURE__ */
|
|
3159
|
+
judged === null ? /* @__PURE__ */ jsxs14("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
2987
3160
|
"Reading ",
|
|
2988
3161
|
fieldName(field),
|
|
2989
3162
|
"'s choices\u2026"
|
|
2990
|
-
] }) : "ask" in judged ? /* @__PURE__ */
|
|
3163
|
+
] }) : "ask" in judged ? /* @__PURE__ */ jsx16(
|
|
2991
3164
|
ChoiceAskButtons,
|
|
2992
3165
|
{
|
|
2993
3166
|
field,
|
|
@@ -3003,10 +3176,10 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
3003
3176
|
},
|
|
3004
3177
|
onCancel: () => onCancel?.()
|
|
3005
3178
|
}
|
|
3006
|
-
) : "refusal" in judged ? /* @__PURE__ */
|
|
3007
|
-
/* @__PURE__ */
|
|
3008
|
-
judged.cancelOnly && onCancel ? /* @__PURE__ */
|
|
3009
|
-
] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */
|
|
3179
|
+
) : "refusal" in judged ? /* @__PURE__ */ jsxs14("span", { className: "flex flex-col gap-1", children: [
|
|
3180
|
+
/* @__PURE__ */ jsx16("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: judged.refusal }),
|
|
3181
|
+
judged.cancelOnly && onCancel ? /* @__PURE__ */ jsx16("span", { "data-records-choice-ask": "", children: /* @__PURE__ */ jsx16(Button8, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => onCancel(), children: "Cancel" }) }) : null
|
|
3182
|
+
] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ jsxs14("span", { "data-records-typed-reads-as": "", className: "text-[10px] text-muted-foreground", children: [
|
|
3010
3183
|
isChoiceAddition(judged.value) ? `Adds ${quoted(judged.value.add)} to the choices for ${fieldName(field)}. ` : null,
|
|
3011
3184
|
"Reads as",
|
|
3012
3185
|
" ",
|
|
@@ -3017,7 +3190,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
3017
3190
|
}).join(", ")
|
|
3018
3191
|
) : (() => {
|
|
3019
3192
|
const shown2 = format ?? (kind === "datetime" ? { id: carriesTimeOfDay(field, judged.value) ? "datetime" : "date" } : void 0);
|
|
3020
|
-
return shown2 ? /* @__PURE__ */
|
|
3193
|
+
return shown2 ? /* @__PURE__ */ jsx16(FormattedValue, { value: judged.value, format: shown2 }) : String(judged.value);
|
|
3021
3194
|
})()
|
|
3022
3195
|
] })
|
|
3023
3196
|
] });
|
|
@@ -3030,13 +3203,13 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3030
3203
|
const host = useRecordsUi();
|
|
3031
3204
|
const kind = editorKindFor(field);
|
|
3032
3205
|
const inputId = id ?? `field-${field.key}`;
|
|
3033
|
-
const ownDetails =
|
|
3034
|
-
if (isTypedDraft(value)) return /* @__PURE__ */
|
|
3035
|
-
if (isSignatureField(field)) return /* @__PURE__ */
|
|
3206
|
+
const ownDetails = useOptionalRecordsClient7() === null;
|
|
3207
|
+
if (isTypedDraft(value)) return /* @__PURE__ */ jsx16(TypedTextControl, { field, value, onChange, disabled, id: inputId, onCommit, onCancel });
|
|
3208
|
+
if (isSignatureField(field)) return /* @__PURE__ */ jsx16(SignaturePad, { id: inputId, value, onChange, disabled });
|
|
3036
3209
|
const newerControl = newerKindControl({ field, value, onChange, disabled, id: inputId });
|
|
3037
3210
|
if (newerControl !== void 0) return newerControl;
|
|
3038
3211
|
const format = formatForField(field);
|
|
3039
|
-
if (format && format.id === "time") return /* @__PURE__ */
|
|
3212
|
+
if (format && format.id === "time") return /* @__PURE__ */ jsx16(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
|
|
3040
3213
|
if (format && !FORMAT_BLIND_KINDS.has(String(kind))) {
|
|
3041
3214
|
const own3 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field), ownDetails });
|
|
3042
3215
|
if (own3) return own3;
|
|
@@ -3045,17 +3218,17 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3045
3218
|
case "formula":
|
|
3046
3219
|
case "lookup":
|
|
3047
3220
|
case "rollup":
|
|
3048
|
-
return /* @__PURE__ */
|
|
3221
|
+
return /* @__PURE__ */ jsxs14("div", { id: inputId, className: "rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground", children: [
|
|
3049
3222
|
value === null || value === void 0 ? "\u2014" : String(value),
|
|
3050
|
-
/* @__PURE__ */
|
|
3223
|
+
/* @__PURE__ */ jsxs14("span", { className: "ml-2 italic", children: [
|
|
3051
3224
|
fieldName(field),
|
|
3052
3225
|
" is worked out by the system, so it cannot be typed in"
|
|
3053
3226
|
] })
|
|
3054
3227
|
] });
|
|
3055
3228
|
case "json":
|
|
3056
|
-
return /* @__PURE__ */
|
|
3229
|
+
return /* @__PURE__ */ jsx16(JsonControl, { field, value, onChange, disabled, id: inputId });
|
|
3057
3230
|
case "long_text":
|
|
3058
|
-
return /* @__PURE__ */
|
|
3231
|
+
return /* @__PURE__ */ jsx16(
|
|
3059
3232
|
BasicTextarea2,
|
|
3060
3233
|
{
|
|
3061
3234
|
id: inputId,
|
|
@@ -3068,7 +3241,7 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3068
3241
|
case "number":
|
|
3069
3242
|
case "currency":
|
|
3070
3243
|
case "percent":
|
|
3071
|
-
return /* @__PURE__ */
|
|
3244
|
+
return /* @__PURE__ */ jsx16(
|
|
3072
3245
|
BasicInput6,
|
|
3073
3246
|
{
|
|
3074
3247
|
id: inputId,
|
|
@@ -3081,11 +3254,11 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3081
3254
|
}
|
|
3082
3255
|
);
|
|
3083
3256
|
case "datetime":
|
|
3084
|
-
return /* @__PURE__ */
|
|
3257
|
+
return /* @__PURE__ */ jsx16(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
|
|
3085
3258
|
case "email":
|
|
3086
3259
|
case "phone":
|
|
3087
3260
|
case "url":
|
|
3088
|
-
return /* @__PURE__ */
|
|
3261
|
+
return /* @__PURE__ */ jsx16(
|
|
3089
3262
|
BasicInput6,
|
|
3090
3263
|
{
|
|
3091
3264
|
id: inputId,
|
|
@@ -3097,24 +3270,24 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3097
3270
|
}
|
|
3098
3271
|
);
|
|
3099
3272
|
case "checkbox":
|
|
3100
|
-
return /* @__PURE__ */
|
|
3273
|
+
return /* @__PURE__ */ jsx16(CheckboxControl, { field, value, onChange, disabled, id: inputId });
|
|
3101
3274
|
case "select":
|
|
3102
3275
|
case "multi_select":
|
|
3103
|
-
return /* @__PURE__ */
|
|
3276
|
+
return /* @__PURE__ */ jsx16(OptionControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
|
|
3104
3277
|
case "member":
|
|
3105
|
-
return /* @__PURE__ */
|
|
3278
|
+
return /* @__PURE__ */ jsx16(PersonPicker, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
|
|
3106
3279
|
case "entity_reference":
|
|
3107
|
-
return /* @__PURE__ */
|
|
3280
|
+
return /* @__PURE__ */ jsx16(EntityReferenceControl, { field, value, onChange, disabled, id: inputId });
|
|
3108
3281
|
case "attachment":
|
|
3109
3282
|
if (hostTakesFiles(host)) {
|
|
3110
|
-
return /* @__PURE__ */
|
|
3283
|
+
return /* @__PURE__ */ jsx16(AttachmentControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose });
|
|
3111
3284
|
}
|
|
3112
|
-
return /* @__PURE__ */
|
|
3285
|
+
return /* @__PURE__ */ jsx16(RelationPicker, { field, value, onChange, disabled, id: inputId });
|
|
3113
3286
|
case "relation":
|
|
3114
|
-
return /* @__PURE__ */
|
|
3287
|
+
return /* @__PURE__ */ jsx16(RelationPicker, { field, value, onChange, disabled, id: inputId });
|
|
3115
3288
|
default:
|
|
3116
3289
|
if (typeof value === "boolean" || field.config?.["kind"] === "boolean") {
|
|
3117
|
-
return /* @__PURE__ */
|
|
3290
|
+
return /* @__PURE__ */ jsx16(
|
|
3118
3291
|
Checkbox,
|
|
3119
3292
|
{
|
|
3120
3293
|
id: inputId,
|
|
@@ -3124,7 +3297,7 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3124
3297
|
}
|
|
3125
3298
|
);
|
|
3126
3299
|
}
|
|
3127
|
-
return /* @__PURE__ */
|
|
3300
|
+
return /* @__PURE__ */ jsx16(
|
|
3128
3301
|
BasicInput6,
|
|
3129
3302
|
{
|
|
3130
3303
|
id: inputId,
|
|
@@ -3137,8 +3310,8 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3137
3310
|
}
|
|
3138
3311
|
}
|
|
3139
3312
|
function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
3140
|
-
const [text, setText] =
|
|
3141
|
-
const [refusal2, setRefusal] =
|
|
3313
|
+
const [text, setText] = useState14(() => openingText(field, value));
|
|
3314
|
+
const [refusal2, setRefusal] = useState14(null);
|
|
3142
3315
|
const sent = useRef9(value);
|
|
3143
3316
|
useEffect10(() => {
|
|
3144
3317
|
if (value === sent.current) return;
|
|
@@ -3158,9 +3331,9 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
|
3158
3331
|
setRefusal(judged.refusal);
|
|
3159
3332
|
}
|
|
3160
3333
|
};
|
|
3161
|
-
return /* @__PURE__ */
|
|
3162
|
-
/* @__PURE__ */
|
|
3163
|
-
/* @__PURE__ */
|
|
3334
|
+
return /* @__PURE__ */ jsxs14("span", { className: "flex flex-col gap-0.5", children: [
|
|
3335
|
+
/* @__PURE__ */ jsxs14("span", { className: "flex min-w-0 items-center gap-0.5", children: [
|
|
3336
|
+
/* @__PURE__ */ jsx16(
|
|
3164
3337
|
BasicInput6,
|
|
3165
3338
|
{
|
|
3166
3339
|
id,
|
|
@@ -3177,15 +3350,15 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
|
3177
3350
|
}
|
|
3178
3351
|
}
|
|
3179
3352
|
),
|
|
3180
|
-
helper && !disabled ? /* @__PURE__ */
|
|
3353
|
+
helper && !disabled ? /* @__PURE__ */ jsx16(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field) }) : null
|
|
3181
3354
|
] }),
|
|
3182
|
-
refusal2 ? /* @__PURE__ */
|
|
3355
|
+
refusal2 ? /* @__PURE__ */ jsx16("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal2 }) : null
|
|
3183
3356
|
] });
|
|
3184
3357
|
}
|
|
3185
3358
|
function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
3186
3359
|
const unanswered = value === null || value === void 0;
|
|
3187
|
-
return /* @__PURE__ */
|
|
3188
|
-
/* @__PURE__ */
|
|
3360
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
3361
|
+
/* @__PURE__ */ jsx16(
|
|
3189
3362
|
Checkbox,
|
|
3190
3363
|
{
|
|
3191
3364
|
id,
|
|
@@ -3195,9 +3368,9 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
|
3195
3368
|
onCheckedChange: (next) => onChange(next === true)
|
|
3196
3369
|
}
|
|
3197
3370
|
),
|
|
3198
|
-
unanswered ? /* @__PURE__ */
|
|
3199
|
-
/* @__PURE__ */
|
|
3200
|
-
field.required ? null : /* @__PURE__ */
|
|
3371
|
+
unanswered ? /* @__PURE__ */ jsx16("span", { className: "text-xs italic text-muted-foreground", children: "not answered yet" }) : /* @__PURE__ */ jsxs14(Fragment4, { children: [
|
|
3372
|
+
/* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground", children: value === true ? "Yes" : "No" }),
|
|
3373
|
+
field.required ? null : /* @__PURE__ */ jsx16(
|
|
3201
3374
|
Button8,
|
|
3202
3375
|
{
|
|
3203
3376
|
size: "sm",
|
|
@@ -3213,10 +3386,10 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
|
3213
3386
|
}
|
|
3214
3387
|
function JsonControl({ field, value, onChange, disabled, id }) {
|
|
3215
3388
|
const initial = value === null || value === void 0 ? "" : typeof value === "string" ? value : JSON.stringify(value, null, 2);
|
|
3216
|
-
const [text, setText] =
|
|
3217
|
-
const [broken, setBroken] =
|
|
3218
|
-
return /* @__PURE__ */
|
|
3219
|
-
/* @__PURE__ */
|
|
3389
|
+
const [text, setText] = useState14(initial);
|
|
3390
|
+
const [broken, setBroken] = useState14(null);
|
|
3391
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
|
|
3392
|
+
/* @__PURE__ */ jsx16(
|
|
3220
3393
|
BasicTextarea2,
|
|
3221
3394
|
{
|
|
3222
3395
|
id,
|
|
@@ -3250,7 +3423,7 @@ function JsonControl({ field, value, onChange, disabled, id }) {
|
|
|
3250
3423
|
),
|
|
3251
3424
|
broken ? (
|
|
3252
3425
|
// The typed text is still in the box: the notice owns the two doors out.
|
|
3253
|
-
/* @__PURE__ */
|
|
3426
|
+
/* @__PURE__ */ jsx16(
|
|
3254
3427
|
RefusalNotice,
|
|
3255
3428
|
{
|
|
3256
3429
|
error: broken,
|
|
@@ -3274,10 +3447,10 @@ function inTheStoresOrder(options) {
|
|
|
3274
3447
|
return [...options].sort((a, b) => position(a) - position(b) || made(a).localeCompare(made(b)));
|
|
3275
3448
|
}
|
|
3276
3449
|
function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose, addsChoices, initialSearch, asForm }) {
|
|
3277
|
-
const client =
|
|
3278
|
-
const [options, setOptions] =
|
|
3279
|
-
const [refusal2, setRefusal] =
|
|
3280
|
-
const [reread, setReread] =
|
|
3450
|
+
const client = useOptionalRecordsClient7();
|
|
3451
|
+
const [options, setOptions] = useState14(null);
|
|
3452
|
+
const [refusal2, setRefusal] = useState14(null);
|
|
3453
|
+
const [reread, setReread] = useState14(0);
|
|
3281
3454
|
useEffect10(() => {
|
|
3282
3455
|
if (!client) return;
|
|
3283
3456
|
let cancelled = false;
|
|
@@ -3292,11 +3465,11 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3292
3465
|
}, [client, field.id, reread]);
|
|
3293
3466
|
const handed = publicChoicesOf(field);
|
|
3294
3467
|
if (!client && handed.length > 0) {
|
|
3295
|
-
return /* @__PURE__ */
|
|
3468
|
+
return /* @__PURE__ */ jsx16(ChoiceAnswer, { field, choices: handed, value, onChange, disabled, id });
|
|
3296
3469
|
}
|
|
3297
3470
|
if (!client) {
|
|
3298
|
-
return /* @__PURE__ */
|
|
3299
|
-
/* @__PURE__ */
|
|
3471
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
|
|
3472
|
+
/* @__PURE__ */ jsx16(
|
|
3300
3473
|
BasicInput6,
|
|
3301
3474
|
{
|
|
3302
3475
|
id,
|
|
@@ -3305,15 +3478,15 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3305
3478
|
onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
|
|
3306
3479
|
}
|
|
3307
3480
|
),
|
|
3308
|
-
/* @__PURE__ */
|
|
3481
|
+
/* @__PURE__ */ jsx16("p", { className: "text-xs text-muted-foreground", children: "This is normally picked from a list. A page answered without an account cannot read that list, so type your answer and whoever receives it will match it up." })
|
|
3309
3482
|
] });
|
|
3310
3483
|
}
|
|
3311
3484
|
if (refusal2)
|
|
3312
|
-
return /* @__PURE__ */
|
|
3313
|
-
if (!options) return /* @__PURE__ */
|
|
3485
|
+
return /* @__PURE__ */ jsx16("div", { id, children: /* @__PURE__ */ jsx16(RefusalLine, { error: refusal2 }) });
|
|
3486
|
+
if (!options) return /* @__PURE__ */ jsx16("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
|
|
3314
3487
|
if (asForm && options.length > 0) {
|
|
3315
3488
|
const titled = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3316
|
-
return /* @__PURE__ */
|
|
3489
|
+
return /* @__PURE__ */ jsx16(
|
|
3317
3490
|
ChoiceAnswer,
|
|
3318
3491
|
{
|
|
3319
3492
|
field,
|
|
@@ -3330,7 +3503,7 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3330
3503
|
);
|
|
3331
3504
|
}
|
|
3332
3505
|
if (CHOICE_EDITOR_ADDS_WHAT_IS_TYPED) {
|
|
3333
|
-
return /* @__PURE__ */
|
|
3506
|
+
return /* @__PURE__ */ jsx16(
|
|
3334
3507
|
OpenChoicePicker,
|
|
3335
3508
|
{
|
|
3336
3509
|
field,
|
|
@@ -3349,13 +3522,13 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3349
3522
|
);
|
|
3350
3523
|
}
|
|
3351
3524
|
if (options.length === 0) {
|
|
3352
|
-
return /* @__PURE__ */
|
|
3525
|
+
return /* @__PURE__ */ jsx16("p", { id, className: "text-xs text-muted-foreground", children: field.options_table_id ? `${fieldName(field)} takes its choices from a Table that has no records yet \u2014 add the choices there and they appear here.` : `${fieldName(field)} does not name the Table its choices come from yet, so there is nothing to choose. A table admin sets it in the field editor.` });
|
|
3353
3526
|
}
|
|
3354
3527
|
const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3355
3528
|
if (field.multi) {
|
|
3356
3529
|
const chosen = options.filter((option) => choiceValuesOf(value).some((v) => isTheChosen(option, v)));
|
|
3357
3530
|
const picked = new Set(chosen.map((option) => optionKey2(option)));
|
|
3358
|
-
const toggles = /* @__PURE__ */
|
|
3531
|
+
const toggles = /* @__PURE__ */ jsx16("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ jsx16(
|
|
3359
3532
|
Button8,
|
|
3360
3533
|
{
|
|
3361
3534
|
type: "button",
|
|
@@ -3373,7 +3546,7 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3373
3546
|
option.id
|
|
3374
3547
|
)) });
|
|
3375
3548
|
if (!autoOpen) return toggles;
|
|
3376
|
-
return /* @__PURE__ */
|
|
3549
|
+
return /* @__PURE__ */ jsxs14(
|
|
3377
3550
|
Popover4,
|
|
3378
3551
|
{
|
|
3379
3552
|
defaultOpen: true,
|
|
@@ -3381,15 +3554,15 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3381
3554
|
if (!open) onClose?.();
|
|
3382
3555
|
},
|
|
3383
3556
|
children: [
|
|
3384
|
-
/* @__PURE__ */
|
|
3385
|
-
/* @__PURE__ */
|
|
3557
|
+
/* @__PURE__ */ jsx16(PopoverTrigger4, { asChild: true, children: /* @__PURE__ */ jsx16(Button8, { id, type: "button", size: "sm", variant: "outline", className: "h-6 max-w-full truncate", children: chosen.length === 0 ? "Choose" : chosen.map(titleOf).join(", ") }) }),
|
|
3558
|
+
/* @__PURE__ */ jsx16(PopoverContent4, { sizing: "content", className: "max-w-[20rem] p-2", align: "start", children: toggles })
|
|
3386
3559
|
]
|
|
3387
3560
|
}
|
|
3388
3561
|
);
|
|
3389
3562
|
}
|
|
3390
3563
|
const current = options.find((option) => isTheChosen(option, value));
|
|
3391
|
-
return /* @__PURE__ */
|
|
3392
|
-
|
|
3564
|
+
return /* @__PURE__ */ jsxs14(
|
|
3565
|
+
Select2,
|
|
3393
3566
|
{
|
|
3394
3567
|
value: current ? optionKey2(current) : "",
|
|
3395
3568
|
disabled: disabled ?? false,
|
|
@@ -3402,8 +3575,8 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3402
3575
|
}
|
|
3403
3576
|
} : {},
|
|
3404
3577
|
children: [
|
|
3405
|
-
/* @__PURE__ */
|
|
3406
|
-
/* @__PURE__ */
|
|
3578
|
+
/* @__PURE__ */ jsx16(SelectTrigger2, { id, size: "sm", children: /* @__PURE__ */ jsx16(SelectValue2, { placeholder: "Choose" }) }),
|
|
3579
|
+
/* @__PURE__ */ jsx16(SelectContent2, { children: options.map((option) => /* @__PURE__ */ jsx16(SelectItem2, { value: optionKey2(option), children: titleOf(option) }, option.id)) })
|
|
3407
3580
|
]
|
|
3408
3581
|
}
|
|
3409
3582
|
);
|
|
@@ -3422,18 +3595,18 @@ function OpenChoicePicker({
|
|
|
3422
3595
|
allowOther = true,
|
|
3423
3596
|
onChoicesChanged
|
|
3424
3597
|
}) {
|
|
3425
|
-
const client =
|
|
3598
|
+
const client = useOptionalRecordsClient7();
|
|
3426
3599
|
const nudge = useChoiceNudge();
|
|
3427
|
-
const [open, setOpenState] =
|
|
3600
|
+
const [open, setOpenState] = useState14(autoOpen === true);
|
|
3428
3601
|
const onCloseRef = useRef9(onClose);
|
|
3429
3602
|
onCloseRef.current = onClose;
|
|
3430
3603
|
const setOpen = useCallback4((next) => {
|
|
3431
3604
|
setOpenState(next);
|
|
3432
3605
|
if (!next) onCloseRef.current?.();
|
|
3433
3606
|
}, []);
|
|
3434
|
-
const [search, setSearch] =
|
|
3435
|
-
const [adding, setAdding] =
|
|
3436
|
-
const [addRefused, setAddRefused] =
|
|
3607
|
+
const [search, setSearch] = useState14(initialSearch ?? "");
|
|
3608
|
+
const [adding, setAdding] = useState14(false);
|
|
3609
|
+
const [addRefused, setAddRefused] = useState14(null);
|
|
3437
3610
|
const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3438
3611
|
const held = withoutAddition(value);
|
|
3439
3612
|
const current = choiceValuesOf(held.value);
|
|
@@ -3485,7 +3658,7 @@ function OpenChoicePicker({
|
|
|
3485
3658
|
});
|
|
3486
3659
|
};
|
|
3487
3660
|
const offList = q !== "" && decided.decision !== "chosen" && decided.decision !== "empty";
|
|
3488
|
-
const foot = offList && decided.decision === "ask" ? /* @__PURE__ */
|
|
3661
|
+
const foot = offList && decided.decision === "ask" ? /* @__PURE__ */ jsx16(
|
|
3489
3662
|
ChoiceAskButtons,
|
|
3490
3663
|
{
|
|
3491
3664
|
field,
|
|
@@ -3502,14 +3675,14 @@ function OpenChoicePicker({
|
|
|
3502
3675
|
}
|
|
3503
3676
|
) : null;
|
|
3504
3677
|
const add = offList && decided.decision === "add" ? { label: `Add \u201C${q}\u201D to the choices`, onAdd: addTyped, disabled: adding } : offList && decided.decision === "keep_as_typed" ? { label: `Keep \u201C${q}\u201D as typed`, onAdd: () => choose(q) } : null;
|
|
3505
|
-
return /* @__PURE__ */
|
|
3678
|
+
return /* @__PURE__ */ jsxs14("div", { id, className: "flex flex-wrap items-center gap-1", children: [
|
|
3506
3679
|
pickedWords.map((word, i) => {
|
|
3507
3680
|
const chip = chipOf(options.find((o) => isTheChosen(o, current[i])), word);
|
|
3508
|
-
return /* @__PURE__ */
|
|
3681
|
+
return /* @__PURE__ */ jsx16(Badge3, { variant: "outline", className: cn12("text-[11px]", chip.className), "data-records-choice-chip": "", children: word }, word);
|
|
3509
3682
|
}),
|
|
3510
3683
|
disabled ? null : (
|
|
3511
3684
|
// THE ONE "PICK OR ADD" BUILDER (PickOrAdd.tsx) — the relation picker draws the same one.
|
|
3512
|
-
/* @__PURE__ */
|
|
3685
|
+
/* @__PURE__ */ jsx16(
|
|
3513
3686
|
PickOrAdd,
|
|
3514
3687
|
{
|
|
3515
3688
|
triggerLabel: `Pick for ${fieldName(field)}`,
|
|
@@ -3531,15 +3704,15 @@ function OpenChoicePicker({
|
|
|
3531
3704
|
const option = options.find((o) => o.id === optionId);
|
|
3532
3705
|
if (option) choose(optionKey2(option));
|
|
3533
3706
|
},
|
|
3534
|
-
empty: q === "" ? /* @__PURE__ */
|
|
3707
|
+
empty: q === "" ? /* @__PURE__ */ jsx16("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
|
|
3535
3708
|
add,
|
|
3536
3709
|
foot,
|
|
3537
3710
|
...offList && decided.decision === "ask" && !adding ? { onEnterWithNoMatch: addTyped } : {},
|
|
3538
|
-
footNote: addRefused ? /* @__PURE__ */
|
|
3711
|
+
footNote: addRefused ? /* @__PURE__ */ jsx16(RefusalLine, { error: addRefused }) : offList && decided.decision === "not_a_choice" ? (
|
|
3539
3712
|
// never_add on a column that takes only its choices: said, never a silent nothing.
|
|
3540
|
-
/* @__PURE__ */
|
|
3541
|
-
/* @__PURE__ */
|
|
3542
|
-
autoOpen ? /* @__PURE__ */
|
|
3713
|
+
/* @__PURE__ */ jsxs14(Fragment4, { children: [
|
|
3714
|
+
/* @__PURE__ */ jsx16("p", { "data-records-typed-refusal": "", className: "p-2 text-xs text-muted-foreground", children: notAChoiceSentence(field, [q]) }),
|
|
3715
|
+
autoOpen ? /* @__PURE__ */ jsx16("span", { "data-records-choice-ask": "", className: "px-2 pb-1", children: /* @__PURE__ */ jsx16(Button8, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => setOpen(false), children: "Cancel" }) }) : null
|
|
3543
3716
|
] })
|
|
3544
3717
|
) : null
|
|
3545
3718
|
}
|
|
@@ -3558,9 +3731,9 @@ function RecordChip({
|
|
|
3558
3731
|
// name. So it caps at its container and ends in an ellipsis with the whole name in
|
|
3559
3732
|
// its tooltip, rather than being cut mid-word by whatever box it landed in
|
|
3560
3733
|
// (lane FIX-14, 2026-09-22).
|
|
3561
|
-
/* @__PURE__ */
|
|
3562
|
-
/* @__PURE__ */
|
|
3563
|
-
onRemove ? /* @__PURE__ */
|
|
3734
|
+
/* @__PURE__ */ jsxs14(Badge3, { variant: "secondary", className: cn12("max-w-full gap-1 text-[11px]", className), title, children: [
|
|
3735
|
+
/* @__PURE__ */ jsx16("span", { className: "min-w-0 truncate", children: title }),
|
|
3736
|
+
onRemove ? /* @__PURE__ */ jsx16("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${title}`, className: "shrink-0 opacity-60 hover:opacity-100", children: "\xD7" }) : null
|
|
3564
3737
|
] })
|
|
3565
3738
|
);
|
|
3566
3739
|
}
|
|
@@ -3572,7 +3745,8 @@ function publicChoicesOf(field) {
|
|
|
3572
3745
|
return typeof o.key === "string" && typeof o.label === "string" ? [{ key: o.key, label: o.label }] : [];
|
|
3573
3746
|
});
|
|
3574
3747
|
}
|
|
3575
|
-
var
|
|
3748
|
+
var FORM_SEARCH_AFTER = 8;
|
|
3749
|
+
var CHOICE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
3576
3750
|
function ChoiceAnswer({
|
|
3577
3751
|
field,
|
|
3578
3752
|
choices,
|
|
@@ -3582,7 +3756,7 @@ function ChoiceAnswer({
|
|
|
3582
3756
|
id,
|
|
3583
3757
|
isChosen
|
|
3584
3758
|
}) {
|
|
3585
|
-
const [search, setSearch] =
|
|
3759
|
+
const [search, setSearch] = useState14("");
|
|
3586
3760
|
const held = field.multi ? choiceValuesOf(value) : value === null || value === void 0 || value === "" ? [] : [value];
|
|
3587
3761
|
const on = (choice) => held.some((v) => isChosen ? isChosen(choice, v) : String(v) === choice.key || String(v) === choice.label);
|
|
3588
3762
|
const press = (choice) => {
|
|
@@ -3593,40 +3767,59 @@ function ChoiceAnswer({
|
|
|
3593
3767
|
const keys = choices.filter((c) => c.key === choice.key ? !on(c) : on(c)).map((c) => c.key);
|
|
3594
3768
|
onChange(keys.length === 0 ? null : keys);
|
|
3595
3769
|
};
|
|
3596
|
-
const
|
|
3770
|
+
const lettered = choices.length <= CHOICE_LETTERS.length;
|
|
3771
|
+
const option = (choice) => {
|
|
3597
3772
|
const chosen = on(choice);
|
|
3598
|
-
const
|
|
3599
|
-
return /* @__PURE__ */
|
|
3773
|
+
const letter = lettered ? CHOICE_LETTERS[choices.indexOf(choice)] : null;
|
|
3774
|
+
return /* @__PURE__ */ jsxs14(
|
|
3600
3775
|
"button",
|
|
3601
3776
|
{
|
|
3602
3777
|
type: "button",
|
|
3603
3778
|
role: field.multi ? "checkbox" : "radio",
|
|
3604
3779
|
"aria-checked": chosen,
|
|
3780
|
+
"aria-label": choice.label,
|
|
3605
3781
|
disabled,
|
|
3606
3782
|
onClick: () => press(choice),
|
|
3607
|
-
"data-records-choice-chip": "",
|
|
3608
3783
|
"data-records-choice-answer": choice.key,
|
|
3609
|
-
className:
|
|
3610
|
-
"
|
|
3611
|
-
|
|
3612
|
-
chosen ? "ring-2 ring-ring ring-offset-1" : "opacity-80 hover:opacity-100"
|
|
3784
|
+
className: cn12(
|
|
3785
|
+
"flex min-h-11 w-full items-center gap-3 rounded-md border px-3 py-2 text-left text-base font-medium text-foreground transition-colors sm:min-h-10 sm:text-sm",
|
|
3786
|
+
chosen ? "border-primary bg-primary/10" : "border-primary/30 bg-primary/[0.03] hover:bg-primary/10"
|
|
3613
3787
|
),
|
|
3614
3788
|
children: [
|
|
3615
|
-
|
|
3616
|
-
|
|
3789
|
+
letter ? /* @__PURE__ */ jsx16(
|
|
3790
|
+
"kbd",
|
|
3791
|
+
{
|
|
3792
|
+
"aria-hidden": "true",
|
|
3793
|
+
className: cn12(
|
|
3794
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border font-sans text-xs font-semibold",
|
|
3795
|
+
chosen ? "border-primary bg-primary text-primary-foreground" : "border-primary/40 text-primary"
|
|
3796
|
+
),
|
|
3797
|
+
children: letter
|
|
3798
|
+
}
|
|
3799
|
+
) : null,
|
|
3800
|
+
/* @__PURE__ */ jsx16("span", { className: "min-w-0 flex-1 break-words", children: choice.label }),
|
|
3801
|
+
chosen ? /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: "shrink-0 text-primary", children: "\u2713" }) : null
|
|
3617
3802
|
]
|
|
3618
3803
|
},
|
|
3619
3804
|
choice.key
|
|
3620
3805
|
);
|
|
3621
3806
|
};
|
|
3622
|
-
const
|
|
3623
|
-
|
|
3624
|
-
|
|
3807
|
+
const onKeyDown = (event) => {
|
|
3808
|
+
if (!lettered || disabled || event.metaKey || event.ctrlKey || event.altKey) return;
|
|
3809
|
+
if (event.target.tagName === "INPUT") return;
|
|
3810
|
+
const at = CHOICE_LETTERS.indexOf(event.key.toUpperCase());
|
|
3811
|
+
if (event.key.length !== 1 || at < 0 || at >= choices.length) return;
|
|
3812
|
+
event.preventDefault();
|
|
3813
|
+
press(choices[at]);
|
|
3814
|
+
};
|
|
3815
|
+
const group = { role: field.multi ? "group" : "radiogroup", "aria-label": fieldName(field), onKeyDown };
|
|
3816
|
+
if (choices.length <= FORM_SEARCH_AFTER) {
|
|
3817
|
+
return /* @__PURE__ */ jsx16("div", { id, className: "flex w-full flex-col gap-2", ...group, children: choices.map(option) });
|
|
3625
3818
|
}
|
|
3626
3819
|
const q = search.trim().toLowerCase();
|
|
3627
3820
|
const shown2 = q === "" ? choices : choices.filter((c) => c.label.toLowerCase().includes(q));
|
|
3628
|
-
return /* @__PURE__ */
|
|
3629
|
-
/* @__PURE__ */
|
|
3821
|
+
return /* @__PURE__ */ jsxs14("div", { id, className: "flex w-full flex-col gap-2", onKeyDown, children: [
|
|
3822
|
+
/* @__PURE__ */ jsx16(
|
|
3630
3823
|
BasicInput6,
|
|
3631
3824
|
{
|
|
3632
3825
|
value: search,
|
|
@@ -3634,12 +3827,12 @@ function ChoiceAnswer({
|
|
|
3634
3827
|
placeholder: "Search",
|
|
3635
3828
|
"aria-label": `Search \u2014 ${fieldName(field)}`,
|
|
3636
3829
|
autoComplete: "off",
|
|
3637
|
-
className: "h-11 text-base sm:h-
|
|
3830
|
+
className: "h-11 text-base sm:h-9 sm:text-sm"
|
|
3638
3831
|
}
|
|
3639
3832
|
),
|
|
3640
|
-
/* @__PURE__ */
|
|
3641
|
-
shown2.map(
|
|
3642
|
-
shown2.length === 0 ? /* @__PURE__ */
|
|
3833
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex max-h-80 w-full flex-col gap-2 overflow-y-auto", role: group.role, "aria-label": group["aria-label"], children: [
|
|
3834
|
+
shown2.map(option),
|
|
3835
|
+
shown2.length === 0 ? /* @__PURE__ */ jsx16("p", { className: "text-xs text-muted-foreground", children: "No match" }) : null
|
|
3643
3836
|
] })
|
|
3644
3837
|
] });
|
|
3645
3838
|
}
|
|
@@ -3647,17 +3840,17 @@ function ChoiceAnswer({
|
|
|
3647
3840
|
// src/RecordsMount.tsx
|
|
3648
3841
|
import { useRef as useRef10 } from "react";
|
|
3649
3842
|
import { RecordsProvider } from "@ai-matrx/records/react";
|
|
3650
|
-
import { jsx as
|
|
3843
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
3651
3844
|
function personActor(userId) {
|
|
3652
3845
|
return userId ? { actor: "user", user_id: userId } : { actor: "user" };
|
|
3653
3846
|
}
|
|
3654
3847
|
|
|
3655
3848
|
// src/tablePicking.tsx
|
|
3656
|
-
import { useEffect as useEffect11, useMemo as useMemo6, useState as
|
|
3849
|
+
import { useCallback as useCallback5, useEffect as useEffect11, useMemo as useMemo6, useState as useState15 } from "react";
|
|
3657
3850
|
import { withTablePlacement } from "@ai-matrx/records";
|
|
3658
3851
|
import { useRecordsClient as useRecordsClient2, useTables } from "@ai-matrx/records/react";
|
|
3659
|
-
import { Checkbox as Checkbox2, cn as
|
|
3660
|
-
import { jsx as
|
|
3852
|
+
import { Checkbox as Checkbox2, cn as cn13 } from "@ai-matrx/design-system";
|
|
3853
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3661
3854
|
var APP_TABLE_PREFIX = "records_ui_";
|
|
3662
3855
|
function isValueSet(table) {
|
|
3663
3856
|
if (table.kept_for === "choices") return true;
|
|
@@ -3700,26 +3893,44 @@ function madeOn(stamp) {
|
|
|
3700
3893
|
}
|
|
3701
3894
|
|
|
3702
3895
|
// src/TablePickers.tsx
|
|
3703
|
-
import { Fragment as Fragment5, jsx as
|
|
3896
|
+
import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3897
|
+
var SHARED_FOR_MS = 5e3;
|
|
3898
|
+
var sharedReads = /* @__PURE__ */ new WeakMap();
|
|
3899
|
+
function readTablesAnywhere(dataSource) {
|
|
3900
|
+
const held = sharedReads.get(dataSource);
|
|
3901
|
+
if (held && Date.now() - held.at < SHARED_FOR_MS) return held.read;
|
|
3902
|
+
const read = Promise.resolve(dataSource.rpc("data_home_tables", {}, { schema: "custom" })).then(
|
|
3903
|
+
({ data, error }) => {
|
|
3904
|
+
if (error) {
|
|
3905
|
+
return {
|
|
3906
|
+
loading: false,
|
|
3907
|
+
error: refusalSentence({ message: String(error["message"] ?? "") }) || "Tables could not be read.",
|
|
3908
|
+
rows: []
|
|
3909
|
+
};
|
|
3910
|
+
}
|
|
3911
|
+
const rows = (Array.isArray(data) ? data : []).slice();
|
|
3912
|
+
rows.sort((a, b) => a.table_name.localeCompare(b.table_name));
|
|
3913
|
+
return { loading: false, error: null, rows };
|
|
3914
|
+
},
|
|
3915
|
+
(thrown) => ({
|
|
3916
|
+
loading: false,
|
|
3917
|
+
error: String(thrown?.message ?? thrown) || "Tables could not be read.",
|
|
3918
|
+
rows: []
|
|
3919
|
+
})
|
|
3920
|
+
);
|
|
3921
|
+
sharedReads.set(dataSource, { at: Date.now(), read });
|
|
3922
|
+
void read.then((result) => {
|
|
3923
|
+
if (result.error && sharedReads.get(dataSource)?.read === read) sharedReads.delete(dataSource);
|
|
3924
|
+
});
|
|
3925
|
+
return read;
|
|
3926
|
+
}
|
|
3704
3927
|
function useTablesAnywhere(dataSource) {
|
|
3705
|
-
const [state, setState] =
|
|
3928
|
+
const [state, setState] = useState16({ loading: true, error: null, rows: [] });
|
|
3706
3929
|
useEffect12(() => {
|
|
3707
3930
|
let live = true;
|
|
3708
|
-
void
|
|
3709
|
-
(
|
|
3710
|
-
|
|
3711
|
-
if (error) {
|
|
3712
|
-
setState({ loading: false, error: refusalSentence({ message: String(error["message"] ?? "") }) || "Tables could not be read.", rows: [] });
|
|
3713
|
-
return;
|
|
3714
|
-
}
|
|
3715
|
-
const rows = (Array.isArray(data) ? data : []).slice();
|
|
3716
|
-
rows.sort((a, b) => a.table_name.localeCompare(b.table_name));
|
|
3717
|
-
setState({ loading: false, error: null, rows });
|
|
3718
|
-
},
|
|
3719
|
-
(thrown) => {
|
|
3720
|
-
if (live) setState({ loading: false, error: String(thrown?.message ?? thrown), rows: [] });
|
|
3721
|
-
}
|
|
3722
|
-
);
|
|
3931
|
+
void readTablesAnywhere(dataSource).then((result) => {
|
|
3932
|
+
if (live) setState(result);
|
|
3933
|
+
});
|
|
3723
3934
|
return () => {
|
|
3724
3935
|
live = false;
|
|
3725
3936
|
};
|
|
@@ -3740,8 +3951,8 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
|
|
|
3740
3951
|
keywords: t.organization_name
|
|
3741
3952
|
}));
|
|
3742
3953
|
const missing = Boolean(value) && !list.loading && !list.error && !list.rows.some((t) => t.table_id === value);
|
|
3743
|
-
return /* @__PURE__ */
|
|
3744
|
-
/* @__PURE__ */
|
|
3954
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
|
|
3955
|
+
/* @__PURE__ */ jsx19(
|
|
3745
3956
|
CreatablePicker,
|
|
3746
3957
|
{
|
|
3747
3958
|
value: value || null,
|
|
@@ -3755,23 +3966,24 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
|
|
|
3755
3966
|
ariaLabel: "Table"
|
|
3756
3967
|
}
|
|
3757
3968
|
),
|
|
3758
|
-
list.error && /* @__PURE__ */
|
|
3759
|
-
missing && /* @__PURE__ */
|
|
3969
|
+
list.error && /* @__PURE__ */ jsx19(RefusalLine, { error: refusal("door", list.error, "Try again in a moment.") }),
|
|
3970
|
+
missing && /* @__PURE__ */ jsx19("p", { className: "text-[11px] text-destructive", children: "This table is archived or not shared with you." })
|
|
3760
3971
|
] });
|
|
3761
3972
|
}
|
|
3762
|
-
function TableScope({ dataSource, userId, tableId, children, fallback = null, tables }) {
|
|
3973
|
+
function TableScope({ dataSource, userId, tableId, children, fallback = null, unavailable, tables }) {
|
|
3763
3974
|
const own3 = useTablesAnywhere(dataSource);
|
|
3764
3975
|
const list = tables ?? own3;
|
|
3765
3976
|
const organizationId = list.rows.find((t) => t.table_id === tableId)?.organization_id ?? null;
|
|
3766
|
-
if (
|
|
3767
|
-
return /* @__PURE__ */
|
|
3977
|
+
if (tableId && !organizationId && !list.loading) return /* @__PURE__ */ jsx19(Fragment5, { children: unavailable ?? fallback });
|
|
3978
|
+
if (!tableId || !organizationId) return /* @__PURE__ */ jsx19(Fragment5, { children: fallback });
|
|
3979
|
+
return /* @__PURE__ */ jsx19(RecordsProvider2, { config: { dataSource, actor: personActor(userId), organizationId }, children });
|
|
3768
3980
|
}
|
|
3769
3981
|
function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
3770
3982
|
const fields = useFields(tableId);
|
|
3771
3983
|
const all = useMemo7(() => fields.data ?? [], [fields.data]);
|
|
3772
3984
|
const byKey = useMemo7(() => new Map(all.map((f) => [f.key, f])), [all]);
|
|
3773
3985
|
const keys = Object.keys(value);
|
|
3774
|
-
const [adding, setAdding] =
|
|
3986
|
+
const [adding, setAdding] = useState16(false);
|
|
3775
3987
|
const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
|
|
3776
3988
|
const rename = (from, to) => {
|
|
3777
3989
|
if (from === to) return;
|
|
@@ -3784,11 +3996,11 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3784
3996
|
void _gone;
|
|
3785
3997
|
onChange(rest);
|
|
3786
3998
|
};
|
|
3787
|
-
return /* @__PURE__ */
|
|
3788
|
-
fields.error && /* @__PURE__ */
|
|
3999
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-2", children: [
|
|
4000
|
+
fields.error && /* @__PURE__ */ jsx19(RefusalLine, { error: fields.error }),
|
|
3789
4001
|
keys.map((key) => {
|
|
3790
4002
|
const field = byKey.get(key);
|
|
3791
|
-
return /* @__PURE__ */
|
|
4003
|
+
return /* @__PURE__ */ jsx19(
|
|
3792
4004
|
ColumnValueRow,
|
|
3793
4005
|
{
|
|
3794
4006
|
columnKey: key,
|
|
@@ -3804,7 +4016,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3804
4016
|
key
|
|
3805
4017
|
);
|
|
3806
4018
|
}),
|
|
3807
|
-
adding && /* @__PURE__ */
|
|
4019
|
+
adding && /* @__PURE__ */ jsx19(
|
|
3808
4020
|
ColumnValueRow,
|
|
3809
4021
|
{
|
|
3810
4022
|
columnKey: null,
|
|
@@ -3821,7 +4033,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3821
4033
|
onRemove: () => setAdding(false)
|
|
3822
4034
|
}
|
|
3823
4035
|
),
|
|
3824
|
-
!disabled && !adding && keys.length < all.length && /* @__PURE__ */
|
|
4036
|
+
!disabled && !adding && keys.length < all.length && /* @__PURE__ */ jsx19(Button9, { type: "button", variant: "outline", size: "sm", className: "self-start", onClick: () => setAdding(true), children: addLabel })
|
|
3825
4037
|
] });
|
|
3826
4038
|
}
|
|
3827
4039
|
function ColumnValueRow({
|
|
@@ -3837,9 +4049,9 @@ function ColumnValueRow({
|
|
|
3837
4049
|
}) {
|
|
3838
4050
|
const orphan = columnKey !== null && !loading && field === void 0;
|
|
3839
4051
|
const shown2 = orphan ? [{ value: columnKey, label: columnKey, hint: "Not a column" }, ...options] : options;
|
|
3840
|
-
return /* @__PURE__ */
|
|
3841
|
-
/* @__PURE__ */
|
|
3842
|
-
/* @__PURE__ */
|
|
4052
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1 rounded-md border border-border/60 p-2", children: [
|
|
4053
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
4054
|
+
/* @__PURE__ */ jsx19("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx19(
|
|
3843
4055
|
CreatablePicker,
|
|
3844
4056
|
{
|
|
3845
4057
|
value: columnKey,
|
|
@@ -3853,9 +4065,9 @@ function ColumnValueRow({
|
|
|
3853
4065
|
ariaLabel: "Column"
|
|
3854
4066
|
}
|
|
3855
4067
|
) }),
|
|
3856
|
-
!disabled && /* @__PURE__ */
|
|
4068
|
+
!disabled && /* @__PURE__ */ jsx19(Button9, { type: "button", variant: "ghost", size: "sm", "aria-label": "Remove", onClick: onRemove, children: "\u2715" })
|
|
3857
4069
|
] }),
|
|
3858
|
-
field ? /* @__PURE__ */
|
|
4070
|
+
field ? /* @__PURE__ */ jsx19(FieldControl, { field, value, onChange: onValue, disabled }) : orphan ? /* @__PURE__ */ jsx19("p", { className: "text-[11px] text-muted-foreground", children: value === null || value === void 0 ? "\u2014" : String(value) }) : null
|
|
3859
4071
|
] });
|
|
3860
4072
|
}
|
|
3861
4073
|
function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
@@ -3867,8 +4079,8 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
|
3867
4079
|
label: rowNameIn(table.data ?? null, row)
|
|
3868
4080
|
}));
|
|
3869
4081
|
const missing = Boolean(value) && !records.loading && !records.error && !rows.some((r) => r.id === value);
|
|
3870
|
-
return /* @__PURE__ */
|
|
3871
|
-
/* @__PURE__ */
|
|
4082
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
|
|
4083
|
+
/* @__PURE__ */ jsx19(
|
|
3872
4084
|
CreatablePicker,
|
|
3873
4085
|
{
|
|
3874
4086
|
value: value || null,
|
|
@@ -3882,7 +4094,7 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
|
3882
4094
|
ariaLabel: "Record"
|
|
3883
4095
|
}
|
|
3884
4096
|
),
|
|
3885
|
-
records.error && /* @__PURE__ */
|
|
4097
|
+
records.error && /* @__PURE__ */ jsx19(RefusalLine, { error: records.error })
|
|
3886
4098
|
] });
|
|
3887
4099
|
}
|
|
3888
4100
|
|
|
@@ -3890,8 +4102,8 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
|
3890
4102
|
import { useEffect as useEffect13, useMemo as useMemo8 } from "react";
|
|
3891
4103
|
import { isEntityReferenceConfig } from "@ai-matrx/records";
|
|
3892
4104
|
import { useFields as useFields2, useTable as useTable2 } from "@ai-matrx/records/react";
|
|
3893
|
-
import { BasicInput as BasicInput7, Button as Button10, CreatablePicker as CreatablePicker2, cn as
|
|
3894
|
-
import { jsx as
|
|
4105
|
+
import { BasicInput as BasicInput7, Button as Button10, CreatablePicker as CreatablePicker2, cn as cn14 } from "@ai-matrx/design-system";
|
|
4106
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3895
4107
|
var DATA_BINDING_SHAPES = [
|
|
3896
4108
|
{ value: "collection", label: "The whole table" },
|
|
3897
4109
|
{ value: "reference", label: "One record" },
|
|
@@ -3958,9 +4170,9 @@ function DataBindingPicker({ dataSource, userId, binding, onChange, disabled, de
|
|
|
3958
4170
|
...binding.semantic_type === "collection" && defaultRowLimit ? { limit: defaultRowLimit } : {}
|
|
3959
4171
|
});
|
|
3960
4172
|
};
|
|
3961
|
-
return /* @__PURE__ */
|
|
3962
|
-
/* @__PURE__ */
|
|
3963
|
-
/* @__PURE__ */
|
|
4173
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2", children: [
|
|
4174
|
+
/* @__PURE__ */ jsx20(TablePicker, { dataSource, value: tableId, onChange: selectTable, disabled: Boolean(disabled), tables }),
|
|
4175
|
+
/* @__PURE__ */ jsx20(TableScope, { dataSource, userId, tableId, tables, children: tableId && /* @__PURE__ */ jsx20(
|
|
3964
4176
|
BindingDetails,
|
|
3965
4177
|
{
|
|
3966
4178
|
tableId,
|
|
@@ -4024,8 +4236,8 @@ function BindingDetails({
|
|
|
4024
4236
|
const fieldOptions = fieldList.map((f) => ({ value: f.key, label: fieldName(f) }));
|
|
4025
4237
|
const template = binding.transform?.template ?? "";
|
|
4026
4238
|
const setTemplate = (next) => onChange({ ...binding, transform: { join: "\n", ...binding.transform, name: "list", template: next } });
|
|
4027
|
-
return /* @__PURE__ */
|
|
4028
|
-
/* @__PURE__ */
|
|
4239
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2", children: [
|
|
4240
|
+
/* @__PURE__ */ jsx20("div", { className: "flex flex-wrap gap-1", role: "radiogroup", "aria-label": "What to read", children: DATA_BINDING_SHAPES.map((s) => /* @__PURE__ */ jsx20(
|
|
4029
4241
|
Button10,
|
|
4030
4242
|
{
|
|
4031
4243
|
type: "button",
|
|
@@ -4039,7 +4251,7 @@ function BindingDetails({
|
|
|
4039
4251
|
},
|
|
4040
4252
|
s.value
|
|
4041
4253
|
)) }),
|
|
4042
|
-
shape !== "collection" && /* @__PURE__ */
|
|
4254
|
+
shape !== "collection" && /* @__PURE__ */ jsx20(
|
|
4043
4255
|
RecordPicker,
|
|
4044
4256
|
{
|
|
4045
4257
|
tableId,
|
|
@@ -4048,7 +4260,7 @@ function BindingDetails({
|
|
|
4048
4260
|
disabled: Boolean(disabled)
|
|
4049
4261
|
}
|
|
4050
4262
|
),
|
|
4051
|
-
shape === "value" && /* @__PURE__ */
|
|
4263
|
+
shape === "value" && /* @__PURE__ */ jsx20(
|
|
4052
4264
|
CreatablePicker2,
|
|
4053
4265
|
{
|
|
4054
4266
|
value: binding.field_key ?? null,
|
|
@@ -4062,11 +4274,11 @@ function BindingDetails({
|
|
|
4062
4274
|
ariaLabel: "Column"
|
|
4063
4275
|
}
|
|
4064
4276
|
),
|
|
4065
|
-
shape !== "value" && /* @__PURE__ */
|
|
4066
|
-
/* @__PURE__ */
|
|
4277
|
+
shape !== "value" && /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
|
|
4278
|
+
/* @__PURE__ */ jsx20(
|
|
4067
4279
|
"textarea",
|
|
4068
4280
|
{
|
|
4069
|
-
className:
|
|
4281
|
+
className: cn14(
|
|
4070
4282
|
"min-h-[3.5rem] w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs"
|
|
4071
4283
|
),
|
|
4072
4284
|
"aria-label": "Each row reads as",
|
|
@@ -4075,7 +4287,7 @@ function BindingDetails({
|
|
|
4075
4287
|
onChange: (e) => setTemplate(e.target.value)
|
|
4076
4288
|
}
|
|
4077
4289
|
),
|
|
4078
|
-
!disabled && /* @__PURE__ */
|
|
4290
|
+
!disabled && /* @__PURE__ */ jsx20("div", { className: "flex flex-wrap gap-1", children: fieldList.flatMap(bindingPlaceholdersFor).map((p) => /* @__PURE__ */ jsx20(
|
|
4079
4291
|
Button10,
|
|
4080
4292
|
{
|
|
4081
4293
|
type: "button",
|
|
@@ -4088,9 +4300,9 @@ function BindingDetails({
|
|
|
4088
4300
|
p.token
|
|
4089
4301
|
)) })
|
|
4090
4302
|
] }),
|
|
4091
|
-
shape === "collection" && /* @__PURE__ */
|
|
4303
|
+
shape === "collection" && /* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
4092
4304
|
"Up to",
|
|
4093
|
-
/* @__PURE__ */
|
|
4305
|
+
/* @__PURE__ */ jsx20(
|
|
4094
4306
|
BasicInput7,
|
|
4095
4307
|
{
|
|
4096
4308
|
type: "number",
|
|
@@ -4107,9 +4319,9 @@ function BindingDetails({
|
|
|
4107
4319
|
),
|
|
4108
4320
|
"rows"
|
|
4109
4321
|
] }),
|
|
4110
|
-
/* @__PURE__ */
|
|
4111
|
-
/* @__PURE__ */
|
|
4112
|
-
DATA_BINDING_MISSING.map((m) => /* @__PURE__ */
|
|
4322
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex flex-wrap items-center gap-1", role: "radiogroup", "aria-label": "If nothing is found", children: [
|
|
4323
|
+
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: "If nothing is found" }),
|
|
4324
|
+
DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ jsx20(
|
|
4113
4325
|
Button10,
|
|
4114
4326
|
{
|
|
4115
4327
|
type: "button",
|
|
@@ -4133,7 +4345,7 @@ import { useFields as useFields3, useRecord, useTable as useTable3 } from "@ai-m
|
|
|
4133
4345
|
// src/values.tsx
|
|
4134
4346
|
import { formatColumnValue } from "@ai-matrx/design-system/data-table";
|
|
4135
4347
|
import { formatFieldValue as formatFieldValue3 } from "@ai-matrx/design-system/field-formats";
|
|
4136
|
-
import { Badge as Badge5, cn as
|
|
4348
|
+
import { Badge as Badge5, cn as cn16 } from "@ai-matrx/design-system";
|
|
4137
4349
|
|
|
4138
4350
|
// src/enumLabels.ts
|
|
4139
4351
|
function exhaustiveValuesOf() {
|
|
@@ -4170,10 +4382,10 @@ var ABSENCE_WORD_LABEL = {
|
|
|
4170
4382
|
import { wholeValueOf } from "@ai-matrx/records/core";
|
|
4171
4383
|
|
|
4172
4384
|
// src/WholeValue.tsx
|
|
4173
|
-
import { useEffect as useEffect14, useState as
|
|
4385
|
+
import { useEffect as useEffect14, useState as useState17 } from "react";
|
|
4174
4386
|
import { wholeValueSize } from "@ai-matrx/records/core";
|
|
4175
4387
|
import { BasicTextarea as BasicTextarea3 } from "@ai-matrx/design-system";
|
|
4176
|
-
import { jsx as
|
|
4388
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4177
4389
|
var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
|
|
4178
4390
|
function wholeValueLine(pointer) {
|
|
4179
4391
|
return `Open the whole text (${wholeValueSize(pointer)})`;
|
|
@@ -4182,18 +4394,21 @@ function WholeValueCell({ words, pointer }) {
|
|
|
4182
4394
|
const host = useRecordsUi();
|
|
4183
4395
|
const href = host.hrefForFile?.({ fileId: pointer.file_id });
|
|
4184
4396
|
const line = wholeValueLine(pointer);
|
|
4185
|
-
return /* @__PURE__ */
|
|
4186
|
-
/* @__PURE__ */
|
|
4397
|
+
return /* @__PURE__ */ jsxs18("span", { className: "flex min-w-0 items-baseline gap-2", "data-whole-value-file": pointer.file_id, children: [
|
|
4398
|
+
/* @__PURE__ */ jsxs18("span", { className: "truncate", title: `The first ${pointer.shown_chars} of ${pointer.chars} characters`, children: [
|
|
4187
4399
|
words,
|
|
4188
4400
|
"\u2026"
|
|
4189
4401
|
] }),
|
|
4190
|
-
href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */
|
|
4402
|
+
href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ jsx21("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ jsx21("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${wholeValueSize(pointer)} in a file` })
|
|
4191
4403
|
] });
|
|
4192
4404
|
}
|
|
4193
4405
|
|
|
4406
|
+
// src/values.tsx
|
|
4407
|
+
import { formatPhone as formatPhone2 } from "@ai-matrx/design-system/field-formats";
|
|
4408
|
+
|
|
4194
4409
|
// src/ReferenceChips.tsx
|
|
4195
4410
|
import { entityRefsOf as entityRefsOf2 } from "@ai-matrx/records";
|
|
4196
|
-
import { Badge as Badge4, cn as
|
|
4411
|
+
import { Badge as Badge4, cn as cn15 } from "@ai-matrx/design-system";
|
|
4197
4412
|
|
|
4198
4413
|
// src/kindValues.ts
|
|
4199
4414
|
import { tryDecodeDirective } from "@ai-matrx/content-ir/directives";
|
|
@@ -4247,7 +4462,7 @@ function kindLabel(kind) {
|
|
|
4247
4462
|
}
|
|
4248
4463
|
|
|
4249
4464
|
// src/ReferenceChips.tsx
|
|
4250
|
-
import { jsx as
|
|
4465
|
+
import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4251
4466
|
function referencesOf(field, value, kind, labels) {
|
|
4252
4467
|
if (kind === "entity_reference") {
|
|
4253
4468
|
return entityRefsOf2(value).map((r) => ({ token: r.token, id: r.id, label: r.label }));
|
|
@@ -4268,11 +4483,11 @@ function ReferenceChip({ reference, waiting }) {
|
|
|
4268
4483
|
const host = useRecordsUi();
|
|
4269
4484
|
const words = reference.label ?? (reference.token === "record" ? waiting ?? "Loading\u2026" : WITHHELD_ENTITY_LABEL);
|
|
4270
4485
|
const drawn = host.renderReference ? host.renderReference({ ...reference, label: reference.label ?? words }) : null;
|
|
4271
|
-
return /* @__PURE__ */
|
|
4486
|
+
return /* @__PURE__ */ jsxs19(
|
|
4272
4487
|
Badge4,
|
|
4273
4488
|
{
|
|
4274
4489
|
variant: "secondary",
|
|
4275
|
-
className:
|
|
4490
|
+
className: cn15(
|
|
4276
4491
|
"max-w-full min-w-0 gap-1 px-1.5 py-0 text-[11px] font-normal",
|
|
4277
4492
|
reference.archived && "opacity-70"
|
|
4278
4493
|
),
|
|
@@ -4280,15 +4495,15 @@ function ReferenceChip({ reference, waiting }) {
|
|
|
4280
4495
|
"data-records-reference-archived": reference.archived ? "" : void 0,
|
|
4281
4496
|
title: reference.archived ? ARCHIVED_REFERENCE_TIP : words,
|
|
4282
4497
|
children: [
|
|
4283
|
-
drawn ?? /* @__PURE__ */
|
|
4284
|
-
reference.archived ? /* @__PURE__ */
|
|
4498
|
+
drawn ?? /* @__PURE__ */ jsx22("span", { className: "truncate", children: words }),
|
|
4499
|
+
reference.archived ? /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
|
|
4285
4500
|
]
|
|
4286
4501
|
}
|
|
4287
4502
|
);
|
|
4288
4503
|
}
|
|
4289
4504
|
function ReferenceChips({ refs, waiting }) {
|
|
4290
|
-
if (refs.length === 0) return /* @__PURE__ */
|
|
4291
|
-
return /* @__PURE__ */
|
|
4505
|
+
if (refs.length === 0) return /* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
4506
|
+
return /* @__PURE__ */ jsx22("span", { className: "flex min-w-0 flex-wrap gap-1", "data-records-reference-chips": "", children: refs.map((r) => /* @__PURE__ */ jsx22(ReferenceChip, { reference: r, waiting }, `${r.token}:${r.id}`)) });
|
|
4292
4507
|
}
|
|
4293
4508
|
function KindValueCell({
|
|
4294
4509
|
kv,
|
|
@@ -4297,18 +4512,18 @@ function KindValueCell({
|
|
|
4297
4512
|
}) {
|
|
4298
4513
|
const host = useRecordsUi();
|
|
4299
4514
|
if (host.renderKind) {
|
|
4300
|
-
return /* @__PURE__ */
|
|
4515
|
+
return /* @__PURE__ */ jsx22("span", { className: "flex min-w-0 max-w-full items-center", "data-records-kind-value": kv.kind, children: host.renderKind({ value: kv.value, kind: kv.kind, where, title }) });
|
|
4301
4516
|
}
|
|
4302
4517
|
const named = kv.items.map(kindItemWords).filter((w) => w !== null);
|
|
4303
|
-
return /* @__PURE__ */
|
|
4518
|
+
return /* @__PURE__ */ jsx22("span", { className: cn15("flex min-w-0 flex-wrap gap-1"), "data-records-kind-value": kv.kind, title: JSON.stringify(kv.value), children: named.length > 0 ? named.map((w, i) => /* @__PURE__ */ jsx22(Badge4, { variant: "secondary", className: "px-1.5 py-0 text-[11px] font-normal", children: w }, `${w}-${i}`)) : /* @__PURE__ */ jsx22(Badge4, { variant: "outline", className: "px-1.5 py-0 text-[11px] font-normal", children: kindLabel(kv.kind) }) });
|
|
4304
4519
|
}
|
|
4305
4520
|
|
|
4306
4521
|
// src/values.tsx
|
|
4307
4522
|
import { newerKindWords } from "@ai-matrx/records";
|
|
4308
|
-
import { Fragment as Fragment6, jsx as
|
|
4309
|
-
function statusMark(field, item) {
|
|
4310
|
-
const mark = statusMarkOf(field, item);
|
|
4311
|
-
return mark ? /* @__PURE__ */
|
|
4523
|
+
import { Fragment as Fragment6, jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4524
|
+
function statusMark(field, item, document2) {
|
|
4525
|
+
const mark = statusMarkOf(field, item, document2);
|
|
4526
|
+
return mark ? /* @__PURE__ */ jsx23("span", { "aria-label": mark.words, title: mark.words, className: "mr-1", "data-records-status-group": mark.group, children: mark.mark }) : null;
|
|
4312
4527
|
}
|
|
4313
4528
|
function envelopeFor(document2, key) {
|
|
4314
4529
|
const block = document2?._values;
|
|
@@ -4352,32 +4567,32 @@ var ABSENCE_WORDS = ABSENCE_WORD_LABEL;
|
|
|
4352
4567
|
function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
4353
4568
|
const envelope = envelopeFor(document2, field.key);
|
|
4354
4569
|
if (envelope?.absent) {
|
|
4355
|
-
return /* @__PURE__ */
|
|
4570
|
+
return /* @__PURE__ */ jsx23("span", { className: "text-xs italic text-muted-foreground", title: `VAL-2: ${envelope.absent}`, children: ABSENCE_WORDS[String(envelope.absent)] ?? String(envelope.absent) });
|
|
4356
4571
|
}
|
|
4357
4572
|
if (value === null || value === void 0 || value === "") {
|
|
4358
4573
|
const gone = unresolvedFor(document2, field.key);
|
|
4359
4574
|
if (gone) {
|
|
4360
|
-
return /* @__PURE__ */
|
|
4575
|
+
return /* @__PURE__ */ jsx23("span", { className: "text-xs italic text-muted-foreground", title: `It pointed at ${gone}`, children: "The record this pointed at no longer exists" });
|
|
4361
4576
|
}
|
|
4362
4577
|
const computed = computedEmptyOf(field, document2);
|
|
4363
|
-
if (computed?.sentence) return /* @__PURE__ */
|
|
4364
|
-
if (computed?.words) return /* @__PURE__ */
|
|
4578
|
+
if (computed?.sentence) return /* @__PURE__ */ jsx23("span", { className: "text-xs italic text-muted-foreground", children: computed.sentence });
|
|
4579
|
+
if (computed?.words) return /* @__PURE__ */ jsx23("span", { "data-records-empty-why": computed.kind, children: computed.words });
|
|
4365
4580
|
if (computed?.why) {
|
|
4366
|
-
return /* @__PURE__ */
|
|
4581
|
+
return /* @__PURE__ */ jsx23("span", { className: "text-muted-foreground", title: computed.why, "data-records-empty-why": computed.kind, children: "\u2014" });
|
|
4367
4582
|
}
|
|
4368
|
-
return /* @__PURE__ */
|
|
4583
|
+
return /* @__PURE__ */ jsx23("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
4369
4584
|
}
|
|
4370
|
-
if (isSignatureField(field)) return /* @__PURE__ */
|
|
4585
|
+
if (isSignatureField(field)) return /* @__PURE__ */ jsx23(SignatureValue, { value, fieldKey: field.key, document: document2 });
|
|
4371
4586
|
const newer = newerKindValue(field, value);
|
|
4372
4587
|
if (newer !== void 0) return newer;
|
|
4373
4588
|
const whole = typeof value === "string" ? wholeValueOf(document2, field.key) : null;
|
|
4374
|
-
if (whole) return /* @__PURE__ */
|
|
4589
|
+
if (whole) return /* @__PURE__ */ jsx23(WholeValueCell, { words: value, pointer: whole });
|
|
4375
4590
|
const kind = editorKindFor(field);
|
|
4376
4591
|
if (kind === "relation" || kind === "entity_reference") {
|
|
4377
|
-
return /* @__PURE__ */
|
|
4592
|
+
return /* @__PURE__ */ jsx23(ReferenceChips, { refs: referencesOf(field, value, kind, labels), waiting: stillWaitingFor });
|
|
4378
4593
|
}
|
|
4379
4594
|
const kv = kind === "attachment" || kind === "member" ? null : kindValueOf(value);
|
|
4380
|
-
if (kv) return /* @__PURE__ */
|
|
4595
|
+
if (kv) return /* @__PURE__ */ jsx23(KindValueCell, { kv, where: "cell", title: field.label });
|
|
4381
4596
|
const chosen = kind === "select" || kind === "multi_select";
|
|
4382
4597
|
const chipOf = (item) => {
|
|
4383
4598
|
const look = choiceChipLookOf(field, item, scalarText(field, item, labels));
|
|
@@ -4385,17 +4600,17 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4385
4600
|
};
|
|
4386
4601
|
if (chosen) {
|
|
4387
4602
|
const items = Array.isArray(value) ? value : [value];
|
|
4388
|
-
return /* @__PURE__ */
|
|
4603
|
+
return /* @__PURE__ */ jsx23("span", { className: "flex flex-wrap gap-1", "data-records-choice-chips": "", children: items.map((item, i) => {
|
|
4389
4604
|
const chip = chipOf(item);
|
|
4390
|
-
return /* @__PURE__ */
|
|
4605
|
+
return /* @__PURE__ */ jsxs20(
|
|
4391
4606
|
Badge5,
|
|
4392
4607
|
{
|
|
4393
4608
|
variant: "outline",
|
|
4394
|
-
className:
|
|
4609
|
+
className: cn16("text-[11px]", chip.className),
|
|
4395
4610
|
"data-records-choice-chip": "",
|
|
4396
4611
|
...chip.tinted ? { "data-records-choice-tint": "" } : {},
|
|
4397
4612
|
children: [
|
|
4398
|
-
statusMark(field, item),
|
|
4613
|
+
statusMark(field, item, Array.isArray(value) ? void 0 : document2),
|
|
4399
4614
|
scalarText(field, item, labels, Array.isArray(value) ? void 0 : stillWaitingFor)
|
|
4400
4615
|
]
|
|
4401
4616
|
},
|
|
@@ -4403,13 +4618,13 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4403
4618
|
);
|
|
4404
4619
|
}) });
|
|
4405
4620
|
}
|
|
4406
|
-
if (kind === "attachment") return /* @__PURE__ */
|
|
4621
|
+
if (kind === "attachment") return /* @__PURE__ */ jsx23(AttachmentChips, { value });
|
|
4407
4622
|
if (Array.isArray(value)) {
|
|
4408
|
-
return /* @__PURE__ */
|
|
4623
|
+
return /* @__PURE__ */ jsx23("span", { className: "flex flex-wrap gap-1", children: value.map((item, i) => /* @__PURE__ */ jsx23(Badge5, { variant: "secondary", className: "text-[11px]", children: scalarText(field, item, labels) }, `${String(item)}-${i}`)) });
|
|
4409
4624
|
}
|
|
4410
4625
|
if (kind === "url" && typeof value === "string") {
|
|
4411
4626
|
const href = value.includes("://") ? value : `https://${value}`;
|
|
4412
|
-
return /* @__PURE__ */
|
|
4627
|
+
return /* @__PURE__ */ jsxs20(
|
|
4413
4628
|
"a",
|
|
4414
4629
|
{
|
|
4415
4630
|
className: "inline-flex min-w-0 max-w-full items-center gap-1 rounded-md border border-border bg-muted/60 px-1.5 py-0.5 text-[11px] text-foreground hover:bg-accent",
|
|
@@ -4420,14 +4635,14 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4420
4635
|
"data-records-link-chip": "",
|
|
4421
4636
|
onClick: (event) => event.stopPropagation(),
|
|
4422
4637
|
children: [
|
|
4423
|
-
/* @__PURE__ */
|
|
4424
|
-
/* @__PURE__ */
|
|
4638
|
+
/* @__PURE__ */ jsx23("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2197" }),
|
|
4639
|
+
/* @__PURE__ */ jsx23("span", { className: "truncate", children: linkChipText(value) })
|
|
4425
4640
|
]
|
|
4426
4641
|
}
|
|
4427
4642
|
);
|
|
4428
4643
|
}
|
|
4429
4644
|
if (kind === "phone" && typeof value === "string" && value.trim() !== "") {
|
|
4430
|
-
return /* @__PURE__ */
|
|
4645
|
+
return /* @__PURE__ */ jsx23(
|
|
4431
4646
|
"a",
|
|
4432
4647
|
{
|
|
4433
4648
|
className: "truncate tabular-nums text-primary underline-offset-2 hover:underline",
|
|
@@ -4435,17 +4650,17 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4435
4650
|
title: value,
|
|
4436
4651
|
"data-records-phone": "",
|
|
4437
4652
|
onClick: (event) => event.stopPropagation(),
|
|
4438
|
-
children:
|
|
4653
|
+
children: formatPhone2(value)
|
|
4439
4654
|
}
|
|
4440
4655
|
);
|
|
4441
4656
|
}
|
|
4442
4657
|
if (kind === "email" && typeof value === "string") {
|
|
4443
|
-
return /* @__PURE__ */
|
|
4658
|
+
return /* @__PURE__ */ jsx23("a", { className: "truncate text-primary underline-offset-2 hover:underline", href: `mailto:${value}`, children: value });
|
|
4444
4659
|
}
|
|
4445
4660
|
if (typeof value === "boolean") {
|
|
4446
|
-
return /* @__PURE__ */
|
|
4661
|
+
return /* @__PURE__ */ jsx23("span", { className: kind === "checkbox" ? "text-sm" : "", title: value ? "Yes" : "No", children: value ? "\u2713" : "\u2014" });
|
|
4447
4662
|
}
|
|
4448
|
-
return /* @__PURE__ */
|
|
4663
|
+
return /* @__PURE__ */ jsx23("span", { className: cn16("truncate", kind === "number" || kind === "currency" || kind === "percent" ? "tabular-nums" : ""), children: scalarText(field, value, labels, stillWaitingFor) });
|
|
4449
4664
|
}
|
|
4450
4665
|
function scalarText(field, value, labels, stillWaitingFor) {
|
|
4451
4666
|
if (value === null || value === void 0) return "\u2014";
|
|
@@ -4486,13 +4701,13 @@ function scalarText(field, value, labels, stillWaitingFor) {
|
|
|
4486
4701
|
}
|
|
4487
4702
|
|
|
4488
4703
|
// src/PickedSummaries.tsx
|
|
4489
|
-
import { Fragment as Fragment7, jsx as
|
|
4704
|
+
import { Fragment as Fragment7, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4490
4705
|
function TableNameText({ dataSource, tableId }) {
|
|
4491
4706
|
const tables = useTablesAnywhere(dataSource);
|
|
4492
|
-
if (!tableId) return /* @__PURE__ */
|
|
4493
|
-
if (tables.loading) return /* @__PURE__ */
|
|
4494
|
-
if (tables.error) return /* @__PURE__ */
|
|
4495
|
-
return /* @__PURE__ */
|
|
4707
|
+
if (!tableId) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2014" });
|
|
4708
|
+
if (tables.loading) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" });
|
|
4709
|
+
if (tables.error) return /* @__PURE__ */ jsx24(Fragment7, { children: "Couldn't load the table's name" });
|
|
4710
|
+
return /* @__PURE__ */ jsx24(Fragment7, { children: tables.rows.find((t) => t.table_id === tableId)?.table_name ?? "\u2014" });
|
|
4496
4711
|
}
|
|
4497
4712
|
function ColumnValuesText({
|
|
4498
4713
|
dataSource,
|
|
@@ -4500,28 +4715,38 @@ function ColumnValuesText({
|
|
|
4500
4715
|
tableId,
|
|
4501
4716
|
value
|
|
4502
4717
|
}) {
|
|
4503
|
-
if (!tableId) return /* @__PURE__ */
|
|
4504
|
-
return /* @__PURE__ */
|
|
4718
|
+
if (!tableId) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2014" });
|
|
4719
|
+
return /* @__PURE__ */ jsx24(
|
|
4720
|
+
TableScope,
|
|
4721
|
+
{
|
|
4722
|
+
dataSource,
|
|
4723
|
+
userId,
|
|
4724
|
+
tableId,
|
|
4725
|
+
fallback: /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" }),
|
|
4726
|
+
unavailable: /* @__PURE__ */ jsx24(Fragment7, { children: "Couldn't load this table's columns" }),
|
|
4727
|
+
children: /* @__PURE__ */ jsx24(RecordLabelProvider, { children: /* @__PURE__ */ jsx24(ColumnValuesWords, { tableId, value }) })
|
|
4728
|
+
}
|
|
4729
|
+
);
|
|
4505
4730
|
}
|
|
4506
4731
|
function ColumnValuesWords({ tableId, value }) {
|
|
4507
4732
|
const fields = useFields3(tableId);
|
|
4508
4733
|
const labels = useRecordLabels(fields.data ?? void 0);
|
|
4509
|
-
if (fields.loading) return /* @__PURE__ */
|
|
4510
|
-
if (fields.error) return /* @__PURE__ */
|
|
4734
|
+
if (fields.loading) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" });
|
|
4735
|
+
if (fields.error) return /* @__PURE__ */ jsx24(Fragment7, { children: "Couldn't load this table's columns" });
|
|
4511
4736
|
const parts = [];
|
|
4512
4737
|
for (const [key, stored] of Object.entries(value)) {
|
|
4513
4738
|
if (key.startsWith("_")) continue;
|
|
4514
4739
|
const field = (fields.data ?? []).find((f) => f.key === key);
|
|
4515
|
-
if (parts.length) parts.push(/* @__PURE__ */
|
|
4740
|
+
if (parts.length) parts.push(/* @__PURE__ */ jsx24("span", { children: ", " }, `${key}-sep`));
|
|
4516
4741
|
parts.push(
|
|
4517
|
-
/* @__PURE__ */
|
|
4742
|
+
/* @__PURE__ */ jsxs21("span", { children: [
|
|
4518
4743
|
field ? fieldName(field) : "A removed column",
|
|
4519
4744
|
" is ",
|
|
4520
4745
|
field ? renderValue(field, stored, void 0, labels) : "\u2014"
|
|
4521
4746
|
] }, key)
|
|
4522
4747
|
);
|
|
4523
4748
|
}
|
|
4524
|
-
return parts.length ? /* @__PURE__ */
|
|
4749
|
+
return parts.length ? /* @__PURE__ */ jsx24(Fragment7, { children: parts }) : /* @__PURE__ */ jsx24(Fragment7, { children: "\u2014" });
|
|
4525
4750
|
}
|
|
4526
4751
|
function RecordNameText({
|
|
4527
4752
|
dataSource,
|
|
@@ -4529,31 +4754,41 @@ function RecordNameText({
|
|
|
4529
4754
|
tableId,
|
|
4530
4755
|
recordId
|
|
4531
4756
|
}) {
|
|
4532
|
-
if (!tableId || !recordId) return /* @__PURE__ */
|
|
4533
|
-
return /* @__PURE__ */
|
|
4757
|
+
if (!tableId || !recordId) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2014" });
|
|
4758
|
+
return /* @__PURE__ */ jsx24(
|
|
4759
|
+
TableScope,
|
|
4760
|
+
{
|
|
4761
|
+
dataSource,
|
|
4762
|
+
userId,
|
|
4763
|
+
tableId,
|
|
4764
|
+
fallback: /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" }),
|
|
4765
|
+
unavailable: /* @__PURE__ */ jsx24(Fragment7, { children: "Couldn't load this record" }),
|
|
4766
|
+
children: /* @__PURE__ */ jsx24(RecordNameWords, { tableId, recordId })
|
|
4767
|
+
}
|
|
4768
|
+
);
|
|
4534
4769
|
}
|
|
4535
4770
|
function RecordNameWords({ tableId, recordId }) {
|
|
4536
4771
|
const table = useTable3(tableId);
|
|
4537
4772
|
const record = useRecord(recordId);
|
|
4538
|
-
if (record.loading || table.loading) return /* @__PURE__ */
|
|
4539
|
-
if (record.error) return /* @__PURE__ */
|
|
4540
|
-
if (!record.data) return /* @__PURE__ */
|
|
4541
|
-
return /* @__PURE__ */
|
|
4773
|
+
if (record.loading || table.loading) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" });
|
|
4774
|
+
if (record.error) return /* @__PURE__ */ jsx24(Fragment7, { children: "Couldn't load this record" });
|
|
4775
|
+
if (!record.data) return /* @__PURE__ */ jsx24(Fragment7, { children: "A record you cannot open" });
|
|
4776
|
+
return /* @__PURE__ */ jsx24(Fragment7, { children: recordName(record.data.document, table.data?.title_field ?? null) });
|
|
4542
4777
|
}
|
|
4543
4778
|
|
|
4544
4779
|
// src/HeldChangeDecision.tsx
|
|
4545
|
-
import { useEffect as useEffect15, useState as
|
|
4780
|
+
import { useEffect as useEffect15, useState as useState18 } from "react";
|
|
4546
4781
|
import { RecordsProvider as RecordsProvider3, useRecordsClient as useRecordsClient3 } from "@ai-matrx/records/react";
|
|
4547
4782
|
import { Button as Button11 } from "@ai-matrx/design-system";
|
|
4548
|
-
import { jsx as
|
|
4783
|
+
import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4549
4784
|
function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, onDecided }) {
|
|
4550
|
-
return /* @__PURE__ */
|
|
4785
|
+
return /* @__PURE__ */ jsx25(RecordsProvider3, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ jsx25(Decision, { approvalId, onDecided }) });
|
|
4551
4786
|
}
|
|
4552
4787
|
function Decision({ approvalId, onDecided }) {
|
|
4553
4788
|
const client = useRecordsClient3();
|
|
4554
|
-
const [may, setMay] =
|
|
4555
|
-
const [busy, setBusy] =
|
|
4556
|
-
const [error, setError] =
|
|
4789
|
+
const [may, setMay] = useState18(null);
|
|
4790
|
+
const [busy, setBusy] = useState18(null);
|
|
4791
|
+
const [error, setError] = useState18(null);
|
|
4557
4792
|
useEffect15(() => {
|
|
4558
4793
|
let live = true;
|
|
4559
4794
|
void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
|
|
@@ -4576,13 +4811,13 @@ function Decision({ approvalId, onDecided }) {
|
|
|
4576
4811
|
if (res.ok) onDecided(approve);
|
|
4577
4812
|
else setError(res.error);
|
|
4578
4813
|
};
|
|
4579
|
-
if (may === null) return /* @__PURE__ */
|
|
4580
|
-
return /* @__PURE__ */
|
|
4581
|
-
may ? /* @__PURE__ */
|
|
4582
|
-
/* @__PURE__ */
|
|
4583
|
-
/* @__PURE__ */
|
|
4584
|
-
] }) : !error && /* @__PURE__ */
|
|
4585
|
-
error ? /* @__PURE__ */
|
|
4814
|
+
if (may === null) return /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground", children: "Checking who can decide\u2026" });
|
|
4815
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-1.5", children: [
|
|
4816
|
+
may ? /* @__PURE__ */ jsxs22("div", { className: "flex gap-2", children: [
|
|
4817
|
+
/* @__PURE__ */ jsx25(Button11, { type: "button", size: "sm", disabled: busy !== null, onClick: () => void decide(true), children: busy === "approve" ? "Approving\u2026" : "Approve" }),
|
|
4818
|
+
/* @__PURE__ */ jsx25(Button11, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void decide(false), children: busy === "refuse" ? "Refusing\u2026" : "Refuse" })
|
|
4819
|
+
] }) : !error && /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground", children: "An owner or admin of this organization decides this." }),
|
|
4820
|
+
error ? /* @__PURE__ */ jsx25(RefusalLine, { error }) : null
|
|
4586
4821
|
] });
|
|
4587
4822
|
}
|
|
4588
4823
|
export {
|