@ai-matrx/records-ui 0.93.146 → 0.95.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +142 -0
- package/dist/index.cjs +22160 -17446
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +555 -61
- package/dist/index.d.ts +555 -61
- package/dist/index.js +12610 -7849
- package/dist/index.js.map +1 -1
- package/dist/object-actions.cjs +34 -1
- package/dist/object-actions.cjs.map +1 -1
- package/dist/object-actions.d.cts +1 -1
- package/dist/object-actions.d.ts +1 -1
- package/dist/object-actions.js +34 -1
- package/dist/object-actions.js.map +1 -1
- package/dist/{objectActions-Dgdr0E4b.d.cts → objectActions-DozKWxks.d.cts} +27 -1
- package/dist/{objectActions-Dgdr0E4b.d.ts → objectActions-DozKWxks.d.ts} +27 -1
- package/dist/pickers.cjs +826 -593
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.d.cts +4 -1
- package/dist/pickers.d.ts +4 -1
- package/dist/pickers.js +714 -479
- package/dist/pickers.js.map +1 -1
- package/package.json +4 -4
package/dist/pickers.cjs
CHANGED
|
@@ -42,15 +42,15 @@ __export(pickers_exports, {
|
|
|
42
42
|
module.exports = __toCommonJS(pickers_exports);
|
|
43
43
|
|
|
44
44
|
// src/TablePickers.tsx
|
|
45
|
-
var
|
|
46
|
-
var
|
|
47
|
-
var
|
|
45
|
+
var import_react30 = require("react");
|
|
46
|
+
var import_react31 = require("@ai-matrx/records/react");
|
|
47
|
+
var import_design_system16 = require("@ai-matrx/design-system");
|
|
48
48
|
|
|
49
49
|
// src/editors.tsx
|
|
50
|
-
var
|
|
50
|
+
var import_react24 = require("react");
|
|
51
51
|
var import_records10 = require("@ai-matrx/records");
|
|
52
|
-
var
|
|
53
|
-
var
|
|
52
|
+
var import_react25 = require("@ai-matrx/records/react");
|
|
53
|
+
var import_design_system14 = require("@ai-matrx/design-system");
|
|
54
54
|
|
|
55
55
|
// src/dates.ts
|
|
56
56
|
var import_field_formats = require("@ai-matrx/design-system/field-formats");
|
|
@@ -109,7 +109,7 @@ function newerKindValue(field, value, opts = {}) {
|
|
|
109
109
|
}
|
|
110
110
|
case "created_by":
|
|
111
111
|
case "modified_by":
|
|
112
|
-
return (0, import_records.isPersonStamp)(value) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PersonStampChip, {
|
|
112
|
+
return (0, import_records.isPersonStamp)(value) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PersonStampChip, { stamp: value }) : void 0;
|
|
113
113
|
case "address":
|
|
114
114
|
return (0, import_records.isAddressValue)(value) || typeof value === "string" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AddressLink, { value }) : void 0;
|
|
115
115
|
case "barcode":
|
|
@@ -125,10 +125,12 @@ function newerKindValue(field, value, opts = {}) {
|
|
|
125
125
|
return void 0;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
function PersonStampChip({
|
|
129
|
-
const words =
|
|
130
|
-
const
|
|
131
|
-
|
|
128
|
+
function PersonStampChip({ stamp }) {
|
|
129
|
+
const words = (0, import_records.personStampText)(stamp) ?? import_records.NOT_A_MEMBER_WORDS;
|
|
130
|
+
const tier = stamp.actor ?? "user";
|
|
131
|
+
const name = tier === "user" ? stamp.name : null;
|
|
132
|
+
const initial = tier === "system" ? "\u2699" : tier === "agent" ? "\u2726" : name && name.trim() !== "" ? name.trim()[0].toUpperCase() : "?";
|
|
133
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1.5", "data-records-person-stamp": tier, children: [
|
|
132
134
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
133
135
|
"span",
|
|
134
136
|
{
|
|
@@ -137,7 +139,7 @@ function PersonStampChip({ name }) {
|
|
|
137
139
|
children: initial
|
|
138
140
|
}
|
|
139
141
|
),
|
|
140
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_design_system.cn)("truncate",
|
|
142
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_design_system.cn)("truncate", tier === "user" && !name ? "italic text-muted-foreground" : ""), children: words })
|
|
141
143
|
] });
|
|
142
144
|
}
|
|
143
145
|
function AddressLink({ value }) {
|
|
@@ -162,12 +164,13 @@ function AddressLink({ value }) {
|
|
|
162
164
|
);
|
|
163
165
|
}
|
|
164
166
|
var STATUS_GROUP_MARK = { todo: "\u25CB", in_progress: "\u25D0", done: "\u25CF" };
|
|
165
|
-
function statusMarkOf(field, value) {
|
|
167
|
+
function statusMarkOf(field, value, document2) {
|
|
166
168
|
if ((0, import_records.newerKindOf)(field) !== "status" || typeof value !== "string") return null;
|
|
167
|
-
const
|
|
169
|
+
const chosen = document2?.["_choices"]?.[field.key];
|
|
170
|
+
const key = chosen && typeof chosen === "object" && typeof chosen.key === "string" ? chosen.key : value;
|
|
171
|
+
const group = (0, import_records.statusGroupOf)(field, key);
|
|
168
172
|
return { mark: STATUS_GROUP_MARK[group], group, words: import_records.STATUS_GROUP_WORDS[group] };
|
|
169
173
|
}
|
|
170
|
-
var SAFE_HREF = /^(https?:\/\/|mailto:)/i;
|
|
171
174
|
function inline(text, key) {
|
|
172
175
|
const out = [];
|
|
173
176
|
let at = 0;
|
|
@@ -194,9 +197,9 @@ function marks(text, key) {
|
|
|
194
197
|
if (tok.startsWith("**") || tok.startsWith("__")) out.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: tok.slice(2, -2) }, k));
|
|
195
198
|
else if (tok.startsWith("[")) {
|
|
196
199
|
const link = /^\[([^\]]+)\]\(([^)\s]+)\)$/.exec(tok);
|
|
197
|
-
const href = link?.[2] ?? "";
|
|
200
|
+
const href = (0, import_records.safeLinkHref)(link?.[2] ?? "");
|
|
198
201
|
out.push(
|
|
199
|
-
|
|
202
|
+
href ? /* @__PURE__ */ (0, import_jsx_runtime.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
|
|
200
203
|
);
|
|
201
204
|
} else out.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { children: tok.slice(1, -1) }, k));
|
|
202
205
|
last = at + tok.length;
|
|
@@ -406,6 +409,59 @@ function BarcodeControl({ value, onChange, disabled, id }) {
|
|
|
406
409
|
] });
|
|
407
410
|
}
|
|
408
411
|
|
|
412
|
+
// src/choiceLooks.ts
|
|
413
|
+
var import_data_table = require("@ai-matrx/design-system/data-table");
|
|
414
|
+
function displayFormatOf(field) {
|
|
415
|
+
const raw = field.display_format;
|
|
416
|
+
if (!raw || typeof raw !== "object") return null;
|
|
417
|
+
const id = raw.id;
|
|
418
|
+
if (typeof id !== "string" || id === "") return null;
|
|
419
|
+
const options = raw.options;
|
|
420
|
+
return { id, options: options && typeof options === "object" ? options : {} };
|
|
421
|
+
}
|
|
422
|
+
function isStyleColor(v) {
|
|
423
|
+
return typeof v === "string" && import_data_table.STYLE_COLORS.includes(v);
|
|
424
|
+
}
|
|
425
|
+
function choiceLooksOf(field) {
|
|
426
|
+
const display = displayFormatOf(field);
|
|
427
|
+
const choices = display?.options["choices"];
|
|
428
|
+
if (!Array.isArray(choices)) return [];
|
|
429
|
+
const out = [];
|
|
430
|
+
for (const c of choices) {
|
|
431
|
+
if (!c || typeof c !== "object") continue;
|
|
432
|
+
const value = c.value;
|
|
433
|
+
if (typeof value !== "string" || value.trim() === "") continue;
|
|
434
|
+
const color = c.color;
|
|
435
|
+
const label = c.label;
|
|
436
|
+
out.push({
|
|
437
|
+
value: value.trim(),
|
|
438
|
+
...typeof label === "string" && label.trim() !== "" ? { label: label.trim() } : {},
|
|
439
|
+
...isStyleColor(color) ? { color } : {}
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
return out;
|
|
443
|
+
}
|
|
444
|
+
function choiceWord(value) {
|
|
445
|
+
return String(value ?? "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
446
|
+
}
|
|
447
|
+
function storedChoiceColor(field, value) {
|
|
448
|
+
if (value === null || value === void 0 || value === "") return void 0;
|
|
449
|
+
const word = choiceWord(value);
|
|
450
|
+
if (word === "") return void 0;
|
|
451
|
+
for (const look of choiceLooksOf(field)) {
|
|
452
|
+
if (!look.color) continue;
|
|
453
|
+
if (choiceWord(look.value) === word || look.label && choiceWord(look.label) === word) return look.color;
|
|
454
|
+
}
|
|
455
|
+
return void 0;
|
|
456
|
+
}
|
|
457
|
+
function choiceChipLookOf(field, ...words) {
|
|
458
|
+
for (const word of words) {
|
|
459
|
+
const color = storedChoiceColor(field, word);
|
|
460
|
+
if (color) return { className: import_data_table.CHOICE_CHIP_CLASS[color], color };
|
|
461
|
+
}
|
|
462
|
+
return { className: import_data_table.NEUTRAL_CHIP_CLASS, color: null };
|
|
463
|
+
}
|
|
464
|
+
|
|
409
465
|
// src/parity.ts
|
|
410
466
|
var import_records2 = require("@ai-matrx/records");
|
|
411
467
|
var import_text_case = require("@ai-matrx/kit/text-case");
|
|
@@ -630,7 +686,12 @@ var TITLE = {
|
|
|
630
686
|
already_exists: "That already exists",
|
|
631
687
|
not_supported: "That cannot be done here",
|
|
632
688
|
store_limit: "This has got as big as it can",
|
|
633
|
-
|
|
689
|
+
// 🚨 NOT "THE SWITCH IS OFF" (lane 7 W1 fix round 1). PGRST202 / PGRST205 land here, and the
|
|
690
|
+
// commonest cause is a door this screen asks for that the database it talks to does not serve
|
|
691
|
+
// YET — a release in flight. Telling the person her organization has its store switched off was
|
|
692
|
+
// false (the switch is answered by its own door, `platform.unified_data_store_on`). Honest:
|
|
693
|
+
// nothing happened, and it is ours, and it passes.
|
|
694
|
+
store_not_served: "This isn't available right now",
|
|
634
695
|
unreachable: "We could not reach your data",
|
|
635
696
|
needs_approval: "This is waiting on someone's approval",
|
|
636
697
|
stale_read: "Your view of this is a moment behind",
|
|
@@ -648,7 +709,7 @@ var REMEDY = {
|
|
|
648
709
|
already_exists: "Use a different name.",
|
|
649
710
|
not_supported: "There is another way to do this \u2014 ask, and we will point you at it.",
|
|
650
711
|
store_limit: "Split it up, or ask us to raise the ceiling for your organization.",
|
|
651
|
-
store_not_served: "
|
|
712
|
+
store_not_served: "Nothing was changed. Try again in a few minutes.",
|
|
652
713
|
// 🚨 NOTHING WAS WRITTEN AND NOTHING WAS REFUSED (lane TAILS-6). The call
|
|
653
714
|
// never arrived, so "try again" is the honest instruction rather than a
|
|
654
715
|
// consolation — and saying nothing changed is the half a person actually
|
|
@@ -1147,8 +1208,8 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
|
|
|
1147
1208
|
}
|
|
1148
1209
|
|
|
1149
1210
|
// src/gridAttachments.tsx
|
|
1150
|
-
var
|
|
1151
|
-
var
|
|
1211
|
+
var import_react12 = require("react");
|
|
1212
|
+
var import_react13 = require("@ai-matrx/records/react");
|
|
1152
1213
|
var import_design_system7 = require("@ai-matrx/design-system");
|
|
1153
1214
|
|
|
1154
1215
|
// src/host.tsx
|
|
@@ -1226,14 +1287,15 @@ function useRecordsUi() {
|
|
|
1226
1287
|
}
|
|
1227
1288
|
|
|
1228
1289
|
// src/labels.tsx
|
|
1229
|
-
var
|
|
1230
|
-
var
|
|
1290
|
+
var import_react9 = require("react");
|
|
1291
|
+
var import_react10 = require("@ai-matrx/records/react");
|
|
1231
1292
|
var import_records5 = require("@ai-matrx/records");
|
|
1232
1293
|
var import_uuid2 = require("@ai-matrx/kit/uuid");
|
|
1233
1294
|
|
|
1234
1295
|
// src/signature.tsx
|
|
1235
1296
|
var import_react7 = require("react");
|
|
1236
1297
|
var import_design_system5 = require("@ai-matrx/design-system");
|
|
1298
|
+
var import_react8 = require("@ai-matrx/records/react");
|
|
1237
1299
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1238
1300
|
var DRAWN = /^data:image\/(png|jpeg);base64,[A-Za-z0-9+/=]{64,}$/;
|
|
1239
1301
|
function drawnSignatureOf(value) {
|
|
@@ -1244,18 +1306,105 @@ function signatureWords(value) {
|
|
|
1244
1306
|
if (value === null || value === void 0 || value === "") return null;
|
|
1245
1307
|
return drawnSignatureOf(value) ? SIGNED_WORD : String(value);
|
|
1246
1308
|
}
|
|
1247
|
-
function
|
|
1309
|
+
function signatureFileOf(source) {
|
|
1310
|
+
if (!source || typeof source !== "object") return null;
|
|
1311
|
+
const src = source;
|
|
1312
|
+
const id = src["signature_file_id"];
|
|
1313
|
+
return src["kind"] === "signature" && typeof id === "string" && id !== "" ? id : null;
|
|
1314
|
+
}
|
|
1315
|
+
function signatureFileIn(document2, key) {
|
|
1316
|
+
const values = document2?.["_values"];
|
|
1317
|
+
const src = values?.[key]?.src;
|
|
1318
|
+
if (typeof src === "string") {
|
|
1319
|
+
const sources = document2?.["_sources"];
|
|
1320
|
+
return signatureFileOf(sources?.[src]);
|
|
1321
|
+
}
|
|
1322
|
+
return signatureFileOf(src);
|
|
1323
|
+
}
|
|
1324
|
+
var SOURCES = /* @__PURE__ */ new WeakMap();
|
|
1325
|
+
var FILES = /* @__PURE__ */ new WeakMap();
|
|
1326
|
+
function signatureFilesOf(client, recordId) {
|
|
1327
|
+
let held = SOURCES.get(client);
|
|
1328
|
+
if (!held) SOURCES.set(client, held = /* @__PURE__ */ new Map());
|
|
1329
|
+
let asked2 = held.get(recordId);
|
|
1330
|
+
if (!asked2) {
|
|
1331
|
+
asked2 = client.recordValuesVersioned({ record_id: recordId }).then((answered) => {
|
|
1332
|
+
if (!answered.ok) return {};
|
|
1333
|
+
return Object.fromEntries(answered.data.map((v) => [v.field_key, signatureFileOf(v.source)]));
|
|
1334
|
+
});
|
|
1335
|
+
held.set(recordId, asked2);
|
|
1336
|
+
}
|
|
1337
|
+
return asked2;
|
|
1338
|
+
}
|
|
1339
|
+
function drawingOf(client, fileId) {
|
|
1340
|
+
let held = FILES.get(client);
|
|
1341
|
+
if (!held) FILES.set(client, held = /* @__PURE__ */ new Map());
|
|
1342
|
+
let asked2 = held.get(fileId);
|
|
1343
|
+
if (!asked2) {
|
|
1344
|
+
asked2 = client.recordRead({ record_id: fileId }).then((answered) => {
|
|
1345
|
+
if (!answered.ok) return { src: null, hostFileId: null };
|
|
1346
|
+
const doc = answered.data.document ?? {};
|
|
1347
|
+
const content = drawnSignatureOf(doc["content"]);
|
|
1348
|
+
const hostFileId = typeof doc["file_id"] === "string" && doc["file_id"] !== "" ? doc["file_id"] : null;
|
|
1349
|
+
return { src: content, hostFileId };
|
|
1350
|
+
});
|
|
1351
|
+
held.set(fileId, asked2);
|
|
1352
|
+
}
|
|
1353
|
+
return asked2;
|
|
1354
|
+
}
|
|
1355
|
+
function DrawnImage({ src, inCell }) {
|
|
1356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1357
|
+
"img",
|
|
1358
|
+
{
|
|
1359
|
+
src,
|
|
1360
|
+
alt: SIGNED_WORD,
|
|
1361
|
+
"data-records-signature": "",
|
|
1362
|
+
className: (0, import_design_system5.cn)("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
|
|
1363
|
+
}
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
function SignatureDrawing({
|
|
1367
|
+
recordId,
|
|
1368
|
+
fieldKey,
|
|
1369
|
+
fileId: knownFile,
|
|
1370
|
+
value,
|
|
1371
|
+
inCell
|
|
1372
|
+
}) {
|
|
1373
|
+
const client = (0, import_react8.useOptionalRecordsClient)();
|
|
1374
|
+
const host = useRecordsUi();
|
|
1375
|
+
const [drawing, setDrawing] = (0, import_react7.useState)(null);
|
|
1376
|
+
(0, import_react7.useEffect)(() => {
|
|
1377
|
+
let cancelled = false;
|
|
1378
|
+
setDrawing(null);
|
|
1379
|
+
if (!client) return;
|
|
1380
|
+
void (async () => {
|
|
1381
|
+
const fileId = knownFile ?? (recordId && fieldKey ? (await signatureFilesOf(client, recordId))[fieldKey] ?? null : null);
|
|
1382
|
+
if (!fileId || cancelled) return;
|
|
1383
|
+
const read = await drawingOf(client, fileId);
|
|
1384
|
+
if (!cancelled) setDrawing(read);
|
|
1385
|
+
})();
|
|
1386
|
+
return () => {
|
|
1387
|
+
cancelled = true;
|
|
1388
|
+
};
|
|
1389
|
+
}, [client, recordId, fieldKey, knownFile]);
|
|
1390
|
+
if (drawing?.src) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DrawnImage, { src: drawing.src, inCell });
|
|
1391
|
+
if (drawing?.hostFileId && host.fileImage) {
|
|
1392
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: (0, import_design_system5.cn)("inline-block max-w-[12rem] dark:invert", inCell ? "h-7" : "h-12"), "data-records-signature": "", children: host.fileImage({ fileId: drawing.hostFileId, alt: SIGNED_WORD }) });
|
|
1393
|
+
}
|
|
1394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-serif italic", children: String(value) });
|
|
1395
|
+
}
|
|
1396
|
+
function SignatureValue({
|
|
1397
|
+
value,
|
|
1398
|
+
inCell,
|
|
1399
|
+
recordId,
|
|
1400
|
+
fieldKey,
|
|
1401
|
+
document: document2
|
|
1402
|
+
}) {
|
|
1248
1403
|
const drawn = drawnSignatureOf(value);
|
|
1249
|
-
if (drawn) {
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
src: drawn,
|
|
1254
|
-
alt: SIGNED_WORD,
|
|
1255
|
-
"data-records-signature": "",
|
|
1256
|
-
className: (0, import_design_system5.cn)("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
|
|
1257
|
-
}
|
|
1258
|
-
);
|
|
1404
|
+
if (drawn) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DrawnImage, { src: drawn, inCell });
|
|
1405
|
+
const fileId = fieldKey ? signatureFileIn(document2, fieldKey) : null;
|
|
1406
|
+
if (value === SIGNED_WORD && (fileId || recordId && fieldKey)) {
|
|
1407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SignatureDrawing, { recordId: recordId ?? null, fieldKey: fieldKey ?? null, fileId, value, inCell });
|
|
1259
1408
|
}
|
|
1260
1409
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-serif italic", children: String(value) });
|
|
1261
1410
|
}
|
|
@@ -1415,7 +1564,7 @@ function encodeAt(canvas, type, maxWidth, quality) {
|
|
|
1415
1564
|
|
|
1416
1565
|
// src/labels.tsx
|
|
1417
1566
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1418
|
-
var LabelContext = (0,
|
|
1567
|
+
var LabelContext = (0, import_react9.createContext)({
|
|
1419
1568
|
// With no provider the resolver is ABSENT, not silently empty: a caller gets
|
|
1420
1569
|
// null and says "Loading…" forever, which is visible. The mount always
|
|
1421
1570
|
// provides one, so this is only ever a bare unit test.
|
|
@@ -1443,15 +1592,15 @@ function pointsAtRecords(field) {
|
|
|
1443
1592
|
return field.type === "list" || field.type === "relation";
|
|
1444
1593
|
}
|
|
1445
1594
|
function RecordLabelProvider({ children }) {
|
|
1446
|
-
const client = (0,
|
|
1447
|
-
const [names, setNames] = (0,
|
|
1448
|
-
const [archivedRefs, setArchivedRefs] = (0,
|
|
1449
|
-
const [settled, setSettled] = (0,
|
|
1450
|
-
const [waitingLines, setWaitingLines] = (0,
|
|
1451
|
-
const asked2 = (0,
|
|
1452
|
-
const chased = (0,
|
|
1453
|
-
const timers = (0,
|
|
1454
|
-
const startWaitClock = (0,
|
|
1595
|
+
const client = (0, import_react10.useRecordsClient)();
|
|
1596
|
+
const [names, setNames] = (0, import_react9.useState)({});
|
|
1597
|
+
const [archivedRefs, setArchivedRefs] = (0, import_react9.useState)({});
|
|
1598
|
+
const [settled, setSettled] = (0, import_react9.useState)({});
|
|
1599
|
+
const [waitingLines, setWaitingLines] = (0, import_react9.useState)({});
|
|
1600
|
+
const asked2 = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
|
|
1601
|
+
const chased = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
|
|
1602
|
+
const timers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
1603
|
+
const startWaitClock = (0, import_react9.useCallback)((field, target) => {
|
|
1455
1604
|
if (timers.current.has(field.id)) return;
|
|
1456
1605
|
timers.current.set(
|
|
1457
1606
|
field.id,
|
|
@@ -1463,7 +1612,7 @@ function RecordLabelProvider({ children }) {
|
|
|
1463
1612
|
}, SAY_WHAT_YOU_ARE_WAITING_FOR_AFTER_MS)
|
|
1464
1613
|
);
|
|
1465
1614
|
}, []);
|
|
1466
|
-
const stopWaitClock = (0,
|
|
1615
|
+
const stopWaitClock = (0, import_react9.useCallback)((fieldId) => {
|
|
1467
1616
|
const timer = timers.current.get(fieldId);
|
|
1468
1617
|
if (timer) {
|
|
1469
1618
|
clearTimeout(timer);
|
|
@@ -1476,14 +1625,14 @@ function RecordLabelProvider({ children }) {
|
|
|
1476
1625
|
return next;
|
|
1477
1626
|
});
|
|
1478
1627
|
}, []);
|
|
1479
|
-
(0,
|
|
1628
|
+
(0, import_react9.useEffect)(
|
|
1480
1629
|
() => () => {
|
|
1481
1630
|
for (const timer of timers.current.values()) clearTimeout(timer);
|
|
1482
1631
|
timers.current.clear();
|
|
1483
1632
|
},
|
|
1484
1633
|
[]
|
|
1485
1634
|
);
|
|
1486
|
-
const want = (0,
|
|
1635
|
+
const want = (0, import_react9.useCallback)(
|
|
1487
1636
|
(field) => {
|
|
1488
1637
|
if (!pointsAtRecords(field)) return;
|
|
1489
1638
|
if (asked2.current.has(field.id)) return;
|
|
@@ -1518,9 +1667,9 @@ function RecordLabelProvider({ children }) {
|
|
|
1518
1667
|
},
|
|
1519
1668
|
[client, startWaitClock, stopWaitClock]
|
|
1520
1669
|
);
|
|
1521
|
-
const queued = (0,
|
|
1522
|
-
const flushing = (0,
|
|
1523
|
-
const flush = (0,
|
|
1670
|
+
const queued = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
1671
|
+
const flushing = (0, import_react9.useRef)(null);
|
|
1672
|
+
const flush = (0, import_react9.useCallback)(() => {
|
|
1524
1673
|
flushing.current = null;
|
|
1525
1674
|
const batch = [...queued.current.values()];
|
|
1526
1675
|
queued.current.clear();
|
|
@@ -1547,7 +1696,7 @@ function RecordLabelProvider({ children }) {
|
|
|
1547
1696
|
for (const { field } of batch) stopWaitClock(field.id);
|
|
1548
1697
|
})();
|
|
1549
1698
|
}, [client, stopWaitClock]);
|
|
1550
|
-
const chase = (0,
|
|
1699
|
+
const chase = (0, import_react9.useCallback)(
|
|
1551
1700
|
(field, id) => {
|
|
1552
1701
|
const key = `${field.id}:${id}`;
|
|
1553
1702
|
if (chased.current.has(key)) return;
|
|
@@ -1560,14 +1709,14 @@ function RecordLabelProvider({ children }) {
|
|
|
1560
1709
|
},
|
|
1561
1710
|
[flush, startWaitClock]
|
|
1562
1711
|
);
|
|
1563
|
-
(0,
|
|
1712
|
+
(0, import_react9.useEffect)(
|
|
1564
1713
|
() => () => {
|
|
1565
1714
|
if (flushing.current !== null) clearTimeout(flushing.current);
|
|
1566
1715
|
},
|
|
1567
1716
|
[]
|
|
1568
1717
|
);
|
|
1569
|
-
const rereadFor = (0,
|
|
1570
|
-
const lookupWords = (0,
|
|
1718
|
+
const rereadFor = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
|
|
1719
|
+
const lookupWords = (0, import_react9.useCallback)(
|
|
1571
1720
|
(field, id) => {
|
|
1572
1721
|
if (field.type === "list" && !isId(id)) {
|
|
1573
1722
|
const named = names[choiceKeyName(field.id, id)];
|
|
@@ -1587,7 +1736,7 @@ function RecordLabelProvider({ children }) {
|
|
|
1587
1736
|
},
|
|
1588
1737
|
[names, settled, chase, want]
|
|
1589
1738
|
);
|
|
1590
|
-
const lookup = (0,
|
|
1739
|
+
const lookup = (0, import_react9.useMemo)(
|
|
1591
1740
|
() => {
|
|
1592
1741
|
const answer = ((field, id) => lookupWords(field, id));
|
|
1593
1742
|
answer.archived = (field, id) => archivedRefs[`${field.id}:${id}`] === true;
|
|
@@ -1595,20 +1744,20 @@ function RecordLabelProvider({ children }) {
|
|
|
1595
1744
|
},
|
|
1596
1745
|
[lookupWords, archivedRefs]
|
|
1597
1746
|
);
|
|
1598
|
-
const waiting = (0,
|
|
1599
|
-
const value = (0,
|
|
1747
|
+
const waiting = (0, import_react9.useCallback)((field) => waitingLines[field.id] ?? null, [waitingLines]);
|
|
1748
|
+
const value = (0, import_react9.useMemo)(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
|
|
1600
1749
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LabelContext.Provider, { value, children });
|
|
1601
1750
|
}
|
|
1602
1751
|
function useRecordLabels(fields) {
|
|
1603
|
-
const { lookup, want } = (0,
|
|
1604
|
-
(0,
|
|
1752
|
+
const { lookup, want } = (0, import_react9.useContext)(LabelContext);
|
|
1753
|
+
(0, import_react9.useEffect)(() => {
|
|
1605
1754
|
for (const field of fields ?? []) want(field);
|
|
1606
1755
|
}, [fields, want]);
|
|
1607
1756
|
return lookup;
|
|
1608
1757
|
}
|
|
1609
1758
|
|
|
1610
1759
|
// src/FilePicker.tsx
|
|
1611
|
-
var
|
|
1760
|
+
var import_react11 = require("react");
|
|
1612
1761
|
var import_design_system6 = require("@ai-matrx/design-system");
|
|
1613
1762
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1614
1763
|
function FilePicker({
|
|
@@ -1622,17 +1771,17 @@ function FilePicker({
|
|
|
1622
1771
|
chosenName,
|
|
1623
1772
|
className
|
|
1624
1773
|
}) {
|
|
1625
|
-
const inputId = (0,
|
|
1626
|
-
const input = (0,
|
|
1627
|
-
const [over, setOver] = (0,
|
|
1628
|
-
const take = (0,
|
|
1774
|
+
const inputId = (0, import_react11.useId)();
|
|
1775
|
+
const input = (0, import_react11.useRef)(null);
|
|
1776
|
+
const [over, setOver] = (0, import_react11.useState)(false);
|
|
1777
|
+
const take = (0, import_react11.useCallback)(
|
|
1629
1778
|
(file) => {
|
|
1630
1779
|
if (!file || disabled) return;
|
|
1631
1780
|
onFile(file);
|
|
1632
1781
|
},
|
|
1633
1782
|
[disabled, onFile]
|
|
1634
1783
|
);
|
|
1635
|
-
const onDrop = (0,
|
|
1784
|
+
const onDrop = (0, import_react11.useCallback)(
|
|
1636
1785
|
(e) => {
|
|
1637
1786
|
e.preventDefault();
|
|
1638
1787
|
setOver(false);
|
|
@@ -1725,10 +1874,10 @@ function rememberHostFileIds(ids) {
|
|
|
1725
1874
|
var FILE_CHIP_UNREAD = "File";
|
|
1726
1875
|
var FILE_CHIP_NO_PAGE = "This screen has no way to open files yet.";
|
|
1727
1876
|
function AttachmentChip({ id, onRemove }) {
|
|
1728
|
-
const client = (0,
|
|
1877
|
+
const client = (0, import_react13.useOptionalRecordsClient)();
|
|
1729
1878
|
const host = useRecordsUi();
|
|
1730
|
-
const [read, setRead] = (0,
|
|
1731
|
-
(0,
|
|
1879
|
+
const [read, setRead] = (0, import_react12.useState)(null);
|
|
1880
|
+
(0, import_react12.useEffect)(() => {
|
|
1732
1881
|
let cancelled = false;
|
|
1733
1882
|
if (!client) {
|
|
1734
1883
|
setRead({ name: null, fileId: null, why: null });
|
|
@@ -1803,9 +1952,9 @@ function AttachmentControl({
|
|
|
1803
1952
|
onClose
|
|
1804
1953
|
}) {
|
|
1805
1954
|
const host = useRecordsUi();
|
|
1806
|
-
const [busy, setBusy] = (0,
|
|
1807
|
-
const [why, setWhy] = (0,
|
|
1808
|
-
const latest = (0,
|
|
1955
|
+
const [busy, setBusy] = (0, import_react12.useState)(false);
|
|
1956
|
+
const [why, setWhy] = (0, import_react12.useState)(null);
|
|
1957
|
+
const latest = (0, import_react12.useRef)(value);
|
|
1809
1958
|
latest.current = value;
|
|
1810
1959
|
const multiple = Boolean(field.multi);
|
|
1811
1960
|
const pick = async () => {
|
|
@@ -1826,8 +1975,8 @@ function AttachmentControl({
|
|
|
1826
1975
|
setBusy(false);
|
|
1827
1976
|
onClose?.();
|
|
1828
1977
|
};
|
|
1829
|
-
const opened = (0,
|
|
1830
|
-
(0,
|
|
1978
|
+
const opened = (0, import_react12.useRef)(false);
|
|
1979
|
+
(0, import_react12.useEffect)(() => {
|
|
1831
1980
|
if (!autoOpen || opened.current || !host.pickFiles) return;
|
|
1832
1981
|
opened.current = true;
|
|
1833
1982
|
void pick();
|
|
@@ -1870,11 +2019,99 @@ function AttachmentControl({
|
|
|
1870
2019
|
}
|
|
1871
2020
|
|
|
1872
2021
|
// src/EntityReferenceControl.tsx
|
|
1873
|
-
var
|
|
2022
|
+
var import_react15 = require("react");
|
|
1874
2023
|
var import_records6 = require("@ai-matrx/records");
|
|
1875
|
-
var
|
|
2024
|
+
var import_react16 = require("@ai-matrx/records/react");
|
|
2025
|
+
var import_design_system9 = require("@ai-matrx/design-system");
|
|
2026
|
+
|
|
2027
|
+
// src/PickOne.tsx
|
|
2028
|
+
var import_react14 = require("react");
|
|
1876
2029
|
var import_design_system8 = require("@ai-matrx/design-system");
|
|
1877
2030
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2031
|
+
var PICK_ONE_SEARCH_AFTER = 7;
|
|
2032
|
+
var EMPTY = "__records_pick_one_empty__";
|
|
2033
|
+
var inner = (v) => v === "" ? EMPTY : v;
|
|
2034
|
+
var outer = (v) => v === EMPTY ? "" : v;
|
|
2035
|
+
function PickOne({
|
|
2036
|
+
value,
|
|
2037
|
+
onChange,
|
|
2038
|
+
options,
|
|
2039
|
+
label,
|
|
2040
|
+
placeholder,
|
|
2041
|
+
id,
|
|
2042
|
+
className,
|
|
2043
|
+
disabled,
|
|
2044
|
+
attrs
|
|
2045
|
+
}) {
|
|
2046
|
+
const [open, setOpen] = (0, import_react14.useState)(false);
|
|
2047
|
+
const [search, setSearch] = (0, import_react14.useState)("");
|
|
2048
|
+
const current = options.find((o) => o.value === value);
|
|
2049
|
+
if (options.length > PICK_ONE_SEARCH_AFTER) {
|
|
2050
|
+
const q = search.trim().toLowerCase();
|
|
2051
|
+
const shown2 = q === "" ? options : options.filter((o) => o.label.toLowerCase().includes(q));
|
|
2052
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: (0, import_design_system8.cn)("inline-flex min-w-0", className), "data-records-pick-one": "search", "data-pick-value": value, ...attrs ?? {}, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2053
|
+
PickOrAdd,
|
|
2054
|
+
{
|
|
2055
|
+
triggerLabel: label,
|
|
2056
|
+
triggerText: current?.label ?? placeholder ?? "",
|
|
2057
|
+
triggerId: id,
|
|
2058
|
+
open: open && !disabled,
|
|
2059
|
+
onOpenChange: (next) => {
|
|
2060
|
+
setOpen(next);
|
|
2061
|
+
if (!next) setSearch("");
|
|
2062
|
+
},
|
|
2063
|
+
search,
|
|
2064
|
+
onSearch: setSearch,
|
|
2065
|
+
items: shown2.map((o) => ({
|
|
2066
|
+
id: inner(o.value),
|
|
2067
|
+
label: o.label,
|
|
2068
|
+
detail: o.group,
|
|
2069
|
+
picked: o.value === value,
|
|
2070
|
+
attrs: { "data-pick-value": o.value, ...o.group ? { "data-pick-group": o.group } : {} }
|
|
2071
|
+
})),
|
|
2072
|
+
onPick: (picked) => {
|
|
2073
|
+
onChange(outer(picked));
|
|
2074
|
+
setOpen(false);
|
|
2075
|
+
setSearch("");
|
|
2076
|
+
},
|
|
2077
|
+
empty: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "No match" })
|
|
2078
|
+
}
|
|
2079
|
+
) });
|
|
2080
|
+
}
|
|
2081
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_design_system8.Select, { value: current ? inner(current.value) : "", onValueChange: (v) => onChange(outer(v)), disabled: disabled ?? false, children: [
|
|
2082
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2083
|
+
import_design_system8.SelectTrigger,
|
|
2084
|
+
{
|
|
2085
|
+
id,
|
|
2086
|
+
size: "sm",
|
|
2087
|
+
"aria-label": label,
|
|
2088
|
+
className: (0, import_design_system8.cn)("h-7 w-auto min-w-[7rem] text-xs", className),
|
|
2089
|
+
"data-records-pick-one": "list",
|
|
2090
|
+
"data-pick-value": value,
|
|
2091
|
+
...attrs ?? {},
|
|
2092
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectValue, { placeholder })
|
|
2093
|
+
}
|
|
2094
|
+
),
|
|
2095
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectContent, { children: groupsOf(options).map(
|
|
2096
|
+
([group, items]) => group ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_design_system8.SelectGroup, { children: [
|
|
2097
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectLabel, { children: group }),
|
|
2098
|
+
items.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectItem, { value: inner(o.value), "data-pick-value": o.value, "data-pick-group": group, children: o.label }, inner(o.value)))
|
|
2099
|
+
] }, group) : items.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectItem, { value: inner(o.value), "data-pick-value": o.value, children: o.label }, inner(o.value)))
|
|
2100
|
+
) })
|
|
2101
|
+
] });
|
|
2102
|
+
}
|
|
2103
|
+
function groupsOf(options) {
|
|
2104
|
+
const out = [];
|
|
2105
|
+
for (const o of options) {
|
|
2106
|
+
const last = out[out.length - 1];
|
|
2107
|
+
if (last && last[0] === o.group) last[1].push(o);
|
|
2108
|
+
else out.push([o.group, [o]]);
|
|
2109
|
+
}
|
|
2110
|
+
return out;
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
// src/EntityReferenceControl.tsx
|
|
2114
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1878
2115
|
var WITHHELD_ENTITY_LABEL = "Something you have not been given access to";
|
|
1879
2116
|
var ENTITY_REFERENCE_EMPTY = "Nothing is pointed at yet.";
|
|
1880
2117
|
function entityReferenceText(value) {
|
|
@@ -1888,20 +2125,20 @@ function allowedKindsOf(field) {
|
|
|
1888
2125
|
return kinds.map((k) => String(k).trim().toLowerCase()).filter(Boolean);
|
|
1889
2126
|
}
|
|
1890
2127
|
function EntityReferenceControl(props) {
|
|
1891
|
-
const client = (0,
|
|
1892
|
-
return client ? /* @__PURE__ */ (0,
|
|
2128
|
+
const client = (0, import_react16.useOptionalRecordsClient)();
|
|
2129
|
+
return client ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(WithWords, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Chips, { ...props, words: null, picker: null });
|
|
1893
2130
|
}
|
|
1894
2131
|
function WithWords(props) {
|
|
1895
|
-
const refs = (0,
|
|
1896
|
-
const [known, setKnown] = (0,
|
|
2132
|
+
const refs = (0, import_react15.useMemo)(() => (0, import_records6.entityRefsOf)(props.value), [props.value]);
|
|
2133
|
+
const [known, setKnown] = (0, import_react15.useState)([]);
|
|
1897
2134
|
const withKnown = refs.map((r) => r.label === null ? known.find((k) => k.token === r.token && k.id === r.id) ?? r : r);
|
|
1898
|
-
const unlabelled = (0,
|
|
2135
|
+
const unlabelled = (0, import_react15.useMemo)(
|
|
1899
2136
|
() => withKnown.filter((r) => r.label === null).map((r) => ({ token: r.token, id: r.id })),
|
|
1900
2137
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1901
2138
|
[JSON.stringify(withKnown)]
|
|
1902
2139
|
);
|
|
1903
|
-
const words = (0,
|
|
1904
|
-
const picker = props.disabled ? null : /* @__PURE__ */ (0,
|
|
2140
|
+
const words = (0, import_react16.useEntityReferenceWords)(unlabelled);
|
|
2141
|
+
const picker = props.disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1905
2142
|
EntityReferencePicker,
|
|
1906
2143
|
{
|
|
1907
2144
|
field: props.field,
|
|
@@ -1914,7 +2151,7 @@ function WithWords(props) {
|
|
|
1914
2151
|
}
|
|
1915
2152
|
}
|
|
1916
2153
|
);
|
|
1917
|
-
return /* @__PURE__ */ (0,
|
|
2154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Chips, { ...props, value: withKnown, words, picker });
|
|
1918
2155
|
}
|
|
1919
2156
|
function EntityReferencePicker({
|
|
1920
2157
|
field,
|
|
@@ -1922,13 +2159,13 @@ function EntityReferencePicker({
|
|
|
1922
2159
|
onPick
|
|
1923
2160
|
}) {
|
|
1924
2161
|
const allowed = allowedKindsOf(field);
|
|
1925
|
-
const kinds = (0,
|
|
2162
|
+
const kinds = (0, import_react16.useEntityReferenceKinds)();
|
|
1926
2163
|
const labelOfKind = (token) => kinds.data?.find((k) => k.token === token)?.label ?? token.replace(/_/g, " ");
|
|
1927
|
-
const [open, setOpen] = (0,
|
|
1928
|
-
const [search, setSearch] = (0,
|
|
1929
|
-
const [only, setOnly] = (0,
|
|
2164
|
+
const [open, setOpen] = (0, import_react15.useState)(false);
|
|
2165
|
+
const [search, setSearch] = (0, import_react15.useState)("");
|
|
2166
|
+
const [only, setOnly] = (0, import_react15.useState)(null);
|
|
1930
2167
|
const tokens = only ? [only] : allowed;
|
|
1931
|
-
const found = (0,
|
|
2168
|
+
const found = (0, import_react16.useEntityReferenceSearch)(tokens, search, open);
|
|
1932
2169
|
const multi = Boolean(field.multi);
|
|
1933
2170
|
const items = (found.data ?? []).map((r) => ({
|
|
1934
2171
|
id: `${r.token}:${r.id}`,
|
|
@@ -1937,8 +2174,8 @@ function EntityReferencePicker({
|
|
|
1937
2174
|
picked: refs.some((x) => x.token === r.token && x.id === r.id),
|
|
1938
2175
|
attrs: { "data-entity-reference-candidate": `${r.token}:${r.id}` }
|
|
1939
2176
|
}));
|
|
1940
|
-
const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ (0,
|
|
1941
|
-
|
|
2177
|
+
const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-1 flex flex-wrap gap-1", role: "group", "aria-label": `Which kind \u2014 ${field.label}`, children: [null, ...allowed].map((token) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2178
|
+
import_design_system9.Button,
|
|
1942
2179
|
{
|
|
1943
2180
|
type: "button",
|
|
1944
2181
|
size: "sm",
|
|
@@ -1949,26 +2186,23 @@ function EntityReferencePicker({
|
|
|
1949
2186
|
children: token ? labelOfKind(token) : "Any"
|
|
1950
2187
|
},
|
|
1951
2188
|
token ?? "any"
|
|
1952
|
-
)) }) : /* @__PURE__ */ (0,
|
|
1953
|
-
|
|
2189
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2190
|
+
PickOne,
|
|
1954
2191
|
{
|
|
1955
|
-
|
|
1956
|
-
"
|
|
2192
|
+
label: `Which kind \u2014 ${field.label}`,
|
|
2193
|
+
className: "mb-1 w-full",
|
|
1957
2194
|
value: only ?? "",
|
|
1958
|
-
onChange: (
|
|
1959
|
-
|
|
1960
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "Any kind" }),
|
|
1961
|
-
allowed.map((token) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: token, children: labelOfKind(token) }, token))
|
|
1962
|
-
]
|
|
2195
|
+
onChange: (picked) => setOnly(picked || null),
|
|
2196
|
+
options: [{ value: "", label: "Any kind" }, ...allowed.map((token) => ({ value: token, label: labelOfKind(token) }))]
|
|
1963
2197
|
}
|
|
1964
2198
|
) : null;
|
|
1965
|
-
const notice = /* @__PURE__ */ (0,
|
|
2199
|
+
const notice = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1966
2200
|
kindChoice,
|
|
1967
|
-
found.error ? /* @__PURE__ */ (0,
|
|
1968
|
-
found.loading && !found.data ? /* @__PURE__ */ (0,
|
|
2201
|
+
found.error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RefusalLine, { error: found.error, className: "px-2 py-1 text-[11px]" }) : null,
|
|
2202
|
+
found.loading && !found.data ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: "Searching\u2026" }) : null
|
|
1969
2203
|
] });
|
|
1970
2204
|
const kindWords = allowed.length === 1 ? labelOfKind(allowed[0]).toLowerCase() : "thing";
|
|
1971
|
-
return /* @__PURE__ */ (0,
|
|
2205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1972
2206
|
PickOrAdd,
|
|
1973
2207
|
{
|
|
1974
2208
|
triggerLabel: `Pick for ${field.label}`,
|
|
@@ -1982,7 +2216,7 @@ function EntityReferencePicker({
|
|
|
1982
2216
|
onSearch: setSearch,
|
|
1983
2217
|
items,
|
|
1984
2218
|
notice,
|
|
1985
|
-
empty: found.loading ? null : /* @__PURE__ */ (0,
|
|
2219
|
+
empty: found.loading ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("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.` }),
|
|
1986
2220
|
onPick: (key) => {
|
|
1987
2221
|
const r = (found.data ?? []).find((x) => `${x.token}:${x.id}` === key);
|
|
1988
2222
|
if (!r) return;
|
|
@@ -2002,7 +2236,7 @@ function Chips({
|
|
|
2002
2236
|
words,
|
|
2003
2237
|
picker
|
|
2004
2238
|
}) {
|
|
2005
|
-
const refs = (0,
|
|
2239
|
+
const refs = (0, import_react15.useMemo)(() => (0, import_records6.entityRefsOf)(value), [value]);
|
|
2006
2240
|
const labelOf = (token, refId, own3) => {
|
|
2007
2241
|
if (own3) return own3;
|
|
2008
2242
|
const read = words?.data?.find((w) => w.token === token && w.id === refId)?.label;
|
|
@@ -2012,13 +2246,13 @@ function Chips({
|
|
|
2012
2246
|
return WITHHELD_ENTITY_LABEL;
|
|
2013
2247
|
};
|
|
2014
2248
|
const multi = Boolean(field.multi);
|
|
2015
|
-
return /* @__PURE__ */ (0,
|
|
2016
|
-
refs.length === 0 && !picker ? /* @__PURE__ */ (0,
|
|
2249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { id, className: (0, import_design_system9.cn)("flex flex-wrap items-center gap-1", className), "aria-label": `What ${field.label} points at`, children: [
|
|
2250
|
+
refs.length === 0 && !picker ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-[11px] text-muted-foreground", children: ENTITY_REFERENCE_EMPTY }) : null,
|
|
2017
2251
|
refs.map((r) => {
|
|
2018
2252
|
const label = labelOf(r.token, r.id, r.label);
|
|
2019
|
-
return /* @__PURE__ */ (0,
|
|
2253
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_design_system9.Badge, { variant: "secondary", className: "gap-1 text-[11px]", "data-entity-reference-chip": `${r.token}:${r.id}`, children: [
|
|
2020
2254
|
label,
|
|
2021
|
-
disabled ? null : /* @__PURE__ */ (0,
|
|
2255
|
+
disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2022
2256
|
"button",
|
|
2023
2257
|
{
|
|
2024
2258
|
type: "button",
|
|
@@ -2038,11 +2272,11 @@ function Chips({
|
|
|
2038
2272
|
}
|
|
2039
2273
|
|
|
2040
2274
|
// src/PersonPicker.tsx
|
|
2041
|
-
var
|
|
2275
|
+
var import_react17 = require("react");
|
|
2042
2276
|
var import_records7 = require("@ai-matrx/records");
|
|
2043
|
-
var
|
|
2044
|
-
var
|
|
2045
|
-
var
|
|
2277
|
+
var import_react18 = require("@ai-matrx/records/react");
|
|
2278
|
+
var import_design_system10 = require("@ai-matrx/design-system");
|
|
2279
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2046
2280
|
function personFromRow(row) {
|
|
2047
2281
|
const data = row.document ?? {};
|
|
2048
2282
|
const userId = data["user_id"];
|
|
@@ -2073,27 +2307,27 @@ async function personRecordForMember(client, personTableId, people, member) {
|
|
|
2073
2307
|
return written;
|
|
2074
2308
|
}
|
|
2075
2309
|
function PersonPicker({ field, value, onChange, disabled, id, className, autoOpen, onClose, initialSearch }) {
|
|
2076
|
-
const client = (0,
|
|
2310
|
+
const client = (0, import_react18.useOptionalRecordsClient)();
|
|
2077
2311
|
const host = useRecordsUi();
|
|
2078
|
-
const [members, setMembers] = (0,
|
|
2079
|
-
const [people, setPeople] = (0,
|
|
2080
|
-
const [error, setError] = (0,
|
|
2081
|
-
const [search, setSearch] = (0,
|
|
2082
|
-
const [open, setOpenState] = (0,
|
|
2083
|
-
const onCloseRef = (0,
|
|
2312
|
+
const [members, setMembers] = (0, import_react17.useState)(null);
|
|
2313
|
+
const [people, setPeople] = (0, import_react17.useState)([]);
|
|
2314
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
2315
|
+
const [search, setSearch] = (0, import_react17.useState)(initialSearch ?? "");
|
|
2316
|
+
const [open, setOpenState] = (0, import_react17.useState)(autoOpen === true);
|
|
2317
|
+
const onCloseRef = (0, import_react17.useRef)(onClose);
|
|
2084
2318
|
onCloseRef.current = onClose;
|
|
2085
|
-
const setOpen = (0,
|
|
2319
|
+
const setOpen = (0, import_react17.useCallback)((next) => {
|
|
2086
2320
|
setOpenState(next);
|
|
2087
2321
|
if (!next) onCloseRef.current?.();
|
|
2088
2322
|
}, []);
|
|
2089
|
-
const [busy, setBusy] = (0,
|
|
2323
|
+
const [busy, setBusy] = (0, import_react17.useState)(false);
|
|
2090
2324
|
const membersPort = host.members;
|
|
2091
2325
|
const personTable = field.relation_target;
|
|
2092
|
-
const picked = (0,
|
|
2326
|
+
const picked = (0, import_react17.useMemo)(
|
|
2093
2327
|
() => Array.isArray(value) ? value.map(String) : value === null || value === void 0 ? [] : [String(value)],
|
|
2094
2328
|
[value]
|
|
2095
2329
|
);
|
|
2096
|
-
const load = (0,
|
|
2330
|
+
const load = (0, import_react17.useCallback)(async () => {
|
|
2097
2331
|
if (!membersPort || !client) return;
|
|
2098
2332
|
const [roster, records] = await Promise.all([
|
|
2099
2333
|
membersPort(),
|
|
@@ -2106,11 +2340,11 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2106
2340
|
}
|
|
2107
2341
|
setPeople(records ? records.data.rows.map(personFromRow).filter((p) => p.userId !== null) : []);
|
|
2108
2342
|
}, [membersPort, client, personTable]);
|
|
2109
|
-
(0,
|
|
2343
|
+
(0, import_react17.useEffect)(() => {
|
|
2110
2344
|
if (!open) return;
|
|
2111
2345
|
void load();
|
|
2112
2346
|
}, [open, load]);
|
|
2113
|
-
(0,
|
|
2347
|
+
(0, import_react17.useEffect)(() => {
|
|
2114
2348
|
if (picked.length === 0 || !personTable || people.length > 0 || !client) return;
|
|
2115
2349
|
let cancelled = false;
|
|
2116
2350
|
void client.list({ table_id: personTable, limit: 500 }).then((result) => {
|
|
@@ -2131,12 +2365,12 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2131
2365
|
},
|
|
2132
2366
|
onClose: () => setOpen(false)
|
|
2133
2367
|
});
|
|
2134
|
-
const pickRef = (0,
|
|
2368
|
+
const pickRef = (0, import_react17.useRef)(null);
|
|
2135
2369
|
if (!membersPort || !client) {
|
|
2136
|
-
return /* @__PURE__ */ (0,
|
|
2370
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: (0, import_design_system10.cn)("text-xs text-muted-foreground", className), children: NO_MEMBERS_REASON });
|
|
2137
2371
|
}
|
|
2138
2372
|
if (!personTable) {
|
|
2139
|
-
return /* @__PURE__ */ (0,
|
|
2373
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: (0, import_design_system10.cn)("text-xs text-muted-foreground", className), children: [
|
|
2140
2374
|
fieldName(field),
|
|
2141
2375
|
" is a person field, but it does not say which Table the people are records of yet, so there is nothing to pick from. A table admin sets its target in the field editor."
|
|
2142
2376
|
] });
|
|
@@ -2179,8 +2413,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2179
2413
|
const pickedUserIds = new Set(
|
|
2180
2414
|
picked.map((recordId) => people.find((p) => p.id === recordId)?.userId).filter(Boolean)
|
|
2181
2415
|
);
|
|
2182
|
-
return /* @__PURE__ */ (0,
|
|
2183
|
-
picked.map((recordId) => /* @__PURE__ */ (0,
|
|
2416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: (0, import_design_system10.cn)("flex flex-wrap items-center gap-1", className), children: [
|
|
2417
|
+
picked.map((recordId) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2184
2418
|
RecordChip,
|
|
2185
2419
|
{
|
|
2186
2420
|
title: nameOfRecord(recordId),
|
|
@@ -2188,9 +2422,9 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2188
2422
|
},
|
|
2189
2423
|
recordId
|
|
2190
2424
|
)),
|
|
2191
|
-
disabled ? null : /* @__PURE__ */ (0,
|
|
2192
|
-
/* @__PURE__ */ (0,
|
|
2193
|
-
|
|
2425
|
+
disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system10.Popover, { open, onOpenChange: setOpen, children: [
|
|
2426
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system10.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2427
|
+
import_design_system10.Button,
|
|
2194
2428
|
{
|
|
2195
2429
|
id,
|
|
2196
2430
|
type: "button",
|
|
@@ -2200,8 +2434,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2200
2434
|
children: picked.length === 0 ? "Pick a person" : "Change"
|
|
2201
2435
|
}
|
|
2202
2436
|
) }),
|
|
2203
|
-
/* @__PURE__ */ (0,
|
|
2204
|
-
|
|
2437
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2438
|
+
import_design_system10.PopoverContent,
|
|
2205
2439
|
{
|
|
2206
2440
|
sizing: "content",
|
|
2207
2441
|
className: "p-1",
|
|
@@ -2209,8 +2443,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2209
2443
|
"data-matrx-cell-editor": "",
|
|
2210
2444
|
onKeyDown: (event) => event.stopPropagation(),
|
|
2211
2445
|
children: [
|
|
2212
|
-
/* @__PURE__ */ (0,
|
|
2213
|
-
|
|
2446
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2447
|
+
import_design_system10.BasicInput,
|
|
2214
2448
|
{
|
|
2215
2449
|
value: search,
|
|
2216
2450
|
onChange: (e) => setSearch(e.target.value),
|
|
@@ -2222,31 +2456,31 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2222
2456
|
className: "mb-1 h-7 text-xs"
|
|
2223
2457
|
}
|
|
2224
2458
|
),
|
|
2225
|
-
error ? /* @__PURE__ */ (0,
|
|
2226
|
-
members === null ? /* @__PURE__ */ (0,
|
|
2227
|
-
/* @__PURE__ */ (0,
|
|
2228
|
-
/* @__PURE__ */ (0,
|
|
2459
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefusalLine, { error, className: "p-2" }) : null,
|
|
2460
|
+
members === null ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading the members\u2026" }) : null,
|
|
2461
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system10.ScrollArea, { className: "max-h-56", children: [
|
|
2462
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { role: "listbox", "aria-label": `People for ${fieldName(field)}`, children: visible.map((member, index) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2229
2463
|
"button",
|
|
2230
2464
|
{
|
|
2231
2465
|
type: "button",
|
|
2232
2466
|
disabled: busy,
|
|
2233
2467
|
"data-pick-highlighted": index === keys.highlight ? "" : void 0,
|
|
2234
2468
|
onClick: () => void pick(member),
|
|
2235
|
-
className: (0,
|
|
2469
|
+
className: (0, import_design_system10.cn)(
|
|
2236
2470
|
"w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-muted",
|
|
2237
2471
|
pickedUserIds.has(member.userId) ? "bg-accent text-accent-foreground" : "",
|
|
2238
2472
|
index === keys.highlight ? "ring-1 ring-ring" : ""
|
|
2239
2473
|
),
|
|
2240
2474
|
children: [
|
|
2241
|
-
/* @__PURE__ */ (0,
|
|
2242
|
-
member.email && member.email !== memberName(member) ? /* @__PURE__ */ (0,
|
|
2475
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: memberName(member) }),
|
|
2476
|
+
member.email && member.email !== memberName(member) ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ml-1.5 opacity-60", children: [
|
|
2243
2477
|
"\xB7 ",
|
|
2244
2478
|
member.email
|
|
2245
2479
|
] }) : null
|
|
2246
2480
|
]
|
|
2247
2481
|
}
|
|
2248
2482
|
) }, member.userId)) }),
|
|
2249
|
-
members !== null && visible.length === 0 ? /* @__PURE__ */ (0,
|
|
2483
|
+
members !== null && visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: members.length === 0 ? "This organization has no other members yet, so there is nobody to assign." : "Nobody in this organization matches." }) : null
|
|
2250
2484
|
] })
|
|
2251
2485
|
]
|
|
2252
2486
|
}
|
|
@@ -2256,7 +2490,7 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2256
2490
|
}
|
|
2257
2491
|
|
|
2258
2492
|
// src/presentation.ts
|
|
2259
|
-
var
|
|
2493
|
+
var import_data_table2 = require("@ai-matrx/design-system/data-table");
|
|
2260
2494
|
var import_field_formats2 = require("@ai-matrx/design-system/field-formats");
|
|
2261
2495
|
var import_records8 = require("@ai-matrx/records");
|
|
2262
2496
|
var DRAWN_KINDS = /* @__PURE__ */ new Set(["select", "multi_select", "relation", "member", "person", "attachment", "file", "entity_reference", "checkbox", "boolean", "signature", "json"]);
|
|
@@ -2318,16 +2552,16 @@ function currencyCodeFor(unit) {
|
|
|
2318
2552
|
}
|
|
2319
2553
|
|
|
2320
2554
|
// src/formatControls.tsx
|
|
2321
|
-
var
|
|
2322
|
-
var
|
|
2555
|
+
var import_react20 = require("react");
|
|
2556
|
+
var import_design_system12 = require("@ai-matrx/design-system");
|
|
2323
2557
|
var import_field_formats4 = require("@ai-matrx/design-system/field-formats");
|
|
2324
2558
|
|
|
2325
2559
|
// src/formattedValue.tsx
|
|
2326
|
-
var
|
|
2327
|
-
var
|
|
2560
|
+
var import_react19 = require("react");
|
|
2561
|
+
var import_data_table3 = require("@ai-matrx/design-system/data-table");
|
|
2328
2562
|
var import_field_formats3 = require("@ai-matrx/design-system/field-formats");
|
|
2329
|
-
var
|
|
2330
|
-
var
|
|
2563
|
+
var import_design_system11 = require("@ai-matrx/design-system");
|
|
2564
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2331
2565
|
var LINK = "inline-flex min-w-0 items-center gap-1 text-primary hover:underline";
|
|
2332
2566
|
var own2 = (event) => event.stopPropagation();
|
|
2333
2567
|
function numberOf(value) {
|
|
@@ -2345,11 +2579,11 @@ function RatingStars({
|
|
|
2345
2579
|
label,
|
|
2346
2580
|
selectFirst
|
|
2347
2581
|
}) {
|
|
2348
|
-
const armed = (0,
|
|
2582
|
+
const armed = (0, import_react19.useRef)(true);
|
|
2349
2583
|
const score = numberOf(value) ?? 0;
|
|
2350
2584
|
const shown2 = Math.round(score);
|
|
2351
2585
|
const said = `${shown2} out of ${max}`;
|
|
2352
|
-
return /* @__PURE__ */ (0,
|
|
2586
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2353
2587
|
"span",
|
|
2354
2588
|
{
|
|
2355
2589
|
"data-records-rating": "",
|
|
@@ -2361,8 +2595,8 @@ function RatingStars({
|
|
|
2361
2595
|
children: Array.from({ length: max }, (_, i) => {
|
|
2362
2596
|
const n = i + 1;
|
|
2363
2597
|
const lit = n <= shown2;
|
|
2364
|
-
const star = /* @__PURE__ */ (0,
|
|
2365
|
-
return onRate ? /* @__PURE__ */ (0,
|
|
2598
|
+
const star = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { "aria-hidden": true, className: (0, import_design_system11.cn)("text-sm leading-none", lit ? "text-amber-400" : "text-muted-foreground/40"), children: "\u2605" });
|
|
2599
|
+
return onRate ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2366
2600
|
"button",
|
|
2367
2601
|
{
|
|
2368
2602
|
type: "button",
|
|
@@ -2387,7 +2621,7 @@ function RatingStars({
|
|
|
2387
2621
|
children: star
|
|
2388
2622
|
},
|
|
2389
2623
|
n
|
|
2390
|
-
) : /* @__PURE__ */ (0,
|
|
2624
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: star }, n);
|
|
2391
2625
|
})
|
|
2392
2626
|
}
|
|
2393
2627
|
);
|
|
@@ -2395,13 +2629,13 @@ function RatingStars({
|
|
|
2395
2629
|
function rich(id, text, raw, format) {
|
|
2396
2630
|
switch (id) {
|
|
2397
2631
|
case "email":
|
|
2398
|
-
return /* @__PURE__ */ (0,
|
|
2632
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("a", { href: `mailto:${text}`, className: LINK, onClick: own2, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate", children: text }) });
|
|
2399
2633
|
case "url":
|
|
2400
|
-
return /* @__PURE__ */ (0,
|
|
2634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("a", { href: text.includes("://") ? text : `https://${text}`, target: "_blank", rel: "noopener noreferrer", className: LINK, onClick: own2, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate", children: text }) });
|
|
2401
2635
|
case "phone":
|
|
2402
|
-
return /* @__PURE__ */ (0,
|
|
2636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("a", { href: `tel:${text.replace(/[^\d+]/g, "")}`, className: LINK, onClick: own2, title: text, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate tabular-nums", children: (0, import_field_formats3.formatPhone)(text) }) });
|
|
2403
2637
|
case "address":
|
|
2404
|
-
return /* @__PURE__ */ (0,
|
|
2638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2405
2639
|
"a",
|
|
2406
2640
|
{
|
|
2407
2641
|
href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(text)}`,
|
|
@@ -2410,7 +2644,7 @@ function rich(id, text, raw, format) {
|
|
|
2410
2644
|
className: LINK,
|
|
2411
2645
|
title: "Open in maps",
|
|
2412
2646
|
onClick: own2,
|
|
2413
|
-
children: /* @__PURE__ */ (0,
|
|
2647
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate", children: text })
|
|
2414
2648
|
}
|
|
2415
2649
|
);
|
|
2416
2650
|
case "progress": {
|
|
@@ -2418,8 +2652,8 @@ function rich(id, text, raw, format) {
|
|
|
2418
2652
|
if (n === null) return void 0;
|
|
2419
2653
|
const pct = format.options?.percentScale === "fraction" ? n * 100 : n;
|
|
2420
2654
|
const clamped = Math.max(0, Math.min(100, pct));
|
|
2421
|
-
return /* @__PURE__ */ (0,
|
|
2422
|
-
/* @__PURE__ */ (0,
|
|
2655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "inline-flex w-full min-w-0 items-center gap-2", title: text, children: [
|
|
2656
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2423
2657
|
"span",
|
|
2424
2658
|
{
|
|
2425
2659
|
role: "progressbar",
|
|
@@ -2427,24 +2661,24 @@ function rich(id, text, raw, format) {
|
|
|
2427
2661
|
"aria-valuemax": 100,
|
|
2428
2662
|
"aria-valuenow": Math.round(clamped),
|
|
2429
2663
|
className: "h-1.5 min-w-8 flex-1 overflow-hidden rounded-full bg-muted",
|
|
2430
|
-
children: /* @__PURE__ */ (0,
|
|
2664
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: (0, import_design_system11.cn)("block h-full rounded-full", pct >= 100 ? "bg-emerald-500" : "bg-primary"), style: { width: `${clamped}%` } })
|
|
2431
2665
|
}
|
|
2432
2666
|
),
|
|
2433
|
-
/* @__PURE__ */ (0,
|
|
2667
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: text })
|
|
2434
2668
|
] });
|
|
2435
2669
|
}
|
|
2436
2670
|
case "color":
|
|
2437
|
-
return /* @__PURE__ */ (0,
|
|
2438
|
-
/* @__PURE__ */ (0,
|
|
2439
|
-
/* @__PURE__ */ (0,
|
|
2671
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
2672
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "h-4 w-4 shrink-0 rounded border border-border", style: { backgroundColor: text } }),
|
|
2673
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("code", { className: "font-mono text-xs", children: text })
|
|
2440
2674
|
] });
|
|
2441
2675
|
case "tags": {
|
|
2442
2676
|
const items = Array.isArray(raw) ? raw.map(String) : text.split(",").map((s) => s.trim()).filter(Boolean);
|
|
2443
2677
|
if (items.length === 0) return void 0;
|
|
2444
|
-
return /* @__PURE__ */ (0,
|
|
2678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "flex flex-wrap items-center gap-1", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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}`)) });
|
|
2445
2679
|
}
|
|
2446
2680
|
case "rating":
|
|
2447
|
-
return numberOf(raw) === null ? void 0 : /* @__PURE__ */ (0,
|
|
2681
|
+
return numberOf(raw) === null ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RatingStars, { value: raw, max: format.options?.ratingMax ?? 5 });
|
|
2448
2682
|
default:
|
|
2449
2683
|
return void 0;
|
|
2450
2684
|
}
|
|
@@ -2459,21 +2693,11 @@ function FormattedValue({
|
|
|
2459
2693
|
const score = numberOf(value);
|
|
2460
2694
|
const max = format.options?.ratingMax ?? 5;
|
|
2461
2695
|
if (def?.id === "rating" && onRate && (value === null || value === void 0 || value === "" || score !== null && score >= 0 && score <= max)) {
|
|
2462
|
-
return /* @__PURE__ */ (0,
|
|
2696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, onRate, selectFirst });
|
|
2463
2697
|
}
|
|
2464
2698
|
const result = (0, import_field_formats3.formatFieldValue)(value, format);
|
|
2465
|
-
if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ (0,
|
|
2466
|
-
return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ (0,
|
|
2467
|
-
}
|
|
2468
|
-
function formatPhone(raw) {
|
|
2469
|
-
const text = raw.trim();
|
|
2470
|
-
const digits = text.replace(/\D/g, "");
|
|
2471
|
-
if (/[a-z]/i.test(text.replace(/ext\.?|x/gi, ""))) return text;
|
|
2472
|
-
if (digits.length === 10 && !text.startsWith("+")) return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
|
|
2473
|
-
if (digits.length === 11 && digits.startsWith("1") && (text.startsWith("+1") || text.startsWith("1") || !text.startsWith("+"))) {
|
|
2474
|
-
return `+1 (${digits.slice(1, 4)}) ${digits.slice(4, 7)}-${digits.slice(7)}`;
|
|
2475
|
-
}
|
|
2476
|
-
return text;
|
|
2699
|
+
if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_data_table3.FormattedCell, { result });
|
|
2700
|
+
return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_data_table3.FormattedCell, { result });
|
|
2477
2701
|
}
|
|
2478
2702
|
function linkChipText(raw) {
|
|
2479
2703
|
try {
|
|
@@ -2487,7 +2711,7 @@ function linkChipText(raw) {
|
|
|
2487
2711
|
}
|
|
2488
2712
|
|
|
2489
2713
|
// src/formatControls.tsx
|
|
2490
|
-
var
|
|
2714
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2491
2715
|
var TYPED_NUMBERS = /* @__PURE__ */ new Set(["currency", "percent", "progress", "decimal", "duration", "file_size", "integer"]);
|
|
2492
2716
|
function scaled(format) {
|
|
2493
2717
|
return (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction";
|
|
@@ -2504,14 +2728,14 @@ function keptValue(format, raw) {
|
|
|
2504
2728
|
return parsed;
|
|
2505
2729
|
}
|
|
2506
2730
|
function NumberInFormat({ format, value, onChange, disabled, id }) {
|
|
2507
|
-
const [text, setText] = (0,
|
|
2508
|
-
const lastSent = (0,
|
|
2509
|
-
(0,
|
|
2731
|
+
const [text, setText] = (0, import_react20.useState)(() => typedText(format, value));
|
|
2732
|
+
const lastSent = (0, import_react20.useRef)(void 0);
|
|
2733
|
+
(0, import_react20.useEffect)(() => {
|
|
2510
2734
|
if (value === lastSent.current) return;
|
|
2511
2735
|
setText(typedText(format, value));
|
|
2512
2736
|
}, [value, format]);
|
|
2513
|
-
return /* @__PURE__ */ (0,
|
|
2514
|
-
|
|
2737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2738
|
+
import_design_system12.BasicInput,
|
|
2515
2739
|
{
|
|
2516
2740
|
id,
|
|
2517
2741
|
inputMode: "decimal",
|
|
@@ -2535,17 +2759,17 @@ function formatControl(args) {
|
|
|
2535
2759
|
const text = value === null || value === void 0 ? "" : String(value);
|
|
2536
2760
|
const commit = (raw) => onChange(raw === "" ? null : (0, import_field_formats4.parseFieldInput)(raw, format));
|
|
2537
2761
|
if (def.id === "rating") {
|
|
2538
|
-
return disabled ? /* @__PURE__ */ (0,
|
|
2762
|
+
return disabled ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, label }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { id, className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, label, onRate: (n) => onChange(n) }) });
|
|
2539
2763
|
}
|
|
2540
|
-
if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ (0,
|
|
2764
|
+
if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NumberInFormat, { ...args });
|
|
2541
2765
|
switch (def.editor) {
|
|
2542
2766
|
// A TIME OF DAY is not this file's: `FieldControl` draws the typed box and its helper
|
|
2543
2767
|
// (`TypedWordsControl`), never the browser's time control (grids review 3, 2026-09-30).
|
|
2544
2768
|
case "email":
|
|
2545
2769
|
case "url":
|
|
2546
2770
|
case "tel":
|
|
2547
|
-
return /* @__PURE__ */ (0,
|
|
2548
|
-
|
|
2771
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2772
|
+
import_design_system12.BasicInput,
|
|
2549
2773
|
{
|
|
2550
2774
|
id,
|
|
2551
2775
|
type: def.editor,
|
|
@@ -2556,9 +2780,9 @@ function formatControl(args) {
|
|
|
2556
2780
|
}
|
|
2557
2781
|
);
|
|
2558
2782
|
case "color":
|
|
2559
|
-
return /* @__PURE__ */ (0,
|
|
2560
|
-
/* @__PURE__ */ (0,
|
|
2561
|
-
|
|
2783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
2784
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2785
|
+
import_design_system12.BasicInput,
|
|
2562
2786
|
{
|
|
2563
2787
|
id: `${id}-swatch`,
|
|
2564
2788
|
type: "color",
|
|
@@ -2569,20 +2793,20 @@ function formatControl(args) {
|
|
|
2569
2793
|
onChange: (e) => commit(e.target.value)
|
|
2570
2794
|
}
|
|
2571
2795
|
),
|
|
2572
|
-
/* @__PURE__ */ (0,
|
|
2796
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system12.BasicInput, { id, value: text, placeholder: "#3b82f6", disabled, onChange: (e) => commit(e.target.value) })
|
|
2573
2797
|
] });
|
|
2574
2798
|
case "textarea":
|
|
2575
|
-
return /* @__PURE__ */ (0,
|
|
2799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system12.BasicTextarea, { id, rows: 4, value: text, disabled, onChange: (e) => commit(e.target.value) });
|
|
2576
2800
|
default:
|
|
2577
2801
|
return null;
|
|
2578
2802
|
}
|
|
2579
2803
|
}
|
|
2580
2804
|
|
|
2581
2805
|
// src/typedDateHelper.tsx
|
|
2582
|
-
var
|
|
2583
|
-
var
|
|
2806
|
+
var import_react21 = require("react");
|
|
2807
|
+
var import_design_system13 = require("@ai-matrx/design-system");
|
|
2584
2808
|
var import_records9 = require("@ai-matrx/records");
|
|
2585
|
-
var
|
|
2809
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2586
2810
|
var WEEK = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
2587
2811
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
2588
2812
|
function pad(n) {
|
|
@@ -2611,23 +2835,23 @@ function wordsFor(kind, day, time) {
|
|
|
2611
2835
|
}
|
|
2612
2836
|
var keepFocus = { onMouseDown: (e) => e.preventDefault(), tabIndex: -1 };
|
|
2613
2837
|
function CalendarGlyph() {
|
|
2614
|
-
return /* @__PURE__ */ (0,
|
|
2615
|
-
/* @__PURE__ */ (0,
|
|
2616
|
-
/* @__PURE__ */ (0,
|
|
2838
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2839
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
|
|
2840
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M16 2v4M8 2v4M3 10h18" })
|
|
2617
2841
|
] });
|
|
2618
2842
|
}
|
|
2619
2843
|
function ClockGlyph() {
|
|
2620
|
-
return /* @__PURE__ */ (0,
|
|
2621
|
-
/* @__PURE__ */ (0,
|
|
2622
|
-
/* @__PURE__ */ (0,
|
|
2844
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2845
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2846
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M12 6v6l4 2" })
|
|
2623
2847
|
] });
|
|
2624
2848
|
}
|
|
2625
2849
|
function TypedDateHelper({ kind, text, onText, label }) {
|
|
2626
|
-
const [open, setOpen] = (0,
|
|
2850
|
+
const [open, setOpen] = (0, import_react21.useState)(false);
|
|
2627
2851
|
const held = readBox(text, kind);
|
|
2628
2852
|
const today = /* @__PURE__ */ new Date();
|
|
2629
2853
|
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);
|
|
2630
|
-
const [month, setMonth] = (0,
|
|
2854
|
+
const [month, setMonth] = (0, import_react21.useState)(null);
|
|
2631
2855
|
const shown2 = month ?? { y: start.getFullYear(), m: start.getMonth() };
|
|
2632
2856
|
const first = new Date(shown2.y, shown2.m, 1).getDay();
|
|
2633
2857
|
const days = new Date(shown2.y, shown2.m + 1, 0).getDate();
|
|
@@ -2648,8 +2872,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2648
2872
|
const at = new Date(shown2.y, shown2.m + by, 1);
|
|
2649
2873
|
setMonth({ y: at.getFullYear(), m: at.getMonth() });
|
|
2650
2874
|
};
|
|
2651
|
-
return /* @__PURE__ */ (0,
|
|
2652
|
-
/* @__PURE__ */ (0,
|
|
2875
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system13.Popover, { open, onOpenChange: setOpen, children: [
|
|
2876
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2653
2877
|
"button",
|
|
2654
2878
|
{
|
|
2655
2879
|
type: "button",
|
|
@@ -2658,11 +2882,11 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2658
2882
|
"aria-label": kind === "time" ? `Pick a time for ${label}` : `Pick a date for ${label}`,
|
|
2659
2883
|
title: kind === "time" ? "Pick a time" : "Pick a date",
|
|
2660
2884
|
className: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
2661
|
-
children: kind === "time" ? /* @__PURE__ */ (0,
|
|
2885
|
+
children: kind === "time" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ClockGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CalendarGlyph, {})
|
|
2662
2886
|
}
|
|
2663
2887
|
) }),
|
|
2664
|
-
/* @__PURE__ */ (0,
|
|
2665
|
-
|
|
2888
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2889
|
+
import_design_system13.PopoverContent,
|
|
2666
2890
|
{
|
|
2667
2891
|
sizing: "content",
|
|
2668
2892
|
align: "start",
|
|
@@ -2671,29 +2895,29 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2671
2895
|
"data-records-date-helper-panel": "",
|
|
2672
2896
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
2673
2897
|
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
2674
|
-
children: /* @__PURE__ */ (0,
|
|
2675
|
-
kind === "time" ? null : /* @__PURE__ */ (0,
|
|
2676
|
-
/* @__PURE__ */ (0,
|
|
2677
|
-
/* @__PURE__ */ (0,
|
|
2678
|
-
/* @__PURE__ */ (0,
|
|
2898
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex gap-2", children: [
|
|
2899
|
+
kind === "time" ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", role: "grid", "aria-label": `${MONTHS[shown2.m]} ${shown2.y}`, children: [
|
|
2900
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center justify-between text-xs font-medium", children: [
|
|
2901
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", ...keepFocus, "aria-label": "Previous month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(-1), children: "\u2039" }),
|
|
2902
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
|
|
2679
2903
|
MONTHS[shown2.m],
|
|
2680
2904
|
" ",
|
|
2681
2905
|
shown2.y
|
|
2682
2906
|
] }),
|
|
2683
|
-
/* @__PURE__ */ (0,
|
|
2907
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", ...keepFocus, "aria-label": "Next month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(1), children: "\u203A" })
|
|
2684
2908
|
] }),
|
|
2685
|
-
/* @__PURE__ */ (0,
|
|
2686
|
-
WEEK.map((w) => /* @__PURE__ */ (0,
|
|
2909
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "grid grid-cols-7 gap-0.5 text-center text-[11px]", children: [
|
|
2910
|
+
WEEK.map((w) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-muted-foreground", children: w }, w)),
|
|
2687
2911
|
cells.map((d, i) => {
|
|
2688
|
-
if (d === null) return /* @__PURE__ */ (0,
|
|
2912
|
+
if (d === null) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", {}, `blank-${i}`);
|
|
2689
2913
|
const key = `${shown2.y}-${pad(shown2.m + 1)}-${pad(d)}`;
|
|
2690
|
-
return /* @__PURE__ */ (0,
|
|
2914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2691
2915
|
"button",
|
|
2692
2916
|
{
|
|
2693
2917
|
type: "button",
|
|
2694
2918
|
...keepFocus,
|
|
2695
2919
|
"data-records-date-helper-day": key,
|
|
2696
|
-
className: (0,
|
|
2920
|
+
className: (0, import_design_system13.cn)(
|
|
2697
2921
|
"h-6 w-6 rounded tabular-nums hover:bg-muted",
|
|
2698
2922
|
key === held.day ? "bg-primary text-primary-foreground hover:bg-primary" : "",
|
|
2699
2923
|
key === todayKey && key !== held.day ? "ring-1 ring-ring" : ""
|
|
@@ -2706,13 +2930,13 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2706
2930
|
})
|
|
2707
2931
|
] })
|
|
2708
2932
|
] }),
|
|
2709
|
-
kind === "date" ? null : /* @__PURE__ */ (0,
|
|
2933
|
+
kind === "date" ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex max-h-48 flex-col overflow-y-auto pr-1 text-[11px]", "aria-label": "Times", children: times.map((t) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2710
2934
|
"button",
|
|
2711
2935
|
{
|
|
2712
2936
|
type: "button",
|
|
2713
2937
|
...keepFocus,
|
|
2714
2938
|
"data-records-date-helper-time": `${pad(t.h)}:${pad(t.m)}`,
|
|
2715
|
-
className: (0,
|
|
2939
|
+
className: (0, import_design_system13.cn)(
|
|
2716
2940
|
"whitespace-nowrap rounded px-2 py-0.5 text-left tabular-nums hover:bg-muted",
|
|
2717
2941
|
held.time && held.time.h === t.h && held.time.m === t.m ? "bg-primary text-primary-foreground" : ""
|
|
2718
2942
|
),
|
|
@@ -2728,8 +2952,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2728
2952
|
}
|
|
2729
2953
|
|
|
2730
2954
|
// src/choiceNudge.ts
|
|
2731
|
-
var
|
|
2732
|
-
var
|
|
2955
|
+
var import_react22 = require("react");
|
|
2956
|
+
var import_react23 = require("@ai-matrx/records/react");
|
|
2733
2957
|
var asked = /* @__PURE__ */ new WeakMap();
|
|
2734
2958
|
function choiceNudgeOf(client) {
|
|
2735
2959
|
let answer = asked.get(client);
|
|
@@ -2743,9 +2967,9 @@ function choiceNudgeOf(client) {
|
|
|
2743
2967
|
return answer;
|
|
2744
2968
|
}
|
|
2745
2969
|
function useChoiceNudge(enabled = true) {
|
|
2746
|
-
const client = (0,
|
|
2747
|
-
const [nudge, setNudge] = (0,
|
|
2748
|
-
(0,
|
|
2970
|
+
const client = (0, import_react23.useOptionalRecordsClient)();
|
|
2971
|
+
const [nudge, setNudge] = (0, import_react22.useState)(null);
|
|
2972
|
+
(0, import_react22.useEffect)(() => {
|
|
2749
2973
|
if (!enabled || !client) return;
|
|
2750
2974
|
let live = true;
|
|
2751
2975
|
void choiceNudgeOf(client).then((answer) => {
|
|
@@ -2759,61 +2983,8 @@ function useChoiceNudge(enabled = true) {
|
|
|
2759
2983
|
return nudge;
|
|
2760
2984
|
}
|
|
2761
2985
|
|
|
2762
|
-
// src/choiceLooks.ts
|
|
2763
|
-
var import_data_table3 = require("@ai-matrx/design-system/data-table");
|
|
2764
|
-
function displayFormatOf(field) {
|
|
2765
|
-
const raw = field.display_format;
|
|
2766
|
-
if (!raw || typeof raw !== "object") return null;
|
|
2767
|
-
const id = raw.id;
|
|
2768
|
-
if (typeof id !== "string" || id === "") return null;
|
|
2769
|
-
const options = raw.options;
|
|
2770
|
-
return { id, options: options && typeof options === "object" ? options : {} };
|
|
2771
|
-
}
|
|
2772
|
-
function isStyleColor(v) {
|
|
2773
|
-
return typeof v === "string" && import_data_table3.STYLE_COLORS.includes(v);
|
|
2774
|
-
}
|
|
2775
|
-
function choiceLooksOf(field) {
|
|
2776
|
-
const display = displayFormatOf(field);
|
|
2777
|
-
const choices = display?.options["choices"];
|
|
2778
|
-
if (!Array.isArray(choices)) return [];
|
|
2779
|
-
const out = [];
|
|
2780
|
-
for (const c of choices) {
|
|
2781
|
-
if (!c || typeof c !== "object") continue;
|
|
2782
|
-
const value = c.value;
|
|
2783
|
-
if (typeof value !== "string" || value.trim() === "") continue;
|
|
2784
|
-
const color = c.color;
|
|
2785
|
-
const label = c.label;
|
|
2786
|
-
out.push({
|
|
2787
|
-
value: value.trim(),
|
|
2788
|
-
...typeof label === "string" && label.trim() !== "" ? { label: label.trim() } : {},
|
|
2789
|
-
...isStyleColor(color) ? { color } : {}
|
|
2790
|
-
});
|
|
2791
|
-
}
|
|
2792
|
-
return out;
|
|
2793
|
-
}
|
|
2794
|
-
function choiceWord(value) {
|
|
2795
|
-
return String(value ?? "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
2796
|
-
}
|
|
2797
|
-
function storedChoiceColor(field, value) {
|
|
2798
|
-
if (value === null || value === void 0 || value === "") return void 0;
|
|
2799
|
-
const word = choiceWord(value);
|
|
2800
|
-
if (word === "") return void 0;
|
|
2801
|
-
for (const look of choiceLooksOf(field)) {
|
|
2802
|
-
if (!look.color) continue;
|
|
2803
|
-
if (choiceWord(look.value) === word || look.label && choiceWord(look.label) === word) return look.color;
|
|
2804
|
-
}
|
|
2805
|
-
return void 0;
|
|
2806
|
-
}
|
|
2807
|
-
function choiceChipLookOf(field, ...words) {
|
|
2808
|
-
for (const word of words) {
|
|
2809
|
-
const color = storedChoiceColor(field, word);
|
|
2810
|
-
if (color) return { className: import_data_table3.CHOICE_CHIP_CLASS[color], color };
|
|
2811
|
-
}
|
|
2812
|
-
return { className: import_data_table3.NEUTRAL_CHIP_CLASS, color: null };
|
|
2813
|
-
}
|
|
2814
|
-
|
|
2815
2986
|
// src/editors.tsx
|
|
2816
|
-
var
|
|
2987
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2817
2988
|
var CHOICE_EDITOR_ADDS_WHAT_IS_TYPED = true;
|
|
2818
2989
|
function isChoiceAddition(value) {
|
|
2819
2990
|
return typeof value === "object" && value !== null && value.addingChoices === true;
|
|
@@ -2843,12 +3014,12 @@ function ChoiceAskButtons({
|
|
|
2843
3014
|
onCancel,
|
|
2844
3015
|
busy
|
|
2845
3016
|
}) {
|
|
2846
|
-
return /* @__PURE__ */ (0,
|
|
2847
|
-
/* @__PURE__ */ (0,
|
|
2848
|
-
/* @__PURE__ */ (0,
|
|
2849
|
-
/* @__PURE__ */ (0,
|
|
2850
|
-
keepOffered ? /* @__PURE__ */ (0,
|
|
2851
|
-
/* @__PURE__ */ (0,
|
|
3017
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { "data-records-choice-ask": "", role: "group", "aria-label": choiceAskSentence(field, words), className: "flex flex-col gap-1", children: [
|
|
3018
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field, words) }),
|
|
3019
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-wrap items-center gap-1", children: [
|
|
3020
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onAdd, children: "Add" }),
|
|
3021
|
+
keepOffered ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", variant: "outline", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onKeep, children: "Keep as typed" }) : null,
|
|
3022
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onCancel, children: "Cancel" })
|
|
2852
3023
|
] })
|
|
2853
3024
|
] });
|
|
2854
3025
|
}
|
|
@@ -2931,12 +3102,12 @@ function openingText(field, value) {
|
|
|
2931
3102
|
return format ? typedText(format, value) : String(value);
|
|
2932
3103
|
}
|
|
2933
3104
|
function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCancel }) {
|
|
2934
|
-
const client = (0,
|
|
3105
|
+
const client = (0, import_react25.useOptionalRecordsClient)();
|
|
2935
3106
|
const kind = String(editorKindFor(field));
|
|
2936
3107
|
const needsChoices = kind === "select" || kind === "multi_select";
|
|
2937
3108
|
const nudge = useChoiceNudge(needsChoices);
|
|
2938
|
-
const [choices, setChoices] = (0,
|
|
2939
|
-
(0,
|
|
3109
|
+
const [choices, setChoices] = (0, import_react24.useState)(null);
|
|
3110
|
+
(0, import_react24.useEffect)(() => {
|
|
2940
3111
|
if (!needsChoices || !client) return;
|
|
2941
3112
|
let cancelled = false;
|
|
2942
3113
|
void client.fieldOptions({ field_id: field.id }).then((result) => {
|
|
@@ -2946,7 +3117,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2946
3117
|
cancelled = true;
|
|
2947
3118
|
};
|
|
2948
3119
|
}, [client, field.id, needsChoices]);
|
|
2949
|
-
(0,
|
|
3120
|
+
(0, import_react24.useEffect)(() => {
|
|
2950
3121
|
if (choices && nudge && value.judged === null) onChange({ ...value, judged: judgeTyped(field, value.text, choices, nudge) });
|
|
2951
3122
|
}, [choices, nudge, value, field, onChange]);
|
|
2952
3123
|
const judged = value.judged;
|
|
@@ -2958,8 +3129,8 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2958
3129
|
judged: judgeTyped(field, text, needsChoices ? choices : void 0, needsChoices ? nudge : void 0),
|
|
2959
3130
|
...value.openedAs !== void 0 ? { openedAs: value.openedAs } : {}
|
|
2960
3131
|
});
|
|
2961
|
-
const box = /* @__PURE__ */ (0,
|
|
2962
|
-
|
|
3132
|
+
const box = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3133
|
+
import_design_system14.BasicInput,
|
|
2963
3134
|
{
|
|
2964
3135
|
id,
|
|
2965
3136
|
value: value.text,
|
|
@@ -2970,16 +3141,16 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2970
3141
|
onChange: (e) => retype(e.target.value)
|
|
2971
3142
|
}
|
|
2972
3143
|
);
|
|
2973
|
-
return /* @__PURE__ */ (0,
|
|
2974
|
-
helper && !disabled ? /* @__PURE__ */ (0,
|
|
3144
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col gap-0.5", children: [
|
|
3145
|
+
helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex min-w-0 items-center gap-0.5", children: [
|
|
2975
3146
|
box,
|
|
2976
|
-
/* @__PURE__ */ (0,
|
|
3147
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field) })
|
|
2977
3148
|
] }) : box,
|
|
2978
|
-
judged === null ? /* @__PURE__ */ (0,
|
|
3149
|
+
judged === null ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
2979
3150
|
"Reading ",
|
|
2980
3151
|
fieldName(field),
|
|
2981
3152
|
"'s choices\u2026"
|
|
2982
|
-
] }) : "ask" in judged ? /* @__PURE__ */ (0,
|
|
3153
|
+
] }) : "ask" in judged ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2983
3154
|
ChoiceAskButtons,
|
|
2984
3155
|
{
|
|
2985
3156
|
field,
|
|
@@ -2995,10 +3166,10 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2995
3166
|
},
|
|
2996
3167
|
onCancel: () => onCancel?.()
|
|
2997
3168
|
}
|
|
2998
|
-
) : "refusal" in judged ? /* @__PURE__ */ (0,
|
|
2999
|
-
/* @__PURE__ */ (0,
|
|
3000
|
-
judged.cancelOnly && onCancel ? /* @__PURE__ */ (0,
|
|
3001
|
-
] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ (0,
|
|
3169
|
+
) : "refusal" in judged ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col gap-1", children: [
|
|
3170
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: judged.refusal }),
|
|
3171
|
+
judged.cancelOnly && onCancel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "data-records-choice-ask": "", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => onCancel(), children: "Cancel" }) }) : null
|
|
3172
|
+
] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { "data-records-typed-reads-as": "", className: "text-[10px] text-muted-foreground", children: [
|
|
3002
3173
|
isChoiceAddition(judged.value) ? `Adds ${quoted(judged.value.add)} to the choices for ${fieldName(field)}. ` : null,
|
|
3003
3174
|
"Reads as",
|
|
3004
3175
|
" ",
|
|
@@ -3009,7 +3180,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
3009
3180
|
}).join(", ")
|
|
3010
3181
|
) : (() => {
|
|
3011
3182
|
const shown2 = format ?? (kind === "datetime" ? { id: carriesTimeOfDay(field, judged.value) ? "datetime" : "date" } : void 0);
|
|
3012
|
-
return shown2 ? /* @__PURE__ */ (0,
|
|
3183
|
+
return shown2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FormattedValue, { value: judged.value, format: shown2 }) : String(judged.value);
|
|
3013
3184
|
})()
|
|
3014
3185
|
] })
|
|
3015
3186
|
] });
|
|
@@ -3022,13 +3193,13 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3022
3193
|
const host = useRecordsUi();
|
|
3023
3194
|
const kind = editorKindFor(field);
|
|
3024
3195
|
const inputId = id ?? `field-${field.key}`;
|
|
3025
|
-
const ownDetails = (0,
|
|
3026
|
-
if (isTypedDraft(value)) return /* @__PURE__ */ (0,
|
|
3027
|
-
if (isSignatureField(field)) return /* @__PURE__ */ (0,
|
|
3196
|
+
const ownDetails = (0, import_react25.useOptionalRecordsClient)() === null;
|
|
3197
|
+
if (isTypedDraft(value)) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedTextControl, { field, value, onChange, disabled, id: inputId, onCommit, onCancel });
|
|
3198
|
+
if (isSignatureField(field)) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SignaturePad, { id: inputId, value, onChange, disabled });
|
|
3028
3199
|
const newerControl = newerKindControl({ field, value, onChange, disabled, id: inputId });
|
|
3029
3200
|
if (newerControl !== void 0) return newerControl;
|
|
3030
3201
|
const format = formatForField(field);
|
|
3031
|
-
if (format && format.id === "time") return /* @__PURE__ */ (0,
|
|
3202
|
+
if (format && format.id === "time") return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
|
|
3032
3203
|
if (format && !FORMAT_BLIND_KINDS.has(String(kind))) {
|
|
3033
3204
|
const own3 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field), ownDetails });
|
|
3034
3205
|
if (own3) return own3;
|
|
@@ -3037,18 +3208,18 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3037
3208
|
case "formula":
|
|
3038
3209
|
case "lookup":
|
|
3039
3210
|
case "rollup":
|
|
3040
|
-
return /* @__PURE__ */ (0,
|
|
3211
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { id: inputId, className: "rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground", children: [
|
|
3041
3212
|
value === null || value === void 0 ? "\u2014" : String(value),
|
|
3042
|
-
/* @__PURE__ */ (0,
|
|
3213
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "ml-2 italic", children: [
|
|
3043
3214
|
fieldName(field),
|
|
3044
3215
|
" is worked out by the system, so it cannot be typed in"
|
|
3045
3216
|
] })
|
|
3046
3217
|
] });
|
|
3047
3218
|
case "json":
|
|
3048
|
-
return /* @__PURE__ */ (0,
|
|
3219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(JsonControl, { field, value, onChange, disabled, id: inputId });
|
|
3049
3220
|
case "long_text":
|
|
3050
|
-
return /* @__PURE__ */ (0,
|
|
3051
|
-
|
|
3221
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3222
|
+
import_design_system14.BasicTextarea,
|
|
3052
3223
|
{
|
|
3053
3224
|
id: inputId,
|
|
3054
3225
|
rows: 3,
|
|
@@ -3060,8 +3231,8 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3060
3231
|
case "number":
|
|
3061
3232
|
case "currency":
|
|
3062
3233
|
case "percent":
|
|
3063
|
-
return /* @__PURE__ */ (0,
|
|
3064
|
-
|
|
3234
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3235
|
+
import_design_system14.BasicInput,
|
|
3065
3236
|
{
|
|
3066
3237
|
id: inputId,
|
|
3067
3238
|
type: "number",
|
|
@@ -3073,12 +3244,12 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3073
3244
|
}
|
|
3074
3245
|
);
|
|
3075
3246
|
case "datetime":
|
|
3076
|
-
return /* @__PURE__ */ (0,
|
|
3247
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
|
|
3077
3248
|
case "email":
|
|
3078
3249
|
case "phone":
|
|
3079
3250
|
case "url":
|
|
3080
|
-
return /* @__PURE__ */ (0,
|
|
3081
|
-
|
|
3251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3252
|
+
import_design_system14.BasicInput,
|
|
3082
3253
|
{
|
|
3083
3254
|
id: inputId,
|
|
3084
3255
|
type: kind === "email" ? "email" : kind === "phone" ? "tel" : "url",
|
|
@@ -3089,25 +3260,25 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3089
3260
|
}
|
|
3090
3261
|
);
|
|
3091
3262
|
case "checkbox":
|
|
3092
|
-
return /* @__PURE__ */ (0,
|
|
3263
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CheckboxControl, { field, value, onChange, disabled, id: inputId });
|
|
3093
3264
|
case "select":
|
|
3094
3265
|
case "multi_select":
|
|
3095
|
-
return /* @__PURE__ */ (0,
|
|
3266
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(OptionControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
|
|
3096
3267
|
case "member":
|
|
3097
|
-
return /* @__PURE__ */ (0,
|
|
3268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PersonPicker, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
|
|
3098
3269
|
case "entity_reference":
|
|
3099
|
-
return /* @__PURE__ */ (0,
|
|
3270
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(EntityReferenceControl, { field, value, onChange, disabled, id: inputId });
|
|
3100
3271
|
case "attachment":
|
|
3101
3272
|
if (hostTakesFiles(host)) {
|
|
3102
|
-
return /* @__PURE__ */ (0,
|
|
3273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AttachmentControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose });
|
|
3103
3274
|
}
|
|
3104
|
-
return /* @__PURE__ */ (0,
|
|
3275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
|
|
3105
3276
|
case "relation":
|
|
3106
|
-
return /* @__PURE__ */ (0,
|
|
3277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
|
|
3107
3278
|
default:
|
|
3108
3279
|
if (typeof value === "boolean" || field.config?.["kind"] === "boolean") {
|
|
3109
|
-
return /* @__PURE__ */ (0,
|
|
3110
|
-
|
|
3280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3281
|
+
import_design_system14.Checkbox,
|
|
3111
3282
|
{
|
|
3112
3283
|
id: inputId,
|
|
3113
3284
|
checked: value === true,
|
|
@@ -3116,8 +3287,8 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3116
3287
|
}
|
|
3117
3288
|
);
|
|
3118
3289
|
}
|
|
3119
|
-
return /* @__PURE__ */ (0,
|
|
3120
|
-
|
|
3290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3291
|
+
import_design_system14.BasicInput,
|
|
3121
3292
|
{
|
|
3122
3293
|
id: inputId,
|
|
3123
3294
|
...ownDetails && isPersonsName(field) ? { autoComplete: "name" } : {},
|
|
@@ -3129,10 +3300,10 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3129
3300
|
}
|
|
3130
3301
|
}
|
|
3131
3302
|
function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
3132
|
-
const [text, setText] = (0,
|
|
3133
|
-
const [refusal2, setRefusal] = (0,
|
|
3134
|
-
const sent = (0,
|
|
3135
|
-
(0,
|
|
3303
|
+
const [text, setText] = (0, import_react24.useState)(() => openingText(field, value));
|
|
3304
|
+
const [refusal2, setRefusal] = (0, import_react24.useState)(null);
|
|
3305
|
+
const sent = (0, import_react24.useRef)(value);
|
|
3306
|
+
(0, import_react24.useEffect)(() => {
|
|
3136
3307
|
if (value === sent.current) return;
|
|
3137
3308
|
sent.current = value;
|
|
3138
3309
|
setText(openingText(field, value));
|
|
@@ -3150,10 +3321,10 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
|
3150
3321
|
setRefusal(judged.refusal);
|
|
3151
3322
|
}
|
|
3152
3323
|
};
|
|
3153
|
-
return /* @__PURE__ */ (0,
|
|
3154
|
-
/* @__PURE__ */ (0,
|
|
3155
|
-
/* @__PURE__ */ (0,
|
|
3156
|
-
|
|
3324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col gap-0.5", children: [
|
|
3325
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex min-w-0 items-center gap-0.5", children: [
|
|
3326
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3327
|
+
import_design_system14.BasicInput,
|
|
3157
3328
|
{
|
|
3158
3329
|
id,
|
|
3159
3330
|
value: text,
|
|
@@ -3169,16 +3340,16 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
|
3169
3340
|
}
|
|
3170
3341
|
}
|
|
3171
3342
|
),
|
|
3172
|
-
helper && !disabled ? /* @__PURE__ */ (0,
|
|
3343
|
+
helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field) }) : null
|
|
3173
3344
|
] }),
|
|
3174
|
-
refusal2 ? /* @__PURE__ */ (0,
|
|
3345
|
+
refusal2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal2 }) : null
|
|
3175
3346
|
] });
|
|
3176
3347
|
}
|
|
3177
3348
|
function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
3178
3349
|
const unanswered = value === null || value === void 0;
|
|
3179
|
-
return /* @__PURE__ */ (0,
|
|
3180
|
-
/* @__PURE__ */ (0,
|
|
3181
|
-
|
|
3350
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3351
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3352
|
+
import_design_system14.Checkbox,
|
|
3182
3353
|
{
|
|
3183
3354
|
id,
|
|
3184
3355
|
checked: value === true,
|
|
@@ -3187,10 +3358,10 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
|
3187
3358
|
onCheckedChange: (next) => onChange(next === true)
|
|
3188
3359
|
}
|
|
3189
3360
|
),
|
|
3190
|
-
unanswered ? /* @__PURE__ */ (0,
|
|
3191
|
-
/* @__PURE__ */ (0,
|
|
3192
|
-
field.required ? null : /* @__PURE__ */ (0,
|
|
3193
|
-
|
|
3361
|
+
unanswered ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-xs italic text-muted-foreground", children: "not answered yet" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3362
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-xs text-muted-foreground", children: value === true ? "Yes" : "No" }),
|
|
3363
|
+
field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3364
|
+
import_design_system14.Button,
|
|
3194
3365
|
{
|
|
3195
3366
|
size: "sm",
|
|
3196
3367
|
variant: "ghost",
|
|
@@ -3205,11 +3376,11 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
|
3205
3376
|
}
|
|
3206
3377
|
function JsonControl({ field, value, onChange, disabled, id }) {
|
|
3207
3378
|
const initial = value === null || value === void 0 ? "" : typeof value === "string" ? value : JSON.stringify(value, null, 2);
|
|
3208
|
-
const [text, setText] = (0,
|
|
3209
|
-
const [broken, setBroken] = (0,
|
|
3210
|
-
return /* @__PURE__ */ (0,
|
|
3211
|
-
/* @__PURE__ */ (0,
|
|
3212
|
-
|
|
3379
|
+
const [text, setText] = (0, import_react24.useState)(initial);
|
|
3380
|
+
const [broken, setBroken] = (0, import_react24.useState)(null);
|
|
3381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3382
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3383
|
+
import_design_system14.BasicTextarea,
|
|
3213
3384
|
{
|
|
3214
3385
|
id,
|
|
3215
3386
|
rows: 4,
|
|
@@ -3242,7 +3413,7 @@ function JsonControl({ field, value, onChange, disabled, id }) {
|
|
|
3242
3413
|
),
|
|
3243
3414
|
broken ? (
|
|
3244
3415
|
// The typed text is still in the box: the notice owns the two doors out.
|
|
3245
|
-
/* @__PURE__ */ (0,
|
|
3416
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3246
3417
|
RefusalNotice,
|
|
3247
3418
|
{
|
|
3248
3419
|
error: broken,
|
|
@@ -3266,11 +3437,11 @@ function inTheStoresOrder(options) {
|
|
|
3266
3437
|
return [...options].sort((a, b) => position(a) - position(b) || made(a).localeCompare(made(b)));
|
|
3267
3438
|
}
|
|
3268
3439
|
function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose, addsChoices, initialSearch, asForm }) {
|
|
3269
|
-
const client = (0,
|
|
3270
|
-
const [options, setOptions] = (0,
|
|
3271
|
-
const [refusal2, setRefusal] = (0,
|
|
3272
|
-
const [reread, setReread] = (0,
|
|
3273
|
-
(0,
|
|
3440
|
+
const client = (0, import_react25.useOptionalRecordsClient)();
|
|
3441
|
+
const [options, setOptions] = (0, import_react24.useState)(null);
|
|
3442
|
+
const [refusal2, setRefusal] = (0, import_react24.useState)(null);
|
|
3443
|
+
const [reread, setReread] = (0, import_react24.useState)(0);
|
|
3444
|
+
(0, import_react24.useEffect)(() => {
|
|
3274
3445
|
if (!client) return;
|
|
3275
3446
|
let cancelled = false;
|
|
3276
3447
|
void client.fieldOptions({ field_id: field.id }).then((result) => {
|
|
@@ -3284,12 +3455,12 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3284
3455
|
}, [client, field.id, reread]);
|
|
3285
3456
|
const handed = publicChoicesOf(field);
|
|
3286
3457
|
if (!client && handed.length > 0) {
|
|
3287
|
-
return /* @__PURE__ */ (0,
|
|
3458
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChoiceAnswer, { field, choices: handed, value, onChange, disabled, id });
|
|
3288
3459
|
}
|
|
3289
3460
|
if (!client) {
|
|
3290
|
-
return /* @__PURE__ */ (0,
|
|
3291
|
-
/* @__PURE__ */ (0,
|
|
3292
|
-
|
|
3461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3462
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3463
|
+
import_design_system14.BasicInput,
|
|
3293
3464
|
{
|
|
3294
3465
|
id,
|
|
3295
3466
|
value: value === null || value === void 0 ? "" : String(value),
|
|
@@ -3297,15 +3468,15 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3297
3468
|
onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
|
|
3298
3469
|
}
|
|
3299
3470
|
),
|
|
3300
|
-
/* @__PURE__ */ (0,
|
|
3471
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("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." })
|
|
3301
3472
|
] });
|
|
3302
3473
|
}
|
|
3303
3474
|
if (refusal2)
|
|
3304
|
-
return /* @__PURE__ */ (0,
|
|
3305
|
-
if (!options) return /* @__PURE__ */ (0,
|
|
3475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { id, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RefusalLine, { error: refusal2 }) });
|
|
3476
|
+
if (!options) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
|
|
3306
3477
|
if (asForm && options.length > 0) {
|
|
3307
3478
|
const titled = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3308
|
-
return /* @__PURE__ */ (0,
|
|
3479
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3309
3480
|
ChoiceAnswer,
|
|
3310
3481
|
{
|
|
3311
3482
|
field,
|
|
@@ -3322,7 +3493,7 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3322
3493
|
);
|
|
3323
3494
|
}
|
|
3324
3495
|
if (CHOICE_EDITOR_ADDS_WHAT_IS_TYPED) {
|
|
3325
|
-
return /* @__PURE__ */ (0,
|
|
3496
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3326
3497
|
OpenChoicePicker,
|
|
3327
3498
|
{
|
|
3328
3499
|
field,
|
|
@@ -3341,14 +3512,14 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3341
3512
|
);
|
|
3342
3513
|
}
|
|
3343
3514
|
if (options.length === 0) {
|
|
3344
|
-
return /* @__PURE__ */ (0,
|
|
3515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("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.` });
|
|
3345
3516
|
}
|
|
3346
3517
|
const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3347
3518
|
if (field.multi) {
|
|
3348
3519
|
const chosen = options.filter((option) => (0, import_records10.choiceValuesOf)(value).some((v) => (0, import_records10.isTheChosen)(option, v)));
|
|
3349
3520
|
const picked = new Set(chosen.map((option) => (0, import_records10.optionKey)(option)));
|
|
3350
|
-
const toggles = /* @__PURE__ */ (0,
|
|
3351
|
-
|
|
3521
|
+
const toggles = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3522
|
+
import_design_system14.Button,
|
|
3352
3523
|
{
|
|
3353
3524
|
type: "button",
|
|
3354
3525
|
size: "sm",
|
|
@@ -3365,23 +3536,23 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3365
3536
|
option.id
|
|
3366
3537
|
)) });
|
|
3367
3538
|
if (!autoOpen) return toggles;
|
|
3368
|
-
return /* @__PURE__ */ (0,
|
|
3369
|
-
|
|
3539
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3540
|
+
import_design_system14.Popover,
|
|
3370
3541
|
{
|
|
3371
3542
|
defaultOpen: true,
|
|
3372
3543
|
onOpenChange: (open) => {
|
|
3373
3544
|
if (!open) onClose?.();
|
|
3374
3545
|
},
|
|
3375
3546
|
children: [
|
|
3376
|
-
/* @__PURE__ */ (0,
|
|
3377
|
-
/* @__PURE__ */ (0,
|
|
3547
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { id, type: "button", size: "sm", variant: "outline", className: "h-6 max-w-full truncate", children: chosen.length === 0 ? "Choose" : chosen.map(titleOf).join(", ") }) }),
|
|
3548
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.PopoverContent, { sizing: "content", className: "max-w-[20rem] p-2", align: "start", children: toggles })
|
|
3378
3549
|
]
|
|
3379
3550
|
}
|
|
3380
3551
|
);
|
|
3381
3552
|
}
|
|
3382
3553
|
const current = options.find((option) => (0, import_records10.isTheChosen)(option, value));
|
|
3383
|
-
return /* @__PURE__ */ (0,
|
|
3384
|
-
|
|
3554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3555
|
+
import_design_system14.Select,
|
|
3385
3556
|
{
|
|
3386
3557
|
value: current ? (0, import_records10.optionKey)(current) : "",
|
|
3387
3558
|
disabled: disabled ?? false,
|
|
@@ -3394,8 +3565,8 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3394
3565
|
}
|
|
3395
3566
|
} : {},
|
|
3396
3567
|
children: [
|
|
3397
|
-
/* @__PURE__ */ (0,
|
|
3398
|
-
/* @__PURE__ */ (0,
|
|
3568
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.SelectTrigger, { id, size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.SelectValue, { placeholder: "Choose" }) }),
|
|
3569
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.SelectItem, { value: (0, import_records10.optionKey)(option), children: titleOf(option) }, option.id)) })
|
|
3399
3570
|
]
|
|
3400
3571
|
}
|
|
3401
3572
|
);
|
|
@@ -3414,18 +3585,18 @@ function OpenChoicePicker({
|
|
|
3414
3585
|
allowOther = true,
|
|
3415
3586
|
onChoicesChanged
|
|
3416
3587
|
}) {
|
|
3417
|
-
const client = (0,
|
|
3588
|
+
const client = (0, import_react25.useOptionalRecordsClient)();
|
|
3418
3589
|
const nudge = useChoiceNudge();
|
|
3419
|
-
const [open, setOpenState] = (0,
|
|
3420
|
-
const onCloseRef = (0,
|
|
3590
|
+
const [open, setOpenState] = (0, import_react24.useState)(autoOpen === true);
|
|
3591
|
+
const onCloseRef = (0, import_react24.useRef)(onClose);
|
|
3421
3592
|
onCloseRef.current = onClose;
|
|
3422
|
-
const setOpen = (0,
|
|
3593
|
+
const setOpen = (0, import_react24.useCallback)((next) => {
|
|
3423
3594
|
setOpenState(next);
|
|
3424
3595
|
if (!next) onCloseRef.current?.();
|
|
3425
3596
|
}, []);
|
|
3426
|
-
const [search, setSearch] = (0,
|
|
3427
|
-
const [adding, setAdding] = (0,
|
|
3428
|
-
const [addRefused, setAddRefused] = (0,
|
|
3597
|
+
const [search, setSearch] = (0, import_react24.useState)(initialSearch ?? "");
|
|
3598
|
+
const [adding, setAdding] = (0, import_react24.useState)(false);
|
|
3599
|
+
const [addRefused, setAddRefused] = (0, import_react24.useState)(null);
|
|
3429
3600
|
const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3430
3601
|
const held = withoutAddition(value);
|
|
3431
3602
|
const current = (0, import_records10.choiceValuesOf)(held.value);
|
|
@@ -3477,7 +3648,7 @@ function OpenChoicePicker({
|
|
|
3477
3648
|
});
|
|
3478
3649
|
};
|
|
3479
3650
|
const offList = q !== "" && decided.decision !== "chosen" && decided.decision !== "empty";
|
|
3480
|
-
const foot = offList && decided.decision === "ask" ? /* @__PURE__ */ (0,
|
|
3651
|
+
const foot = offList && decided.decision === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3481
3652
|
ChoiceAskButtons,
|
|
3482
3653
|
{
|
|
3483
3654
|
field,
|
|
@@ -3494,14 +3665,14 @@ function OpenChoicePicker({
|
|
|
3494
3665
|
}
|
|
3495
3666
|
) : null;
|
|
3496
3667
|
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;
|
|
3497
|
-
return /* @__PURE__ */ (0,
|
|
3668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { id, className: "flex flex-wrap items-center gap-1", children: [
|
|
3498
3669
|
pickedWords.map((word, i) => {
|
|
3499
3670
|
const chip = chipOf(options.find((o) => (0, import_records10.isTheChosen)(o, current[i])), word);
|
|
3500
|
-
return /* @__PURE__ */ (0,
|
|
3671
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Badge, { variant: "outline", className: (0, import_design_system14.cn)("text-[11px]", chip.className), "data-records-choice-chip": "", children: word }, word);
|
|
3501
3672
|
}),
|
|
3502
3673
|
disabled ? null : (
|
|
3503
3674
|
// THE ONE "PICK OR ADD" BUILDER (PickOrAdd.tsx) — the relation picker draws the same one.
|
|
3504
|
-
/* @__PURE__ */ (0,
|
|
3675
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3505
3676
|
PickOrAdd,
|
|
3506
3677
|
{
|
|
3507
3678
|
triggerLabel: `Pick for ${fieldName(field)}`,
|
|
@@ -3523,15 +3694,15 @@ function OpenChoicePicker({
|
|
|
3523
3694
|
const option = options.find((o) => o.id === optionId);
|
|
3524
3695
|
if (option) choose((0, import_records10.optionKey)(option));
|
|
3525
3696
|
},
|
|
3526
|
-
empty: q === "" ? /* @__PURE__ */ (0,
|
|
3697
|
+
empty: q === "" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
|
|
3527
3698
|
add,
|
|
3528
3699
|
foot,
|
|
3529
3700
|
...offList && decided.decision === "ask" && !adding ? { onEnterWithNoMatch: addTyped } : {},
|
|
3530
|
-
footNote: addRefused ? /* @__PURE__ */ (0,
|
|
3701
|
+
footNote: addRefused ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RefusalLine, { error: addRefused }) : offList && decided.decision === "not_a_choice" ? (
|
|
3531
3702
|
// never_add on a column that takes only its choices: said, never a silent nothing.
|
|
3532
|
-
/* @__PURE__ */ (0,
|
|
3533
|
-
/* @__PURE__ */ (0,
|
|
3534
|
-
autoOpen ? /* @__PURE__ */ (0,
|
|
3703
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3704
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { "data-records-typed-refusal": "", className: "p-2 text-xs text-muted-foreground", children: notAChoiceSentence(field, [q]) }),
|
|
3705
|
+
autoOpen ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "data-records-choice-ask": "", className: "px-2 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => setOpen(false), children: "Cancel" }) }) : null
|
|
3535
3706
|
] })
|
|
3536
3707
|
) : null
|
|
3537
3708
|
}
|
|
@@ -3550,9 +3721,9 @@ function RecordChip({
|
|
|
3550
3721
|
// name. So it caps at its container and ends in an ellipsis with the whole name in
|
|
3551
3722
|
// its tooltip, rather than being cut mid-word by whatever box it landed in
|
|
3552
3723
|
// (lane FIX-14, 2026-09-22).
|
|
3553
|
-
/* @__PURE__ */ (0,
|
|
3554
|
-
/* @__PURE__ */ (0,
|
|
3555
|
-
onRemove ? /* @__PURE__ */ (0,
|
|
3724
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system14.Badge, { variant: "secondary", className: (0, import_design_system14.cn)("max-w-full gap-1 text-[11px]", className), title, children: [
|
|
3725
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate", children: title }),
|
|
3726
|
+
onRemove ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${title}`, className: "shrink-0 opacity-60 hover:opacity-100", children: "\xD7" }) : null
|
|
3556
3727
|
] })
|
|
3557
3728
|
);
|
|
3558
3729
|
}
|
|
@@ -3564,7 +3735,8 @@ function publicChoicesOf(field) {
|
|
|
3564
3735
|
return typeof o.key === "string" && typeof o.label === "string" ? [{ key: o.key, label: o.label }] : [];
|
|
3565
3736
|
});
|
|
3566
3737
|
}
|
|
3567
|
-
var
|
|
3738
|
+
var FORM_SEARCH_AFTER = 8;
|
|
3739
|
+
var CHOICE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
3568
3740
|
function ChoiceAnswer({
|
|
3569
3741
|
field,
|
|
3570
3742
|
choices,
|
|
@@ -3574,7 +3746,7 @@ function ChoiceAnswer({
|
|
|
3574
3746
|
id,
|
|
3575
3747
|
isChosen
|
|
3576
3748
|
}) {
|
|
3577
|
-
const [search, setSearch] = (0,
|
|
3749
|
+
const [search, setSearch] = (0, import_react24.useState)("");
|
|
3578
3750
|
const held = field.multi ? (0, import_records10.choiceValuesOf)(value) : value === null || value === void 0 || value === "" ? [] : [value];
|
|
3579
3751
|
const on = (choice) => held.some((v) => isChosen ? isChosen(choice, v) : String(v) === choice.key || String(v) === choice.label);
|
|
3580
3752
|
const press = (choice) => {
|
|
@@ -3585,71 +3757,90 @@ function ChoiceAnswer({
|
|
|
3585
3757
|
const keys = choices.filter((c) => c.key === choice.key ? !on(c) : on(c)).map((c) => c.key);
|
|
3586
3758
|
onChange(keys.length === 0 ? null : keys);
|
|
3587
3759
|
};
|
|
3588
|
-
const
|
|
3760
|
+
const lettered = choices.length <= CHOICE_LETTERS.length;
|
|
3761
|
+
const option = (choice) => {
|
|
3589
3762
|
const chosen = on(choice);
|
|
3590
|
-
const
|
|
3591
|
-
return /* @__PURE__ */ (0,
|
|
3763
|
+
const letter = lettered ? CHOICE_LETTERS[choices.indexOf(choice)] : null;
|
|
3764
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3592
3765
|
"button",
|
|
3593
3766
|
{
|
|
3594
3767
|
type: "button",
|
|
3595
3768
|
role: field.multi ? "checkbox" : "radio",
|
|
3596
3769
|
"aria-checked": chosen,
|
|
3770
|
+
"aria-label": choice.label,
|
|
3597
3771
|
disabled,
|
|
3598
3772
|
onClick: () => press(choice),
|
|
3599
|
-
"data-records-choice-chip": "",
|
|
3600
3773
|
"data-records-choice-answer": choice.key,
|
|
3601
|
-
className: (0,
|
|
3602
|
-
"
|
|
3603
|
-
|
|
3604
|
-
chosen ? "ring-2 ring-ring ring-offset-1" : "opacity-80 hover:opacity-100"
|
|
3774
|
+
className: (0, import_design_system14.cn)(
|
|
3775
|
+
"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",
|
|
3776
|
+
chosen ? "border-primary bg-primary/10" : "border-primary/30 bg-primary/[0.03] hover:bg-primary/10"
|
|
3605
3777
|
),
|
|
3606
3778
|
children: [
|
|
3607
|
-
|
|
3608
|
-
|
|
3779
|
+
letter ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3780
|
+
"kbd",
|
|
3781
|
+
{
|
|
3782
|
+
"aria-hidden": "true",
|
|
3783
|
+
className: (0, import_design_system14.cn)(
|
|
3784
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border font-sans text-xs font-semibold",
|
|
3785
|
+
chosen ? "border-primary bg-primary text-primary-foreground" : "border-primary/40 text-primary"
|
|
3786
|
+
),
|
|
3787
|
+
children: letter
|
|
3788
|
+
}
|
|
3789
|
+
) : null,
|
|
3790
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 flex-1 break-words", children: choice.label }),
|
|
3791
|
+
chosen ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "aria-hidden": "true", className: "shrink-0 text-primary", children: "\u2713" }) : null
|
|
3609
3792
|
]
|
|
3610
3793
|
},
|
|
3611
3794
|
choice.key
|
|
3612
3795
|
);
|
|
3613
3796
|
};
|
|
3614
|
-
const
|
|
3615
|
-
|
|
3616
|
-
|
|
3797
|
+
const onKeyDown = (event) => {
|
|
3798
|
+
if (!lettered || disabled || event.metaKey || event.ctrlKey || event.altKey) return;
|
|
3799
|
+
if (event.target.tagName === "INPUT") return;
|
|
3800
|
+
const at = CHOICE_LETTERS.indexOf(event.key.toUpperCase());
|
|
3801
|
+
if (event.key.length !== 1 || at < 0 || at >= choices.length) return;
|
|
3802
|
+
event.preventDefault();
|
|
3803
|
+
press(choices[at]);
|
|
3804
|
+
};
|
|
3805
|
+
const group = { role: field.multi ? "group" : "radiogroup", "aria-label": fieldName(field), onKeyDown };
|
|
3806
|
+
if (choices.length <= FORM_SEARCH_AFTER) {
|
|
3807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { id, className: "flex w-full flex-col gap-2", ...group, children: choices.map(option) });
|
|
3617
3808
|
}
|
|
3618
3809
|
const q = search.trim().toLowerCase();
|
|
3619
3810
|
const shown2 = q === "" ? choices : choices.filter((c) => c.label.toLowerCase().includes(q));
|
|
3620
|
-
return /* @__PURE__ */ (0,
|
|
3621
|
-
/* @__PURE__ */ (0,
|
|
3622
|
-
|
|
3811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { id, className: "flex w-full flex-col gap-2", onKeyDown, children: [
|
|
3812
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3813
|
+
import_design_system14.BasicInput,
|
|
3623
3814
|
{
|
|
3624
3815
|
value: search,
|
|
3625
3816
|
onChange: (e) => setSearch(e.target.value),
|
|
3626
3817
|
placeholder: "Search",
|
|
3627
3818
|
"aria-label": `Search \u2014 ${fieldName(field)}`,
|
|
3628
3819
|
autoComplete: "off",
|
|
3629
|
-
className: "h-11 text-base sm:h-
|
|
3820
|
+
className: "h-11 text-base sm:h-9 sm:text-sm"
|
|
3630
3821
|
}
|
|
3631
3822
|
),
|
|
3632
|
-
/* @__PURE__ */ (0,
|
|
3633
|
-
shown2.map(
|
|
3634
|
-
shown2.length === 0 ? /* @__PURE__ */ (0,
|
|
3823
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex max-h-80 w-full flex-col gap-2 overflow-y-auto", role: group.role, "aria-label": group["aria-label"], children: [
|
|
3824
|
+
shown2.map(option),
|
|
3825
|
+
shown2.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-muted-foreground", children: "No match" }) : null
|
|
3635
3826
|
] })
|
|
3636
3827
|
] });
|
|
3637
3828
|
}
|
|
3638
3829
|
|
|
3639
3830
|
// src/RecordsMount.tsx
|
|
3640
|
-
var
|
|
3641
|
-
var
|
|
3642
|
-
var
|
|
3831
|
+
var import_react26 = require("react");
|
|
3832
|
+
var import_react27 = require("@ai-matrx/records/react");
|
|
3833
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3643
3834
|
function personActor(userId) {
|
|
3644
3835
|
return userId ? { actor: "user", user_id: userId } : { actor: "user" };
|
|
3645
3836
|
}
|
|
3646
3837
|
|
|
3647
3838
|
// src/tablePicking.tsx
|
|
3648
|
-
var
|
|
3839
|
+
var import_react28 = require("react");
|
|
3649
3840
|
var import_records11 = require("@ai-matrx/records");
|
|
3650
|
-
var
|
|
3651
|
-
var
|
|
3652
|
-
var
|
|
3841
|
+
var import_react29 = require("@ai-matrx/records/react");
|
|
3842
|
+
var import_design_system15 = require("@ai-matrx/design-system");
|
|
3843
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3653
3844
|
var APP_TABLE_PREFIX = "records_ui_";
|
|
3654
3845
|
function isValueSet(table) {
|
|
3655
3846
|
if (table.kept_for === "choices") return true;
|
|
@@ -3692,26 +3883,44 @@ function madeOn(stamp) {
|
|
|
3692
3883
|
}
|
|
3693
3884
|
|
|
3694
3885
|
// src/TablePickers.tsx
|
|
3695
|
-
var
|
|
3886
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3887
|
+
var SHARED_FOR_MS = 5e3;
|
|
3888
|
+
var sharedReads = /* @__PURE__ */ new WeakMap();
|
|
3889
|
+
function readTablesAnywhere(dataSource) {
|
|
3890
|
+
const held = sharedReads.get(dataSource);
|
|
3891
|
+
if (held && Date.now() - held.at < SHARED_FOR_MS) return held.read;
|
|
3892
|
+
const read = Promise.resolve(dataSource.rpc("data_home_tables", {}, { schema: "custom" })).then(
|
|
3893
|
+
({ data, error }) => {
|
|
3894
|
+
if (error) {
|
|
3895
|
+
return {
|
|
3896
|
+
loading: false,
|
|
3897
|
+
error: refusalSentence({ message: String(error["message"] ?? "") }) || "Tables could not be read.",
|
|
3898
|
+
rows: []
|
|
3899
|
+
};
|
|
3900
|
+
}
|
|
3901
|
+
const rows = (Array.isArray(data) ? data : []).slice();
|
|
3902
|
+
rows.sort((a, b) => a.table_name.localeCompare(b.table_name));
|
|
3903
|
+
return { loading: false, error: null, rows };
|
|
3904
|
+
},
|
|
3905
|
+
(thrown) => ({
|
|
3906
|
+
loading: false,
|
|
3907
|
+
error: String(thrown?.message ?? thrown) || "Tables could not be read.",
|
|
3908
|
+
rows: []
|
|
3909
|
+
})
|
|
3910
|
+
);
|
|
3911
|
+
sharedReads.set(dataSource, { at: Date.now(), read });
|
|
3912
|
+
void read.then((result) => {
|
|
3913
|
+
if (result.error && sharedReads.get(dataSource)?.read === read) sharedReads.delete(dataSource);
|
|
3914
|
+
});
|
|
3915
|
+
return read;
|
|
3916
|
+
}
|
|
3696
3917
|
function useTablesAnywhere(dataSource) {
|
|
3697
|
-
const [state, setState] = (0,
|
|
3698
|
-
(0,
|
|
3918
|
+
const [state, setState] = (0, import_react30.useState)({ loading: true, error: null, rows: [] });
|
|
3919
|
+
(0, import_react30.useEffect)(() => {
|
|
3699
3920
|
let live = true;
|
|
3700
|
-
void
|
|
3701
|
-
(
|
|
3702
|
-
|
|
3703
|
-
if (error) {
|
|
3704
|
-
setState({ loading: false, error: refusalSentence({ message: String(error["message"] ?? "") }) || "Tables could not be read.", rows: [] });
|
|
3705
|
-
return;
|
|
3706
|
-
}
|
|
3707
|
-
const rows = (Array.isArray(data) ? data : []).slice();
|
|
3708
|
-
rows.sort((a, b) => a.table_name.localeCompare(b.table_name));
|
|
3709
|
-
setState({ loading: false, error: null, rows });
|
|
3710
|
-
},
|
|
3711
|
-
(thrown) => {
|
|
3712
|
-
if (live) setState({ loading: false, error: String(thrown?.message ?? thrown), rows: [] });
|
|
3713
|
-
}
|
|
3714
|
-
);
|
|
3921
|
+
void readTablesAnywhere(dataSource).then((result) => {
|
|
3922
|
+
if (live) setState(result);
|
|
3923
|
+
});
|
|
3715
3924
|
return () => {
|
|
3716
3925
|
live = false;
|
|
3717
3926
|
};
|
|
@@ -3732,9 +3941,9 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
|
|
|
3732
3941
|
keywords: t.organization_name
|
|
3733
3942
|
}));
|
|
3734
3943
|
const missing = Boolean(value) && !list.loading && !list.error && !list.rows.some((t) => t.table_id === value);
|
|
3735
|
-
return /* @__PURE__ */ (0,
|
|
3736
|
-
/* @__PURE__ */ (0,
|
|
3737
|
-
|
|
3944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3945
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3946
|
+
import_design_system16.CreatablePicker,
|
|
3738
3947
|
{
|
|
3739
3948
|
value: value || null,
|
|
3740
3949
|
options,
|
|
@@ -3747,23 +3956,24 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
|
|
|
3747
3956
|
ariaLabel: "Table"
|
|
3748
3957
|
}
|
|
3749
3958
|
),
|
|
3750
|
-
list.error && /* @__PURE__ */ (0,
|
|
3751
|
-
missing && /* @__PURE__ */ (0,
|
|
3959
|
+
list.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefusalLine, { error: refusal("door", list.error, "Try again in a moment.") }),
|
|
3960
|
+
missing && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-[11px] text-destructive", children: "This table is archived or not shared with you." })
|
|
3752
3961
|
] });
|
|
3753
3962
|
}
|
|
3754
|
-
function TableScope({ dataSource, userId, tableId, children, fallback = null, tables }) {
|
|
3963
|
+
function TableScope({ dataSource, userId, tableId, children, fallback = null, unavailable, tables }) {
|
|
3755
3964
|
const own3 = useTablesAnywhere(dataSource);
|
|
3756
3965
|
const list = tables ?? own3;
|
|
3757
3966
|
const organizationId = list.rows.find((t) => t.table_id === tableId)?.organization_id ?? null;
|
|
3758
|
-
if (
|
|
3759
|
-
return /* @__PURE__ */ (0,
|
|
3967
|
+
if (tableId && !organizationId && !list.loading) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: unavailable ?? fallback });
|
|
3968
|
+
if (!tableId || !organizationId) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: fallback });
|
|
3969
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react31.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children });
|
|
3760
3970
|
}
|
|
3761
3971
|
function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
3762
|
-
const fields = (0,
|
|
3763
|
-
const all = (0,
|
|
3764
|
-
const byKey = (0,
|
|
3972
|
+
const fields = (0, import_react31.useFields)(tableId);
|
|
3973
|
+
const all = (0, import_react30.useMemo)(() => fields.data ?? [], [fields.data]);
|
|
3974
|
+
const byKey = (0, import_react30.useMemo)(() => new Map(all.map((f) => [f.key, f])), [all]);
|
|
3765
3975
|
const keys = Object.keys(value);
|
|
3766
|
-
const [adding, setAdding] = (0,
|
|
3976
|
+
const [adding, setAdding] = (0, import_react30.useState)(false);
|
|
3767
3977
|
const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
|
|
3768
3978
|
const rename = (from, to) => {
|
|
3769
3979
|
if (from === to) return;
|
|
@@ -3776,11 +3986,11 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3776
3986
|
void _gone;
|
|
3777
3987
|
onChange(rest);
|
|
3778
3988
|
};
|
|
3779
|
-
return /* @__PURE__ */ (0,
|
|
3780
|
-
fields.error && /* @__PURE__ */ (0,
|
|
3989
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
3990
|
+
fields.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefusalLine, { error: fields.error }),
|
|
3781
3991
|
keys.map((key) => {
|
|
3782
3992
|
const field = byKey.get(key);
|
|
3783
|
-
return /* @__PURE__ */ (0,
|
|
3993
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3784
3994
|
ColumnValueRow,
|
|
3785
3995
|
{
|
|
3786
3996
|
columnKey: key,
|
|
@@ -3796,7 +4006,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3796
4006
|
key
|
|
3797
4007
|
);
|
|
3798
4008
|
}),
|
|
3799
|
-
adding && /* @__PURE__ */ (0,
|
|
4009
|
+
adding && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3800
4010
|
ColumnValueRow,
|
|
3801
4011
|
{
|
|
3802
4012
|
columnKey: null,
|
|
@@ -3813,7 +4023,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3813
4023
|
onRemove: () => setAdding(false)
|
|
3814
4024
|
}
|
|
3815
4025
|
),
|
|
3816
|
-
!disabled && !adding && keys.length < all.length && /* @__PURE__ */ (0,
|
|
4026
|
+
!disabled && !adding && keys.length < all.length && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_design_system16.Button, { type: "button", variant: "outline", size: "sm", className: "self-start", onClick: () => setAdding(true), children: addLabel })
|
|
3817
4027
|
] });
|
|
3818
4028
|
}
|
|
3819
4029
|
function ColumnValueRow({
|
|
@@ -3829,10 +4039,10 @@ function ColumnValueRow({
|
|
|
3829
4039
|
}) {
|
|
3830
4040
|
const orphan = columnKey !== null && !loading && field === void 0;
|
|
3831
4041
|
const shown2 = orphan ? [{ value: columnKey, label: columnKey, hint: "Not a column" }, ...options] : options;
|
|
3832
|
-
return /* @__PURE__ */ (0,
|
|
3833
|
-
/* @__PURE__ */ (0,
|
|
3834
|
-
/* @__PURE__ */ (0,
|
|
3835
|
-
|
|
4042
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1 rounded-md border border-border/60 p-2", children: [
|
|
4043
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4044
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4045
|
+
import_design_system16.CreatablePicker,
|
|
3836
4046
|
{
|
|
3837
4047
|
value: columnKey,
|
|
3838
4048
|
options: shown2,
|
|
@@ -3845,23 +4055,23 @@ function ColumnValueRow({
|
|
|
3845
4055
|
ariaLabel: "Column"
|
|
3846
4056
|
}
|
|
3847
4057
|
) }),
|
|
3848
|
-
!disabled && /* @__PURE__ */ (0,
|
|
4058
|
+
!disabled && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_design_system16.Button, { type: "button", variant: "ghost", size: "sm", "aria-label": "Remove", onClick: onRemove, children: "\u2715" })
|
|
3849
4059
|
] }),
|
|
3850
|
-
field ? /* @__PURE__ */ (0,
|
|
4060
|
+
field ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(FieldControl, { field, value, onChange: onValue, disabled }) : orphan ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-[11px] text-muted-foreground", children: value === null || value === void 0 ? "\u2014" : String(value) }) : null
|
|
3851
4061
|
] });
|
|
3852
4062
|
}
|
|
3853
4063
|
function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
3854
|
-
const table = (0,
|
|
3855
|
-
const records = (0,
|
|
4064
|
+
const table = (0, import_react31.useTable)(tableId);
|
|
4065
|
+
const records = (0, import_react31.useRecords)(tableId, { pageSize: 200 });
|
|
3856
4066
|
const rows = records.data?.rows ?? [];
|
|
3857
4067
|
const options = rows.map((row) => ({
|
|
3858
4068
|
value: row.id,
|
|
3859
4069
|
label: rowNameIn(table.data ?? null, row)
|
|
3860
4070
|
}));
|
|
3861
4071
|
const missing = Boolean(value) && !records.loading && !records.error && !rows.some((r) => r.id === value);
|
|
3862
|
-
return /* @__PURE__ */ (0,
|
|
3863
|
-
/* @__PURE__ */ (0,
|
|
3864
|
-
|
|
4072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
4073
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4074
|
+
import_design_system16.CreatablePicker,
|
|
3865
4075
|
{
|
|
3866
4076
|
value: value || null,
|
|
3867
4077
|
options,
|
|
@@ -3874,16 +4084,16 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
|
3874
4084
|
ariaLabel: "Record"
|
|
3875
4085
|
}
|
|
3876
4086
|
),
|
|
3877
|
-
records.error && /* @__PURE__ */ (0,
|
|
4087
|
+
records.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefusalLine, { error: records.error })
|
|
3878
4088
|
] });
|
|
3879
4089
|
}
|
|
3880
4090
|
|
|
3881
4091
|
// src/DataBindingPicker.tsx
|
|
3882
|
-
var
|
|
4092
|
+
var import_react32 = require("react");
|
|
3883
4093
|
var import_records12 = require("@ai-matrx/records");
|
|
3884
|
-
var
|
|
3885
|
-
var
|
|
3886
|
-
var
|
|
4094
|
+
var import_react33 = require("@ai-matrx/records/react");
|
|
4095
|
+
var import_design_system17 = require("@ai-matrx/design-system");
|
|
4096
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3887
4097
|
var DATA_BINDING_SHAPES = [
|
|
3888
4098
|
{ value: "collection", label: "The whole table" },
|
|
3889
4099
|
{ value: "reference", label: "One record" },
|
|
@@ -3950,9 +4160,9 @@ function DataBindingPicker({ dataSource, userId, binding, onChange, disabled, de
|
|
|
3950
4160
|
...binding.semantic_type === "collection" && defaultRowLimit ? { limit: defaultRowLimit } : {}
|
|
3951
4161
|
});
|
|
3952
4162
|
};
|
|
3953
|
-
return /* @__PURE__ */ (0,
|
|
3954
|
-
/* @__PURE__ */ (0,
|
|
3955
|
-
/* @__PURE__ */ (0,
|
|
4163
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
4164
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TablePicker, { dataSource, value: tableId, onChange: selectTable, disabled: Boolean(disabled), tables }),
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TableScope, { dataSource, userId, tableId, tables, children: tableId && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3956
4166
|
BindingDetails,
|
|
3957
4167
|
{
|
|
3958
4168
|
tableId,
|
|
@@ -3971,11 +4181,11 @@ function BindingDetails({
|
|
|
3971
4181
|
disabled,
|
|
3972
4182
|
defaultRowLimit
|
|
3973
4183
|
}) {
|
|
3974
|
-
const table = (0,
|
|
3975
|
-
const fields = (0,
|
|
3976
|
-
const fieldList = (0,
|
|
4184
|
+
const table = (0, import_react33.useTable)(tableId);
|
|
4185
|
+
const fields = (0, import_react33.useFields)(tableId);
|
|
4186
|
+
const fieldList = (0, import_react32.useMemo)(() => fields.data ?? [], [fields.data]);
|
|
3977
4187
|
const shape = binding.semantic_type;
|
|
3978
|
-
(0,
|
|
4188
|
+
(0, import_react32.useEffect)(() => {
|
|
3979
4189
|
if (disabled || shape === "value" || binding.transform || fields.loading || fieldList.length === 0) return;
|
|
3980
4190
|
onChange({
|
|
3981
4191
|
...binding,
|
|
@@ -4016,9 +4226,9 @@ function BindingDetails({
|
|
|
4016
4226
|
const fieldOptions = fieldList.map((f) => ({ value: f.key, label: fieldName(f) }));
|
|
4017
4227
|
const template = binding.transform?.template ?? "";
|
|
4018
4228
|
const setTemplate = (next) => onChange({ ...binding, transform: { join: "\n", ...binding.transform, name: "list", template: next } });
|
|
4019
|
-
return /* @__PURE__ */ (0,
|
|
4020
|
-
/* @__PURE__ */ (0,
|
|
4021
|
-
|
|
4229
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
4230
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-wrap gap-1", role: "radiogroup", "aria-label": "What to read", children: DATA_BINDING_SHAPES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4231
|
+
import_design_system17.Button,
|
|
4022
4232
|
{
|
|
4023
4233
|
type: "button",
|
|
4024
4234
|
size: "sm",
|
|
@@ -4031,7 +4241,7 @@ function BindingDetails({
|
|
|
4031
4241
|
},
|
|
4032
4242
|
s.value
|
|
4033
4243
|
)) }),
|
|
4034
|
-
shape !== "collection" && /* @__PURE__ */ (0,
|
|
4244
|
+
shape !== "collection" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4035
4245
|
RecordPicker,
|
|
4036
4246
|
{
|
|
4037
4247
|
tableId,
|
|
@@ -4040,8 +4250,8 @@ function BindingDetails({
|
|
|
4040
4250
|
disabled: Boolean(disabled)
|
|
4041
4251
|
}
|
|
4042
4252
|
),
|
|
4043
|
-
shape === "value" && /* @__PURE__ */ (0,
|
|
4044
|
-
|
|
4253
|
+
shape === "value" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4254
|
+
import_design_system17.CreatablePicker,
|
|
4045
4255
|
{
|
|
4046
4256
|
value: binding.field_key ?? null,
|
|
4047
4257
|
options: fieldOptions,
|
|
@@ -4054,11 +4264,11 @@ function BindingDetails({
|
|
|
4054
4264
|
ariaLabel: "Column"
|
|
4055
4265
|
}
|
|
4056
4266
|
),
|
|
4057
|
-
shape !== "value" && /* @__PURE__ */ (0,
|
|
4058
|
-
/* @__PURE__ */ (0,
|
|
4267
|
+
shape !== "value" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
4268
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4059
4269
|
"textarea",
|
|
4060
4270
|
{
|
|
4061
|
-
className: (0,
|
|
4271
|
+
className: (0, import_design_system17.cn)(
|
|
4062
4272
|
"min-h-[3.5rem] w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs"
|
|
4063
4273
|
),
|
|
4064
4274
|
"aria-label": "Each row reads as",
|
|
@@ -4067,8 +4277,8 @@ function BindingDetails({
|
|
|
4067
4277
|
onChange: (e) => setTemplate(e.target.value)
|
|
4068
4278
|
}
|
|
4069
4279
|
),
|
|
4070
|
-
!disabled && /* @__PURE__ */ (0,
|
|
4071
|
-
|
|
4280
|
+
!disabled && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-wrap gap-1", children: fieldList.flatMap(bindingPlaceholdersFor).map((p) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4281
|
+
import_design_system17.Button,
|
|
4072
4282
|
{
|
|
4073
4283
|
type: "button",
|
|
4074
4284
|
size: "sm",
|
|
@@ -4080,10 +4290,10 @@ function BindingDetails({
|
|
|
4080
4290
|
p.token
|
|
4081
4291
|
)) })
|
|
4082
4292
|
] }),
|
|
4083
|
-
shape === "collection" && /* @__PURE__ */ (0,
|
|
4293
|
+
shape === "collection" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
4084
4294
|
"Up to",
|
|
4085
|
-
/* @__PURE__ */ (0,
|
|
4086
|
-
|
|
4295
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4296
|
+
import_design_system17.BasicInput,
|
|
4087
4297
|
{
|
|
4088
4298
|
type: "number",
|
|
4089
4299
|
min: 1,
|
|
@@ -4099,10 +4309,10 @@ function BindingDetails({
|
|
|
4099
4309
|
),
|
|
4100
4310
|
"rows"
|
|
4101
4311
|
] }),
|
|
4102
|
-
/* @__PURE__ */ (0,
|
|
4103
|
-
/* @__PURE__ */ (0,
|
|
4104
|
-
DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ (0,
|
|
4105
|
-
|
|
4312
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "radiogroup", "aria-label": "If nothing is found", children: [
|
|
4313
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: "If nothing is found" }),
|
|
4314
|
+
DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4315
|
+
import_design_system17.Button,
|
|
4106
4316
|
{
|
|
4107
4317
|
type: "button",
|
|
4108
4318
|
size: "sm",
|
|
@@ -4120,12 +4330,12 @@ function BindingDetails({
|
|
|
4120
4330
|
}
|
|
4121
4331
|
|
|
4122
4332
|
// src/PickedSummaries.tsx
|
|
4123
|
-
var
|
|
4333
|
+
var import_react35 = require("@ai-matrx/records/react");
|
|
4124
4334
|
|
|
4125
4335
|
// src/values.tsx
|
|
4126
4336
|
var import_data_table4 = require("@ai-matrx/design-system/data-table");
|
|
4127
4337
|
var import_field_formats5 = require("@ai-matrx/design-system/field-formats");
|
|
4128
|
-
var
|
|
4338
|
+
var import_design_system20 = require("@ai-matrx/design-system");
|
|
4129
4339
|
|
|
4130
4340
|
// src/enumLabels.ts
|
|
4131
4341
|
function exhaustiveValuesOf() {
|
|
@@ -4162,10 +4372,10 @@ var ABSENCE_WORD_LABEL = {
|
|
|
4162
4372
|
var import_core2 = require("@ai-matrx/records/core");
|
|
4163
4373
|
|
|
4164
4374
|
// src/WholeValue.tsx
|
|
4165
|
-
var
|
|
4375
|
+
var import_react34 = require("react");
|
|
4166
4376
|
var import_core = require("@ai-matrx/records/core");
|
|
4167
|
-
var
|
|
4168
|
-
var
|
|
4377
|
+
var import_design_system18 = require("@ai-matrx/design-system");
|
|
4378
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4169
4379
|
var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
|
|
4170
4380
|
function wholeValueLine(pointer) {
|
|
4171
4381
|
return `Open the whole text (${(0, import_core.wholeValueSize)(pointer)})`;
|
|
@@ -4174,18 +4384,21 @@ function WholeValueCell({ words, pointer }) {
|
|
|
4174
4384
|
const host = useRecordsUi();
|
|
4175
4385
|
const href = host.hrefForFile?.({ fileId: pointer.file_id });
|
|
4176
4386
|
const line = wholeValueLine(pointer);
|
|
4177
|
-
return /* @__PURE__ */ (0,
|
|
4178
|
-
/* @__PURE__ */ (0,
|
|
4387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "flex min-w-0 items-baseline gap-2", "data-whole-value-file": pointer.file_id, children: [
|
|
4388
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "truncate", title: `The first ${pointer.shown_chars} of ${pointer.chars} characters`, children: [
|
|
4179
4389
|
words,
|
|
4180
4390
|
"\u2026"
|
|
4181
4391
|
] }),
|
|
4182
|
-
href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0,
|
|
4392
|
+
href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${(0, import_core.wholeValueSize)(pointer)} in a file` })
|
|
4183
4393
|
] });
|
|
4184
4394
|
}
|
|
4185
4395
|
|
|
4396
|
+
// src/values.tsx
|
|
4397
|
+
var import_field_formats6 = require("@ai-matrx/design-system/field-formats");
|
|
4398
|
+
|
|
4186
4399
|
// src/ReferenceChips.tsx
|
|
4187
4400
|
var import_records13 = require("@ai-matrx/records");
|
|
4188
|
-
var
|
|
4401
|
+
var import_design_system19 = require("@ai-matrx/design-system");
|
|
4189
4402
|
|
|
4190
4403
|
// src/kindValues.ts
|
|
4191
4404
|
var import_directives = require("@ai-matrx/content-ir/directives");
|
|
@@ -4239,7 +4452,7 @@ function kindLabel(kind) {
|
|
|
4239
4452
|
}
|
|
4240
4453
|
|
|
4241
4454
|
// src/ReferenceChips.tsx
|
|
4242
|
-
var
|
|
4455
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4243
4456
|
function referencesOf(field, value, kind, labels) {
|
|
4244
4457
|
if (kind === "entity_reference") {
|
|
4245
4458
|
return (0, import_records13.entityRefsOf)(value).map((r) => ({ token: r.token, id: r.id, label: r.label }));
|
|
@@ -4260,11 +4473,11 @@ function ReferenceChip({ reference, waiting }) {
|
|
|
4260
4473
|
const host = useRecordsUi();
|
|
4261
4474
|
const words = reference.label ?? (reference.token === "record" ? waiting ?? "Loading\u2026" : WITHHELD_ENTITY_LABEL);
|
|
4262
4475
|
const drawn = host.renderReference ? host.renderReference({ ...reference, label: reference.label ?? words }) : null;
|
|
4263
|
-
return /* @__PURE__ */ (0,
|
|
4264
|
-
|
|
4476
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4477
|
+
import_design_system19.Badge,
|
|
4265
4478
|
{
|
|
4266
4479
|
variant: "secondary",
|
|
4267
|
-
className: (0,
|
|
4480
|
+
className: (0, import_design_system19.cn)(
|
|
4268
4481
|
"max-w-full min-w-0 gap-1 px-1.5 py-0 text-[11px] font-normal",
|
|
4269
4482
|
reference.archived && "opacity-70"
|
|
4270
4483
|
),
|
|
@@ -4272,15 +4485,15 @@ function ReferenceChip({ reference, waiting }) {
|
|
|
4272
4485
|
"data-records-reference-archived": reference.archived ? "" : void 0,
|
|
4273
4486
|
title: reference.archived ? ARCHIVED_REFERENCE_TIP : words,
|
|
4274
4487
|
children: [
|
|
4275
|
-
drawn ?? /* @__PURE__ */ (0,
|
|
4276
|
-
reference.archived ? /* @__PURE__ */ (0,
|
|
4488
|
+
drawn ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate", children: words }),
|
|
4489
|
+
reference.archived ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
|
|
4277
4490
|
]
|
|
4278
4491
|
}
|
|
4279
4492
|
);
|
|
4280
4493
|
}
|
|
4281
4494
|
function ReferenceChips({ refs, waiting }) {
|
|
4282
|
-
if (refs.length === 0) return /* @__PURE__ */ (0,
|
|
4283
|
-
return /* @__PURE__ */ (0,
|
|
4495
|
+
if (refs.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
4496
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "flex min-w-0 flex-wrap gap-1", "data-records-reference-chips": "", children: refs.map((r) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ReferenceChip, { reference: r, waiting }, `${r.token}:${r.id}`)) });
|
|
4284
4497
|
}
|
|
4285
4498
|
function KindValueCell({
|
|
4286
4499
|
kv,
|
|
@@ -4289,18 +4502,18 @@ function KindValueCell({
|
|
|
4289
4502
|
}) {
|
|
4290
4503
|
const host = useRecordsUi();
|
|
4291
4504
|
if (host.renderKind) {
|
|
4292
|
-
return /* @__PURE__ */ (0,
|
|
4505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("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 }) });
|
|
4293
4506
|
}
|
|
4294
4507
|
const named = kv.items.map(kindItemWords).filter((w) => w !== null);
|
|
4295
|
-
return /* @__PURE__ */ (0,
|
|
4508
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: (0, import_design_system19.cn)("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__ */ (0, import_jsx_runtime22.jsx)(import_design_system19.Badge, { variant: "secondary", className: "px-1.5 py-0 text-[11px] font-normal", children: w }, `${w}-${i}`)) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_design_system19.Badge, { variant: "outline", className: "px-1.5 py-0 text-[11px] font-normal", children: kindLabel(kv.kind) }) });
|
|
4296
4509
|
}
|
|
4297
4510
|
|
|
4298
4511
|
// src/values.tsx
|
|
4299
4512
|
var import_records14 = require("@ai-matrx/records");
|
|
4300
|
-
var
|
|
4301
|
-
function statusMark(field, item) {
|
|
4302
|
-
const mark = statusMarkOf(field, item);
|
|
4303
|
-
return mark ? /* @__PURE__ */ (0,
|
|
4513
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4514
|
+
function statusMark(field, item, document2) {
|
|
4515
|
+
const mark = statusMarkOf(field, item, document2);
|
|
4516
|
+
return mark ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-label": mark.words, title: mark.words, className: "mr-1", "data-records-status-group": mark.group, children: mark.mark }) : null;
|
|
4304
4517
|
}
|
|
4305
4518
|
function envelopeFor(document2, key) {
|
|
4306
4519
|
const block = document2?._values;
|
|
@@ -4344,32 +4557,32 @@ var ABSENCE_WORDS = ABSENCE_WORD_LABEL;
|
|
|
4344
4557
|
function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
4345
4558
|
const envelope = envelopeFor(document2, field.key);
|
|
4346
4559
|
if (envelope?.absent) {
|
|
4347
|
-
return /* @__PURE__ */ (0,
|
|
4560
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs italic text-muted-foreground", title: `VAL-2: ${envelope.absent}`, children: ABSENCE_WORDS[String(envelope.absent)] ?? String(envelope.absent) });
|
|
4348
4561
|
}
|
|
4349
4562
|
if (value === null || value === void 0 || value === "") {
|
|
4350
4563
|
const gone = unresolvedFor(document2, field.key);
|
|
4351
4564
|
if (gone) {
|
|
4352
|
-
return /* @__PURE__ */ (0,
|
|
4565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs italic text-muted-foreground", title: `It pointed at ${gone}`, children: "The record this pointed at no longer exists" });
|
|
4353
4566
|
}
|
|
4354
4567
|
const computed = computedEmptyOf(field, document2);
|
|
4355
|
-
if (computed?.sentence) return /* @__PURE__ */ (0,
|
|
4356
|
-
if (computed?.words) return /* @__PURE__ */ (0,
|
|
4568
|
+
if (computed?.sentence) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs italic text-muted-foreground", children: computed.sentence });
|
|
4569
|
+
if (computed?.words) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "data-records-empty-why": computed.kind, children: computed.words });
|
|
4357
4570
|
if (computed?.why) {
|
|
4358
|
-
return /* @__PURE__ */ (0,
|
|
4571
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-muted-foreground", title: computed.why, "data-records-empty-why": computed.kind, children: "\u2014" });
|
|
4359
4572
|
}
|
|
4360
|
-
return /* @__PURE__ */ (0,
|
|
4573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
4361
4574
|
}
|
|
4362
|
-
if (isSignatureField(field)) return /* @__PURE__ */ (0,
|
|
4575
|
+
if (isSignatureField(field)) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SignatureValue, { value, fieldKey: field.key, document: document2 });
|
|
4363
4576
|
const newer = newerKindValue(field, value);
|
|
4364
4577
|
if (newer !== void 0) return newer;
|
|
4365
4578
|
const whole = typeof value === "string" ? (0, import_core2.wholeValueOf)(document2, field.key) : null;
|
|
4366
|
-
if (whole) return /* @__PURE__ */ (0,
|
|
4579
|
+
if (whole) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(WholeValueCell, { words: value, pointer: whole });
|
|
4367
4580
|
const kind = editorKindFor(field);
|
|
4368
4581
|
if (kind === "relation" || kind === "entity_reference") {
|
|
4369
|
-
return /* @__PURE__ */ (0,
|
|
4582
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReferenceChips, { refs: referencesOf(field, value, kind, labels), waiting: stillWaitingFor });
|
|
4370
4583
|
}
|
|
4371
4584
|
const kv = kind === "attachment" || kind === "member" ? null : kindValueOf(value);
|
|
4372
|
-
if (kv) return /* @__PURE__ */ (0,
|
|
4585
|
+
if (kv) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(KindValueCell, { kv, where: "cell", title: field.label });
|
|
4373
4586
|
const chosen = kind === "select" || kind === "multi_select";
|
|
4374
4587
|
const chipOf = (item) => {
|
|
4375
4588
|
const look = choiceChipLookOf(field, item, scalarText(field, item, labels));
|
|
@@ -4377,17 +4590,17 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4377
4590
|
};
|
|
4378
4591
|
if (chosen) {
|
|
4379
4592
|
const items = Array.isArray(value) ? value : [value];
|
|
4380
|
-
return /* @__PURE__ */ (0,
|
|
4593
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "flex flex-wrap gap-1", "data-records-choice-chips": "", children: items.map((item, i) => {
|
|
4381
4594
|
const chip = chipOf(item);
|
|
4382
|
-
return /* @__PURE__ */ (0,
|
|
4383
|
-
|
|
4595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
4596
|
+
import_design_system20.Badge,
|
|
4384
4597
|
{
|
|
4385
4598
|
variant: "outline",
|
|
4386
|
-
className: (0,
|
|
4599
|
+
className: (0, import_design_system20.cn)("text-[11px]", chip.className),
|
|
4387
4600
|
"data-records-choice-chip": "",
|
|
4388
4601
|
...chip.tinted ? { "data-records-choice-tint": "" } : {},
|
|
4389
4602
|
children: [
|
|
4390
|
-
statusMark(field, item),
|
|
4603
|
+
statusMark(field, item, Array.isArray(value) ? void 0 : document2),
|
|
4391
4604
|
scalarText(field, item, labels, Array.isArray(value) ? void 0 : stillWaitingFor)
|
|
4392
4605
|
]
|
|
4393
4606
|
},
|
|
@@ -4395,13 +4608,13 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4395
4608
|
);
|
|
4396
4609
|
}) });
|
|
4397
4610
|
}
|
|
4398
|
-
if (kind === "attachment") return /* @__PURE__ */ (0,
|
|
4611
|
+
if (kind === "attachment") return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AttachmentChips, { value });
|
|
4399
4612
|
if (Array.isArray(value)) {
|
|
4400
|
-
return /* @__PURE__ */ (0,
|
|
4613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "flex flex-wrap gap-1", children: value.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system20.Badge, { variant: "secondary", className: "text-[11px]", children: scalarText(field, item, labels) }, `${String(item)}-${i}`)) });
|
|
4401
4614
|
}
|
|
4402
4615
|
if (kind === "url" && typeof value === "string") {
|
|
4403
4616
|
const href = value.includes("://") ? value : `https://${value}`;
|
|
4404
|
-
return /* @__PURE__ */ (0,
|
|
4617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
4405
4618
|
"a",
|
|
4406
4619
|
{
|
|
4407
4620
|
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",
|
|
@@ -4412,14 +4625,14 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4412
4625
|
"data-records-link-chip": "",
|
|
4413
4626
|
onClick: (event) => event.stopPropagation(),
|
|
4414
4627
|
children: [
|
|
4415
|
-
/* @__PURE__ */ (0,
|
|
4416
|
-
/* @__PURE__ */ (0,
|
|
4628
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2197" }),
|
|
4629
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate", children: linkChipText(value) })
|
|
4417
4630
|
]
|
|
4418
4631
|
}
|
|
4419
4632
|
);
|
|
4420
4633
|
}
|
|
4421
4634
|
if (kind === "phone" && typeof value === "string" && value.trim() !== "") {
|
|
4422
|
-
return /* @__PURE__ */ (0,
|
|
4635
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4423
4636
|
"a",
|
|
4424
4637
|
{
|
|
4425
4638
|
className: "truncate tabular-nums text-primary underline-offset-2 hover:underline",
|
|
@@ -4427,17 +4640,17 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4427
4640
|
title: value,
|
|
4428
4641
|
"data-records-phone": "",
|
|
4429
4642
|
onClick: (event) => event.stopPropagation(),
|
|
4430
|
-
children: formatPhone(value)
|
|
4643
|
+
children: (0, import_field_formats6.formatPhone)(value)
|
|
4431
4644
|
}
|
|
4432
4645
|
);
|
|
4433
4646
|
}
|
|
4434
4647
|
if (kind === "email" && typeof value === "string") {
|
|
4435
|
-
return /* @__PURE__ */ (0,
|
|
4648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("a", { className: "truncate text-primary underline-offset-2 hover:underline", href: `mailto:${value}`, children: value });
|
|
4436
4649
|
}
|
|
4437
4650
|
if (typeof value === "boolean") {
|
|
4438
|
-
return /* @__PURE__ */ (0,
|
|
4651
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: kind === "checkbox" ? "text-sm" : "", title: value ? "Yes" : "No", children: value ? "\u2713" : "\u2014" });
|
|
4439
4652
|
}
|
|
4440
|
-
return /* @__PURE__ */ (0,
|
|
4653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: (0, import_design_system20.cn)("truncate", kind === "number" || kind === "currency" || kind === "percent" ? "tabular-nums" : ""), children: scalarText(field, value, labels, stillWaitingFor) });
|
|
4441
4654
|
}
|
|
4442
4655
|
function scalarText(field, value, labels, stillWaitingFor) {
|
|
4443
4656
|
if (value === null || value === void 0) return "\u2014";
|
|
@@ -4478,13 +4691,13 @@ function scalarText(field, value, labels, stillWaitingFor) {
|
|
|
4478
4691
|
}
|
|
4479
4692
|
|
|
4480
4693
|
// src/PickedSummaries.tsx
|
|
4481
|
-
var
|
|
4694
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4482
4695
|
function TableNameText({ dataSource, tableId }) {
|
|
4483
4696
|
const tables = useTablesAnywhere(dataSource);
|
|
4484
|
-
if (!tableId) return /* @__PURE__ */ (0,
|
|
4485
|
-
if (tables.loading) return /* @__PURE__ */ (0,
|
|
4486
|
-
if (tables.error) return /* @__PURE__ */ (0,
|
|
4487
|
-
return /* @__PURE__ */ (0,
|
|
4697
|
+
if (!tableId) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
|
|
4698
|
+
if (tables.loading) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" });
|
|
4699
|
+
if (tables.error) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load the table's name" });
|
|
4700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: tables.rows.find((t) => t.table_id === tableId)?.table_name ?? "\u2014" });
|
|
4488
4701
|
}
|
|
4489
4702
|
function ColumnValuesText({
|
|
4490
4703
|
dataSource,
|
|
@@ -4492,28 +4705,38 @@ function ColumnValuesText({
|
|
|
4492
4705
|
tableId,
|
|
4493
4706
|
value
|
|
4494
4707
|
}) {
|
|
4495
|
-
if (!tableId) return /* @__PURE__ */ (0,
|
|
4496
|
-
return /* @__PURE__ */ (0,
|
|
4708
|
+
if (!tableId) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
|
|
4709
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4710
|
+
TableScope,
|
|
4711
|
+
{
|
|
4712
|
+
dataSource,
|
|
4713
|
+
userId,
|
|
4714
|
+
tableId,
|
|
4715
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" }),
|
|
4716
|
+
unavailable: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this table's columns" }),
|
|
4717
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RecordLabelProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ColumnValuesWords, { tableId, value }) })
|
|
4718
|
+
}
|
|
4719
|
+
);
|
|
4497
4720
|
}
|
|
4498
4721
|
function ColumnValuesWords({ tableId, value }) {
|
|
4499
|
-
const fields = (0,
|
|
4722
|
+
const fields = (0, import_react35.useFields)(tableId);
|
|
4500
4723
|
const labels = useRecordLabels(fields.data ?? void 0);
|
|
4501
|
-
if (fields.loading) return /* @__PURE__ */ (0,
|
|
4502
|
-
if (fields.error) return /* @__PURE__ */ (0,
|
|
4724
|
+
if (fields.loading) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" });
|
|
4725
|
+
if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this table's columns" });
|
|
4503
4726
|
const parts = [];
|
|
4504
4727
|
for (const [key, stored] of Object.entries(value)) {
|
|
4505
4728
|
if (key.startsWith("_")) continue;
|
|
4506
4729
|
const field = (fields.data ?? []).find((f) => f.key === key);
|
|
4507
|
-
if (parts.length) parts.push(/* @__PURE__ */ (0,
|
|
4730
|
+
if (parts.length) parts.push(/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: ", " }, `${key}-sep`));
|
|
4508
4731
|
parts.push(
|
|
4509
|
-
/* @__PURE__ */ (0,
|
|
4732
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { children: [
|
|
4510
4733
|
field ? fieldName(field) : "A removed column",
|
|
4511
4734
|
" is ",
|
|
4512
4735
|
field ? renderValue(field, stored, void 0, labels) : "\u2014"
|
|
4513
4736
|
] }, key)
|
|
4514
4737
|
);
|
|
4515
4738
|
}
|
|
4516
|
-
return parts.length ? /* @__PURE__ */ (0,
|
|
4739
|
+
return parts.length ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: parts }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
|
|
4517
4740
|
}
|
|
4518
4741
|
function RecordNameText({
|
|
4519
4742
|
dataSource,
|
|
@@ -4521,32 +4744,42 @@ function RecordNameText({
|
|
|
4521
4744
|
tableId,
|
|
4522
4745
|
recordId
|
|
4523
4746
|
}) {
|
|
4524
|
-
if (!tableId || !recordId) return /* @__PURE__ */ (0,
|
|
4525
|
-
return /* @__PURE__ */ (0,
|
|
4747
|
+
if (!tableId || !recordId) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
|
|
4748
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4749
|
+
TableScope,
|
|
4750
|
+
{
|
|
4751
|
+
dataSource,
|
|
4752
|
+
userId,
|
|
4753
|
+
tableId,
|
|
4754
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" }),
|
|
4755
|
+
unavailable: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this record" }),
|
|
4756
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RecordNameWords, { tableId, recordId })
|
|
4757
|
+
}
|
|
4758
|
+
);
|
|
4526
4759
|
}
|
|
4527
4760
|
function RecordNameWords({ tableId, recordId }) {
|
|
4528
|
-
const table = (0,
|
|
4529
|
-
const record = (0,
|
|
4530
|
-
if (record.loading || table.loading) return /* @__PURE__ */ (0,
|
|
4531
|
-
if (record.error) return /* @__PURE__ */ (0,
|
|
4532
|
-
if (!record.data) return /* @__PURE__ */ (0,
|
|
4533
|
-
return /* @__PURE__ */ (0,
|
|
4761
|
+
const table = (0, import_react35.useTable)(tableId);
|
|
4762
|
+
const record = (0, import_react35.useRecord)(recordId);
|
|
4763
|
+
if (record.loading || table.loading) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" });
|
|
4764
|
+
if (record.error) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this record" });
|
|
4765
|
+
if (!record.data) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "A record you cannot open" });
|
|
4766
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: recordName(record.data.document, table.data?.title_field ?? null) });
|
|
4534
4767
|
}
|
|
4535
4768
|
|
|
4536
4769
|
// src/HeldChangeDecision.tsx
|
|
4537
|
-
var
|
|
4538
|
-
var
|
|
4539
|
-
var
|
|
4540
|
-
var
|
|
4770
|
+
var import_react36 = require("react");
|
|
4771
|
+
var import_react37 = require("@ai-matrx/records/react");
|
|
4772
|
+
var import_design_system21 = require("@ai-matrx/design-system");
|
|
4773
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4541
4774
|
function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, onDecided }) {
|
|
4542
|
-
return /* @__PURE__ */ (0,
|
|
4775
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react37.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Decision, { approvalId, onDecided }) });
|
|
4543
4776
|
}
|
|
4544
4777
|
function Decision({ approvalId, onDecided }) {
|
|
4545
|
-
const client = (0,
|
|
4546
|
-
const [may, setMay] = (0,
|
|
4547
|
-
const [busy, setBusy] = (0,
|
|
4548
|
-
const [error, setError] = (0,
|
|
4549
|
-
(0,
|
|
4778
|
+
const client = (0, import_react37.useRecordsClient)();
|
|
4779
|
+
const [may, setMay] = (0, import_react36.useState)(null);
|
|
4780
|
+
const [busy, setBusy] = (0, import_react36.useState)(null);
|
|
4781
|
+
const [error, setError] = (0, import_react36.useState)(null);
|
|
4782
|
+
(0, import_react36.useEffect)(() => {
|
|
4550
4783
|
let live = true;
|
|
4551
4784
|
void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
|
|
4552
4785
|
if (!live) return;
|
|
@@ -4568,13 +4801,13 @@ function Decision({ approvalId, onDecided }) {
|
|
|
4568
4801
|
if (res.ok) onDecided(approve);
|
|
4569
4802
|
else setError(res.error);
|
|
4570
4803
|
};
|
|
4571
|
-
if (may === null) return /* @__PURE__ */ (0,
|
|
4572
|
-
return /* @__PURE__ */ (0,
|
|
4573
|
-
may ? /* @__PURE__ */ (0,
|
|
4574
|
-
/* @__PURE__ */ (0,
|
|
4575
|
-
/* @__PURE__ */ (0,
|
|
4576
|
-
] }) : !error && /* @__PURE__ */ (0,
|
|
4577
|
-
error ? /* @__PURE__ */ (0,
|
|
4804
|
+
if (may === null) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: "Checking who can decide\u2026" });
|
|
4805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
4806
|
+
may ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-2", children: [
|
|
4807
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_design_system21.Button, { type: "button", size: "sm", disabled: busy !== null, onClick: () => void decide(true), children: busy === "approve" ? "Approving\u2026" : "Approve" }),
|
|
4808
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_design_system21.Button, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void decide(false), children: busy === "refuse" ? "Refusing\u2026" : "Refuse" })
|
|
4809
|
+
] }) : !error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: "An owner or admin of this organization decides this." }),
|
|
4810
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(RefusalLine, { error }) : null
|
|
4578
4811
|
] });
|
|
4579
4812
|
}
|
|
4580
4813
|
//# sourceMappingURL=pickers.cjs.map
|