@ai-matrx/records-ui 0.93.142 → 0.93.153
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 +126 -0
- package/dist/index.cjs +16946 -15022
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +212 -43
- package/dist/index.d.ts +212 -43
- package/dist/index.js +10363 -8438
- package/dist/index.js.map +1 -1
- package/dist/object-actions.cjs +127 -28
- 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 +125 -26
- package/dist/object-actions.js.map +1 -1
- package/dist/{objectActions-BSbblgf-.d.cts → objectActions-Dgdr0E4b.d.cts} +52 -11
- package/dist/{objectActions-BSbblgf-.d.ts → objectActions-Dgdr0E4b.d.ts} +52 -11
- package/dist/pickers.cjs +745 -493
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.d.cts +12 -1
- package/dist/pickers.d.ts +12 -1
- package/dist/pickers.js +633 -379
- package/dist/pickers.js.map +1 -1
- package/package.json +2 -2
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;
|
|
@@ -451,6 +456,7 @@ function rowNameIn(table, row, fallback = "Untitled") {
|
|
|
451
456
|
return recordName(row?.document, table?.title_field ?? null, fallback);
|
|
452
457
|
}
|
|
453
458
|
var WITHHELD_RECORD_LABEL = "A record you have not been given access to";
|
|
459
|
+
var UNREAD_RECORD_LABEL = "Couldn't load this name";
|
|
454
460
|
|
|
455
461
|
// src/RelationPicker.tsx
|
|
456
462
|
import { useEffect as useEffect3, useMemo, useState as useState3 } from "react";
|
|
@@ -621,7 +627,12 @@ var TITLE = {
|
|
|
621
627
|
already_exists: "That already exists",
|
|
622
628
|
not_supported: "That cannot be done here",
|
|
623
629
|
store_limit: "This has got as big as it can",
|
|
624
|
-
|
|
630
|
+
// 🚨 NOT "THE SWITCH IS OFF" (lane 7 W1 fix round 1). PGRST202 / PGRST205 land here, and the
|
|
631
|
+
// commonest cause is a door this screen asks for that the database it talks to does not serve
|
|
632
|
+
// YET — a release in flight. Telling the person her organization has its store switched off was
|
|
633
|
+
// false (the switch is answered by its own door, `platform.unified_data_store_on`). Honest:
|
|
634
|
+
// nothing happened, and it is ours, and it passes.
|
|
635
|
+
store_not_served: "This isn't available right now",
|
|
625
636
|
unreachable: "We could not reach your data",
|
|
626
637
|
needs_approval: "This is waiting on someone's approval",
|
|
627
638
|
stale_read: "Your view of this is a moment behind",
|
|
@@ -639,7 +650,7 @@ var REMEDY = {
|
|
|
639
650
|
already_exists: "Use a different name.",
|
|
640
651
|
not_supported: "There is another way to do this \u2014 ask, and we will point you at it.",
|
|
641
652
|
store_limit: "Split it up, or ask us to raise the ceiling for your organization.",
|
|
642
|
-
store_not_served: "
|
|
653
|
+
store_not_served: "Nothing was changed. Try again in a few minutes.",
|
|
643
654
|
// 🚨 NOTHING WAS WRITTEN AND NOTHING WAS REFUSED (lane TAILS-6). The call
|
|
644
655
|
// never arrived, so "try again" is the honest instruction rather than a
|
|
645
656
|
// consolation — and saying nothing changed is the half a person actually
|
|
@@ -929,7 +940,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
|
|
|
929
940
|
const learned = {};
|
|
930
941
|
for (const id2 of wanted) {
|
|
931
942
|
const said = result.ok ? result.data[id2] : void 0;
|
|
932
|
-
learned[id2] = typeof said === "string" && said !== "" ? said : WITHHELD_RECORD_LABEL;
|
|
943
|
+
learned[id2] = !result.ok ? UNREAD_RECORD_LABEL : typeof said === "string" && said !== "" ? said : WITHHELD_RECORD_LABEL;
|
|
933
944
|
}
|
|
934
945
|
setWords((current) => ({ ...current, ...learned }));
|
|
935
946
|
});
|
|
@@ -1139,7 +1150,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
|
|
|
1139
1150
|
|
|
1140
1151
|
// src/gridAttachments.tsx
|
|
1141
1152
|
import { useEffect as useEffect6, useRef as useRef5, useState as useState7 } from "react";
|
|
1142
|
-
import { useOptionalRecordsClient as
|
|
1153
|
+
import { useOptionalRecordsClient as useOptionalRecordsClient3 } from "@ai-matrx/records/react";
|
|
1143
1154
|
import { Badge, Button as Button5 } from "@ai-matrx/design-system";
|
|
1144
1155
|
|
|
1145
1156
|
// src/host.tsx
|
|
@@ -1225,6 +1236,7 @@ import { isUuidShape as isUuidShape2 } from "@ai-matrx/kit/uuid";
|
|
|
1225
1236
|
// src/signature.tsx
|
|
1226
1237
|
import { useEffect as useEffect4, useRef as useRef2, useState as useState4 } from "react";
|
|
1227
1238
|
import { Button as Button3, ErrorBox as ErrorBox2, cn as cn5 } from "@ai-matrx/design-system";
|
|
1239
|
+
import { useOptionalRecordsClient as useOptionalRecordsClient2 } from "@ai-matrx/records/react";
|
|
1228
1240
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1229
1241
|
var DRAWN = /^data:image\/(png|jpeg);base64,[A-Za-z0-9+/=]{64,}$/;
|
|
1230
1242
|
function drawnSignatureOf(value) {
|
|
@@ -1235,18 +1247,105 @@ function signatureWords(value) {
|
|
|
1235
1247
|
if (value === null || value === void 0 || value === "") return null;
|
|
1236
1248
|
return drawnSignatureOf(value) ? SIGNED_WORD : String(value);
|
|
1237
1249
|
}
|
|
1238
|
-
function
|
|
1250
|
+
function signatureFileOf(source) {
|
|
1251
|
+
if (!source || typeof source !== "object") return null;
|
|
1252
|
+
const src = source;
|
|
1253
|
+
const id = src["signature_file_id"];
|
|
1254
|
+
return src["kind"] === "signature" && typeof id === "string" && id !== "" ? id : null;
|
|
1255
|
+
}
|
|
1256
|
+
function signatureFileIn(document2, key) {
|
|
1257
|
+
const values = document2?.["_values"];
|
|
1258
|
+
const src = values?.[key]?.src;
|
|
1259
|
+
if (typeof src === "string") {
|
|
1260
|
+
const sources = document2?.["_sources"];
|
|
1261
|
+
return signatureFileOf(sources?.[src]);
|
|
1262
|
+
}
|
|
1263
|
+
return signatureFileOf(src);
|
|
1264
|
+
}
|
|
1265
|
+
var SOURCES = /* @__PURE__ */ new WeakMap();
|
|
1266
|
+
var FILES = /* @__PURE__ */ new WeakMap();
|
|
1267
|
+
function signatureFilesOf(client, recordId) {
|
|
1268
|
+
let held = SOURCES.get(client);
|
|
1269
|
+
if (!held) SOURCES.set(client, held = /* @__PURE__ */ new Map());
|
|
1270
|
+
let asked2 = held.get(recordId);
|
|
1271
|
+
if (!asked2) {
|
|
1272
|
+
asked2 = client.recordValuesVersioned({ record_id: recordId }).then((answered) => {
|
|
1273
|
+
if (!answered.ok) return {};
|
|
1274
|
+
return Object.fromEntries(answered.data.map((v) => [v.field_key, signatureFileOf(v.source)]));
|
|
1275
|
+
});
|
|
1276
|
+
held.set(recordId, asked2);
|
|
1277
|
+
}
|
|
1278
|
+
return asked2;
|
|
1279
|
+
}
|
|
1280
|
+
function drawingOf(client, fileId) {
|
|
1281
|
+
let held = FILES.get(client);
|
|
1282
|
+
if (!held) FILES.set(client, held = /* @__PURE__ */ new Map());
|
|
1283
|
+
let asked2 = held.get(fileId);
|
|
1284
|
+
if (!asked2) {
|
|
1285
|
+
asked2 = client.recordRead({ record_id: fileId }).then((answered) => {
|
|
1286
|
+
if (!answered.ok) return { src: null, hostFileId: null };
|
|
1287
|
+
const doc = answered.data.document ?? {};
|
|
1288
|
+
const content = drawnSignatureOf(doc["content"]);
|
|
1289
|
+
const hostFileId = typeof doc["file_id"] === "string" && doc["file_id"] !== "" ? doc["file_id"] : null;
|
|
1290
|
+
return { src: content, hostFileId };
|
|
1291
|
+
});
|
|
1292
|
+
held.set(fileId, asked2);
|
|
1293
|
+
}
|
|
1294
|
+
return asked2;
|
|
1295
|
+
}
|
|
1296
|
+
function DrawnImage({ src, inCell }) {
|
|
1297
|
+
return /* @__PURE__ */ jsx6(
|
|
1298
|
+
"img",
|
|
1299
|
+
{
|
|
1300
|
+
src,
|
|
1301
|
+
alt: SIGNED_WORD,
|
|
1302
|
+
"data-records-signature": "",
|
|
1303
|
+
className: cn5("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
|
|
1304
|
+
}
|
|
1305
|
+
);
|
|
1306
|
+
}
|
|
1307
|
+
function SignatureDrawing({
|
|
1308
|
+
recordId,
|
|
1309
|
+
fieldKey,
|
|
1310
|
+
fileId: knownFile,
|
|
1311
|
+
value,
|
|
1312
|
+
inCell
|
|
1313
|
+
}) {
|
|
1314
|
+
const client = useOptionalRecordsClient2();
|
|
1315
|
+
const host = useRecordsUi();
|
|
1316
|
+
const [drawing, setDrawing] = useState4(null);
|
|
1317
|
+
useEffect4(() => {
|
|
1318
|
+
let cancelled = false;
|
|
1319
|
+
setDrawing(null);
|
|
1320
|
+
if (!client) return;
|
|
1321
|
+
void (async () => {
|
|
1322
|
+
const fileId = knownFile ?? (recordId && fieldKey ? (await signatureFilesOf(client, recordId))[fieldKey] ?? null : null);
|
|
1323
|
+
if (!fileId || cancelled) return;
|
|
1324
|
+
const read = await drawingOf(client, fileId);
|
|
1325
|
+
if (!cancelled) setDrawing(read);
|
|
1326
|
+
})();
|
|
1327
|
+
return () => {
|
|
1328
|
+
cancelled = true;
|
|
1329
|
+
};
|
|
1330
|
+
}, [client, recordId, fieldKey, knownFile]);
|
|
1331
|
+
if (drawing?.src) return /* @__PURE__ */ jsx6(DrawnImage, { src: drawing.src, inCell });
|
|
1332
|
+
if (drawing?.hostFileId && host.fileImage) {
|
|
1333
|
+
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 }) });
|
|
1334
|
+
}
|
|
1335
|
+
return /* @__PURE__ */ jsx6("span", { className: "font-serif italic", children: String(value) });
|
|
1336
|
+
}
|
|
1337
|
+
function SignatureValue({
|
|
1338
|
+
value,
|
|
1339
|
+
inCell,
|
|
1340
|
+
recordId,
|
|
1341
|
+
fieldKey,
|
|
1342
|
+
document: document2
|
|
1343
|
+
}) {
|
|
1239
1344
|
const drawn = drawnSignatureOf(value);
|
|
1240
|
-
if (drawn) {
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
src: drawn,
|
|
1245
|
-
alt: SIGNED_WORD,
|
|
1246
|
-
"data-records-signature": "",
|
|
1247
|
-
className: cn5("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
|
|
1248
|
-
}
|
|
1249
|
-
);
|
|
1345
|
+
if (drawn) return /* @__PURE__ */ jsx6(DrawnImage, { src: drawn, inCell });
|
|
1346
|
+
const fileId = fieldKey ? signatureFileIn(document2, fieldKey) : null;
|
|
1347
|
+
if (value === SIGNED_WORD && (fileId || recordId && fieldKey)) {
|
|
1348
|
+
return /* @__PURE__ */ jsx6(SignatureDrawing, { recordId: recordId ?? null, fieldKey: fieldKey ?? null, fileId, value, inCell });
|
|
1250
1349
|
}
|
|
1251
1350
|
return /* @__PURE__ */ jsx6("span", { className: "font-serif italic", children: String(value) });
|
|
1252
1351
|
}
|
|
@@ -1528,7 +1627,7 @@ function RecordLabelProvider({ children }) {
|
|
|
1528
1627
|
});
|
|
1529
1628
|
for (const id of wanted) {
|
|
1530
1629
|
const words = result.ok ? result.data[id] : void 0;
|
|
1531
|
-
learned[id] = typeof words === "string" && words !== "" ? words : WITHHELD_RECORD_LABEL;
|
|
1630
|
+
learned[id] = !result.ok ? UNREAD_RECORD_LABEL : typeof words === "string" && words !== "" ? words : WITHHELD_RECORD_LABEL;
|
|
1532
1631
|
}
|
|
1533
1632
|
if (result.ok) for (const id of result.archived ?? []) archivedNow[`${field.id}:${id}`] = true;
|
|
1534
1633
|
})
|
|
@@ -1716,7 +1815,7 @@ function rememberHostFileIds(ids) {
|
|
|
1716
1815
|
var FILE_CHIP_UNREAD = "File";
|
|
1717
1816
|
var FILE_CHIP_NO_PAGE = "This screen has no way to open files yet.";
|
|
1718
1817
|
function AttachmentChip({ id, onRemove }) {
|
|
1719
|
-
const client =
|
|
1818
|
+
const client = useOptionalRecordsClient3();
|
|
1720
1819
|
const host = useRecordsUi();
|
|
1721
1820
|
const [read, setRead] = useState7(null);
|
|
1722
1821
|
useEffect6(() => {
|
|
@@ -1861,11 +1960,99 @@ function AttachmentControl({
|
|
|
1861
1960
|
}
|
|
1862
1961
|
|
|
1863
1962
|
// src/EntityReferenceControl.tsx
|
|
1864
|
-
import { useMemo as useMemo4, useState as
|
|
1963
|
+
import { useMemo as useMemo4, useState as useState9 } from "react";
|
|
1865
1964
|
import { entityRefsOf, entityRefsToWrite } from "@ai-matrx/records";
|
|
1866
|
-
import { useEntityReferenceKinds, useEntityReferenceSearch, useEntityReferenceWords, useOptionalRecordsClient as
|
|
1867
|
-
import { Badge as Badge2, Button as Button6, cn as
|
|
1868
|
-
|
|
1965
|
+
import { useEntityReferenceKinds, useEntityReferenceSearch, useEntityReferenceWords, useOptionalRecordsClient as useOptionalRecordsClient4 } from "@ai-matrx/records/react";
|
|
1966
|
+
import { Badge as Badge2, Button as Button6, cn as cn8 } from "@ai-matrx/design-system";
|
|
1967
|
+
|
|
1968
|
+
// src/PickOne.tsx
|
|
1969
|
+
import { useState as useState8 } from "react";
|
|
1970
|
+
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, cn as cn7 } from "@ai-matrx/design-system";
|
|
1971
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1972
|
+
var PICK_ONE_SEARCH_AFTER = 7;
|
|
1973
|
+
var EMPTY = "__records_pick_one_empty__";
|
|
1974
|
+
var inner = (v) => v === "" ? EMPTY : v;
|
|
1975
|
+
var outer = (v) => v === EMPTY ? "" : v;
|
|
1976
|
+
function PickOne({
|
|
1977
|
+
value,
|
|
1978
|
+
onChange,
|
|
1979
|
+
options,
|
|
1980
|
+
label,
|
|
1981
|
+
placeholder,
|
|
1982
|
+
id,
|
|
1983
|
+
className,
|
|
1984
|
+
disabled,
|
|
1985
|
+
attrs
|
|
1986
|
+
}) {
|
|
1987
|
+
const [open, setOpen] = useState8(false);
|
|
1988
|
+
const [search, setSearch] = useState8("");
|
|
1989
|
+
const current = options.find((o) => o.value === value);
|
|
1990
|
+
if (options.length > PICK_ONE_SEARCH_AFTER) {
|
|
1991
|
+
const q = search.trim().toLowerCase();
|
|
1992
|
+
const shown2 = q === "" ? options : options.filter((o) => o.label.toLowerCase().includes(q));
|
|
1993
|
+
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(
|
|
1994
|
+
PickOrAdd,
|
|
1995
|
+
{
|
|
1996
|
+
triggerLabel: label,
|
|
1997
|
+
triggerText: current?.label ?? placeholder ?? "",
|
|
1998
|
+
triggerId: id,
|
|
1999
|
+
open: open && !disabled,
|
|
2000
|
+
onOpenChange: (next) => {
|
|
2001
|
+
setOpen(next);
|
|
2002
|
+
if (!next) setSearch("");
|
|
2003
|
+
},
|
|
2004
|
+
search,
|
|
2005
|
+
onSearch: setSearch,
|
|
2006
|
+
items: shown2.map((o) => ({
|
|
2007
|
+
id: inner(o.value),
|
|
2008
|
+
label: o.label,
|
|
2009
|
+
detail: o.group,
|
|
2010
|
+
picked: o.value === value,
|
|
2011
|
+
attrs: { "data-pick-value": o.value, ...o.group ? { "data-pick-group": o.group } : {} }
|
|
2012
|
+
})),
|
|
2013
|
+
onPick: (picked) => {
|
|
2014
|
+
onChange(outer(picked));
|
|
2015
|
+
setOpen(false);
|
|
2016
|
+
setSearch("");
|
|
2017
|
+
},
|
|
2018
|
+
empty: /* @__PURE__ */ jsx10("p", { className: "p-2 text-xs text-muted-foreground", children: "No match" })
|
|
2019
|
+
}
|
|
2020
|
+
) });
|
|
2021
|
+
}
|
|
2022
|
+
return /* @__PURE__ */ jsxs8(Select, { value: current ? inner(current.value) : "", onValueChange: (v) => onChange(outer(v)), disabled: disabled ?? false, children: [
|
|
2023
|
+
/* @__PURE__ */ jsx10(
|
|
2024
|
+
SelectTrigger,
|
|
2025
|
+
{
|
|
2026
|
+
id,
|
|
2027
|
+
size: "sm",
|
|
2028
|
+
"aria-label": label,
|
|
2029
|
+
className: cn7("h-7 w-auto min-w-[7rem] text-xs", className),
|
|
2030
|
+
"data-records-pick-one": "list",
|
|
2031
|
+
"data-pick-value": value,
|
|
2032
|
+
...attrs ?? {},
|
|
2033
|
+
children: /* @__PURE__ */ jsx10(SelectValue, { placeholder })
|
|
2034
|
+
}
|
|
2035
|
+
),
|
|
2036
|
+
/* @__PURE__ */ jsx10(SelectContent, { children: groupsOf(options).map(
|
|
2037
|
+
([group, items]) => group ? /* @__PURE__ */ jsxs8(SelectGroup, { children: [
|
|
2038
|
+
/* @__PURE__ */ jsx10(SelectLabel, { children: group }),
|
|
2039
|
+
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)))
|
|
2040
|
+
] }, group) : items.map((o) => /* @__PURE__ */ jsx10(SelectItem, { value: inner(o.value), "data-pick-value": o.value, children: o.label }, inner(o.value)))
|
|
2041
|
+
) })
|
|
2042
|
+
] });
|
|
2043
|
+
}
|
|
2044
|
+
function groupsOf(options) {
|
|
2045
|
+
const out = [];
|
|
2046
|
+
for (const o of options) {
|
|
2047
|
+
const last = out[out.length - 1];
|
|
2048
|
+
if (last && last[0] === o.group) last[1].push(o);
|
|
2049
|
+
else out.push([o.group, [o]]);
|
|
2050
|
+
}
|
|
2051
|
+
return out;
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
// src/EntityReferenceControl.tsx
|
|
2055
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1869
2056
|
var WITHHELD_ENTITY_LABEL = "Something you have not been given access to";
|
|
1870
2057
|
var ENTITY_REFERENCE_EMPTY = "Nothing is pointed at yet.";
|
|
1871
2058
|
function entityReferenceText(value) {
|
|
@@ -1879,12 +2066,12 @@ function allowedKindsOf(field) {
|
|
|
1879
2066
|
return kinds.map((k) => String(k).trim().toLowerCase()).filter(Boolean);
|
|
1880
2067
|
}
|
|
1881
2068
|
function EntityReferenceControl(props) {
|
|
1882
|
-
const client =
|
|
1883
|
-
return client ? /* @__PURE__ */
|
|
2069
|
+
const client = useOptionalRecordsClient4();
|
|
2070
|
+
return client ? /* @__PURE__ */ jsx11(WithWords, { ...props }) : /* @__PURE__ */ jsx11(Chips, { ...props, words: null, picker: null });
|
|
1884
2071
|
}
|
|
1885
2072
|
function WithWords(props) {
|
|
1886
2073
|
const refs = useMemo4(() => entityRefsOf(props.value), [props.value]);
|
|
1887
|
-
const [known, setKnown] =
|
|
2074
|
+
const [known, setKnown] = useState9([]);
|
|
1888
2075
|
const withKnown = refs.map((r) => r.label === null ? known.find((k) => k.token === r.token && k.id === r.id) ?? r : r);
|
|
1889
2076
|
const unlabelled = useMemo4(
|
|
1890
2077
|
() => withKnown.filter((r) => r.label === null).map((r) => ({ token: r.token, id: r.id })),
|
|
@@ -1892,7 +2079,7 @@ function WithWords(props) {
|
|
|
1892
2079
|
[JSON.stringify(withKnown)]
|
|
1893
2080
|
);
|
|
1894
2081
|
const words = useEntityReferenceWords(unlabelled);
|
|
1895
|
-
const picker = props.disabled ? null : /* @__PURE__ */
|
|
2082
|
+
const picker = props.disabled ? null : /* @__PURE__ */ jsx11(
|
|
1896
2083
|
EntityReferencePicker,
|
|
1897
2084
|
{
|
|
1898
2085
|
field: props.field,
|
|
@@ -1905,7 +2092,7 @@ function WithWords(props) {
|
|
|
1905
2092
|
}
|
|
1906
2093
|
}
|
|
1907
2094
|
);
|
|
1908
|
-
return /* @__PURE__ */
|
|
2095
|
+
return /* @__PURE__ */ jsx11(Chips, { ...props, value: withKnown, words, picker });
|
|
1909
2096
|
}
|
|
1910
2097
|
function EntityReferencePicker({
|
|
1911
2098
|
field,
|
|
@@ -1915,9 +2102,9 @@ function EntityReferencePicker({
|
|
|
1915
2102
|
const allowed = allowedKindsOf(field);
|
|
1916
2103
|
const kinds = useEntityReferenceKinds();
|
|
1917
2104
|
const labelOfKind = (token) => kinds.data?.find((k) => k.token === token)?.label ?? token.replace(/_/g, " ");
|
|
1918
|
-
const [open, setOpen] =
|
|
1919
|
-
const [search, setSearch] =
|
|
1920
|
-
const [only, setOnly] =
|
|
2105
|
+
const [open, setOpen] = useState9(false);
|
|
2106
|
+
const [search, setSearch] = useState9("");
|
|
2107
|
+
const [only, setOnly] = useState9(null);
|
|
1921
2108
|
const tokens = only ? [only] : allowed;
|
|
1922
2109
|
const found = useEntityReferenceSearch(tokens, search, open);
|
|
1923
2110
|
const multi = Boolean(field.multi);
|
|
@@ -1928,7 +2115,7 @@ function EntityReferencePicker({
|
|
|
1928
2115
|
picked: refs.some((x) => x.token === r.token && x.id === r.id),
|
|
1929
2116
|
attrs: { "data-entity-reference-candidate": `${r.token}:${r.id}` }
|
|
1930
2117
|
}));
|
|
1931
|
-
const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */
|
|
2118
|
+
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(
|
|
1932
2119
|
Button6,
|
|
1933
2120
|
{
|
|
1934
2121
|
type: "button",
|
|
@@ -1940,26 +2127,23 @@ function EntityReferencePicker({
|
|
|
1940
2127
|
children: token ? labelOfKind(token) : "Any"
|
|
1941
2128
|
},
|
|
1942
2129
|
token ?? "any"
|
|
1943
|
-
)) }) : /* @__PURE__ */
|
|
1944
|
-
|
|
2130
|
+
)) }) : /* @__PURE__ */ jsx11(
|
|
2131
|
+
PickOne,
|
|
1945
2132
|
{
|
|
1946
|
-
|
|
1947
|
-
"
|
|
2133
|
+
label: `Which kind \u2014 ${field.label}`,
|
|
2134
|
+
className: "mb-1 w-full",
|
|
1948
2135
|
value: only ?? "",
|
|
1949
|
-
onChange: (
|
|
1950
|
-
|
|
1951
|
-
/* @__PURE__ */ jsx10("option", { value: "", children: "Any kind" }),
|
|
1952
|
-
allowed.map((token) => /* @__PURE__ */ jsx10("option", { value: token, children: labelOfKind(token) }, token))
|
|
1953
|
-
]
|
|
2136
|
+
onChange: (picked) => setOnly(picked || null),
|
|
2137
|
+
options: [{ value: "", label: "Any kind" }, ...allowed.map((token) => ({ value: token, label: labelOfKind(token) }))]
|
|
1954
2138
|
}
|
|
1955
2139
|
) : null;
|
|
1956
|
-
const notice = /* @__PURE__ */
|
|
2140
|
+
const notice = /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
1957
2141
|
kindChoice,
|
|
1958
|
-
found.error ? /* @__PURE__ */
|
|
1959
|
-
found.loading && !found.data ? /* @__PURE__ */
|
|
2142
|
+
found.error ? /* @__PURE__ */ jsx11(RefusalLine, { error: found.error, className: "px-2 py-1 text-[11px]" }) : null,
|
|
2143
|
+
found.loading && !found.data ? /* @__PURE__ */ jsx11("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: "Searching\u2026" }) : null
|
|
1960
2144
|
] });
|
|
1961
2145
|
const kindWords = allowed.length === 1 ? labelOfKind(allowed[0]).toLowerCase() : "thing";
|
|
1962
|
-
return /* @__PURE__ */
|
|
2146
|
+
return /* @__PURE__ */ jsx11(
|
|
1963
2147
|
PickOrAdd,
|
|
1964
2148
|
{
|
|
1965
2149
|
triggerLabel: `Pick for ${field.label}`,
|
|
@@ -1973,7 +2157,7 @@ function EntityReferencePicker({
|
|
|
1973
2157
|
onSearch: setSearch,
|
|
1974
2158
|
items,
|
|
1975
2159
|
notice,
|
|
1976
|
-
empty: found.loading ? null : /* @__PURE__ */
|
|
2160
|
+
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.` }),
|
|
1977
2161
|
onPick: (key) => {
|
|
1978
2162
|
const r = (found.data ?? []).find((x) => `${x.token}:${x.id}` === key);
|
|
1979
2163
|
if (!r) return;
|
|
@@ -2003,13 +2187,13 @@ function Chips({
|
|
|
2003
2187
|
return WITHHELD_ENTITY_LABEL;
|
|
2004
2188
|
};
|
|
2005
2189
|
const multi = Boolean(field.multi);
|
|
2006
|
-
return /* @__PURE__ */
|
|
2007
|
-
refs.length === 0 && !picker ? /* @__PURE__ */
|
|
2190
|
+
return /* @__PURE__ */ jsxs9("div", { id, className: cn8("flex flex-wrap items-center gap-1", className), "aria-label": `What ${field.label} points at`, children: [
|
|
2191
|
+
refs.length === 0 && !picker ? /* @__PURE__ */ jsx11("span", { className: "text-[11px] text-muted-foreground", children: ENTITY_REFERENCE_EMPTY }) : null,
|
|
2008
2192
|
refs.map((r) => {
|
|
2009
2193
|
const label = labelOf(r.token, r.id, r.label);
|
|
2010
|
-
return /* @__PURE__ */
|
|
2194
|
+
return /* @__PURE__ */ jsxs9(Badge2, { variant: "secondary", className: "gap-1 text-[11px]", "data-entity-reference-chip": `${r.token}:${r.id}`, children: [
|
|
2011
2195
|
label,
|
|
2012
|
-
disabled ? null : /* @__PURE__ */
|
|
2196
|
+
disabled ? null : /* @__PURE__ */ jsx11(
|
|
2013
2197
|
"button",
|
|
2014
2198
|
{
|
|
2015
2199
|
type: "button",
|
|
@@ -2029,9 +2213,9 @@ function Chips({
|
|
|
2029
2213
|
}
|
|
2030
2214
|
|
|
2031
2215
|
// src/PersonPicker.tsx
|
|
2032
|
-
import { useCallback as useCallback3, useEffect as useEffect7, useMemo as useMemo5, useRef as useRef6, useState as
|
|
2216
|
+
import { useCallback as useCallback3, useEffect as useEffect7, useMemo as useMemo5, useRef as useRef6, useState as useState10 } from "react";
|
|
2033
2217
|
import { rankTypedMatches as rankTypedMatches2 } from "@ai-matrx/records";
|
|
2034
|
-
import { useOptionalRecordsClient as
|
|
2218
|
+
import { useOptionalRecordsClient as useOptionalRecordsClient5 } from "@ai-matrx/records/react";
|
|
2035
2219
|
import {
|
|
2036
2220
|
BasicInput as BasicInput4,
|
|
2037
2221
|
Button as Button7,
|
|
@@ -2039,9 +2223,9 @@ import {
|
|
|
2039
2223
|
PopoverContent as PopoverContent2,
|
|
2040
2224
|
PopoverTrigger as PopoverTrigger2,
|
|
2041
2225
|
ScrollArea as ScrollArea2,
|
|
2042
|
-
cn as
|
|
2226
|
+
cn as cn9
|
|
2043
2227
|
} from "@ai-matrx/design-system";
|
|
2044
|
-
import { jsx as
|
|
2228
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2045
2229
|
function personFromRow(row) {
|
|
2046
2230
|
const data = row.document ?? {};
|
|
2047
2231
|
const userId = data["user_id"];
|
|
@@ -2072,20 +2256,20 @@ async function personRecordForMember(client, personTableId, people, member) {
|
|
|
2072
2256
|
return written;
|
|
2073
2257
|
}
|
|
2074
2258
|
function PersonPicker({ field, value, onChange, disabled, id, className, autoOpen, onClose, initialSearch }) {
|
|
2075
|
-
const client =
|
|
2259
|
+
const client = useOptionalRecordsClient5();
|
|
2076
2260
|
const host = useRecordsUi();
|
|
2077
|
-
const [members, setMembers] =
|
|
2078
|
-
const [people, setPeople] =
|
|
2079
|
-
const [error, setError] =
|
|
2080
|
-
const [search, setSearch] =
|
|
2081
|
-
const [open, setOpenState] =
|
|
2261
|
+
const [members, setMembers] = useState10(null);
|
|
2262
|
+
const [people, setPeople] = useState10([]);
|
|
2263
|
+
const [error, setError] = useState10(null);
|
|
2264
|
+
const [search, setSearch] = useState10(initialSearch ?? "");
|
|
2265
|
+
const [open, setOpenState] = useState10(autoOpen === true);
|
|
2082
2266
|
const onCloseRef = useRef6(onClose);
|
|
2083
2267
|
onCloseRef.current = onClose;
|
|
2084
2268
|
const setOpen = useCallback3((next) => {
|
|
2085
2269
|
setOpenState(next);
|
|
2086
2270
|
if (!next) onCloseRef.current?.();
|
|
2087
2271
|
}, []);
|
|
2088
|
-
const [busy, setBusy] =
|
|
2272
|
+
const [busy, setBusy] = useState10(false);
|
|
2089
2273
|
const membersPort = host.members;
|
|
2090
2274
|
const personTable = field.relation_target;
|
|
2091
2275
|
const picked = useMemo5(
|
|
@@ -2132,10 +2316,10 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2132
2316
|
});
|
|
2133
2317
|
const pickRef = useRef6(null);
|
|
2134
2318
|
if (!membersPort || !client) {
|
|
2135
|
-
return /* @__PURE__ */
|
|
2319
|
+
return /* @__PURE__ */ jsx12("p", { className: cn9("text-xs text-muted-foreground", className), children: NO_MEMBERS_REASON });
|
|
2136
2320
|
}
|
|
2137
2321
|
if (!personTable) {
|
|
2138
|
-
return /* @__PURE__ */
|
|
2322
|
+
return /* @__PURE__ */ jsxs10("p", { className: cn9("text-xs text-muted-foreground", className), children: [
|
|
2139
2323
|
fieldName(field),
|
|
2140
2324
|
" 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."
|
|
2141
2325
|
] });
|
|
@@ -2178,8 +2362,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2178
2362
|
const pickedUserIds = new Set(
|
|
2179
2363
|
picked.map((recordId) => people.find((p) => p.id === recordId)?.userId).filter(Boolean)
|
|
2180
2364
|
);
|
|
2181
|
-
return /* @__PURE__ */
|
|
2182
|
-
picked.map((recordId) => /* @__PURE__ */
|
|
2365
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn9("flex flex-wrap items-center gap-1", className), children: [
|
|
2366
|
+
picked.map((recordId) => /* @__PURE__ */ jsx12(
|
|
2183
2367
|
RecordChip,
|
|
2184
2368
|
{
|
|
2185
2369
|
title: nameOfRecord(recordId),
|
|
@@ -2187,8 +2371,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2187
2371
|
},
|
|
2188
2372
|
recordId
|
|
2189
2373
|
)),
|
|
2190
|
-
disabled ? null : /* @__PURE__ */
|
|
2191
|
-
/* @__PURE__ */
|
|
2374
|
+
disabled ? null : /* @__PURE__ */ jsxs10(Popover2, { open, onOpenChange: setOpen, children: [
|
|
2375
|
+
/* @__PURE__ */ jsx12(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx12(
|
|
2192
2376
|
Button7,
|
|
2193
2377
|
{
|
|
2194
2378
|
id,
|
|
@@ -2199,7 +2383,7 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2199
2383
|
children: picked.length === 0 ? "Pick a person" : "Change"
|
|
2200
2384
|
}
|
|
2201
2385
|
) }),
|
|
2202
|
-
/* @__PURE__ */
|
|
2386
|
+
/* @__PURE__ */ jsxs10(
|
|
2203
2387
|
PopoverContent2,
|
|
2204
2388
|
{
|
|
2205
2389
|
sizing: "content",
|
|
@@ -2208,7 +2392,7 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2208
2392
|
"data-matrx-cell-editor": "",
|
|
2209
2393
|
onKeyDown: (event) => event.stopPropagation(),
|
|
2210
2394
|
children: [
|
|
2211
|
-
/* @__PURE__ */
|
|
2395
|
+
/* @__PURE__ */ jsx12(
|
|
2212
2396
|
BasicInput4,
|
|
2213
2397
|
{
|
|
2214
2398
|
value: search,
|
|
@@ -2221,31 +2405,31 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2221
2405
|
className: "mb-1 h-7 text-xs"
|
|
2222
2406
|
}
|
|
2223
2407
|
),
|
|
2224
|
-
error ? /* @__PURE__ */
|
|
2225
|
-
members === null ? /* @__PURE__ */
|
|
2226
|
-
/* @__PURE__ */
|
|
2227
|
-
/* @__PURE__ */
|
|
2408
|
+
error ? /* @__PURE__ */ jsx12(RefusalLine, { error, className: "p-2" }) : null,
|
|
2409
|
+
members === null ? /* @__PURE__ */ jsx12("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading the members\u2026" }) : null,
|
|
2410
|
+
/* @__PURE__ */ jsxs10(ScrollArea2, { className: "max-h-56", children: [
|
|
2411
|
+
/* @__PURE__ */ jsx12("ul", { role: "listbox", "aria-label": `People for ${fieldName(field)}`, children: visible.map((member, index) => /* @__PURE__ */ jsx12("li", { children: /* @__PURE__ */ jsxs10(
|
|
2228
2412
|
"button",
|
|
2229
2413
|
{
|
|
2230
2414
|
type: "button",
|
|
2231
2415
|
disabled: busy,
|
|
2232
2416
|
"data-pick-highlighted": index === keys.highlight ? "" : void 0,
|
|
2233
2417
|
onClick: () => void pick(member),
|
|
2234
|
-
className:
|
|
2418
|
+
className: cn9(
|
|
2235
2419
|
"w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-muted",
|
|
2236
2420
|
pickedUserIds.has(member.userId) ? "bg-accent text-accent-foreground" : "",
|
|
2237
2421
|
index === keys.highlight ? "ring-1 ring-ring" : ""
|
|
2238
2422
|
),
|
|
2239
2423
|
children: [
|
|
2240
|
-
/* @__PURE__ */
|
|
2241
|
-
member.email && member.email !== memberName(member) ? /* @__PURE__ */
|
|
2424
|
+
/* @__PURE__ */ jsx12("span", { children: memberName(member) }),
|
|
2425
|
+
member.email && member.email !== memberName(member) ? /* @__PURE__ */ jsxs10("span", { className: "ml-1.5 opacity-60", children: [
|
|
2242
2426
|
"\xB7 ",
|
|
2243
2427
|
member.email
|
|
2244
2428
|
] }) : null
|
|
2245
2429
|
]
|
|
2246
2430
|
}
|
|
2247
2431
|
) }, member.userId)) }),
|
|
2248
|
-
members !== null && visible.length === 0 ? /* @__PURE__ */
|
|
2432
|
+
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
|
|
2249
2433
|
] })
|
|
2250
2434
|
]
|
|
2251
2435
|
}
|
|
@@ -2321,7 +2505,7 @@ function currencyCodeFor(unit) {
|
|
|
2321
2505
|
}
|
|
2322
2506
|
|
|
2323
2507
|
// src/formatControls.tsx
|
|
2324
|
-
import { useEffect as useEffect8, useRef as useRef8, useState as
|
|
2508
|
+
import { useEffect as useEffect8, useRef as useRef8, useState as useState11 } from "react";
|
|
2325
2509
|
import { BasicInput as BasicInput5, BasicTextarea } from "@ai-matrx/design-system";
|
|
2326
2510
|
import { getFieldFormat as getFieldFormat3, parseFieldInput } from "@ai-matrx/design-system/field-formats";
|
|
2327
2511
|
|
|
@@ -2329,8 +2513,8 @@ import { getFieldFormat as getFieldFormat3, parseFieldInput } from "@ai-matrx/de
|
|
|
2329
2513
|
import { useRef as useRef7 } from "react";
|
|
2330
2514
|
import { FormattedCell } from "@ai-matrx/design-system/data-table";
|
|
2331
2515
|
import { formatFieldValue as formatFieldValue2, getFieldFormat as getFieldFormat2 } from "@ai-matrx/design-system/field-formats";
|
|
2332
|
-
import { cn as
|
|
2333
|
-
import { jsx as
|
|
2516
|
+
import { cn as cn10 } from "@ai-matrx/design-system";
|
|
2517
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2334
2518
|
var LINK = "inline-flex min-w-0 items-center gap-1 text-primary hover:underline";
|
|
2335
2519
|
var own2 = (event) => event.stopPropagation();
|
|
2336
2520
|
function numberOf(value) {
|
|
@@ -2352,7 +2536,7 @@ function RatingStars({
|
|
|
2352
2536
|
const score = numberOf(value) ?? 0;
|
|
2353
2537
|
const shown2 = Math.round(score);
|
|
2354
2538
|
const said = `${shown2} out of ${max}`;
|
|
2355
|
-
return /* @__PURE__ */
|
|
2539
|
+
return /* @__PURE__ */ jsx13(
|
|
2356
2540
|
"span",
|
|
2357
2541
|
{
|
|
2358
2542
|
"data-records-rating": "",
|
|
@@ -2364,8 +2548,8 @@ function RatingStars({
|
|
|
2364
2548
|
children: Array.from({ length: max }, (_, i) => {
|
|
2365
2549
|
const n = i + 1;
|
|
2366
2550
|
const lit = n <= shown2;
|
|
2367
|
-
const star = /* @__PURE__ */
|
|
2368
|
-
return onRate ? /* @__PURE__ */
|
|
2551
|
+
const star = /* @__PURE__ */ jsx13("span", { "aria-hidden": true, className: cn10("text-sm leading-none", lit ? "text-amber-400" : "text-muted-foreground/40"), children: "\u2605" });
|
|
2552
|
+
return onRate ? /* @__PURE__ */ jsx13(
|
|
2369
2553
|
"button",
|
|
2370
2554
|
{
|
|
2371
2555
|
type: "button",
|
|
@@ -2390,7 +2574,7 @@ function RatingStars({
|
|
|
2390
2574
|
children: star
|
|
2391
2575
|
},
|
|
2392
2576
|
n
|
|
2393
|
-
) : /* @__PURE__ */
|
|
2577
|
+
) : /* @__PURE__ */ jsx13("span", { children: star }, n);
|
|
2394
2578
|
})
|
|
2395
2579
|
}
|
|
2396
2580
|
);
|
|
@@ -2398,13 +2582,13 @@ function RatingStars({
|
|
|
2398
2582
|
function rich(id, text, raw, format) {
|
|
2399
2583
|
switch (id) {
|
|
2400
2584
|
case "email":
|
|
2401
|
-
return /* @__PURE__ */
|
|
2585
|
+
return /* @__PURE__ */ jsx13("a", { href: `mailto:${text}`, className: LINK, onClick: own2, children: /* @__PURE__ */ jsx13("span", { className: "truncate", children: text }) });
|
|
2402
2586
|
case "url":
|
|
2403
|
-
return /* @__PURE__ */
|
|
2587
|
+
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 }) });
|
|
2404
2588
|
case "phone":
|
|
2405
|
-
return /* @__PURE__ */
|
|
2589
|
+
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) }) });
|
|
2406
2590
|
case "address":
|
|
2407
|
-
return /* @__PURE__ */
|
|
2591
|
+
return /* @__PURE__ */ jsx13(
|
|
2408
2592
|
"a",
|
|
2409
2593
|
{
|
|
2410
2594
|
href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(text)}`,
|
|
@@ -2413,7 +2597,7 @@ function rich(id, text, raw, format) {
|
|
|
2413
2597
|
className: LINK,
|
|
2414
2598
|
title: "Open in maps",
|
|
2415
2599
|
onClick: own2,
|
|
2416
|
-
children: /* @__PURE__ */
|
|
2600
|
+
children: /* @__PURE__ */ jsx13("span", { className: "truncate", children: text })
|
|
2417
2601
|
}
|
|
2418
2602
|
);
|
|
2419
2603
|
case "progress": {
|
|
@@ -2421,8 +2605,8 @@ function rich(id, text, raw, format) {
|
|
|
2421
2605
|
if (n === null) return void 0;
|
|
2422
2606
|
const pct = format.options?.percentScale === "fraction" ? n * 100 : n;
|
|
2423
2607
|
const clamped = Math.max(0, Math.min(100, pct));
|
|
2424
|
-
return /* @__PURE__ */
|
|
2425
|
-
/* @__PURE__ */
|
|
2608
|
+
return /* @__PURE__ */ jsxs11("span", { className: "inline-flex w-full min-w-0 items-center gap-2", title: text, children: [
|
|
2609
|
+
/* @__PURE__ */ jsx13(
|
|
2426
2610
|
"span",
|
|
2427
2611
|
{
|
|
2428
2612
|
role: "progressbar",
|
|
@@ -2430,24 +2614,24 @@ function rich(id, text, raw, format) {
|
|
|
2430
2614
|
"aria-valuemax": 100,
|
|
2431
2615
|
"aria-valuenow": Math.round(clamped),
|
|
2432
2616
|
className: "h-1.5 min-w-8 flex-1 overflow-hidden rounded-full bg-muted",
|
|
2433
|
-
children: /* @__PURE__ */
|
|
2617
|
+
children: /* @__PURE__ */ jsx13("span", { className: cn10("block h-full rounded-full", pct >= 100 ? "bg-emerald-500" : "bg-primary"), style: { width: `${clamped}%` } })
|
|
2434
2618
|
}
|
|
2435
2619
|
),
|
|
2436
|
-
/* @__PURE__ */
|
|
2620
|
+
/* @__PURE__ */ jsx13("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: text })
|
|
2437
2621
|
] });
|
|
2438
2622
|
}
|
|
2439
2623
|
case "color":
|
|
2440
|
-
return /* @__PURE__ */
|
|
2441
|
-
/* @__PURE__ */
|
|
2442
|
-
/* @__PURE__ */
|
|
2624
|
+
return /* @__PURE__ */ jsxs11("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
2625
|
+
/* @__PURE__ */ jsx13("span", { className: "h-4 w-4 shrink-0 rounded border border-border", style: { backgroundColor: text } }),
|
|
2626
|
+
/* @__PURE__ */ jsx13("code", { className: "font-mono text-xs", children: text })
|
|
2443
2627
|
] });
|
|
2444
2628
|
case "tags": {
|
|
2445
2629
|
const items = Array.isArray(raw) ? raw.map(String) : text.split(",").map((s) => s.trim()).filter(Boolean);
|
|
2446
2630
|
if (items.length === 0) return void 0;
|
|
2447
|
-
return /* @__PURE__ */
|
|
2631
|
+
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}`)) });
|
|
2448
2632
|
}
|
|
2449
2633
|
case "rating":
|
|
2450
|
-
return numberOf(raw) === null ? void 0 : /* @__PURE__ */
|
|
2634
|
+
return numberOf(raw) === null ? void 0 : /* @__PURE__ */ jsx13(RatingStars, { value: raw, max: format.options?.ratingMax ?? 5 });
|
|
2451
2635
|
default:
|
|
2452
2636
|
return void 0;
|
|
2453
2637
|
}
|
|
@@ -2462,11 +2646,11 @@ function FormattedValue({
|
|
|
2462
2646
|
const score = numberOf(value);
|
|
2463
2647
|
const max = format.options?.ratingMax ?? 5;
|
|
2464
2648
|
if (def?.id === "rating" && onRate && (value === null || value === void 0 || value === "" || score !== null && score >= 0 && score <= max)) {
|
|
2465
|
-
return /* @__PURE__ */
|
|
2649
|
+
return /* @__PURE__ */ jsx13(RatingStars, { value, max: format.options?.ratingMax ?? 5, onRate, selectFirst });
|
|
2466
2650
|
}
|
|
2467
2651
|
const result = formatFieldValue2(value, format);
|
|
2468
|
-
if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */
|
|
2469
|
-
return rich(def.id, result.text, value, format) ?? /* @__PURE__ */
|
|
2652
|
+
if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ jsx13(FormattedCell, { result });
|
|
2653
|
+
return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ jsx13(FormattedCell, { result });
|
|
2470
2654
|
}
|
|
2471
2655
|
function formatPhone(raw) {
|
|
2472
2656
|
const text = raw.trim();
|
|
@@ -2490,7 +2674,7 @@ function linkChipText(raw) {
|
|
|
2490
2674
|
}
|
|
2491
2675
|
|
|
2492
2676
|
// src/formatControls.tsx
|
|
2493
|
-
import { jsx as
|
|
2677
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2494
2678
|
var TYPED_NUMBERS = /* @__PURE__ */ new Set(["currency", "percent", "progress", "decimal", "duration", "file_size", "integer"]);
|
|
2495
2679
|
function scaled(format) {
|
|
2496
2680
|
return (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction";
|
|
@@ -2507,13 +2691,13 @@ function keptValue(format, raw) {
|
|
|
2507
2691
|
return parsed;
|
|
2508
2692
|
}
|
|
2509
2693
|
function NumberInFormat({ format, value, onChange, disabled, id }) {
|
|
2510
|
-
const [text, setText] =
|
|
2694
|
+
const [text, setText] = useState11(() => typedText(format, value));
|
|
2511
2695
|
const lastSent = useRef8(void 0);
|
|
2512
2696
|
useEffect8(() => {
|
|
2513
2697
|
if (value === lastSent.current) return;
|
|
2514
2698
|
setText(typedText(format, value));
|
|
2515
2699
|
}, [value, format]);
|
|
2516
|
-
return /* @__PURE__ */
|
|
2700
|
+
return /* @__PURE__ */ jsx14(
|
|
2517
2701
|
BasicInput5,
|
|
2518
2702
|
{
|
|
2519
2703
|
id,
|
|
@@ -2538,16 +2722,16 @@ function formatControl(args) {
|
|
|
2538
2722
|
const text = value === null || value === void 0 ? "" : String(value);
|
|
2539
2723
|
const commit = (raw) => onChange(raw === "" ? null : parseFieldInput(raw, format));
|
|
2540
2724
|
if (def.id === "rating") {
|
|
2541
|
-
return disabled ? /* @__PURE__ */
|
|
2725
|
+
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) }) });
|
|
2542
2726
|
}
|
|
2543
|
-
if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */
|
|
2727
|
+
if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ jsx14(NumberInFormat, { ...args });
|
|
2544
2728
|
switch (def.editor) {
|
|
2545
2729
|
// A TIME OF DAY is not this file's: `FieldControl` draws the typed box and its helper
|
|
2546
2730
|
// (`TypedWordsControl`), never the browser's time control (grids review 3, 2026-09-30).
|
|
2547
2731
|
case "email":
|
|
2548
2732
|
case "url":
|
|
2549
2733
|
case "tel":
|
|
2550
|
-
return /* @__PURE__ */
|
|
2734
|
+
return /* @__PURE__ */ jsx14(
|
|
2551
2735
|
BasicInput5,
|
|
2552
2736
|
{
|
|
2553
2737
|
id,
|
|
@@ -2559,8 +2743,8 @@ function formatControl(args) {
|
|
|
2559
2743
|
}
|
|
2560
2744
|
);
|
|
2561
2745
|
case "color":
|
|
2562
|
-
return /* @__PURE__ */
|
|
2563
|
-
/* @__PURE__ */
|
|
2746
|
+
return /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-2", children: [
|
|
2747
|
+
/* @__PURE__ */ jsx14(
|
|
2564
2748
|
BasicInput5,
|
|
2565
2749
|
{
|
|
2566
2750
|
id: `${id}-swatch`,
|
|
@@ -2572,20 +2756,20 @@ function formatControl(args) {
|
|
|
2572
2756
|
onChange: (e) => commit(e.target.value)
|
|
2573
2757
|
}
|
|
2574
2758
|
),
|
|
2575
|
-
/* @__PURE__ */
|
|
2759
|
+
/* @__PURE__ */ jsx14(BasicInput5, { id, value: text, placeholder: "#3b82f6", disabled, onChange: (e) => commit(e.target.value) })
|
|
2576
2760
|
] });
|
|
2577
2761
|
case "textarea":
|
|
2578
|
-
return /* @__PURE__ */
|
|
2762
|
+
return /* @__PURE__ */ jsx14(BasicTextarea, { id, rows: 4, value: text, disabled, onChange: (e) => commit(e.target.value) });
|
|
2579
2763
|
default:
|
|
2580
2764
|
return null;
|
|
2581
2765
|
}
|
|
2582
2766
|
}
|
|
2583
2767
|
|
|
2584
2768
|
// src/typedDateHelper.tsx
|
|
2585
|
-
import { useState as
|
|
2586
|
-
import { Popover as Popover3, PopoverContent as PopoverContent3, PopoverTrigger as PopoverTrigger3, cn as
|
|
2769
|
+
import { useState as useState12 } from "react";
|
|
2770
|
+
import { Popover as Popover3, PopoverContent as PopoverContent3, PopoverTrigger as PopoverTrigger3, cn as cn11 } from "@ai-matrx/design-system";
|
|
2587
2771
|
import { readTypedDate, readTypedTime, typedDateText, typedTimeText } from "@ai-matrx/records";
|
|
2588
|
-
import { jsx as
|
|
2772
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2589
2773
|
var WEEK = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
2590
2774
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
2591
2775
|
function pad(n) {
|
|
@@ -2614,23 +2798,23 @@ function wordsFor(kind, day, time) {
|
|
|
2614
2798
|
}
|
|
2615
2799
|
var keepFocus = { onMouseDown: (e) => e.preventDefault(), tabIndex: -1 };
|
|
2616
2800
|
function CalendarGlyph() {
|
|
2617
|
-
return /* @__PURE__ */
|
|
2618
|
-
/* @__PURE__ */
|
|
2619
|
-
/* @__PURE__ */
|
|
2801
|
+
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: [
|
|
2802
|
+
/* @__PURE__ */ jsx15("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
|
|
2803
|
+
/* @__PURE__ */ jsx15("path", { d: "M16 2v4M8 2v4M3 10h18" })
|
|
2620
2804
|
] });
|
|
2621
2805
|
}
|
|
2622
2806
|
function ClockGlyph() {
|
|
2623
|
-
return /* @__PURE__ */
|
|
2624
|
-
/* @__PURE__ */
|
|
2625
|
-
/* @__PURE__ */
|
|
2807
|
+
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: [
|
|
2808
|
+
/* @__PURE__ */ jsx15("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2809
|
+
/* @__PURE__ */ jsx15("path", { d: "M12 6v6l4 2" })
|
|
2626
2810
|
] });
|
|
2627
2811
|
}
|
|
2628
2812
|
function TypedDateHelper({ kind, text, onText, label }) {
|
|
2629
|
-
const [open, setOpen] =
|
|
2813
|
+
const [open, setOpen] = useState12(false);
|
|
2630
2814
|
const held = readBox(text, kind);
|
|
2631
2815
|
const today = /* @__PURE__ */ new Date();
|
|
2632
2816
|
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);
|
|
2633
|
-
const [month, setMonth] =
|
|
2817
|
+
const [month, setMonth] = useState12(null);
|
|
2634
2818
|
const shown2 = month ?? { y: start.getFullYear(), m: start.getMonth() };
|
|
2635
2819
|
const first = new Date(shown2.y, shown2.m, 1).getDay();
|
|
2636
2820
|
const days = new Date(shown2.y, shown2.m + 1, 0).getDate();
|
|
@@ -2651,8 +2835,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2651
2835
|
const at = new Date(shown2.y, shown2.m + by, 1);
|
|
2652
2836
|
setMonth({ y: at.getFullYear(), m: at.getMonth() });
|
|
2653
2837
|
};
|
|
2654
|
-
return /* @__PURE__ */
|
|
2655
|
-
/* @__PURE__ */
|
|
2838
|
+
return /* @__PURE__ */ jsxs13(Popover3, { open, onOpenChange: setOpen, children: [
|
|
2839
|
+
/* @__PURE__ */ jsx15(PopoverTrigger3, { asChild: true, children: /* @__PURE__ */ jsx15(
|
|
2656
2840
|
"button",
|
|
2657
2841
|
{
|
|
2658
2842
|
type: "button",
|
|
@@ -2661,10 +2845,10 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2661
2845
|
"aria-label": kind === "time" ? `Pick a time for ${label}` : `Pick a date for ${label}`,
|
|
2662
2846
|
title: kind === "time" ? "Pick a time" : "Pick a date",
|
|
2663
2847
|
className: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
2664
|
-
children: kind === "time" ? /* @__PURE__ */
|
|
2848
|
+
children: kind === "time" ? /* @__PURE__ */ jsx15(ClockGlyph, {}) : /* @__PURE__ */ jsx15(CalendarGlyph, {})
|
|
2665
2849
|
}
|
|
2666
2850
|
) }),
|
|
2667
|
-
/* @__PURE__ */
|
|
2851
|
+
/* @__PURE__ */ jsx15(
|
|
2668
2852
|
PopoverContent3,
|
|
2669
2853
|
{
|
|
2670
2854
|
sizing: "content",
|
|
@@ -2674,29 +2858,29 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2674
2858
|
"data-records-date-helper-panel": "",
|
|
2675
2859
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
2676
2860
|
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
2677
|
-
children: /* @__PURE__ */
|
|
2678
|
-
kind === "time" ? null : /* @__PURE__ */
|
|
2679
|
-
/* @__PURE__ */
|
|
2680
|
-
/* @__PURE__ */
|
|
2681
|
-
/* @__PURE__ */
|
|
2861
|
+
children: /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
|
|
2862
|
+
kind === "time" ? null : /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1", role: "grid", "aria-label": `${MONTHS[shown2.m]} ${shown2.y}`, children: [
|
|
2863
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between text-xs font-medium", children: [
|
|
2864
|
+
/* @__PURE__ */ jsx15("button", { type: "button", ...keepFocus, "aria-label": "Previous month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(-1), children: "\u2039" }),
|
|
2865
|
+
/* @__PURE__ */ jsxs13("span", { children: [
|
|
2682
2866
|
MONTHS[shown2.m],
|
|
2683
2867
|
" ",
|
|
2684
2868
|
shown2.y
|
|
2685
2869
|
] }),
|
|
2686
|
-
/* @__PURE__ */
|
|
2870
|
+
/* @__PURE__ */ jsx15("button", { type: "button", ...keepFocus, "aria-label": "Next month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(1), children: "\u203A" })
|
|
2687
2871
|
] }),
|
|
2688
|
-
/* @__PURE__ */
|
|
2689
|
-
WEEK.map((w) => /* @__PURE__ */
|
|
2872
|
+
/* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-7 gap-0.5 text-center text-[11px]", children: [
|
|
2873
|
+
WEEK.map((w) => /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: w }, w)),
|
|
2690
2874
|
cells.map((d, i) => {
|
|
2691
|
-
if (d === null) return /* @__PURE__ */
|
|
2875
|
+
if (d === null) return /* @__PURE__ */ jsx15("span", {}, `blank-${i}`);
|
|
2692
2876
|
const key = `${shown2.y}-${pad(shown2.m + 1)}-${pad(d)}`;
|
|
2693
|
-
return /* @__PURE__ */
|
|
2877
|
+
return /* @__PURE__ */ jsx15(
|
|
2694
2878
|
"button",
|
|
2695
2879
|
{
|
|
2696
2880
|
type: "button",
|
|
2697
2881
|
...keepFocus,
|
|
2698
2882
|
"data-records-date-helper-day": key,
|
|
2699
|
-
className:
|
|
2883
|
+
className: cn11(
|
|
2700
2884
|
"h-6 w-6 rounded tabular-nums hover:bg-muted",
|
|
2701
2885
|
key === held.day ? "bg-primary text-primary-foreground hover:bg-primary" : "",
|
|
2702
2886
|
key === todayKey && key !== held.day ? "ring-1 ring-ring" : ""
|
|
@@ -2709,13 +2893,13 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2709
2893
|
})
|
|
2710
2894
|
] })
|
|
2711
2895
|
] }),
|
|
2712
|
-
kind === "date" ? null : /* @__PURE__ */
|
|
2896
|
+
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(
|
|
2713
2897
|
"button",
|
|
2714
2898
|
{
|
|
2715
2899
|
type: "button",
|
|
2716
2900
|
...keepFocus,
|
|
2717
2901
|
"data-records-date-helper-time": `${pad(t.h)}:${pad(t.m)}`,
|
|
2718
|
-
className:
|
|
2902
|
+
className: cn11(
|
|
2719
2903
|
"whitespace-nowrap rounded px-2 py-0.5 text-left tabular-nums hover:bg-muted",
|
|
2720
2904
|
held.time && held.time.h === t.h && held.time.m === t.m ? "bg-primary text-primary-foreground" : ""
|
|
2721
2905
|
),
|
|
@@ -2731,8 +2915,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2731
2915
|
}
|
|
2732
2916
|
|
|
2733
2917
|
// src/choiceNudge.ts
|
|
2734
|
-
import { useEffect as useEffect9, useState as
|
|
2735
|
-
import { useOptionalRecordsClient as
|
|
2918
|
+
import { useEffect as useEffect9, useState as useState13 } from "react";
|
|
2919
|
+
import { useOptionalRecordsClient as useOptionalRecordsClient6 } from "@ai-matrx/records/react";
|
|
2736
2920
|
var asked = /* @__PURE__ */ new WeakMap();
|
|
2737
2921
|
function choiceNudgeOf(client) {
|
|
2738
2922
|
let answer = asked.get(client);
|
|
@@ -2746,8 +2930,8 @@ function choiceNudgeOf(client) {
|
|
|
2746
2930
|
return answer;
|
|
2747
2931
|
}
|
|
2748
2932
|
function useChoiceNudge(enabled = true) {
|
|
2749
|
-
const client =
|
|
2750
|
-
const [nudge, setNudge] =
|
|
2933
|
+
const client = useOptionalRecordsClient6();
|
|
2934
|
+
const [nudge, setNudge] = useState13(null);
|
|
2751
2935
|
useEffect9(() => {
|
|
2752
2936
|
if (!enabled || !client) return;
|
|
2753
2937
|
let live = true;
|
|
@@ -2820,7 +3004,7 @@ function choiceChipLookOf(field, ...words) {
|
|
|
2820
3004
|
}
|
|
2821
3005
|
|
|
2822
3006
|
// src/editors.tsx
|
|
2823
|
-
import { Fragment as Fragment4, jsx as
|
|
3007
|
+
import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2824
3008
|
var CHOICE_EDITOR_ADDS_WHAT_IS_TYPED = true;
|
|
2825
3009
|
function isChoiceAddition(value) {
|
|
2826
3010
|
return typeof value === "object" && value !== null && value.addingChoices === true;
|
|
@@ -2850,12 +3034,12 @@ function ChoiceAskButtons({
|
|
|
2850
3034
|
onCancel,
|
|
2851
3035
|
busy
|
|
2852
3036
|
}) {
|
|
2853
|
-
return /* @__PURE__ */
|
|
2854
|
-
/* @__PURE__ */
|
|
2855
|
-
/* @__PURE__ */
|
|
2856
|
-
/* @__PURE__ */
|
|
2857
|
-
keepOffered ? /* @__PURE__ */
|
|
2858
|
-
/* @__PURE__ */
|
|
3037
|
+
return /* @__PURE__ */ jsxs14("span", { "data-records-choice-ask": "", role: "group", "aria-label": choiceAskSentence(field, words), className: "flex flex-col gap-1", children: [
|
|
3038
|
+
/* @__PURE__ */ jsx16("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field, words) }),
|
|
3039
|
+
/* @__PURE__ */ jsxs14("span", { className: "flex flex-wrap items-center gap-1", children: [
|
|
3040
|
+
/* @__PURE__ */ jsx16(Button8, { type: "button", size: "sm", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onAdd, children: "Add" }),
|
|
3041
|
+
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,
|
|
3042
|
+
/* @__PURE__ */ jsx16(Button8, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onCancel, children: "Cancel" })
|
|
2859
3043
|
] })
|
|
2860
3044
|
] });
|
|
2861
3045
|
}
|
|
@@ -2938,11 +3122,11 @@ function openingText(field, value) {
|
|
|
2938
3122
|
return format ? typedText(format, value) : String(value);
|
|
2939
3123
|
}
|
|
2940
3124
|
function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCancel }) {
|
|
2941
|
-
const client =
|
|
3125
|
+
const client = useOptionalRecordsClient7();
|
|
2942
3126
|
const kind = String(editorKindFor(field));
|
|
2943
3127
|
const needsChoices = kind === "select" || kind === "multi_select";
|
|
2944
3128
|
const nudge = useChoiceNudge(needsChoices);
|
|
2945
|
-
const [choices, setChoices] =
|
|
3129
|
+
const [choices, setChoices] = useState14(null);
|
|
2946
3130
|
useEffect10(() => {
|
|
2947
3131
|
if (!needsChoices || !client) return;
|
|
2948
3132
|
let cancelled = false;
|
|
@@ -2965,7 +3149,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2965
3149
|
judged: judgeTyped(field, text, needsChoices ? choices : void 0, needsChoices ? nudge : void 0),
|
|
2966
3150
|
...value.openedAs !== void 0 ? { openedAs: value.openedAs } : {}
|
|
2967
3151
|
});
|
|
2968
|
-
const box = /* @__PURE__ */
|
|
3152
|
+
const box = /* @__PURE__ */ jsx16(
|
|
2969
3153
|
BasicInput6,
|
|
2970
3154
|
{
|
|
2971
3155
|
id,
|
|
@@ -2977,16 +3161,16 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2977
3161
|
onChange: (e) => retype(e.target.value)
|
|
2978
3162
|
}
|
|
2979
3163
|
);
|
|
2980
|
-
return /* @__PURE__ */
|
|
2981
|
-
helper && !disabled ? /* @__PURE__ */
|
|
3164
|
+
return /* @__PURE__ */ jsxs14("span", { className: "flex flex-col gap-0.5", children: [
|
|
3165
|
+
helper && !disabled ? /* @__PURE__ */ jsxs14("span", { className: "flex min-w-0 items-center gap-0.5", children: [
|
|
2982
3166
|
box,
|
|
2983
|
-
/* @__PURE__ */
|
|
3167
|
+
/* @__PURE__ */ jsx16(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field) })
|
|
2984
3168
|
] }) : box,
|
|
2985
|
-
judged === null ? /* @__PURE__ */
|
|
3169
|
+
judged === null ? /* @__PURE__ */ jsxs14("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
2986
3170
|
"Reading ",
|
|
2987
3171
|
fieldName(field),
|
|
2988
3172
|
"'s choices\u2026"
|
|
2989
|
-
] }) : "ask" in judged ? /* @__PURE__ */
|
|
3173
|
+
] }) : "ask" in judged ? /* @__PURE__ */ jsx16(
|
|
2990
3174
|
ChoiceAskButtons,
|
|
2991
3175
|
{
|
|
2992
3176
|
field,
|
|
@@ -3002,10 +3186,10 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
3002
3186
|
},
|
|
3003
3187
|
onCancel: () => onCancel?.()
|
|
3004
3188
|
}
|
|
3005
|
-
) : "refusal" in judged ? /* @__PURE__ */
|
|
3006
|
-
/* @__PURE__ */
|
|
3007
|
-
judged.cancelOnly && onCancel ? /* @__PURE__ */
|
|
3008
|
-
] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */
|
|
3189
|
+
) : "refusal" in judged ? /* @__PURE__ */ jsxs14("span", { className: "flex flex-col gap-1", children: [
|
|
3190
|
+
/* @__PURE__ */ jsx16("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: judged.refusal }),
|
|
3191
|
+
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
|
|
3192
|
+
] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ jsxs14("span", { "data-records-typed-reads-as": "", className: "text-[10px] text-muted-foreground", children: [
|
|
3009
3193
|
isChoiceAddition(judged.value) ? `Adds ${quoted(judged.value.add)} to the choices for ${fieldName(field)}. ` : null,
|
|
3010
3194
|
"Reads as",
|
|
3011
3195
|
" ",
|
|
@@ -3016,7 +3200,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
3016
3200
|
}).join(", ")
|
|
3017
3201
|
) : (() => {
|
|
3018
3202
|
const shown2 = format ?? (kind === "datetime" ? { id: carriesTimeOfDay(field, judged.value) ? "datetime" : "date" } : void 0);
|
|
3019
|
-
return shown2 ? /* @__PURE__ */
|
|
3203
|
+
return shown2 ? /* @__PURE__ */ jsx16(FormattedValue, { value: judged.value, format: shown2 }) : String(judged.value);
|
|
3020
3204
|
})()
|
|
3021
3205
|
] })
|
|
3022
3206
|
] });
|
|
@@ -3029,13 +3213,13 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3029
3213
|
const host = useRecordsUi();
|
|
3030
3214
|
const kind = editorKindFor(field);
|
|
3031
3215
|
const inputId = id ?? `field-${field.key}`;
|
|
3032
|
-
const ownDetails =
|
|
3033
|
-
if (isTypedDraft(value)) return /* @__PURE__ */
|
|
3034
|
-
if (isSignatureField(field)) return /* @__PURE__ */
|
|
3216
|
+
const ownDetails = useOptionalRecordsClient7() === null;
|
|
3217
|
+
if (isTypedDraft(value)) return /* @__PURE__ */ jsx16(TypedTextControl, { field, value, onChange, disabled, id: inputId, onCommit, onCancel });
|
|
3218
|
+
if (isSignatureField(field)) return /* @__PURE__ */ jsx16(SignaturePad, { id: inputId, value, onChange, disabled });
|
|
3035
3219
|
const newerControl = newerKindControl({ field, value, onChange, disabled, id: inputId });
|
|
3036
3220
|
if (newerControl !== void 0) return newerControl;
|
|
3037
3221
|
const format = formatForField(field);
|
|
3038
|
-
if (format && format.id === "time") return /* @__PURE__ */
|
|
3222
|
+
if (format && format.id === "time") return /* @__PURE__ */ jsx16(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
|
|
3039
3223
|
if (format && !FORMAT_BLIND_KINDS.has(String(kind))) {
|
|
3040
3224
|
const own3 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field), ownDetails });
|
|
3041
3225
|
if (own3) return own3;
|
|
@@ -3044,17 +3228,17 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3044
3228
|
case "formula":
|
|
3045
3229
|
case "lookup":
|
|
3046
3230
|
case "rollup":
|
|
3047
|
-
return /* @__PURE__ */
|
|
3231
|
+
return /* @__PURE__ */ jsxs14("div", { id: inputId, className: "rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground", children: [
|
|
3048
3232
|
value === null || value === void 0 ? "\u2014" : String(value),
|
|
3049
|
-
/* @__PURE__ */
|
|
3233
|
+
/* @__PURE__ */ jsxs14("span", { className: "ml-2 italic", children: [
|
|
3050
3234
|
fieldName(field),
|
|
3051
3235
|
" is worked out by the system, so it cannot be typed in"
|
|
3052
3236
|
] })
|
|
3053
3237
|
] });
|
|
3054
3238
|
case "json":
|
|
3055
|
-
return /* @__PURE__ */
|
|
3239
|
+
return /* @__PURE__ */ jsx16(JsonControl, { field, value, onChange, disabled, id: inputId });
|
|
3056
3240
|
case "long_text":
|
|
3057
|
-
return /* @__PURE__ */
|
|
3241
|
+
return /* @__PURE__ */ jsx16(
|
|
3058
3242
|
BasicTextarea2,
|
|
3059
3243
|
{
|
|
3060
3244
|
id: inputId,
|
|
@@ -3067,7 +3251,7 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3067
3251
|
case "number":
|
|
3068
3252
|
case "currency":
|
|
3069
3253
|
case "percent":
|
|
3070
|
-
return /* @__PURE__ */
|
|
3254
|
+
return /* @__PURE__ */ jsx16(
|
|
3071
3255
|
BasicInput6,
|
|
3072
3256
|
{
|
|
3073
3257
|
id: inputId,
|
|
@@ -3080,11 +3264,11 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3080
3264
|
}
|
|
3081
3265
|
);
|
|
3082
3266
|
case "datetime":
|
|
3083
|
-
return /* @__PURE__ */
|
|
3267
|
+
return /* @__PURE__ */ jsx16(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
|
|
3084
3268
|
case "email":
|
|
3085
3269
|
case "phone":
|
|
3086
3270
|
case "url":
|
|
3087
|
-
return /* @__PURE__ */
|
|
3271
|
+
return /* @__PURE__ */ jsx16(
|
|
3088
3272
|
BasicInput6,
|
|
3089
3273
|
{
|
|
3090
3274
|
id: inputId,
|
|
@@ -3096,24 +3280,24 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3096
3280
|
}
|
|
3097
3281
|
);
|
|
3098
3282
|
case "checkbox":
|
|
3099
|
-
return /* @__PURE__ */
|
|
3283
|
+
return /* @__PURE__ */ jsx16(CheckboxControl, { field, value, onChange, disabled, id: inputId });
|
|
3100
3284
|
case "select":
|
|
3101
3285
|
case "multi_select":
|
|
3102
|
-
return /* @__PURE__ */
|
|
3286
|
+
return /* @__PURE__ */ jsx16(OptionControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
|
|
3103
3287
|
case "member":
|
|
3104
|
-
return /* @__PURE__ */
|
|
3288
|
+
return /* @__PURE__ */ jsx16(PersonPicker, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
|
|
3105
3289
|
case "entity_reference":
|
|
3106
|
-
return /* @__PURE__ */
|
|
3290
|
+
return /* @__PURE__ */ jsx16(EntityReferenceControl, { field, value, onChange, disabled, id: inputId });
|
|
3107
3291
|
case "attachment":
|
|
3108
3292
|
if (hostTakesFiles(host)) {
|
|
3109
|
-
return /* @__PURE__ */
|
|
3293
|
+
return /* @__PURE__ */ jsx16(AttachmentControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose });
|
|
3110
3294
|
}
|
|
3111
|
-
return /* @__PURE__ */
|
|
3295
|
+
return /* @__PURE__ */ jsx16(RelationPicker, { field, value, onChange, disabled, id: inputId });
|
|
3112
3296
|
case "relation":
|
|
3113
|
-
return /* @__PURE__ */
|
|
3297
|
+
return /* @__PURE__ */ jsx16(RelationPicker, { field, value, onChange, disabled, id: inputId });
|
|
3114
3298
|
default:
|
|
3115
3299
|
if (typeof value === "boolean" || field.config?.["kind"] === "boolean") {
|
|
3116
|
-
return /* @__PURE__ */
|
|
3300
|
+
return /* @__PURE__ */ jsx16(
|
|
3117
3301
|
Checkbox,
|
|
3118
3302
|
{
|
|
3119
3303
|
id: inputId,
|
|
@@ -3123,7 +3307,7 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3123
3307
|
}
|
|
3124
3308
|
);
|
|
3125
3309
|
}
|
|
3126
|
-
return /* @__PURE__ */
|
|
3310
|
+
return /* @__PURE__ */ jsx16(
|
|
3127
3311
|
BasicInput6,
|
|
3128
3312
|
{
|
|
3129
3313
|
id: inputId,
|
|
@@ -3136,8 +3320,8 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3136
3320
|
}
|
|
3137
3321
|
}
|
|
3138
3322
|
function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
3139
|
-
const [text, setText] =
|
|
3140
|
-
const [refusal2, setRefusal] =
|
|
3323
|
+
const [text, setText] = useState14(() => openingText(field, value));
|
|
3324
|
+
const [refusal2, setRefusal] = useState14(null);
|
|
3141
3325
|
const sent = useRef9(value);
|
|
3142
3326
|
useEffect10(() => {
|
|
3143
3327
|
if (value === sent.current) return;
|
|
@@ -3157,9 +3341,9 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
|
3157
3341
|
setRefusal(judged.refusal);
|
|
3158
3342
|
}
|
|
3159
3343
|
};
|
|
3160
|
-
return /* @__PURE__ */
|
|
3161
|
-
/* @__PURE__ */
|
|
3162
|
-
/* @__PURE__ */
|
|
3344
|
+
return /* @__PURE__ */ jsxs14("span", { className: "flex flex-col gap-0.5", children: [
|
|
3345
|
+
/* @__PURE__ */ jsxs14("span", { className: "flex min-w-0 items-center gap-0.5", children: [
|
|
3346
|
+
/* @__PURE__ */ jsx16(
|
|
3163
3347
|
BasicInput6,
|
|
3164
3348
|
{
|
|
3165
3349
|
id,
|
|
@@ -3176,15 +3360,15 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
|
3176
3360
|
}
|
|
3177
3361
|
}
|
|
3178
3362
|
),
|
|
3179
|
-
helper && !disabled ? /* @__PURE__ */
|
|
3363
|
+
helper && !disabled ? /* @__PURE__ */ jsx16(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field) }) : null
|
|
3180
3364
|
] }),
|
|
3181
|
-
refusal2 ? /* @__PURE__ */
|
|
3365
|
+
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
|
|
3182
3366
|
] });
|
|
3183
3367
|
}
|
|
3184
3368
|
function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
3185
3369
|
const unanswered = value === null || value === void 0;
|
|
3186
|
-
return /* @__PURE__ */
|
|
3187
|
-
/* @__PURE__ */
|
|
3370
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
3371
|
+
/* @__PURE__ */ jsx16(
|
|
3188
3372
|
Checkbox,
|
|
3189
3373
|
{
|
|
3190
3374
|
id,
|
|
@@ -3194,9 +3378,9 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
|
3194
3378
|
onCheckedChange: (next) => onChange(next === true)
|
|
3195
3379
|
}
|
|
3196
3380
|
),
|
|
3197
|
-
unanswered ? /* @__PURE__ */
|
|
3198
|
-
/* @__PURE__ */
|
|
3199
|
-
field.required ? null : /* @__PURE__ */
|
|
3381
|
+
unanswered ? /* @__PURE__ */ jsx16("span", { className: "text-xs italic text-muted-foreground", children: "not answered yet" }) : /* @__PURE__ */ jsxs14(Fragment4, { children: [
|
|
3382
|
+
/* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground", children: value === true ? "Yes" : "No" }),
|
|
3383
|
+
field.required ? null : /* @__PURE__ */ jsx16(
|
|
3200
3384
|
Button8,
|
|
3201
3385
|
{
|
|
3202
3386
|
size: "sm",
|
|
@@ -3212,10 +3396,10 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
|
3212
3396
|
}
|
|
3213
3397
|
function JsonControl({ field, value, onChange, disabled, id }) {
|
|
3214
3398
|
const initial = value === null || value === void 0 ? "" : typeof value === "string" ? value : JSON.stringify(value, null, 2);
|
|
3215
|
-
const [text, setText] =
|
|
3216
|
-
const [broken, setBroken] =
|
|
3217
|
-
return /* @__PURE__ */
|
|
3218
|
-
/* @__PURE__ */
|
|
3399
|
+
const [text, setText] = useState14(initial);
|
|
3400
|
+
const [broken, setBroken] = useState14(null);
|
|
3401
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
|
|
3402
|
+
/* @__PURE__ */ jsx16(
|
|
3219
3403
|
BasicTextarea2,
|
|
3220
3404
|
{
|
|
3221
3405
|
id,
|
|
@@ -3249,7 +3433,7 @@ function JsonControl({ field, value, onChange, disabled, id }) {
|
|
|
3249
3433
|
),
|
|
3250
3434
|
broken ? (
|
|
3251
3435
|
// The typed text is still in the box: the notice owns the two doors out.
|
|
3252
|
-
/* @__PURE__ */
|
|
3436
|
+
/* @__PURE__ */ jsx16(
|
|
3253
3437
|
RefusalNotice,
|
|
3254
3438
|
{
|
|
3255
3439
|
error: broken,
|
|
@@ -3273,10 +3457,10 @@ function inTheStoresOrder(options) {
|
|
|
3273
3457
|
return [...options].sort((a, b) => position(a) - position(b) || made(a).localeCompare(made(b)));
|
|
3274
3458
|
}
|
|
3275
3459
|
function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose, addsChoices, initialSearch, asForm }) {
|
|
3276
|
-
const client =
|
|
3277
|
-
const [options, setOptions] =
|
|
3278
|
-
const [refusal2, setRefusal] =
|
|
3279
|
-
const [reread, setReread] =
|
|
3460
|
+
const client = useOptionalRecordsClient7();
|
|
3461
|
+
const [options, setOptions] = useState14(null);
|
|
3462
|
+
const [refusal2, setRefusal] = useState14(null);
|
|
3463
|
+
const [reread, setReread] = useState14(0);
|
|
3280
3464
|
useEffect10(() => {
|
|
3281
3465
|
if (!client) return;
|
|
3282
3466
|
let cancelled = false;
|
|
@@ -3291,11 +3475,11 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3291
3475
|
}, [client, field.id, reread]);
|
|
3292
3476
|
const handed = publicChoicesOf(field);
|
|
3293
3477
|
if (!client && handed.length > 0) {
|
|
3294
|
-
return /* @__PURE__ */
|
|
3478
|
+
return /* @__PURE__ */ jsx16(ChoiceAnswer, { field, choices: handed, value, onChange, disabled, id });
|
|
3295
3479
|
}
|
|
3296
3480
|
if (!client) {
|
|
3297
|
-
return /* @__PURE__ */
|
|
3298
|
-
/* @__PURE__ */
|
|
3481
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
|
|
3482
|
+
/* @__PURE__ */ jsx16(
|
|
3299
3483
|
BasicInput6,
|
|
3300
3484
|
{
|
|
3301
3485
|
id,
|
|
@@ -3304,15 +3488,15 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3304
3488
|
onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
|
|
3305
3489
|
}
|
|
3306
3490
|
),
|
|
3307
|
-
/* @__PURE__ */
|
|
3491
|
+
/* @__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." })
|
|
3308
3492
|
] });
|
|
3309
3493
|
}
|
|
3310
3494
|
if (refusal2)
|
|
3311
|
-
return /* @__PURE__ */
|
|
3312
|
-
if (!options) return /* @__PURE__ */
|
|
3495
|
+
return /* @__PURE__ */ jsx16("div", { id, children: /* @__PURE__ */ jsx16(RefusalLine, { error: refusal2 }) });
|
|
3496
|
+
if (!options) return /* @__PURE__ */ jsx16("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
|
|
3313
3497
|
if (asForm && options.length > 0) {
|
|
3314
3498
|
const titled = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3315
|
-
return /* @__PURE__ */
|
|
3499
|
+
return /* @__PURE__ */ jsx16(
|
|
3316
3500
|
ChoiceAnswer,
|
|
3317
3501
|
{
|
|
3318
3502
|
field,
|
|
@@ -3329,7 +3513,7 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3329
3513
|
);
|
|
3330
3514
|
}
|
|
3331
3515
|
if (CHOICE_EDITOR_ADDS_WHAT_IS_TYPED) {
|
|
3332
|
-
return /* @__PURE__ */
|
|
3516
|
+
return /* @__PURE__ */ jsx16(
|
|
3333
3517
|
OpenChoicePicker,
|
|
3334
3518
|
{
|
|
3335
3519
|
field,
|
|
@@ -3348,13 +3532,13 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3348
3532
|
);
|
|
3349
3533
|
}
|
|
3350
3534
|
if (options.length === 0) {
|
|
3351
|
-
return /* @__PURE__ */
|
|
3535
|
+
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.` });
|
|
3352
3536
|
}
|
|
3353
3537
|
const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3354
3538
|
if (field.multi) {
|
|
3355
3539
|
const chosen = options.filter((option) => choiceValuesOf(value).some((v) => isTheChosen(option, v)));
|
|
3356
3540
|
const picked = new Set(chosen.map((option) => optionKey2(option)));
|
|
3357
|
-
const toggles = /* @__PURE__ */
|
|
3541
|
+
const toggles = /* @__PURE__ */ jsx16("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ jsx16(
|
|
3358
3542
|
Button8,
|
|
3359
3543
|
{
|
|
3360
3544
|
type: "button",
|
|
@@ -3372,7 +3556,7 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3372
3556
|
option.id
|
|
3373
3557
|
)) });
|
|
3374
3558
|
if (!autoOpen) return toggles;
|
|
3375
|
-
return /* @__PURE__ */
|
|
3559
|
+
return /* @__PURE__ */ jsxs14(
|
|
3376
3560
|
Popover4,
|
|
3377
3561
|
{
|
|
3378
3562
|
defaultOpen: true,
|
|
@@ -3380,15 +3564,15 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3380
3564
|
if (!open) onClose?.();
|
|
3381
3565
|
},
|
|
3382
3566
|
children: [
|
|
3383
|
-
/* @__PURE__ */
|
|
3384
|
-
/* @__PURE__ */
|
|
3567
|
+
/* @__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(", ") }) }),
|
|
3568
|
+
/* @__PURE__ */ jsx16(PopoverContent4, { sizing: "content", className: "max-w-[20rem] p-2", align: "start", children: toggles })
|
|
3385
3569
|
]
|
|
3386
3570
|
}
|
|
3387
3571
|
);
|
|
3388
3572
|
}
|
|
3389
3573
|
const current = options.find((option) => isTheChosen(option, value));
|
|
3390
|
-
return /* @__PURE__ */
|
|
3391
|
-
|
|
3574
|
+
return /* @__PURE__ */ jsxs14(
|
|
3575
|
+
Select2,
|
|
3392
3576
|
{
|
|
3393
3577
|
value: current ? optionKey2(current) : "",
|
|
3394
3578
|
disabled: disabled ?? false,
|
|
@@ -3401,8 +3585,8 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3401
3585
|
}
|
|
3402
3586
|
} : {},
|
|
3403
3587
|
children: [
|
|
3404
|
-
/* @__PURE__ */
|
|
3405
|
-
/* @__PURE__ */
|
|
3588
|
+
/* @__PURE__ */ jsx16(SelectTrigger2, { id, size: "sm", children: /* @__PURE__ */ jsx16(SelectValue2, { placeholder: "Choose" }) }),
|
|
3589
|
+
/* @__PURE__ */ jsx16(SelectContent2, { children: options.map((option) => /* @__PURE__ */ jsx16(SelectItem2, { value: optionKey2(option), children: titleOf(option) }, option.id)) })
|
|
3406
3590
|
]
|
|
3407
3591
|
}
|
|
3408
3592
|
);
|
|
@@ -3421,18 +3605,18 @@ function OpenChoicePicker({
|
|
|
3421
3605
|
allowOther = true,
|
|
3422
3606
|
onChoicesChanged
|
|
3423
3607
|
}) {
|
|
3424
|
-
const client =
|
|
3608
|
+
const client = useOptionalRecordsClient7();
|
|
3425
3609
|
const nudge = useChoiceNudge();
|
|
3426
|
-
const [open, setOpenState] =
|
|
3610
|
+
const [open, setOpenState] = useState14(autoOpen === true);
|
|
3427
3611
|
const onCloseRef = useRef9(onClose);
|
|
3428
3612
|
onCloseRef.current = onClose;
|
|
3429
3613
|
const setOpen = useCallback4((next) => {
|
|
3430
3614
|
setOpenState(next);
|
|
3431
3615
|
if (!next) onCloseRef.current?.();
|
|
3432
3616
|
}, []);
|
|
3433
|
-
const [search, setSearch] =
|
|
3434
|
-
const [adding, setAdding] =
|
|
3435
|
-
const [addRefused, setAddRefused] =
|
|
3617
|
+
const [search, setSearch] = useState14(initialSearch ?? "");
|
|
3618
|
+
const [adding, setAdding] = useState14(false);
|
|
3619
|
+
const [addRefused, setAddRefused] = useState14(null);
|
|
3436
3620
|
const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3437
3621
|
const held = withoutAddition(value);
|
|
3438
3622
|
const current = choiceValuesOf(held.value);
|
|
@@ -3484,7 +3668,7 @@ function OpenChoicePicker({
|
|
|
3484
3668
|
});
|
|
3485
3669
|
};
|
|
3486
3670
|
const offList = q !== "" && decided.decision !== "chosen" && decided.decision !== "empty";
|
|
3487
|
-
const foot = offList && decided.decision === "ask" ? /* @__PURE__ */
|
|
3671
|
+
const foot = offList && decided.decision === "ask" ? /* @__PURE__ */ jsx16(
|
|
3488
3672
|
ChoiceAskButtons,
|
|
3489
3673
|
{
|
|
3490
3674
|
field,
|
|
@@ -3501,14 +3685,14 @@ function OpenChoicePicker({
|
|
|
3501
3685
|
}
|
|
3502
3686
|
) : null;
|
|
3503
3687
|
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;
|
|
3504
|
-
return /* @__PURE__ */
|
|
3688
|
+
return /* @__PURE__ */ jsxs14("div", { id, className: "flex flex-wrap items-center gap-1", children: [
|
|
3505
3689
|
pickedWords.map((word, i) => {
|
|
3506
3690
|
const chip = chipOf(options.find((o) => isTheChosen(o, current[i])), word);
|
|
3507
|
-
return /* @__PURE__ */
|
|
3691
|
+
return /* @__PURE__ */ jsx16(Badge3, { variant: "outline", className: cn12("text-[11px]", chip.className), "data-records-choice-chip": "", children: word }, word);
|
|
3508
3692
|
}),
|
|
3509
3693
|
disabled ? null : (
|
|
3510
3694
|
// THE ONE "PICK OR ADD" BUILDER (PickOrAdd.tsx) — the relation picker draws the same one.
|
|
3511
|
-
/* @__PURE__ */
|
|
3695
|
+
/* @__PURE__ */ jsx16(
|
|
3512
3696
|
PickOrAdd,
|
|
3513
3697
|
{
|
|
3514
3698
|
triggerLabel: `Pick for ${fieldName(field)}`,
|
|
@@ -3530,15 +3714,15 @@ function OpenChoicePicker({
|
|
|
3530
3714
|
const option = options.find((o) => o.id === optionId);
|
|
3531
3715
|
if (option) choose(optionKey2(option));
|
|
3532
3716
|
},
|
|
3533
|
-
empty: q === "" ? /* @__PURE__ */
|
|
3717
|
+
empty: q === "" ? /* @__PURE__ */ jsx16("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
|
|
3534
3718
|
add,
|
|
3535
3719
|
foot,
|
|
3536
3720
|
...offList && decided.decision === "ask" && !adding ? { onEnterWithNoMatch: addTyped } : {},
|
|
3537
|
-
footNote: addRefused ? /* @__PURE__ */
|
|
3721
|
+
footNote: addRefused ? /* @__PURE__ */ jsx16(RefusalLine, { error: addRefused }) : offList && decided.decision === "not_a_choice" ? (
|
|
3538
3722
|
// never_add on a column that takes only its choices: said, never a silent nothing.
|
|
3539
|
-
/* @__PURE__ */
|
|
3540
|
-
/* @__PURE__ */
|
|
3541
|
-
autoOpen ? /* @__PURE__ */
|
|
3723
|
+
/* @__PURE__ */ jsxs14(Fragment4, { children: [
|
|
3724
|
+
/* @__PURE__ */ jsx16("p", { "data-records-typed-refusal": "", className: "p-2 text-xs text-muted-foreground", children: notAChoiceSentence(field, [q]) }),
|
|
3725
|
+
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
|
|
3542
3726
|
] })
|
|
3543
3727
|
) : null
|
|
3544
3728
|
}
|
|
@@ -3557,9 +3741,9 @@ function RecordChip({
|
|
|
3557
3741
|
// name. So it caps at its container and ends in an ellipsis with the whole name in
|
|
3558
3742
|
// its tooltip, rather than being cut mid-word by whatever box it landed in
|
|
3559
3743
|
// (lane FIX-14, 2026-09-22).
|
|
3560
|
-
/* @__PURE__ */
|
|
3561
|
-
/* @__PURE__ */
|
|
3562
|
-
onRemove ? /* @__PURE__ */
|
|
3744
|
+
/* @__PURE__ */ jsxs14(Badge3, { variant: "secondary", className: cn12("max-w-full gap-1 text-[11px]", className), title, children: [
|
|
3745
|
+
/* @__PURE__ */ jsx16("span", { className: "min-w-0 truncate", children: title }),
|
|
3746
|
+
onRemove ? /* @__PURE__ */ jsx16("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${title}`, className: "shrink-0 opacity-60 hover:opacity-100", children: "\xD7" }) : null
|
|
3563
3747
|
] })
|
|
3564
3748
|
);
|
|
3565
3749
|
}
|
|
@@ -3571,7 +3755,8 @@ function publicChoicesOf(field) {
|
|
|
3571
3755
|
return typeof o.key === "string" && typeof o.label === "string" ? [{ key: o.key, label: o.label }] : [];
|
|
3572
3756
|
});
|
|
3573
3757
|
}
|
|
3574
|
-
var
|
|
3758
|
+
var FORM_SEARCH_AFTER = 8;
|
|
3759
|
+
var CHOICE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
3575
3760
|
function ChoiceAnswer({
|
|
3576
3761
|
field,
|
|
3577
3762
|
choices,
|
|
@@ -3581,7 +3766,7 @@ function ChoiceAnswer({
|
|
|
3581
3766
|
id,
|
|
3582
3767
|
isChosen
|
|
3583
3768
|
}) {
|
|
3584
|
-
const [search, setSearch] =
|
|
3769
|
+
const [search, setSearch] = useState14("");
|
|
3585
3770
|
const held = field.multi ? choiceValuesOf(value) : value === null || value === void 0 || value === "" ? [] : [value];
|
|
3586
3771
|
const on = (choice) => held.some((v) => isChosen ? isChosen(choice, v) : String(v) === choice.key || String(v) === choice.label);
|
|
3587
3772
|
const press = (choice) => {
|
|
@@ -3592,40 +3777,59 @@ function ChoiceAnswer({
|
|
|
3592
3777
|
const keys = choices.filter((c) => c.key === choice.key ? !on(c) : on(c)).map((c) => c.key);
|
|
3593
3778
|
onChange(keys.length === 0 ? null : keys);
|
|
3594
3779
|
};
|
|
3595
|
-
const
|
|
3780
|
+
const lettered = choices.length <= CHOICE_LETTERS.length;
|
|
3781
|
+
const option = (choice) => {
|
|
3596
3782
|
const chosen = on(choice);
|
|
3597
|
-
const
|
|
3598
|
-
return /* @__PURE__ */
|
|
3783
|
+
const letter = lettered ? CHOICE_LETTERS[choices.indexOf(choice)] : null;
|
|
3784
|
+
return /* @__PURE__ */ jsxs14(
|
|
3599
3785
|
"button",
|
|
3600
3786
|
{
|
|
3601
3787
|
type: "button",
|
|
3602
3788
|
role: field.multi ? "checkbox" : "radio",
|
|
3603
3789
|
"aria-checked": chosen,
|
|
3790
|
+
"aria-label": choice.label,
|
|
3604
3791
|
disabled,
|
|
3605
3792
|
onClick: () => press(choice),
|
|
3606
|
-
"data-records-choice-chip": "",
|
|
3607
3793
|
"data-records-choice-answer": choice.key,
|
|
3608
|
-
className:
|
|
3609
|
-
"
|
|
3610
|
-
|
|
3611
|
-
chosen ? "ring-2 ring-ring ring-offset-1" : "opacity-80 hover:opacity-100"
|
|
3794
|
+
className: cn12(
|
|
3795
|
+
"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",
|
|
3796
|
+
chosen ? "border-primary bg-primary/10" : "border-primary/30 bg-primary/[0.03] hover:bg-primary/10"
|
|
3612
3797
|
),
|
|
3613
3798
|
children: [
|
|
3614
|
-
|
|
3615
|
-
|
|
3799
|
+
letter ? /* @__PURE__ */ jsx16(
|
|
3800
|
+
"kbd",
|
|
3801
|
+
{
|
|
3802
|
+
"aria-hidden": "true",
|
|
3803
|
+
className: cn12(
|
|
3804
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border font-sans text-xs font-semibold",
|
|
3805
|
+
chosen ? "border-primary bg-primary text-primary-foreground" : "border-primary/40 text-primary"
|
|
3806
|
+
),
|
|
3807
|
+
children: letter
|
|
3808
|
+
}
|
|
3809
|
+
) : null,
|
|
3810
|
+
/* @__PURE__ */ jsx16("span", { className: "min-w-0 flex-1 break-words", children: choice.label }),
|
|
3811
|
+
chosen ? /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: "shrink-0 text-primary", children: "\u2713" }) : null
|
|
3616
3812
|
]
|
|
3617
3813
|
},
|
|
3618
3814
|
choice.key
|
|
3619
3815
|
);
|
|
3620
3816
|
};
|
|
3621
|
-
const
|
|
3622
|
-
|
|
3623
|
-
|
|
3817
|
+
const onKeyDown = (event) => {
|
|
3818
|
+
if (!lettered || disabled || event.metaKey || event.ctrlKey || event.altKey) return;
|
|
3819
|
+
if (event.target.tagName === "INPUT") return;
|
|
3820
|
+
const at = CHOICE_LETTERS.indexOf(event.key.toUpperCase());
|
|
3821
|
+
if (event.key.length !== 1 || at < 0 || at >= choices.length) return;
|
|
3822
|
+
event.preventDefault();
|
|
3823
|
+
press(choices[at]);
|
|
3824
|
+
};
|
|
3825
|
+
const group = { role: field.multi ? "group" : "radiogroup", "aria-label": fieldName(field), onKeyDown };
|
|
3826
|
+
if (choices.length <= FORM_SEARCH_AFTER) {
|
|
3827
|
+
return /* @__PURE__ */ jsx16("div", { id, className: "flex w-full flex-col gap-2", ...group, children: choices.map(option) });
|
|
3624
3828
|
}
|
|
3625
3829
|
const q = search.trim().toLowerCase();
|
|
3626
3830
|
const shown2 = q === "" ? choices : choices.filter((c) => c.label.toLowerCase().includes(q));
|
|
3627
|
-
return /* @__PURE__ */
|
|
3628
|
-
/* @__PURE__ */
|
|
3831
|
+
return /* @__PURE__ */ jsxs14("div", { id, className: "flex w-full flex-col gap-2", onKeyDown, children: [
|
|
3832
|
+
/* @__PURE__ */ jsx16(
|
|
3629
3833
|
BasicInput6,
|
|
3630
3834
|
{
|
|
3631
3835
|
value: search,
|
|
@@ -3633,12 +3837,12 @@ function ChoiceAnswer({
|
|
|
3633
3837
|
placeholder: "Search",
|
|
3634
3838
|
"aria-label": `Search \u2014 ${fieldName(field)}`,
|
|
3635
3839
|
autoComplete: "off",
|
|
3636
|
-
className: "h-11 text-base sm:h-
|
|
3840
|
+
className: "h-11 text-base sm:h-9 sm:text-sm"
|
|
3637
3841
|
}
|
|
3638
3842
|
),
|
|
3639
|
-
/* @__PURE__ */
|
|
3640
|
-
shown2.map(
|
|
3641
|
-
shown2.length === 0 ? /* @__PURE__ */
|
|
3843
|
+
/* @__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: [
|
|
3844
|
+
shown2.map(option),
|
|
3845
|
+
shown2.length === 0 ? /* @__PURE__ */ jsx16("p", { className: "text-xs text-muted-foreground", children: "No match" }) : null
|
|
3642
3846
|
] })
|
|
3643
3847
|
] });
|
|
3644
3848
|
}
|
|
@@ -3646,17 +3850,17 @@ function ChoiceAnswer({
|
|
|
3646
3850
|
// src/RecordsMount.tsx
|
|
3647
3851
|
import { useRef as useRef10 } from "react";
|
|
3648
3852
|
import { RecordsProvider } from "@ai-matrx/records/react";
|
|
3649
|
-
import { jsx as
|
|
3853
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
3650
3854
|
function personActor(userId) {
|
|
3651
3855
|
return userId ? { actor: "user", user_id: userId } : { actor: "user" };
|
|
3652
3856
|
}
|
|
3653
3857
|
|
|
3654
3858
|
// src/tablePicking.tsx
|
|
3655
|
-
import { useEffect as useEffect11, useMemo as useMemo6, useState as
|
|
3859
|
+
import { useCallback as useCallback5, useEffect as useEffect11, useMemo as useMemo6, useState as useState15 } from "react";
|
|
3656
3860
|
import { withTablePlacement } from "@ai-matrx/records";
|
|
3657
3861
|
import { useRecordsClient as useRecordsClient2, useTables } from "@ai-matrx/records/react";
|
|
3658
|
-
import { Checkbox as Checkbox2, cn as
|
|
3659
|
-
import { jsx as
|
|
3862
|
+
import { Checkbox as Checkbox2, cn as cn13 } from "@ai-matrx/design-system";
|
|
3863
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3660
3864
|
var APP_TABLE_PREFIX = "records_ui_";
|
|
3661
3865
|
function isValueSet(table) {
|
|
3662
3866
|
if (table.kept_for === "choices") return true;
|
|
@@ -3699,9 +3903,9 @@ function madeOn(stamp) {
|
|
|
3699
3903
|
}
|
|
3700
3904
|
|
|
3701
3905
|
// src/TablePickers.tsx
|
|
3702
|
-
import { Fragment as Fragment5, jsx as
|
|
3906
|
+
import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3703
3907
|
function useTablesAnywhere(dataSource) {
|
|
3704
|
-
const [state, setState] =
|
|
3908
|
+
const [state, setState] = useState16({ loading: true, error: null, rows: [] });
|
|
3705
3909
|
useEffect12(() => {
|
|
3706
3910
|
let live = true;
|
|
3707
3911
|
void Promise.resolve(dataSource.rpc("data_home_tables", {}, { schema: "custom" })).then(
|
|
@@ -3739,8 +3943,8 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
|
|
|
3739
3943
|
keywords: t.organization_name
|
|
3740
3944
|
}));
|
|
3741
3945
|
const missing = Boolean(value) && !list.loading && !list.error && !list.rows.some((t) => t.table_id === value);
|
|
3742
|
-
return /* @__PURE__ */
|
|
3743
|
-
/* @__PURE__ */
|
|
3946
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
|
|
3947
|
+
/* @__PURE__ */ jsx19(
|
|
3744
3948
|
CreatablePicker,
|
|
3745
3949
|
{
|
|
3746
3950
|
value: value || null,
|
|
@@ -3754,23 +3958,23 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
|
|
|
3754
3958
|
ariaLabel: "Table"
|
|
3755
3959
|
}
|
|
3756
3960
|
),
|
|
3757
|
-
list.error && /* @__PURE__ */
|
|
3758
|
-
missing && /* @__PURE__ */
|
|
3961
|
+
list.error && /* @__PURE__ */ jsx19(RefusalLine, { error: refusal("door", list.error, "Try again in a moment.") }),
|
|
3962
|
+
missing && /* @__PURE__ */ jsx19("p", { className: "text-[11px] text-destructive", children: "This table is archived or not shared with you." })
|
|
3759
3963
|
] });
|
|
3760
3964
|
}
|
|
3761
3965
|
function TableScope({ dataSource, userId, tableId, children, fallback = null, tables }) {
|
|
3762
3966
|
const own3 = useTablesAnywhere(dataSource);
|
|
3763
3967
|
const list = tables ?? own3;
|
|
3764
3968
|
const organizationId = list.rows.find((t) => t.table_id === tableId)?.organization_id ?? null;
|
|
3765
|
-
if (!tableId || !organizationId) return /* @__PURE__ */
|
|
3766
|
-
return /* @__PURE__ */
|
|
3969
|
+
if (!tableId || !organizationId) return /* @__PURE__ */ jsx19(Fragment5, { children: fallback });
|
|
3970
|
+
return /* @__PURE__ */ jsx19(RecordsProvider2, { config: { dataSource, actor: personActor(userId), organizationId }, children });
|
|
3767
3971
|
}
|
|
3768
3972
|
function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
3769
3973
|
const fields = useFields(tableId);
|
|
3770
3974
|
const all = useMemo7(() => fields.data ?? [], [fields.data]);
|
|
3771
3975
|
const byKey = useMemo7(() => new Map(all.map((f) => [f.key, f])), [all]);
|
|
3772
3976
|
const keys = Object.keys(value);
|
|
3773
|
-
const [adding, setAdding] =
|
|
3977
|
+
const [adding, setAdding] = useState16(false);
|
|
3774
3978
|
const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
|
|
3775
3979
|
const rename = (from, to) => {
|
|
3776
3980
|
if (from === to) return;
|
|
@@ -3783,11 +3987,11 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3783
3987
|
void _gone;
|
|
3784
3988
|
onChange(rest);
|
|
3785
3989
|
};
|
|
3786
|
-
return /* @__PURE__ */
|
|
3787
|
-
fields.error && /* @__PURE__ */
|
|
3990
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-2", children: [
|
|
3991
|
+
fields.error && /* @__PURE__ */ jsx19(RefusalLine, { error: fields.error }),
|
|
3788
3992
|
keys.map((key) => {
|
|
3789
3993
|
const field = byKey.get(key);
|
|
3790
|
-
return /* @__PURE__ */
|
|
3994
|
+
return /* @__PURE__ */ jsx19(
|
|
3791
3995
|
ColumnValueRow,
|
|
3792
3996
|
{
|
|
3793
3997
|
columnKey: key,
|
|
@@ -3803,7 +4007,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3803
4007
|
key
|
|
3804
4008
|
);
|
|
3805
4009
|
}),
|
|
3806
|
-
adding && /* @__PURE__ */
|
|
4010
|
+
adding && /* @__PURE__ */ jsx19(
|
|
3807
4011
|
ColumnValueRow,
|
|
3808
4012
|
{
|
|
3809
4013
|
columnKey: null,
|
|
@@ -3820,7 +4024,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3820
4024
|
onRemove: () => setAdding(false)
|
|
3821
4025
|
}
|
|
3822
4026
|
),
|
|
3823
|
-
!disabled && !adding && keys.length < all.length && /* @__PURE__ */
|
|
4027
|
+
!disabled && !adding && keys.length < all.length && /* @__PURE__ */ jsx19(Button9, { type: "button", variant: "outline", size: "sm", className: "self-start", onClick: () => setAdding(true), children: addLabel })
|
|
3824
4028
|
] });
|
|
3825
4029
|
}
|
|
3826
4030
|
function ColumnValueRow({
|
|
@@ -3836,9 +4040,9 @@ function ColumnValueRow({
|
|
|
3836
4040
|
}) {
|
|
3837
4041
|
const orphan = columnKey !== null && !loading && field === void 0;
|
|
3838
4042
|
const shown2 = orphan ? [{ value: columnKey, label: columnKey, hint: "Not a column" }, ...options] : options;
|
|
3839
|
-
return /* @__PURE__ */
|
|
3840
|
-
/* @__PURE__ */
|
|
3841
|
-
/* @__PURE__ */
|
|
4043
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1 rounded-md border border-border/60 p-2", children: [
|
|
4044
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
4045
|
+
/* @__PURE__ */ jsx19("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx19(
|
|
3842
4046
|
CreatablePicker,
|
|
3843
4047
|
{
|
|
3844
4048
|
value: columnKey,
|
|
@@ -3852,9 +4056,9 @@ function ColumnValueRow({
|
|
|
3852
4056
|
ariaLabel: "Column"
|
|
3853
4057
|
}
|
|
3854
4058
|
) }),
|
|
3855
|
-
!disabled && /* @__PURE__ */
|
|
4059
|
+
!disabled && /* @__PURE__ */ jsx19(Button9, { type: "button", variant: "ghost", size: "sm", "aria-label": "Remove", onClick: onRemove, children: "\u2715" })
|
|
3856
4060
|
] }),
|
|
3857
|
-
field ? /* @__PURE__ */
|
|
4061
|
+
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
|
|
3858
4062
|
] });
|
|
3859
4063
|
}
|
|
3860
4064
|
function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
@@ -3866,8 +4070,8 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
|
3866
4070
|
label: rowNameIn(table.data ?? null, row)
|
|
3867
4071
|
}));
|
|
3868
4072
|
const missing = Boolean(value) && !records.loading && !records.error && !rows.some((r) => r.id === value);
|
|
3869
|
-
return /* @__PURE__ */
|
|
3870
|
-
/* @__PURE__ */
|
|
4073
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
|
|
4074
|
+
/* @__PURE__ */ jsx19(
|
|
3871
4075
|
CreatablePicker,
|
|
3872
4076
|
{
|
|
3873
4077
|
value: value || null,
|
|
@@ -3881,7 +4085,7 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
|
3881
4085
|
ariaLabel: "Record"
|
|
3882
4086
|
}
|
|
3883
4087
|
),
|
|
3884
|
-
records.error && /* @__PURE__ */
|
|
4088
|
+
records.error && /* @__PURE__ */ jsx19(RefusalLine, { error: records.error })
|
|
3885
4089
|
] });
|
|
3886
4090
|
}
|
|
3887
4091
|
|
|
@@ -3889,8 +4093,8 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
|
3889
4093
|
import { useEffect as useEffect13, useMemo as useMemo8 } from "react";
|
|
3890
4094
|
import { isEntityReferenceConfig } from "@ai-matrx/records";
|
|
3891
4095
|
import { useFields as useFields2, useTable as useTable2 } from "@ai-matrx/records/react";
|
|
3892
|
-
import { BasicInput as BasicInput7, Button as Button10, CreatablePicker as CreatablePicker2, cn as
|
|
3893
|
-
import { jsx as
|
|
4096
|
+
import { BasicInput as BasicInput7, Button as Button10, CreatablePicker as CreatablePicker2, cn as cn14 } from "@ai-matrx/design-system";
|
|
4097
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3894
4098
|
var DATA_BINDING_SHAPES = [
|
|
3895
4099
|
{ value: "collection", label: "The whole table" },
|
|
3896
4100
|
{ value: "reference", label: "One record" },
|
|
@@ -3957,9 +4161,9 @@ function DataBindingPicker({ dataSource, userId, binding, onChange, disabled, de
|
|
|
3957
4161
|
...binding.semantic_type === "collection" && defaultRowLimit ? { limit: defaultRowLimit } : {}
|
|
3958
4162
|
});
|
|
3959
4163
|
};
|
|
3960
|
-
return /* @__PURE__ */
|
|
3961
|
-
/* @__PURE__ */
|
|
3962
|
-
/* @__PURE__ */
|
|
4164
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2", children: [
|
|
4165
|
+
/* @__PURE__ */ jsx20(TablePicker, { dataSource, value: tableId, onChange: selectTable, disabled: Boolean(disabled), tables }),
|
|
4166
|
+
/* @__PURE__ */ jsx20(TableScope, { dataSource, userId, tableId, tables, children: tableId && /* @__PURE__ */ jsx20(
|
|
3963
4167
|
BindingDetails,
|
|
3964
4168
|
{
|
|
3965
4169
|
tableId,
|
|
@@ -4023,8 +4227,8 @@ function BindingDetails({
|
|
|
4023
4227
|
const fieldOptions = fieldList.map((f) => ({ value: f.key, label: fieldName(f) }));
|
|
4024
4228
|
const template = binding.transform?.template ?? "";
|
|
4025
4229
|
const setTemplate = (next) => onChange({ ...binding, transform: { join: "\n", ...binding.transform, name: "list", template: next } });
|
|
4026
|
-
return /* @__PURE__ */
|
|
4027
|
-
/* @__PURE__ */
|
|
4230
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2", children: [
|
|
4231
|
+
/* @__PURE__ */ jsx20("div", { className: "flex flex-wrap gap-1", role: "radiogroup", "aria-label": "What to read", children: DATA_BINDING_SHAPES.map((s) => /* @__PURE__ */ jsx20(
|
|
4028
4232
|
Button10,
|
|
4029
4233
|
{
|
|
4030
4234
|
type: "button",
|
|
@@ -4038,7 +4242,7 @@ function BindingDetails({
|
|
|
4038
4242
|
},
|
|
4039
4243
|
s.value
|
|
4040
4244
|
)) }),
|
|
4041
|
-
shape !== "collection" && /* @__PURE__ */
|
|
4245
|
+
shape !== "collection" && /* @__PURE__ */ jsx20(
|
|
4042
4246
|
RecordPicker,
|
|
4043
4247
|
{
|
|
4044
4248
|
tableId,
|
|
@@ -4047,7 +4251,7 @@ function BindingDetails({
|
|
|
4047
4251
|
disabled: Boolean(disabled)
|
|
4048
4252
|
}
|
|
4049
4253
|
),
|
|
4050
|
-
shape === "value" && /* @__PURE__ */
|
|
4254
|
+
shape === "value" && /* @__PURE__ */ jsx20(
|
|
4051
4255
|
CreatablePicker2,
|
|
4052
4256
|
{
|
|
4053
4257
|
value: binding.field_key ?? null,
|
|
@@ -4061,11 +4265,11 @@ function BindingDetails({
|
|
|
4061
4265
|
ariaLabel: "Column"
|
|
4062
4266
|
}
|
|
4063
4267
|
),
|
|
4064
|
-
shape !== "value" && /* @__PURE__ */
|
|
4065
|
-
/* @__PURE__ */
|
|
4268
|
+
shape !== "value" && /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
|
|
4269
|
+
/* @__PURE__ */ jsx20(
|
|
4066
4270
|
"textarea",
|
|
4067
4271
|
{
|
|
4068
|
-
className:
|
|
4272
|
+
className: cn14(
|
|
4069
4273
|
"min-h-[3.5rem] w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs"
|
|
4070
4274
|
),
|
|
4071
4275
|
"aria-label": "Each row reads as",
|
|
@@ -4074,7 +4278,7 @@ function BindingDetails({
|
|
|
4074
4278
|
onChange: (e) => setTemplate(e.target.value)
|
|
4075
4279
|
}
|
|
4076
4280
|
),
|
|
4077
|
-
!disabled && /* @__PURE__ */
|
|
4281
|
+
!disabled && /* @__PURE__ */ jsx20("div", { className: "flex flex-wrap gap-1", children: fieldList.flatMap(bindingPlaceholdersFor).map((p) => /* @__PURE__ */ jsx20(
|
|
4078
4282
|
Button10,
|
|
4079
4283
|
{
|
|
4080
4284
|
type: "button",
|
|
@@ -4087,9 +4291,9 @@ function BindingDetails({
|
|
|
4087
4291
|
p.token
|
|
4088
4292
|
)) })
|
|
4089
4293
|
] }),
|
|
4090
|
-
shape === "collection" && /* @__PURE__ */
|
|
4294
|
+
shape === "collection" && /* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
4091
4295
|
"Up to",
|
|
4092
|
-
/* @__PURE__ */
|
|
4296
|
+
/* @__PURE__ */ jsx20(
|
|
4093
4297
|
BasicInput7,
|
|
4094
4298
|
{
|
|
4095
4299
|
type: "number",
|
|
@@ -4106,9 +4310,9 @@ function BindingDetails({
|
|
|
4106
4310
|
),
|
|
4107
4311
|
"rows"
|
|
4108
4312
|
] }),
|
|
4109
|
-
/* @__PURE__ */
|
|
4110
|
-
/* @__PURE__ */
|
|
4111
|
-
DATA_BINDING_MISSING.map((m) => /* @__PURE__ */
|
|
4313
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex flex-wrap items-center gap-1", role: "radiogroup", "aria-label": "If nothing is found", children: [
|
|
4314
|
+
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: "If nothing is found" }),
|
|
4315
|
+
DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ jsx20(
|
|
4112
4316
|
Button10,
|
|
4113
4317
|
{
|
|
4114
4318
|
type: "button",
|
|
@@ -4132,7 +4336,7 @@ import { useFields as useFields3, useRecord, useTable as useTable3 } from "@ai-m
|
|
|
4132
4336
|
// src/values.tsx
|
|
4133
4337
|
import { formatColumnValue } from "@ai-matrx/design-system/data-table";
|
|
4134
4338
|
import { formatFieldValue as formatFieldValue3 } from "@ai-matrx/design-system/field-formats";
|
|
4135
|
-
import { Badge as Badge5, cn as
|
|
4339
|
+
import { Badge as Badge5, cn as cn16 } from "@ai-matrx/design-system";
|
|
4136
4340
|
|
|
4137
4341
|
// src/enumLabels.ts
|
|
4138
4342
|
function exhaustiveValuesOf() {
|
|
@@ -4169,10 +4373,10 @@ var ABSENCE_WORD_LABEL = {
|
|
|
4169
4373
|
import { wholeValueOf } from "@ai-matrx/records/core";
|
|
4170
4374
|
|
|
4171
4375
|
// src/WholeValue.tsx
|
|
4172
|
-
import { useEffect as useEffect14, useState as
|
|
4376
|
+
import { useEffect as useEffect14, useState as useState17 } from "react";
|
|
4173
4377
|
import { wholeValueSize } from "@ai-matrx/records/core";
|
|
4174
4378
|
import { BasicTextarea as BasicTextarea3 } from "@ai-matrx/design-system";
|
|
4175
|
-
import { jsx as
|
|
4379
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4176
4380
|
var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
|
|
4177
4381
|
function wholeValueLine(pointer) {
|
|
4178
4382
|
return `Open the whole text (${wholeValueSize(pointer)})`;
|
|
@@ -4181,18 +4385,18 @@ function WholeValueCell({ words, pointer }) {
|
|
|
4181
4385
|
const host = useRecordsUi();
|
|
4182
4386
|
const href = host.hrefForFile?.({ fileId: pointer.file_id });
|
|
4183
4387
|
const line = wholeValueLine(pointer);
|
|
4184
|
-
return /* @__PURE__ */
|
|
4185
|
-
/* @__PURE__ */
|
|
4388
|
+
return /* @__PURE__ */ jsxs18("span", { className: "flex min-w-0 items-baseline gap-2", "data-whole-value-file": pointer.file_id, children: [
|
|
4389
|
+
/* @__PURE__ */ jsxs18("span", { className: "truncate", title: `The first ${pointer.shown_chars} of ${pointer.chars} characters`, children: [
|
|
4186
4390
|
words,
|
|
4187
4391
|
"\u2026"
|
|
4188
4392
|
] }),
|
|
4189
|
-
href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */
|
|
4393
|
+
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` })
|
|
4190
4394
|
] });
|
|
4191
4395
|
}
|
|
4192
4396
|
|
|
4193
4397
|
// src/ReferenceChips.tsx
|
|
4194
4398
|
import { entityRefsOf as entityRefsOf2 } from "@ai-matrx/records";
|
|
4195
|
-
import { Badge as Badge4, cn as
|
|
4399
|
+
import { Badge as Badge4, cn as cn15 } from "@ai-matrx/design-system";
|
|
4196
4400
|
|
|
4197
4401
|
// src/kindValues.ts
|
|
4198
4402
|
import { tryDecodeDirective } from "@ai-matrx/content-ir/directives";
|
|
@@ -4246,7 +4450,7 @@ function kindLabel(kind) {
|
|
|
4246
4450
|
}
|
|
4247
4451
|
|
|
4248
4452
|
// src/ReferenceChips.tsx
|
|
4249
|
-
import { jsx as
|
|
4453
|
+
import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4250
4454
|
function referencesOf(field, value, kind, labels) {
|
|
4251
4455
|
if (kind === "entity_reference") {
|
|
4252
4456
|
return entityRefsOf2(value).map((r) => ({ token: r.token, id: r.id, label: r.label }));
|
|
@@ -4267,11 +4471,11 @@ function ReferenceChip({ reference, waiting }) {
|
|
|
4267
4471
|
const host = useRecordsUi();
|
|
4268
4472
|
const words = reference.label ?? (reference.token === "record" ? waiting ?? "Loading\u2026" : WITHHELD_ENTITY_LABEL);
|
|
4269
4473
|
const drawn = host.renderReference ? host.renderReference({ ...reference, label: reference.label ?? words }) : null;
|
|
4270
|
-
return /* @__PURE__ */
|
|
4474
|
+
return /* @__PURE__ */ jsxs19(
|
|
4271
4475
|
Badge4,
|
|
4272
4476
|
{
|
|
4273
4477
|
variant: "secondary",
|
|
4274
|
-
className:
|
|
4478
|
+
className: cn15(
|
|
4275
4479
|
"max-w-full min-w-0 gap-1 px-1.5 py-0 text-[11px] font-normal",
|
|
4276
4480
|
reference.archived && "opacity-70"
|
|
4277
4481
|
),
|
|
@@ -4279,15 +4483,15 @@ function ReferenceChip({ reference, waiting }) {
|
|
|
4279
4483
|
"data-records-reference-archived": reference.archived ? "" : void 0,
|
|
4280
4484
|
title: reference.archived ? ARCHIVED_REFERENCE_TIP : words,
|
|
4281
4485
|
children: [
|
|
4282
|
-
drawn ?? /* @__PURE__ */
|
|
4283
|
-
reference.archived ? /* @__PURE__ */
|
|
4486
|
+
drawn ?? /* @__PURE__ */ jsx22("span", { className: "truncate", children: words }),
|
|
4487
|
+
reference.archived ? /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
|
|
4284
4488
|
]
|
|
4285
4489
|
}
|
|
4286
4490
|
);
|
|
4287
4491
|
}
|
|
4288
4492
|
function ReferenceChips({ refs, waiting }) {
|
|
4289
|
-
if (refs.length === 0) return /* @__PURE__ */
|
|
4290
|
-
return /* @__PURE__ */
|
|
4493
|
+
if (refs.length === 0) return /* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
4494
|
+
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}`)) });
|
|
4291
4495
|
}
|
|
4292
4496
|
function KindValueCell({
|
|
4293
4497
|
kv,
|
|
@@ -4296,18 +4500,18 @@ function KindValueCell({
|
|
|
4296
4500
|
}) {
|
|
4297
4501
|
const host = useRecordsUi();
|
|
4298
4502
|
if (host.renderKind) {
|
|
4299
|
-
return /* @__PURE__ */
|
|
4503
|
+
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 }) });
|
|
4300
4504
|
}
|
|
4301
4505
|
const named = kv.items.map(kindItemWords).filter((w) => w !== null);
|
|
4302
|
-
return /* @__PURE__ */
|
|
4506
|
+
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) }) });
|
|
4303
4507
|
}
|
|
4304
4508
|
|
|
4305
4509
|
// src/values.tsx
|
|
4306
4510
|
import { newerKindWords } from "@ai-matrx/records";
|
|
4307
|
-
import { Fragment as Fragment6, jsx as
|
|
4308
|
-
function statusMark(field, item) {
|
|
4309
|
-
const mark = statusMarkOf(field, item);
|
|
4310
|
-
return mark ? /* @__PURE__ */
|
|
4511
|
+
import { Fragment as Fragment6, jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4512
|
+
function statusMark(field, item, document2) {
|
|
4513
|
+
const mark = statusMarkOf(field, item, document2);
|
|
4514
|
+
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;
|
|
4311
4515
|
}
|
|
4312
4516
|
function envelopeFor(document2, key) {
|
|
4313
4517
|
const block = document2?._values;
|
|
@@ -4351,32 +4555,32 @@ var ABSENCE_WORDS = ABSENCE_WORD_LABEL;
|
|
|
4351
4555
|
function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
4352
4556
|
const envelope = envelopeFor(document2, field.key);
|
|
4353
4557
|
if (envelope?.absent) {
|
|
4354
|
-
return /* @__PURE__ */
|
|
4558
|
+
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) });
|
|
4355
4559
|
}
|
|
4356
4560
|
if (value === null || value === void 0 || value === "") {
|
|
4357
4561
|
const gone = unresolvedFor(document2, field.key);
|
|
4358
4562
|
if (gone) {
|
|
4359
|
-
return /* @__PURE__ */
|
|
4563
|
+
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" });
|
|
4360
4564
|
}
|
|
4361
4565
|
const computed = computedEmptyOf(field, document2);
|
|
4362
|
-
if (computed?.sentence) return /* @__PURE__ */
|
|
4363
|
-
if (computed?.words) return /* @__PURE__ */
|
|
4566
|
+
if (computed?.sentence) return /* @__PURE__ */ jsx23("span", { className: "text-xs italic text-muted-foreground", children: computed.sentence });
|
|
4567
|
+
if (computed?.words) return /* @__PURE__ */ jsx23("span", { "data-records-empty-why": computed.kind, children: computed.words });
|
|
4364
4568
|
if (computed?.why) {
|
|
4365
|
-
return /* @__PURE__ */
|
|
4569
|
+
return /* @__PURE__ */ jsx23("span", { className: "text-muted-foreground", title: computed.why, "data-records-empty-why": computed.kind, children: "\u2014" });
|
|
4366
4570
|
}
|
|
4367
|
-
return /* @__PURE__ */
|
|
4571
|
+
return /* @__PURE__ */ jsx23("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
4368
4572
|
}
|
|
4369
|
-
if (isSignatureField(field)) return /* @__PURE__ */
|
|
4573
|
+
if (isSignatureField(field)) return /* @__PURE__ */ jsx23(SignatureValue, { value, fieldKey: field.key, document: document2 });
|
|
4370
4574
|
const newer = newerKindValue(field, value);
|
|
4371
4575
|
if (newer !== void 0) return newer;
|
|
4372
4576
|
const whole = typeof value === "string" ? wholeValueOf(document2, field.key) : null;
|
|
4373
|
-
if (whole) return /* @__PURE__ */
|
|
4577
|
+
if (whole) return /* @__PURE__ */ jsx23(WholeValueCell, { words: value, pointer: whole });
|
|
4374
4578
|
const kind = editorKindFor(field);
|
|
4375
4579
|
if (kind === "relation" || kind === "entity_reference") {
|
|
4376
|
-
return /* @__PURE__ */
|
|
4580
|
+
return /* @__PURE__ */ jsx23(ReferenceChips, { refs: referencesOf(field, value, kind, labels), waiting: stillWaitingFor });
|
|
4377
4581
|
}
|
|
4378
4582
|
const kv = kind === "attachment" || kind === "member" ? null : kindValueOf(value);
|
|
4379
|
-
if (kv) return /* @__PURE__ */
|
|
4583
|
+
if (kv) return /* @__PURE__ */ jsx23(KindValueCell, { kv, where: "cell", title: field.label });
|
|
4380
4584
|
const chosen = kind === "select" || kind === "multi_select";
|
|
4381
4585
|
const chipOf = (item) => {
|
|
4382
4586
|
const look = choiceChipLookOf(field, item, scalarText(field, item, labels));
|
|
@@ -4384,17 +4588,17 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4384
4588
|
};
|
|
4385
4589
|
if (chosen) {
|
|
4386
4590
|
const items = Array.isArray(value) ? value : [value];
|
|
4387
|
-
return /* @__PURE__ */
|
|
4591
|
+
return /* @__PURE__ */ jsx23("span", { className: "flex flex-wrap gap-1", "data-records-choice-chips": "", children: items.map((item, i) => {
|
|
4388
4592
|
const chip = chipOf(item);
|
|
4389
|
-
return /* @__PURE__ */
|
|
4593
|
+
return /* @__PURE__ */ jsxs20(
|
|
4390
4594
|
Badge5,
|
|
4391
4595
|
{
|
|
4392
4596
|
variant: "outline",
|
|
4393
|
-
className:
|
|
4597
|
+
className: cn16("text-[11px]", chip.className),
|
|
4394
4598
|
"data-records-choice-chip": "",
|
|
4395
4599
|
...chip.tinted ? { "data-records-choice-tint": "" } : {},
|
|
4396
4600
|
children: [
|
|
4397
|
-
statusMark(field, item),
|
|
4601
|
+
statusMark(field, item, Array.isArray(value) ? void 0 : document2),
|
|
4398
4602
|
scalarText(field, item, labels, Array.isArray(value) ? void 0 : stillWaitingFor)
|
|
4399
4603
|
]
|
|
4400
4604
|
},
|
|
@@ -4402,13 +4606,13 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4402
4606
|
);
|
|
4403
4607
|
}) });
|
|
4404
4608
|
}
|
|
4405
|
-
if (kind === "attachment") return /* @__PURE__ */
|
|
4609
|
+
if (kind === "attachment") return /* @__PURE__ */ jsx23(AttachmentChips, { value });
|
|
4406
4610
|
if (Array.isArray(value)) {
|
|
4407
|
-
return /* @__PURE__ */
|
|
4611
|
+
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}`)) });
|
|
4408
4612
|
}
|
|
4409
4613
|
if (kind === "url" && typeof value === "string") {
|
|
4410
4614
|
const href = value.includes("://") ? value : `https://${value}`;
|
|
4411
|
-
return /* @__PURE__ */
|
|
4615
|
+
return /* @__PURE__ */ jsxs20(
|
|
4412
4616
|
"a",
|
|
4413
4617
|
{
|
|
4414
4618
|
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",
|
|
@@ -4419,14 +4623,14 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4419
4623
|
"data-records-link-chip": "",
|
|
4420
4624
|
onClick: (event) => event.stopPropagation(),
|
|
4421
4625
|
children: [
|
|
4422
|
-
/* @__PURE__ */
|
|
4423
|
-
/* @__PURE__ */
|
|
4626
|
+
/* @__PURE__ */ jsx23("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2197" }),
|
|
4627
|
+
/* @__PURE__ */ jsx23("span", { className: "truncate", children: linkChipText(value) })
|
|
4424
4628
|
]
|
|
4425
4629
|
}
|
|
4426
4630
|
);
|
|
4427
4631
|
}
|
|
4428
4632
|
if (kind === "phone" && typeof value === "string" && value.trim() !== "") {
|
|
4429
|
-
return /* @__PURE__ */
|
|
4633
|
+
return /* @__PURE__ */ jsx23(
|
|
4430
4634
|
"a",
|
|
4431
4635
|
{
|
|
4432
4636
|
className: "truncate tabular-nums text-primary underline-offset-2 hover:underline",
|
|
@@ -4439,12 +4643,12 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4439
4643
|
);
|
|
4440
4644
|
}
|
|
4441
4645
|
if (kind === "email" && typeof value === "string") {
|
|
4442
|
-
return /* @__PURE__ */
|
|
4646
|
+
return /* @__PURE__ */ jsx23("a", { className: "truncate text-primary underline-offset-2 hover:underline", href: `mailto:${value}`, children: value });
|
|
4443
4647
|
}
|
|
4444
4648
|
if (typeof value === "boolean") {
|
|
4445
|
-
return /* @__PURE__ */
|
|
4649
|
+
return /* @__PURE__ */ jsx23("span", { className: kind === "checkbox" ? "text-sm" : "", title: value ? "Yes" : "No", children: value ? "\u2713" : "\u2014" });
|
|
4446
4650
|
}
|
|
4447
|
-
return /* @__PURE__ */
|
|
4651
|
+
return /* @__PURE__ */ jsx23("span", { className: cn16("truncate", kind === "number" || kind === "currency" || kind === "percent" ? "tabular-nums" : ""), children: scalarText(field, value, labels, stillWaitingFor) });
|
|
4448
4652
|
}
|
|
4449
4653
|
function scalarText(field, value, labels, stillWaitingFor) {
|
|
4450
4654
|
if (value === null || value === void 0) return "\u2014";
|
|
@@ -4485,12 +4689,13 @@ function scalarText(field, value, labels, stillWaitingFor) {
|
|
|
4485
4689
|
}
|
|
4486
4690
|
|
|
4487
4691
|
// src/PickedSummaries.tsx
|
|
4488
|
-
import { Fragment as Fragment7, jsx as
|
|
4692
|
+
import { Fragment as Fragment7, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4489
4693
|
function TableNameText({ dataSource, tableId }) {
|
|
4490
4694
|
const tables = useTablesAnywhere(dataSource);
|
|
4491
|
-
if (!tableId) return /* @__PURE__ */
|
|
4492
|
-
if (tables.loading) return /* @__PURE__ */
|
|
4493
|
-
return /* @__PURE__ */
|
|
4695
|
+
if (!tableId) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2014" });
|
|
4696
|
+
if (tables.loading) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" });
|
|
4697
|
+
if (tables.error) return /* @__PURE__ */ jsx24(Fragment7, { children: "Couldn't load the table's name" });
|
|
4698
|
+
return /* @__PURE__ */ jsx24(Fragment7, { children: tables.rows.find((t) => t.table_id === tableId)?.table_name ?? "\u2014" });
|
|
4494
4699
|
}
|
|
4495
4700
|
function ColumnValuesText({
|
|
4496
4701
|
dataSource,
|
|
@@ -4498,26 +4703,28 @@ function ColumnValuesText({
|
|
|
4498
4703
|
tableId,
|
|
4499
4704
|
value
|
|
4500
4705
|
}) {
|
|
4501
|
-
if (!tableId) return /* @__PURE__ */
|
|
4502
|
-
return /* @__PURE__ */
|
|
4706
|
+
if (!tableId) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2014" });
|
|
4707
|
+
return /* @__PURE__ */ jsx24(TableScope, { dataSource, userId, tableId, fallback: /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" }), children: /* @__PURE__ */ jsx24(RecordLabelProvider, { children: /* @__PURE__ */ jsx24(ColumnValuesWords, { tableId, value }) }) });
|
|
4503
4708
|
}
|
|
4504
4709
|
function ColumnValuesWords({ tableId, value }) {
|
|
4505
4710
|
const fields = useFields3(tableId);
|
|
4506
4711
|
const labels = useRecordLabels(fields.data ?? void 0);
|
|
4507
|
-
if (fields.loading) return /* @__PURE__ */
|
|
4712
|
+
if (fields.loading) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" });
|
|
4713
|
+
if (fields.error) return /* @__PURE__ */ jsx24(Fragment7, { children: "Couldn't load this table's columns" });
|
|
4508
4714
|
const parts = [];
|
|
4509
4715
|
for (const [key, stored] of Object.entries(value)) {
|
|
4716
|
+
if (key.startsWith("_")) continue;
|
|
4510
4717
|
const field = (fields.data ?? []).find((f) => f.key === key);
|
|
4511
|
-
if (parts.length) parts.push(/* @__PURE__ */
|
|
4718
|
+
if (parts.length) parts.push(/* @__PURE__ */ jsx24("span", { children: ", " }, `${key}-sep`));
|
|
4512
4719
|
parts.push(
|
|
4513
|
-
/* @__PURE__ */
|
|
4720
|
+
/* @__PURE__ */ jsxs21("span", { children: [
|
|
4514
4721
|
field ? fieldName(field) : "A removed column",
|
|
4515
4722
|
" is ",
|
|
4516
4723
|
field ? renderValue(field, stored, void 0, labels) : "\u2014"
|
|
4517
4724
|
] }, key)
|
|
4518
4725
|
);
|
|
4519
4726
|
}
|
|
4520
|
-
return parts.length ? /* @__PURE__ */
|
|
4727
|
+
return parts.length ? /* @__PURE__ */ jsx24(Fragment7, { children: parts }) : /* @__PURE__ */ jsx24(Fragment7, { children: "\u2014" });
|
|
4521
4728
|
}
|
|
4522
4729
|
function RecordNameText({
|
|
4523
4730
|
dataSource,
|
|
@@ -4525,15 +4732,61 @@ function RecordNameText({
|
|
|
4525
4732
|
tableId,
|
|
4526
4733
|
recordId
|
|
4527
4734
|
}) {
|
|
4528
|
-
if (!tableId || !recordId) return /* @__PURE__ */
|
|
4529
|
-
return /* @__PURE__ */
|
|
4735
|
+
if (!tableId || !recordId) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2014" });
|
|
4736
|
+
return /* @__PURE__ */ jsx24(TableScope, { dataSource, userId, tableId, fallback: /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" }), children: /* @__PURE__ */ jsx24(RecordNameWords, { tableId, recordId }) });
|
|
4530
4737
|
}
|
|
4531
4738
|
function RecordNameWords({ tableId, recordId }) {
|
|
4532
4739
|
const table = useTable3(tableId);
|
|
4533
4740
|
const record = useRecord(recordId);
|
|
4534
|
-
if (record.loading || table.loading) return /* @__PURE__ */
|
|
4535
|
-
if (
|
|
4536
|
-
return /* @__PURE__ */
|
|
4741
|
+
if (record.loading || table.loading) return /* @__PURE__ */ jsx24(Fragment7, { children: "\u2026" });
|
|
4742
|
+
if (record.error) return /* @__PURE__ */ jsx24(Fragment7, { children: "Couldn't load this record" });
|
|
4743
|
+
if (!record.data) return /* @__PURE__ */ jsx24(Fragment7, { children: "A record you cannot open" });
|
|
4744
|
+
return /* @__PURE__ */ jsx24(Fragment7, { children: recordName(record.data.document, table.data?.title_field ?? null) });
|
|
4745
|
+
}
|
|
4746
|
+
|
|
4747
|
+
// src/HeldChangeDecision.tsx
|
|
4748
|
+
import { useEffect as useEffect15, useState as useState18 } from "react";
|
|
4749
|
+
import { RecordsProvider as RecordsProvider3, useRecordsClient as useRecordsClient3 } from "@ai-matrx/records/react";
|
|
4750
|
+
import { Button as Button11 } from "@ai-matrx/design-system";
|
|
4751
|
+
import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4752
|
+
function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, onDecided }) {
|
|
4753
|
+
return /* @__PURE__ */ jsx25(RecordsProvider3, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ jsx25(Decision, { approvalId, onDecided }) });
|
|
4754
|
+
}
|
|
4755
|
+
function Decision({ approvalId, onDecided }) {
|
|
4756
|
+
const client = useRecordsClient3();
|
|
4757
|
+
const [may, setMay] = useState18(null);
|
|
4758
|
+
const [busy, setBusy] = useState18(null);
|
|
4759
|
+
const [error, setError] = useState18(null);
|
|
4760
|
+
useEffect15(() => {
|
|
4761
|
+
let live = true;
|
|
4762
|
+
void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
|
|
4763
|
+
if (!live) return;
|
|
4764
|
+
if (res.ok) setMay(res.data);
|
|
4765
|
+
else {
|
|
4766
|
+
setMay(false);
|
|
4767
|
+
setError(res.error);
|
|
4768
|
+
}
|
|
4769
|
+
});
|
|
4770
|
+
return () => {
|
|
4771
|
+
live = false;
|
|
4772
|
+
};
|
|
4773
|
+
}, [client, approvalId]);
|
|
4774
|
+
const decide = async (approve) => {
|
|
4775
|
+
setBusy(approve ? "approve" : "refuse");
|
|
4776
|
+
setError(null);
|
|
4777
|
+
const res = await client.workApprovalDecide({ approval_id: approvalId, approve });
|
|
4778
|
+
setBusy(null);
|
|
4779
|
+
if (res.ok) onDecided(approve);
|
|
4780
|
+
else setError(res.error);
|
|
4781
|
+
};
|
|
4782
|
+
if (may === null) return /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground", children: "Checking who can decide\u2026" });
|
|
4783
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-1.5", children: [
|
|
4784
|
+
may ? /* @__PURE__ */ jsxs22("div", { className: "flex gap-2", children: [
|
|
4785
|
+
/* @__PURE__ */ jsx25(Button11, { type: "button", size: "sm", disabled: busy !== null, onClick: () => void decide(true), children: busy === "approve" ? "Approving\u2026" : "Approve" }),
|
|
4786
|
+
/* @__PURE__ */ jsx25(Button11, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void decide(false), children: busy === "refuse" ? "Refusing\u2026" : "Refuse" })
|
|
4787
|
+
] }) : !error && /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground", children: "An owner or admin of this organization decides this." }),
|
|
4788
|
+
error ? /* @__PURE__ */ jsx25(RefusalLine, { error }) : null
|
|
4789
|
+
] });
|
|
4537
4790
|
}
|
|
4538
4791
|
export {
|
|
4539
4792
|
ColumnValuesEditor,
|
|
@@ -4541,6 +4794,7 @@ export {
|
|
|
4541
4794
|
DATA_BINDING_MISSING,
|
|
4542
4795
|
DATA_BINDING_SHAPES,
|
|
4543
4796
|
DataBindingPicker,
|
|
4797
|
+
HeldChangeDecision,
|
|
4544
4798
|
RecordNameText,
|
|
4545
4799
|
RecordPicker,
|
|
4546
4800
|
TableNameText,
|