@ai-matrx/records-ui 0.93.142 → 0.93.153
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +126 -0
- package/dist/index.cjs +16946 -15022
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +212 -43
- package/dist/index.d.ts +212 -43
- package/dist/index.js +10363 -8438
- package/dist/index.js.map +1 -1
- package/dist/object-actions.cjs +127 -28
- package/dist/object-actions.cjs.map +1 -1
- package/dist/object-actions.d.cts +1 -1
- package/dist/object-actions.d.ts +1 -1
- package/dist/object-actions.js +125 -26
- package/dist/object-actions.js.map +1 -1
- package/dist/{objectActions-BSbblgf-.d.cts → objectActions-Dgdr0E4b.d.cts} +52 -11
- package/dist/{objectActions-BSbblgf-.d.ts → objectActions-Dgdr0E4b.d.ts} +52 -11
- package/dist/pickers.cjs +745 -493
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.d.cts +12 -1
- package/dist/pickers.d.ts +12 -1
- package/dist/pickers.js +633 -379
- package/dist/pickers.js.map +1 -1
- package/package.json +2 -2
package/dist/pickers.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(pickers_exports, {
|
|
|
26
26
|
DATA_BINDING_MISSING: () => DATA_BINDING_MISSING,
|
|
27
27
|
DATA_BINDING_SHAPES: () => DATA_BINDING_SHAPES,
|
|
28
28
|
DataBindingPicker: () => DataBindingPicker,
|
|
29
|
+
HeldChangeDecision: () => HeldChangeDecision,
|
|
29
30
|
RecordNameText: () => RecordNameText,
|
|
30
31
|
RecordPicker: () => RecordPicker,
|
|
31
32
|
TableNameText: () => TableNameText,
|
|
@@ -41,15 +42,15 @@ __export(pickers_exports, {
|
|
|
41
42
|
module.exports = __toCommonJS(pickers_exports);
|
|
42
43
|
|
|
43
44
|
// src/TablePickers.tsx
|
|
44
|
-
var
|
|
45
|
-
var
|
|
46
|
-
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");
|
|
47
48
|
|
|
48
49
|
// src/editors.tsx
|
|
49
|
-
var
|
|
50
|
+
var import_react24 = require("react");
|
|
50
51
|
var import_records10 = require("@ai-matrx/records");
|
|
51
|
-
var
|
|
52
|
-
var
|
|
52
|
+
var import_react25 = require("@ai-matrx/records/react");
|
|
53
|
+
var import_design_system14 = require("@ai-matrx/design-system");
|
|
53
54
|
|
|
54
55
|
// src/dates.ts
|
|
55
56
|
var import_field_formats = require("@ai-matrx/design-system/field-formats");
|
|
@@ -108,7 +109,7 @@ function newerKindValue(field, value, opts = {}) {
|
|
|
108
109
|
}
|
|
109
110
|
case "created_by":
|
|
110
111
|
case "modified_by":
|
|
111
|
-
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;
|
|
112
113
|
case "address":
|
|
113
114
|
return (0, import_records.isAddressValue)(value) || typeof value === "string" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AddressLink, { value }) : void 0;
|
|
114
115
|
case "barcode":
|
|
@@ -124,10 +125,12 @@ function newerKindValue(field, value, opts = {}) {
|
|
|
124
125
|
return void 0;
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
|
-
function PersonStampChip({
|
|
128
|
-
const words =
|
|
129
|
-
const
|
|
130
|
-
|
|
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: [
|
|
131
134
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
132
135
|
"span",
|
|
133
136
|
{
|
|
@@ -136,7 +139,7 @@ function PersonStampChip({ name }) {
|
|
|
136
139
|
children: initial
|
|
137
140
|
}
|
|
138
141
|
),
|
|
139
|
-
/* @__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 })
|
|
140
143
|
] });
|
|
141
144
|
}
|
|
142
145
|
function AddressLink({ value }) {
|
|
@@ -161,12 +164,13 @@ function AddressLink({ value }) {
|
|
|
161
164
|
);
|
|
162
165
|
}
|
|
163
166
|
var STATUS_GROUP_MARK = { todo: "\u25CB", in_progress: "\u25D0", done: "\u25CF" };
|
|
164
|
-
function statusMarkOf(field, value) {
|
|
167
|
+
function statusMarkOf(field, value, document2) {
|
|
165
168
|
if ((0, import_records.newerKindOf)(field) !== "status" || typeof value !== "string") return null;
|
|
166
|
-
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);
|
|
167
172
|
return { mark: STATUS_GROUP_MARK[group], group, words: import_records.STATUS_GROUP_WORDS[group] };
|
|
168
173
|
}
|
|
169
|
-
var SAFE_HREF = /^(https?:\/\/|mailto:)/i;
|
|
170
174
|
function inline(text, key) {
|
|
171
175
|
const out = [];
|
|
172
176
|
let at = 0;
|
|
@@ -193,9 +197,9 @@ function marks(text, key) {
|
|
|
193
197
|
if (tok.startsWith("**") || tok.startsWith("__")) out.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: tok.slice(2, -2) }, k));
|
|
194
198
|
else if (tok.startsWith("[")) {
|
|
195
199
|
const link = /^\[([^\]]+)\]\(([^)\s]+)\)$/.exec(tok);
|
|
196
|
-
const href = link?.[2] ?? "";
|
|
200
|
+
const href = (0, import_records.safeLinkHref)(link?.[2] ?? "");
|
|
197
201
|
out.push(
|
|
198
|
-
|
|
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
|
|
199
203
|
);
|
|
200
204
|
} else out.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { children: tok.slice(1, -1) }, k));
|
|
201
205
|
last = at + tok.length;
|
|
@@ -458,6 +462,7 @@ function rowNameIn(table, row, fallback = "Untitled") {
|
|
|
458
462
|
return recordName(row?.document, table?.title_field ?? null, fallback);
|
|
459
463
|
}
|
|
460
464
|
var WITHHELD_RECORD_LABEL = "A record you have not been given access to";
|
|
465
|
+
var UNREAD_RECORD_LABEL = "Couldn't load this name";
|
|
461
466
|
|
|
462
467
|
// src/RelationPicker.tsx
|
|
463
468
|
var import_react3 = require("react");
|
|
@@ -628,7 +633,12 @@ var TITLE = {
|
|
|
628
633
|
already_exists: "That already exists",
|
|
629
634
|
not_supported: "That cannot be done here",
|
|
630
635
|
store_limit: "This has got as big as it can",
|
|
631
|
-
|
|
636
|
+
// 🚨 NOT "THE SWITCH IS OFF" (lane 7 W1 fix round 1). PGRST202 / PGRST205 land here, and the
|
|
637
|
+
// commonest cause is a door this screen asks for that the database it talks to does not serve
|
|
638
|
+
// YET — a release in flight. Telling the person her organization has its store switched off was
|
|
639
|
+
// false (the switch is answered by its own door, `platform.unified_data_store_on`). Honest:
|
|
640
|
+
// nothing happened, and it is ours, and it passes.
|
|
641
|
+
store_not_served: "This isn't available right now",
|
|
632
642
|
unreachable: "We could not reach your data",
|
|
633
643
|
needs_approval: "This is waiting on someone's approval",
|
|
634
644
|
stale_read: "Your view of this is a moment behind",
|
|
@@ -646,7 +656,7 @@ var REMEDY = {
|
|
|
646
656
|
already_exists: "Use a different name.",
|
|
647
657
|
not_supported: "There is another way to do this \u2014 ask, and we will point you at it.",
|
|
648
658
|
store_limit: "Split it up, or ask us to raise the ceiling for your organization.",
|
|
649
|
-
store_not_served: "
|
|
659
|
+
store_not_served: "Nothing was changed. Try again in a few minutes.",
|
|
650
660
|
// 🚨 NOTHING WAS WRITTEN AND NOTHING WAS REFUSED (lane TAILS-6). The call
|
|
651
661
|
// never arrived, so "try again" is the honest instruction rather than a
|
|
652
662
|
// consolation — and saying nothing changed is the half a person actually
|
|
@@ -940,7 +950,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
|
|
|
940
950
|
const learned = {};
|
|
941
951
|
for (const id2 of wanted) {
|
|
942
952
|
const said = result.ok ? result.data[id2] : void 0;
|
|
943
|
-
learned[id2] = typeof said === "string" && said !== "" ? said : WITHHELD_RECORD_LABEL;
|
|
953
|
+
learned[id2] = !result.ok ? UNREAD_RECORD_LABEL : typeof said === "string" && said !== "" ? said : WITHHELD_RECORD_LABEL;
|
|
944
954
|
}
|
|
945
955
|
setWords((current) => ({ ...current, ...learned }));
|
|
946
956
|
});
|
|
@@ -1145,8 +1155,8 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
|
|
|
1145
1155
|
}
|
|
1146
1156
|
|
|
1147
1157
|
// src/gridAttachments.tsx
|
|
1148
|
-
var
|
|
1149
|
-
var
|
|
1158
|
+
var import_react12 = require("react");
|
|
1159
|
+
var import_react13 = require("@ai-matrx/records/react");
|
|
1150
1160
|
var import_design_system7 = require("@ai-matrx/design-system");
|
|
1151
1161
|
|
|
1152
1162
|
// src/host.tsx
|
|
@@ -1224,14 +1234,15 @@ function useRecordsUi() {
|
|
|
1224
1234
|
}
|
|
1225
1235
|
|
|
1226
1236
|
// src/labels.tsx
|
|
1227
|
-
var
|
|
1228
|
-
var
|
|
1237
|
+
var import_react9 = require("react");
|
|
1238
|
+
var import_react10 = require("@ai-matrx/records/react");
|
|
1229
1239
|
var import_records5 = require("@ai-matrx/records");
|
|
1230
1240
|
var import_uuid2 = require("@ai-matrx/kit/uuid");
|
|
1231
1241
|
|
|
1232
1242
|
// src/signature.tsx
|
|
1233
1243
|
var import_react7 = require("react");
|
|
1234
1244
|
var import_design_system5 = require("@ai-matrx/design-system");
|
|
1245
|
+
var import_react8 = require("@ai-matrx/records/react");
|
|
1235
1246
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1236
1247
|
var DRAWN = /^data:image\/(png|jpeg);base64,[A-Za-z0-9+/=]{64,}$/;
|
|
1237
1248
|
function drawnSignatureOf(value) {
|
|
@@ -1242,18 +1253,105 @@ function signatureWords(value) {
|
|
|
1242
1253
|
if (value === null || value === void 0 || value === "") return null;
|
|
1243
1254
|
return drawnSignatureOf(value) ? SIGNED_WORD : String(value);
|
|
1244
1255
|
}
|
|
1245
|
-
function
|
|
1256
|
+
function signatureFileOf(source) {
|
|
1257
|
+
if (!source || typeof source !== "object") return null;
|
|
1258
|
+
const src = source;
|
|
1259
|
+
const id = src["signature_file_id"];
|
|
1260
|
+
return src["kind"] === "signature" && typeof id === "string" && id !== "" ? id : null;
|
|
1261
|
+
}
|
|
1262
|
+
function signatureFileIn(document2, key) {
|
|
1263
|
+
const values = document2?.["_values"];
|
|
1264
|
+
const src = values?.[key]?.src;
|
|
1265
|
+
if (typeof src === "string") {
|
|
1266
|
+
const sources = document2?.["_sources"];
|
|
1267
|
+
return signatureFileOf(sources?.[src]);
|
|
1268
|
+
}
|
|
1269
|
+
return signatureFileOf(src);
|
|
1270
|
+
}
|
|
1271
|
+
var SOURCES = /* @__PURE__ */ new WeakMap();
|
|
1272
|
+
var FILES = /* @__PURE__ */ new WeakMap();
|
|
1273
|
+
function signatureFilesOf(client, recordId) {
|
|
1274
|
+
let held = SOURCES.get(client);
|
|
1275
|
+
if (!held) SOURCES.set(client, held = /* @__PURE__ */ new Map());
|
|
1276
|
+
let asked2 = held.get(recordId);
|
|
1277
|
+
if (!asked2) {
|
|
1278
|
+
asked2 = client.recordValuesVersioned({ record_id: recordId }).then((answered) => {
|
|
1279
|
+
if (!answered.ok) return {};
|
|
1280
|
+
return Object.fromEntries(answered.data.map((v) => [v.field_key, signatureFileOf(v.source)]));
|
|
1281
|
+
});
|
|
1282
|
+
held.set(recordId, asked2);
|
|
1283
|
+
}
|
|
1284
|
+
return asked2;
|
|
1285
|
+
}
|
|
1286
|
+
function drawingOf(client, fileId) {
|
|
1287
|
+
let held = FILES.get(client);
|
|
1288
|
+
if (!held) FILES.set(client, held = /* @__PURE__ */ new Map());
|
|
1289
|
+
let asked2 = held.get(fileId);
|
|
1290
|
+
if (!asked2) {
|
|
1291
|
+
asked2 = client.recordRead({ record_id: fileId }).then((answered) => {
|
|
1292
|
+
if (!answered.ok) return { src: null, hostFileId: null };
|
|
1293
|
+
const doc = answered.data.document ?? {};
|
|
1294
|
+
const content = drawnSignatureOf(doc["content"]);
|
|
1295
|
+
const hostFileId = typeof doc["file_id"] === "string" && doc["file_id"] !== "" ? doc["file_id"] : null;
|
|
1296
|
+
return { src: content, hostFileId };
|
|
1297
|
+
});
|
|
1298
|
+
held.set(fileId, asked2);
|
|
1299
|
+
}
|
|
1300
|
+
return asked2;
|
|
1301
|
+
}
|
|
1302
|
+
function DrawnImage({ src, inCell }) {
|
|
1303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1304
|
+
"img",
|
|
1305
|
+
{
|
|
1306
|
+
src,
|
|
1307
|
+
alt: SIGNED_WORD,
|
|
1308
|
+
"data-records-signature": "",
|
|
1309
|
+
className: (0, import_design_system5.cn)("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
|
|
1310
|
+
}
|
|
1311
|
+
);
|
|
1312
|
+
}
|
|
1313
|
+
function SignatureDrawing({
|
|
1314
|
+
recordId,
|
|
1315
|
+
fieldKey,
|
|
1316
|
+
fileId: knownFile,
|
|
1317
|
+
value,
|
|
1318
|
+
inCell
|
|
1319
|
+
}) {
|
|
1320
|
+
const client = (0, import_react8.useOptionalRecordsClient)();
|
|
1321
|
+
const host = useRecordsUi();
|
|
1322
|
+
const [drawing, setDrawing] = (0, import_react7.useState)(null);
|
|
1323
|
+
(0, import_react7.useEffect)(() => {
|
|
1324
|
+
let cancelled = false;
|
|
1325
|
+
setDrawing(null);
|
|
1326
|
+
if (!client) return;
|
|
1327
|
+
void (async () => {
|
|
1328
|
+
const fileId = knownFile ?? (recordId && fieldKey ? (await signatureFilesOf(client, recordId))[fieldKey] ?? null : null);
|
|
1329
|
+
if (!fileId || cancelled) return;
|
|
1330
|
+
const read = await drawingOf(client, fileId);
|
|
1331
|
+
if (!cancelled) setDrawing(read);
|
|
1332
|
+
})();
|
|
1333
|
+
return () => {
|
|
1334
|
+
cancelled = true;
|
|
1335
|
+
};
|
|
1336
|
+
}, [client, recordId, fieldKey, knownFile]);
|
|
1337
|
+
if (drawing?.src) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DrawnImage, { src: drawing.src, inCell });
|
|
1338
|
+
if (drawing?.hostFileId && host.fileImage) {
|
|
1339
|
+
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 }) });
|
|
1340
|
+
}
|
|
1341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-serif italic", children: String(value) });
|
|
1342
|
+
}
|
|
1343
|
+
function SignatureValue({
|
|
1344
|
+
value,
|
|
1345
|
+
inCell,
|
|
1346
|
+
recordId,
|
|
1347
|
+
fieldKey,
|
|
1348
|
+
document: document2
|
|
1349
|
+
}) {
|
|
1246
1350
|
const drawn = drawnSignatureOf(value);
|
|
1247
|
-
if (drawn) {
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
src: drawn,
|
|
1252
|
-
alt: SIGNED_WORD,
|
|
1253
|
-
"data-records-signature": "",
|
|
1254
|
-
className: (0, import_design_system5.cn)("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
|
|
1255
|
-
}
|
|
1256
|
-
);
|
|
1351
|
+
if (drawn) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DrawnImage, { src: drawn, inCell });
|
|
1352
|
+
const fileId = fieldKey ? signatureFileIn(document2, fieldKey) : null;
|
|
1353
|
+
if (value === SIGNED_WORD && (fileId || recordId && fieldKey)) {
|
|
1354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SignatureDrawing, { recordId: recordId ?? null, fieldKey: fieldKey ?? null, fileId, value, inCell });
|
|
1257
1355
|
}
|
|
1258
1356
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-serif italic", children: String(value) });
|
|
1259
1357
|
}
|
|
@@ -1413,7 +1511,7 @@ function encodeAt(canvas, type, maxWidth, quality) {
|
|
|
1413
1511
|
|
|
1414
1512
|
// src/labels.tsx
|
|
1415
1513
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1416
|
-
var LabelContext = (0,
|
|
1514
|
+
var LabelContext = (0, import_react9.createContext)({
|
|
1417
1515
|
// With no provider the resolver is ABSENT, not silently empty: a caller gets
|
|
1418
1516
|
// null and says "Loading…" forever, which is visible. The mount always
|
|
1419
1517
|
// provides one, so this is only ever a bare unit test.
|
|
@@ -1441,15 +1539,15 @@ function pointsAtRecords(field) {
|
|
|
1441
1539
|
return field.type === "list" || field.type === "relation";
|
|
1442
1540
|
}
|
|
1443
1541
|
function RecordLabelProvider({ children }) {
|
|
1444
|
-
const client = (0,
|
|
1445
|
-
const [names, setNames] = (0,
|
|
1446
|
-
const [archivedRefs, setArchivedRefs] = (0,
|
|
1447
|
-
const [settled, setSettled] = (0,
|
|
1448
|
-
const [waitingLines, setWaitingLines] = (0,
|
|
1449
|
-
const asked2 = (0,
|
|
1450
|
-
const chased = (0,
|
|
1451
|
-
const timers = (0,
|
|
1452
|
-
const startWaitClock = (0,
|
|
1542
|
+
const client = (0, import_react10.useRecordsClient)();
|
|
1543
|
+
const [names, setNames] = (0, import_react9.useState)({});
|
|
1544
|
+
const [archivedRefs, setArchivedRefs] = (0, import_react9.useState)({});
|
|
1545
|
+
const [settled, setSettled] = (0, import_react9.useState)({});
|
|
1546
|
+
const [waitingLines, setWaitingLines] = (0, import_react9.useState)({});
|
|
1547
|
+
const asked2 = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
|
|
1548
|
+
const chased = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
|
|
1549
|
+
const timers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
1550
|
+
const startWaitClock = (0, import_react9.useCallback)((field, target) => {
|
|
1453
1551
|
if (timers.current.has(field.id)) return;
|
|
1454
1552
|
timers.current.set(
|
|
1455
1553
|
field.id,
|
|
@@ -1461,7 +1559,7 @@ function RecordLabelProvider({ children }) {
|
|
|
1461
1559
|
}, SAY_WHAT_YOU_ARE_WAITING_FOR_AFTER_MS)
|
|
1462
1560
|
);
|
|
1463
1561
|
}, []);
|
|
1464
|
-
const stopWaitClock = (0,
|
|
1562
|
+
const stopWaitClock = (0, import_react9.useCallback)((fieldId) => {
|
|
1465
1563
|
const timer = timers.current.get(fieldId);
|
|
1466
1564
|
if (timer) {
|
|
1467
1565
|
clearTimeout(timer);
|
|
@@ -1474,14 +1572,14 @@ function RecordLabelProvider({ children }) {
|
|
|
1474
1572
|
return next;
|
|
1475
1573
|
});
|
|
1476
1574
|
}, []);
|
|
1477
|
-
(0,
|
|
1575
|
+
(0, import_react9.useEffect)(
|
|
1478
1576
|
() => () => {
|
|
1479
1577
|
for (const timer of timers.current.values()) clearTimeout(timer);
|
|
1480
1578
|
timers.current.clear();
|
|
1481
1579
|
},
|
|
1482
1580
|
[]
|
|
1483
1581
|
);
|
|
1484
|
-
const want = (0,
|
|
1582
|
+
const want = (0, import_react9.useCallback)(
|
|
1485
1583
|
(field) => {
|
|
1486
1584
|
if (!pointsAtRecords(field)) return;
|
|
1487
1585
|
if (asked2.current.has(field.id)) return;
|
|
@@ -1516,9 +1614,9 @@ function RecordLabelProvider({ children }) {
|
|
|
1516
1614
|
},
|
|
1517
1615
|
[client, startWaitClock, stopWaitClock]
|
|
1518
1616
|
);
|
|
1519
|
-
const queued = (0,
|
|
1520
|
-
const flushing = (0,
|
|
1521
|
-
const flush = (0,
|
|
1617
|
+
const queued = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
1618
|
+
const flushing = (0, import_react9.useRef)(null);
|
|
1619
|
+
const flush = (0, import_react9.useCallback)(() => {
|
|
1522
1620
|
flushing.current = null;
|
|
1523
1621
|
const batch = [...queued.current.values()];
|
|
1524
1622
|
queued.current.clear();
|
|
@@ -1535,7 +1633,7 @@ function RecordLabelProvider({ children }) {
|
|
|
1535
1633
|
});
|
|
1536
1634
|
for (const id of wanted) {
|
|
1537
1635
|
const words = result.ok ? result.data[id] : void 0;
|
|
1538
|
-
learned[id] = typeof words === "string" && words !== "" ? words : WITHHELD_RECORD_LABEL;
|
|
1636
|
+
learned[id] = !result.ok ? UNREAD_RECORD_LABEL : typeof words === "string" && words !== "" ? words : WITHHELD_RECORD_LABEL;
|
|
1539
1637
|
}
|
|
1540
1638
|
if (result.ok) for (const id of result.archived ?? []) archivedNow[`${field.id}:${id}`] = true;
|
|
1541
1639
|
})
|
|
@@ -1545,7 +1643,7 @@ function RecordLabelProvider({ children }) {
|
|
|
1545
1643
|
for (const { field } of batch) stopWaitClock(field.id);
|
|
1546
1644
|
})();
|
|
1547
1645
|
}, [client, stopWaitClock]);
|
|
1548
|
-
const chase = (0,
|
|
1646
|
+
const chase = (0, import_react9.useCallback)(
|
|
1549
1647
|
(field, id) => {
|
|
1550
1648
|
const key = `${field.id}:${id}`;
|
|
1551
1649
|
if (chased.current.has(key)) return;
|
|
@@ -1558,14 +1656,14 @@ function RecordLabelProvider({ children }) {
|
|
|
1558
1656
|
},
|
|
1559
1657
|
[flush, startWaitClock]
|
|
1560
1658
|
);
|
|
1561
|
-
(0,
|
|
1659
|
+
(0, import_react9.useEffect)(
|
|
1562
1660
|
() => () => {
|
|
1563
1661
|
if (flushing.current !== null) clearTimeout(flushing.current);
|
|
1564
1662
|
},
|
|
1565
1663
|
[]
|
|
1566
1664
|
);
|
|
1567
|
-
const rereadFor = (0,
|
|
1568
|
-
const lookupWords = (0,
|
|
1665
|
+
const rereadFor = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
|
|
1666
|
+
const lookupWords = (0, import_react9.useCallback)(
|
|
1569
1667
|
(field, id) => {
|
|
1570
1668
|
if (field.type === "list" && !isId(id)) {
|
|
1571
1669
|
const named = names[choiceKeyName(field.id, id)];
|
|
@@ -1585,7 +1683,7 @@ function RecordLabelProvider({ children }) {
|
|
|
1585
1683
|
},
|
|
1586
1684
|
[names, settled, chase, want]
|
|
1587
1685
|
);
|
|
1588
|
-
const lookup = (0,
|
|
1686
|
+
const lookup = (0, import_react9.useMemo)(
|
|
1589
1687
|
() => {
|
|
1590
1688
|
const answer = ((field, id) => lookupWords(field, id));
|
|
1591
1689
|
answer.archived = (field, id) => archivedRefs[`${field.id}:${id}`] === true;
|
|
@@ -1593,20 +1691,20 @@ function RecordLabelProvider({ children }) {
|
|
|
1593
1691
|
},
|
|
1594
1692
|
[lookupWords, archivedRefs]
|
|
1595
1693
|
);
|
|
1596
|
-
const waiting = (0,
|
|
1597
|
-
const value = (0,
|
|
1694
|
+
const waiting = (0, import_react9.useCallback)((field) => waitingLines[field.id] ?? null, [waitingLines]);
|
|
1695
|
+
const value = (0, import_react9.useMemo)(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
|
|
1598
1696
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LabelContext.Provider, { value, children });
|
|
1599
1697
|
}
|
|
1600
1698
|
function useRecordLabels(fields) {
|
|
1601
|
-
const { lookup, want } = (0,
|
|
1602
|
-
(0,
|
|
1699
|
+
const { lookup, want } = (0, import_react9.useContext)(LabelContext);
|
|
1700
|
+
(0, import_react9.useEffect)(() => {
|
|
1603
1701
|
for (const field of fields ?? []) want(field);
|
|
1604
1702
|
}, [fields, want]);
|
|
1605
1703
|
return lookup;
|
|
1606
1704
|
}
|
|
1607
1705
|
|
|
1608
1706
|
// src/FilePicker.tsx
|
|
1609
|
-
var
|
|
1707
|
+
var import_react11 = require("react");
|
|
1610
1708
|
var import_design_system6 = require("@ai-matrx/design-system");
|
|
1611
1709
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1612
1710
|
function FilePicker({
|
|
@@ -1620,17 +1718,17 @@ function FilePicker({
|
|
|
1620
1718
|
chosenName,
|
|
1621
1719
|
className
|
|
1622
1720
|
}) {
|
|
1623
|
-
const inputId = (0,
|
|
1624
|
-
const input = (0,
|
|
1625
|
-
const [over, setOver] = (0,
|
|
1626
|
-
const take = (0,
|
|
1721
|
+
const inputId = (0, import_react11.useId)();
|
|
1722
|
+
const input = (0, import_react11.useRef)(null);
|
|
1723
|
+
const [over, setOver] = (0, import_react11.useState)(false);
|
|
1724
|
+
const take = (0, import_react11.useCallback)(
|
|
1627
1725
|
(file) => {
|
|
1628
1726
|
if (!file || disabled) return;
|
|
1629
1727
|
onFile(file);
|
|
1630
1728
|
},
|
|
1631
1729
|
[disabled, onFile]
|
|
1632
1730
|
);
|
|
1633
|
-
const onDrop = (0,
|
|
1731
|
+
const onDrop = (0, import_react11.useCallback)(
|
|
1634
1732
|
(e) => {
|
|
1635
1733
|
e.preventDefault();
|
|
1636
1734
|
setOver(false);
|
|
@@ -1723,10 +1821,10 @@ function rememberHostFileIds(ids) {
|
|
|
1723
1821
|
var FILE_CHIP_UNREAD = "File";
|
|
1724
1822
|
var FILE_CHIP_NO_PAGE = "This screen has no way to open files yet.";
|
|
1725
1823
|
function AttachmentChip({ id, onRemove }) {
|
|
1726
|
-
const client = (0,
|
|
1824
|
+
const client = (0, import_react13.useOptionalRecordsClient)();
|
|
1727
1825
|
const host = useRecordsUi();
|
|
1728
|
-
const [read, setRead] = (0,
|
|
1729
|
-
(0,
|
|
1826
|
+
const [read, setRead] = (0, import_react12.useState)(null);
|
|
1827
|
+
(0, import_react12.useEffect)(() => {
|
|
1730
1828
|
let cancelled = false;
|
|
1731
1829
|
if (!client) {
|
|
1732
1830
|
setRead({ name: null, fileId: null, why: null });
|
|
@@ -1801,9 +1899,9 @@ function AttachmentControl({
|
|
|
1801
1899
|
onClose
|
|
1802
1900
|
}) {
|
|
1803
1901
|
const host = useRecordsUi();
|
|
1804
|
-
const [busy, setBusy] = (0,
|
|
1805
|
-
const [why, setWhy] = (0,
|
|
1806
|
-
const latest = (0,
|
|
1902
|
+
const [busy, setBusy] = (0, import_react12.useState)(false);
|
|
1903
|
+
const [why, setWhy] = (0, import_react12.useState)(null);
|
|
1904
|
+
const latest = (0, import_react12.useRef)(value);
|
|
1807
1905
|
latest.current = value;
|
|
1808
1906
|
const multiple = Boolean(field.multi);
|
|
1809
1907
|
const pick = async () => {
|
|
@@ -1824,8 +1922,8 @@ function AttachmentControl({
|
|
|
1824
1922
|
setBusy(false);
|
|
1825
1923
|
onClose?.();
|
|
1826
1924
|
};
|
|
1827
|
-
const opened = (0,
|
|
1828
|
-
(0,
|
|
1925
|
+
const opened = (0, import_react12.useRef)(false);
|
|
1926
|
+
(0, import_react12.useEffect)(() => {
|
|
1829
1927
|
if (!autoOpen || opened.current || !host.pickFiles) return;
|
|
1830
1928
|
opened.current = true;
|
|
1831
1929
|
void pick();
|
|
@@ -1868,11 +1966,99 @@ function AttachmentControl({
|
|
|
1868
1966
|
}
|
|
1869
1967
|
|
|
1870
1968
|
// src/EntityReferenceControl.tsx
|
|
1871
|
-
var
|
|
1969
|
+
var import_react15 = require("react");
|
|
1872
1970
|
var import_records6 = require("@ai-matrx/records");
|
|
1873
|
-
var
|
|
1971
|
+
var import_react16 = require("@ai-matrx/records/react");
|
|
1972
|
+
var import_design_system9 = require("@ai-matrx/design-system");
|
|
1973
|
+
|
|
1974
|
+
// src/PickOne.tsx
|
|
1975
|
+
var import_react14 = require("react");
|
|
1874
1976
|
var import_design_system8 = require("@ai-matrx/design-system");
|
|
1875
1977
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1978
|
+
var PICK_ONE_SEARCH_AFTER = 7;
|
|
1979
|
+
var EMPTY = "__records_pick_one_empty__";
|
|
1980
|
+
var inner = (v) => v === "" ? EMPTY : v;
|
|
1981
|
+
var outer = (v) => v === EMPTY ? "" : v;
|
|
1982
|
+
function PickOne({
|
|
1983
|
+
value,
|
|
1984
|
+
onChange,
|
|
1985
|
+
options,
|
|
1986
|
+
label,
|
|
1987
|
+
placeholder,
|
|
1988
|
+
id,
|
|
1989
|
+
className,
|
|
1990
|
+
disabled,
|
|
1991
|
+
attrs
|
|
1992
|
+
}) {
|
|
1993
|
+
const [open, setOpen] = (0, import_react14.useState)(false);
|
|
1994
|
+
const [search, setSearch] = (0, import_react14.useState)("");
|
|
1995
|
+
const current = options.find((o) => o.value === value);
|
|
1996
|
+
if (options.length > PICK_ONE_SEARCH_AFTER) {
|
|
1997
|
+
const q = search.trim().toLowerCase();
|
|
1998
|
+
const shown2 = q === "" ? options : options.filter((o) => o.label.toLowerCase().includes(q));
|
|
1999
|
+
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)(
|
|
2000
|
+
PickOrAdd,
|
|
2001
|
+
{
|
|
2002
|
+
triggerLabel: label,
|
|
2003
|
+
triggerText: current?.label ?? placeholder ?? "",
|
|
2004
|
+
triggerId: id,
|
|
2005
|
+
open: open && !disabled,
|
|
2006
|
+
onOpenChange: (next) => {
|
|
2007
|
+
setOpen(next);
|
|
2008
|
+
if (!next) setSearch("");
|
|
2009
|
+
},
|
|
2010
|
+
search,
|
|
2011
|
+
onSearch: setSearch,
|
|
2012
|
+
items: shown2.map((o) => ({
|
|
2013
|
+
id: inner(o.value),
|
|
2014
|
+
label: o.label,
|
|
2015
|
+
detail: o.group,
|
|
2016
|
+
picked: o.value === value,
|
|
2017
|
+
attrs: { "data-pick-value": o.value, ...o.group ? { "data-pick-group": o.group } : {} }
|
|
2018
|
+
})),
|
|
2019
|
+
onPick: (picked) => {
|
|
2020
|
+
onChange(outer(picked));
|
|
2021
|
+
setOpen(false);
|
|
2022
|
+
setSearch("");
|
|
2023
|
+
},
|
|
2024
|
+
empty: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "No match" })
|
|
2025
|
+
}
|
|
2026
|
+
) });
|
|
2027
|
+
}
|
|
2028
|
+
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: [
|
|
2029
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2030
|
+
import_design_system8.SelectTrigger,
|
|
2031
|
+
{
|
|
2032
|
+
id,
|
|
2033
|
+
size: "sm",
|
|
2034
|
+
"aria-label": label,
|
|
2035
|
+
className: (0, import_design_system8.cn)("h-7 w-auto min-w-[7rem] text-xs", className),
|
|
2036
|
+
"data-records-pick-one": "list",
|
|
2037
|
+
"data-pick-value": value,
|
|
2038
|
+
...attrs ?? {},
|
|
2039
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectValue, { placeholder })
|
|
2040
|
+
}
|
|
2041
|
+
),
|
|
2042
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectContent, { children: groupsOf(options).map(
|
|
2043
|
+
([group, items]) => group ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_design_system8.SelectGroup, { children: [
|
|
2044
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectLabel, { children: group }),
|
|
2045
|
+
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)))
|
|
2046
|
+
] }, 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)))
|
|
2047
|
+
) })
|
|
2048
|
+
] });
|
|
2049
|
+
}
|
|
2050
|
+
function groupsOf(options) {
|
|
2051
|
+
const out = [];
|
|
2052
|
+
for (const o of options) {
|
|
2053
|
+
const last = out[out.length - 1];
|
|
2054
|
+
if (last && last[0] === o.group) last[1].push(o);
|
|
2055
|
+
else out.push([o.group, [o]]);
|
|
2056
|
+
}
|
|
2057
|
+
return out;
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
// src/EntityReferenceControl.tsx
|
|
2061
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1876
2062
|
var WITHHELD_ENTITY_LABEL = "Something you have not been given access to";
|
|
1877
2063
|
var ENTITY_REFERENCE_EMPTY = "Nothing is pointed at yet.";
|
|
1878
2064
|
function entityReferenceText(value) {
|
|
@@ -1886,20 +2072,20 @@ function allowedKindsOf(field) {
|
|
|
1886
2072
|
return kinds.map((k) => String(k).trim().toLowerCase()).filter(Boolean);
|
|
1887
2073
|
}
|
|
1888
2074
|
function EntityReferenceControl(props) {
|
|
1889
|
-
const client = (0,
|
|
1890
|
-
return client ? /* @__PURE__ */ (0,
|
|
2075
|
+
const client = (0, import_react16.useOptionalRecordsClient)();
|
|
2076
|
+
return client ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(WithWords, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Chips, { ...props, words: null, picker: null });
|
|
1891
2077
|
}
|
|
1892
2078
|
function WithWords(props) {
|
|
1893
|
-
const refs = (0,
|
|
1894
|
-
const [known, setKnown] = (0,
|
|
2079
|
+
const refs = (0, import_react15.useMemo)(() => (0, import_records6.entityRefsOf)(props.value), [props.value]);
|
|
2080
|
+
const [known, setKnown] = (0, import_react15.useState)([]);
|
|
1895
2081
|
const withKnown = refs.map((r) => r.label === null ? known.find((k) => k.token === r.token && k.id === r.id) ?? r : r);
|
|
1896
|
-
const unlabelled = (0,
|
|
2082
|
+
const unlabelled = (0, import_react15.useMemo)(
|
|
1897
2083
|
() => withKnown.filter((r) => r.label === null).map((r) => ({ token: r.token, id: r.id })),
|
|
1898
2084
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1899
2085
|
[JSON.stringify(withKnown)]
|
|
1900
2086
|
);
|
|
1901
|
-
const words = (0,
|
|
1902
|
-
const picker = props.disabled ? null : /* @__PURE__ */ (0,
|
|
2087
|
+
const words = (0, import_react16.useEntityReferenceWords)(unlabelled);
|
|
2088
|
+
const picker = props.disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1903
2089
|
EntityReferencePicker,
|
|
1904
2090
|
{
|
|
1905
2091
|
field: props.field,
|
|
@@ -1912,7 +2098,7 @@ function WithWords(props) {
|
|
|
1912
2098
|
}
|
|
1913
2099
|
}
|
|
1914
2100
|
);
|
|
1915
|
-
return /* @__PURE__ */ (0,
|
|
2101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Chips, { ...props, value: withKnown, words, picker });
|
|
1916
2102
|
}
|
|
1917
2103
|
function EntityReferencePicker({
|
|
1918
2104
|
field,
|
|
@@ -1920,13 +2106,13 @@ function EntityReferencePicker({
|
|
|
1920
2106
|
onPick
|
|
1921
2107
|
}) {
|
|
1922
2108
|
const allowed = allowedKindsOf(field);
|
|
1923
|
-
const kinds = (0,
|
|
2109
|
+
const kinds = (0, import_react16.useEntityReferenceKinds)();
|
|
1924
2110
|
const labelOfKind = (token) => kinds.data?.find((k) => k.token === token)?.label ?? token.replace(/_/g, " ");
|
|
1925
|
-
const [open, setOpen] = (0,
|
|
1926
|
-
const [search, setSearch] = (0,
|
|
1927
|
-
const [only, setOnly] = (0,
|
|
2111
|
+
const [open, setOpen] = (0, import_react15.useState)(false);
|
|
2112
|
+
const [search, setSearch] = (0, import_react15.useState)("");
|
|
2113
|
+
const [only, setOnly] = (0, import_react15.useState)(null);
|
|
1928
2114
|
const tokens = only ? [only] : allowed;
|
|
1929
|
-
const found = (0,
|
|
2115
|
+
const found = (0, import_react16.useEntityReferenceSearch)(tokens, search, open);
|
|
1930
2116
|
const multi = Boolean(field.multi);
|
|
1931
2117
|
const items = (found.data ?? []).map((r) => ({
|
|
1932
2118
|
id: `${r.token}:${r.id}`,
|
|
@@ -1935,8 +2121,8 @@ function EntityReferencePicker({
|
|
|
1935
2121
|
picked: refs.some((x) => x.token === r.token && x.id === r.id),
|
|
1936
2122
|
attrs: { "data-entity-reference-candidate": `${r.token}:${r.id}` }
|
|
1937
2123
|
}));
|
|
1938
|
-
const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ (0,
|
|
1939
|
-
|
|
2124
|
+
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)(
|
|
2125
|
+
import_design_system9.Button,
|
|
1940
2126
|
{
|
|
1941
2127
|
type: "button",
|
|
1942
2128
|
size: "sm",
|
|
@@ -1947,26 +2133,23 @@ function EntityReferencePicker({
|
|
|
1947
2133
|
children: token ? labelOfKind(token) : "Any"
|
|
1948
2134
|
},
|
|
1949
2135
|
token ?? "any"
|
|
1950
|
-
)) }) : /* @__PURE__ */ (0,
|
|
1951
|
-
|
|
2136
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2137
|
+
PickOne,
|
|
1952
2138
|
{
|
|
1953
|
-
|
|
1954
|
-
"
|
|
2139
|
+
label: `Which kind \u2014 ${field.label}`,
|
|
2140
|
+
className: "mb-1 w-full",
|
|
1955
2141
|
value: only ?? "",
|
|
1956
|
-
onChange: (
|
|
1957
|
-
|
|
1958
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "Any kind" }),
|
|
1959
|
-
allowed.map((token) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: token, children: labelOfKind(token) }, token))
|
|
1960
|
-
]
|
|
2142
|
+
onChange: (picked) => setOnly(picked || null),
|
|
2143
|
+
options: [{ value: "", label: "Any kind" }, ...allowed.map((token) => ({ value: token, label: labelOfKind(token) }))]
|
|
1961
2144
|
}
|
|
1962
2145
|
) : null;
|
|
1963
|
-
const notice = /* @__PURE__ */ (0,
|
|
2146
|
+
const notice = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1964
2147
|
kindChoice,
|
|
1965
|
-
found.error ? /* @__PURE__ */ (0,
|
|
1966
|
-
found.loading && !found.data ? /* @__PURE__ */ (0,
|
|
2148
|
+
found.error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RefusalLine, { error: found.error, className: "px-2 py-1 text-[11px]" }) : null,
|
|
2149
|
+
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
|
|
1967
2150
|
] });
|
|
1968
2151
|
const kindWords = allowed.length === 1 ? labelOfKind(allowed[0]).toLowerCase() : "thing";
|
|
1969
|
-
return /* @__PURE__ */ (0,
|
|
2152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1970
2153
|
PickOrAdd,
|
|
1971
2154
|
{
|
|
1972
2155
|
triggerLabel: `Pick for ${field.label}`,
|
|
@@ -1980,7 +2163,7 @@ function EntityReferencePicker({
|
|
|
1980
2163
|
onSearch: setSearch,
|
|
1981
2164
|
items,
|
|
1982
2165
|
notice,
|
|
1983
|
-
empty: found.loading ? null : /* @__PURE__ */ (0,
|
|
2166
|
+
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.` }),
|
|
1984
2167
|
onPick: (key) => {
|
|
1985
2168
|
const r = (found.data ?? []).find((x) => `${x.token}:${x.id}` === key);
|
|
1986
2169
|
if (!r) return;
|
|
@@ -2000,7 +2183,7 @@ function Chips({
|
|
|
2000
2183
|
words,
|
|
2001
2184
|
picker
|
|
2002
2185
|
}) {
|
|
2003
|
-
const refs = (0,
|
|
2186
|
+
const refs = (0, import_react15.useMemo)(() => (0, import_records6.entityRefsOf)(value), [value]);
|
|
2004
2187
|
const labelOf = (token, refId, own3) => {
|
|
2005
2188
|
if (own3) return own3;
|
|
2006
2189
|
const read = words?.data?.find((w) => w.token === token && w.id === refId)?.label;
|
|
@@ -2010,13 +2193,13 @@ function Chips({
|
|
|
2010
2193
|
return WITHHELD_ENTITY_LABEL;
|
|
2011
2194
|
};
|
|
2012
2195
|
const multi = Boolean(field.multi);
|
|
2013
|
-
return /* @__PURE__ */ (0,
|
|
2014
|
-
refs.length === 0 && !picker ? /* @__PURE__ */ (0,
|
|
2196
|
+
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: [
|
|
2197
|
+
refs.length === 0 && !picker ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-[11px] text-muted-foreground", children: ENTITY_REFERENCE_EMPTY }) : null,
|
|
2015
2198
|
refs.map((r) => {
|
|
2016
2199
|
const label = labelOf(r.token, r.id, r.label);
|
|
2017
|
-
return /* @__PURE__ */ (0,
|
|
2200
|
+
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: [
|
|
2018
2201
|
label,
|
|
2019
|
-
disabled ? null : /* @__PURE__ */ (0,
|
|
2202
|
+
disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2020
2203
|
"button",
|
|
2021
2204
|
{
|
|
2022
2205
|
type: "button",
|
|
@@ -2036,11 +2219,11 @@ function Chips({
|
|
|
2036
2219
|
}
|
|
2037
2220
|
|
|
2038
2221
|
// src/PersonPicker.tsx
|
|
2039
|
-
var
|
|
2222
|
+
var import_react17 = require("react");
|
|
2040
2223
|
var import_records7 = require("@ai-matrx/records");
|
|
2041
|
-
var
|
|
2042
|
-
var
|
|
2043
|
-
var
|
|
2224
|
+
var import_react18 = require("@ai-matrx/records/react");
|
|
2225
|
+
var import_design_system10 = require("@ai-matrx/design-system");
|
|
2226
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2044
2227
|
function personFromRow(row) {
|
|
2045
2228
|
const data = row.document ?? {};
|
|
2046
2229
|
const userId = data["user_id"];
|
|
@@ -2071,27 +2254,27 @@ async function personRecordForMember(client, personTableId, people, member) {
|
|
|
2071
2254
|
return written;
|
|
2072
2255
|
}
|
|
2073
2256
|
function PersonPicker({ field, value, onChange, disabled, id, className, autoOpen, onClose, initialSearch }) {
|
|
2074
|
-
const client = (0,
|
|
2257
|
+
const client = (0, import_react18.useOptionalRecordsClient)();
|
|
2075
2258
|
const host = useRecordsUi();
|
|
2076
|
-
const [members, setMembers] = (0,
|
|
2077
|
-
const [people, setPeople] = (0,
|
|
2078
|
-
const [error, setError] = (0,
|
|
2079
|
-
const [search, setSearch] = (0,
|
|
2080
|
-
const [open, setOpenState] = (0,
|
|
2081
|
-
const onCloseRef = (0,
|
|
2259
|
+
const [members, setMembers] = (0, import_react17.useState)(null);
|
|
2260
|
+
const [people, setPeople] = (0, import_react17.useState)([]);
|
|
2261
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
2262
|
+
const [search, setSearch] = (0, import_react17.useState)(initialSearch ?? "");
|
|
2263
|
+
const [open, setOpenState] = (0, import_react17.useState)(autoOpen === true);
|
|
2264
|
+
const onCloseRef = (0, import_react17.useRef)(onClose);
|
|
2082
2265
|
onCloseRef.current = onClose;
|
|
2083
|
-
const setOpen = (0,
|
|
2266
|
+
const setOpen = (0, import_react17.useCallback)((next) => {
|
|
2084
2267
|
setOpenState(next);
|
|
2085
2268
|
if (!next) onCloseRef.current?.();
|
|
2086
2269
|
}, []);
|
|
2087
|
-
const [busy, setBusy] = (0,
|
|
2270
|
+
const [busy, setBusy] = (0, import_react17.useState)(false);
|
|
2088
2271
|
const membersPort = host.members;
|
|
2089
2272
|
const personTable = field.relation_target;
|
|
2090
|
-
const picked = (0,
|
|
2273
|
+
const picked = (0, import_react17.useMemo)(
|
|
2091
2274
|
() => Array.isArray(value) ? value.map(String) : value === null || value === void 0 ? [] : [String(value)],
|
|
2092
2275
|
[value]
|
|
2093
2276
|
);
|
|
2094
|
-
const load = (0,
|
|
2277
|
+
const load = (0, import_react17.useCallback)(async () => {
|
|
2095
2278
|
if (!membersPort || !client) return;
|
|
2096
2279
|
const [roster, records] = await Promise.all([
|
|
2097
2280
|
membersPort(),
|
|
@@ -2104,11 +2287,11 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2104
2287
|
}
|
|
2105
2288
|
setPeople(records ? records.data.rows.map(personFromRow).filter((p) => p.userId !== null) : []);
|
|
2106
2289
|
}, [membersPort, client, personTable]);
|
|
2107
|
-
(0,
|
|
2290
|
+
(0, import_react17.useEffect)(() => {
|
|
2108
2291
|
if (!open) return;
|
|
2109
2292
|
void load();
|
|
2110
2293
|
}, [open, load]);
|
|
2111
|
-
(0,
|
|
2294
|
+
(0, import_react17.useEffect)(() => {
|
|
2112
2295
|
if (picked.length === 0 || !personTable || people.length > 0 || !client) return;
|
|
2113
2296
|
let cancelled = false;
|
|
2114
2297
|
void client.list({ table_id: personTable, limit: 500 }).then((result) => {
|
|
@@ -2129,12 +2312,12 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2129
2312
|
},
|
|
2130
2313
|
onClose: () => setOpen(false)
|
|
2131
2314
|
});
|
|
2132
|
-
const pickRef = (0,
|
|
2315
|
+
const pickRef = (0, import_react17.useRef)(null);
|
|
2133
2316
|
if (!membersPort || !client) {
|
|
2134
|
-
return /* @__PURE__ */ (0,
|
|
2317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: (0, import_design_system10.cn)("text-xs text-muted-foreground", className), children: NO_MEMBERS_REASON });
|
|
2135
2318
|
}
|
|
2136
2319
|
if (!personTable) {
|
|
2137
|
-
return /* @__PURE__ */ (0,
|
|
2320
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: (0, import_design_system10.cn)("text-xs text-muted-foreground", className), children: [
|
|
2138
2321
|
fieldName(field),
|
|
2139
2322
|
" 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."
|
|
2140
2323
|
] });
|
|
@@ -2177,8 +2360,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2177
2360
|
const pickedUserIds = new Set(
|
|
2178
2361
|
picked.map((recordId) => people.find((p) => p.id === recordId)?.userId).filter(Boolean)
|
|
2179
2362
|
);
|
|
2180
|
-
return /* @__PURE__ */ (0,
|
|
2181
|
-
picked.map((recordId) => /* @__PURE__ */ (0,
|
|
2363
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: (0, import_design_system10.cn)("flex flex-wrap items-center gap-1", className), children: [
|
|
2364
|
+
picked.map((recordId) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2182
2365
|
RecordChip,
|
|
2183
2366
|
{
|
|
2184
2367
|
title: nameOfRecord(recordId),
|
|
@@ -2186,9 +2369,9 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2186
2369
|
},
|
|
2187
2370
|
recordId
|
|
2188
2371
|
)),
|
|
2189
|
-
disabled ? null : /* @__PURE__ */ (0,
|
|
2190
|
-
/* @__PURE__ */ (0,
|
|
2191
|
-
|
|
2372
|
+
disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system10.Popover, { open, onOpenChange: setOpen, children: [
|
|
2373
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system10.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2374
|
+
import_design_system10.Button,
|
|
2192
2375
|
{
|
|
2193
2376
|
id,
|
|
2194
2377
|
type: "button",
|
|
@@ -2198,8 +2381,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2198
2381
|
children: picked.length === 0 ? "Pick a person" : "Change"
|
|
2199
2382
|
}
|
|
2200
2383
|
) }),
|
|
2201
|
-
/* @__PURE__ */ (0,
|
|
2202
|
-
|
|
2384
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2385
|
+
import_design_system10.PopoverContent,
|
|
2203
2386
|
{
|
|
2204
2387
|
sizing: "content",
|
|
2205
2388
|
className: "p-1",
|
|
@@ -2207,8 +2390,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2207
2390
|
"data-matrx-cell-editor": "",
|
|
2208
2391
|
onKeyDown: (event) => event.stopPropagation(),
|
|
2209
2392
|
children: [
|
|
2210
|
-
/* @__PURE__ */ (0,
|
|
2211
|
-
|
|
2393
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2394
|
+
import_design_system10.BasicInput,
|
|
2212
2395
|
{
|
|
2213
2396
|
value: search,
|
|
2214
2397
|
onChange: (e) => setSearch(e.target.value),
|
|
@@ -2220,31 +2403,31 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
|
|
|
2220
2403
|
className: "mb-1 h-7 text-xs"
|
|
2221
2404
|
}
|
|
2222
2405
|
),
|
|
2223
|
-
error ? /* @__PURE__ */ (0,
|
|
2224
|
-
members === null ? /* @__PURE__ */ (0,
|
|
2225
|
-
/* @__PURE__ */ (0,
|
|
2226
|
-
/* @__PURE__ */ (0,
|
|
2406
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefusalLine, { error, className: "p-2" }) : null,
|
|
2407
|
+
members === null ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading the members\u2026" }) : null,
|
|
2408
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system10.ScrollArea, { className: "max-h-56", children: [
|
|
2409
|
+
/* @__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)(
|
|
2227
2410
|
"button",
|
|
2228
2411
|
{
|
|
2229
2412
|
type: "button",
|
|
2230
2413
|
disabled: busy,
|
|
2231
2414
|
"data-pick-highlighted": index === keys.highlight ? "" : void 0,
|
|
2232
2415
|
onClick: () => void pick(member),
|
|
2233
|
-
className: (0,
|
|
2416
|
+
className: (0, import_design_system10.cn)(
|
|
2234
2417
|
"w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-muted",
|
|
2235
2418
|
pickedUserIds.has(member.userId) ? "bg-accent text-accent-foreground" : "",
|
|
2236
2419
|
index === keys.highlight ? "ring-1 ring-ring" : ""
|
|
2237
2420
|
),
|
|
2238
2421
|
children: [
|
|
2239
|
-
/* @__PURE__ */ (0,
|
|
2240
|
-
member.email && member.email !== memberName(member) ? /* @__PURE__ */ (0,
|
|
2422
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: memberName(member) }),
|
|
2423
|
+
member.email && member.email !== memberName(member) ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ml-1.5 opacity-60", children: [
|
|
2241
2424
|
"\xB7 ",
|
|
2242
2425
|
member.email
|
|
2243
2426
|
] }) : null
|
|
2244
2427
|
]
|
|
2245
2428
|
}
|
|
2246
2429
|
) }, member.userId)) }),
|
|
2247
|
-
members !== null && visible.length === 0 ? /* @__PURE__ */ (0,
|
|
2430
|
+
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
|
|
2248
2431
|
] })
|
|
2249
2432
|
]
|
|
2250
2433
|
}
|
|
@@ -2316,16 +2499,16 @@ function currencyCodeFor(unit) {
|
|
|
2316
2499
|
}
|
|
2317
2500
|
|
|
2318
2501
|
// src/formatControls.tsx
|
|
2319
|
-
var
|
|
2320
|
-
var
|
|
2502
|
+
var import_react20 = require("react");
|
|
2503
|
+
var import_design_system12 = require("@ai-matrx/design-system");
|
|
2321
2504
|
var import_field_formats4 = require("@ai-matrx/design-system/field-formats");
|
|
2322
2505
|
|
|
2323
2506
|
// src/formattedValue.tsx
|
|
2324
|
-
var
|
|
2507
|
+
var import_react19 = require("react");
|
|
2325
2508
|
var import_data_table2 = require("@ai-matrx/design-system/data-table");
|
|
2326
2509
|
var import_field_formats3 = require("@ai-matrx/design-system/field-formats");
|
|
2327
|
-
var
|
|
2328
|
-
var
|
|
2510
|
+
var import_design_system11 = require("@ai-matrx/design-system");
|
|
2511
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2329
2512
|
var LINK = "inline-flex min-w-0 items-center gap-1 text-primary hover:underline";
|
|
2330
2513
|
var own2 = (event) => event.stopPropagation();
|
|
2331
2514
|
function numberOf(value) {
|
|
@@ -2343,11 +2526,11 @@ function RatingStars({
|
|
|
2343
2526
|
label,
|
|
2344
2527
|
selectFirst
|
|
2345
2528
|
}) {
|
|
2346
|
-
const armed = (0,
|
|
2529
|
+
const armed = (0, import_react19.useRef)(true);
|
|
2347
2530
|
const score = numberOf(value) ?? 0;
|
|
2348
2531
|
const shown2 = Math.round(score);
|
|
2349
2532
|
const said = `${shown2} out of ${max}`;
|
|
2350
|
-
return /* @__PURE__ */ (0,
|
|
2533
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2351
2534
|
"span",
|
|
2352
2535
|
{
|
|
2353
2536
|
"data-records-rating": "",
|
|
@@ -2359,8 +2542,8 @@ function RatingStars({
|
|
|
2359
2542
|
children: Array.from({ length: max }, (_, i) => {
|
|
2360
2543
|
const n = i + 1;
|
|
2361
2544
|
const lit = n <= shown2;
|
|
2362
|
-
const star = /* @__PURE__ */ (0,
|
|
2363
|
-
return onRate ? /* @__PURE__ */ (0,
|
|
2545
|
+
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" });
|
|
2546
|
+
return onRate ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2364
2547
|
"button",
|
|
2365
2548
|
{
|
|
2366
2549
|
type: "button",
|
|
@@ -2385,7 +2568,7 @@ function RatingStars({
|
|
|
2385
2568
|
children: star
|
|
2386
2569
|
},
|
|
2387
2570
|
n
|
|
2388
|
-
) : /* @__PURE__ */ (0,
|
|
2571
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: star }, n);
|
|
2389
2572
|
})
|
|
2390
2573
|
}
|
|
2391
2574
|
);
|
|
@@ -2393,13 +2576,13 @@ function RatingStars({
|
|
|
2393
2576
|
function rich(id, text, raw, format) {
|
|
2394
2577
|
switch (id) {
|
|
2395
2578
|
case "email":
|
|
2396
|
-
return /* @__PURE__ */ (0,
|
|
2579
|
+
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 }) });
|
|
2397
2580
|
case "url":
|
|
2398
|
-
return /* @__PURE__ */ (0,
|
|
2581
|
+
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 }) });
|
|
2399
2582
|
case "phone":
|
|
2400
|
-
return /* @__PURE__ */ (0,
|
|
2583
|
+
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: formatPhone(text) }) });
|
|
2401
2584
|
case "address":
|
|
2402
|
-
return /* @__PURE__ */ (0,
|
|
2585
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2403
2586
|
"a",
|
|
2404
2587
|
{
|
|
2405
2588
|
href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(text)}`,
|
|
@@ -2408,7 +2591,7 @@ function rich(id, text, raw, format) {
|
|
|
2408
2591
|
className: LINK,
|
|
2409
2592
|
title: "Open in maps",
|
|
2410
2593
|
onClick: own2,
|
|
2411
|
-
children: /* @__PURE__ */ (0,
|
|
2594
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate", children: text })
|
|
2412
2595
|
}
|
|
2413
2596
|
);
|
|
2414
2597
|
case "progress": {
|
|
@@ -2416,8 +2599,8 @@ function rich(id, text, raw, format) {
|
|
|
2416
2599
|
if (n === null) return void 0;
|
|
2417
2600
|
const pct = format.options?.percentScale === "fraction" ? n * 100 : n;
|
|
2418
2601
|
const clamped = Math.max(0, Math.min(100, pct));
|
|
2419
|
-
return /* @__PURE__ */ (0,
|
|
2420
|
-
/* @__PURE__ */ (0,
|
|
2602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "inline-flex w-full min-w-0 items-center gap-2", title: text, children: [
|
|
2603
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2421
2604
|
"span",
|
|
2422
2605
|
{
|
|
2423
2606
|
role: "progressbar",
|
|
@@ -2425,24 +2608,24 @@ function rich(id, text, raw, format) {
|
|
|
2425
2608
|
"aria-valuemax": 100,
|
|
2426
2609
|
"aria-valuenow": Math.round(clamped),
|
|
2427
2610
|
className: "h-1.5 min-w-8 flex-1 overflow-hidden rounded-full bg-muted",
|
|
2428
|
-
children: /* @__PURE__ */ (0,
|
|
2611
|
+
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}%` } })
|
|
2429
2612
|
}
|
|
2430
2613
|
),
|
|
2431
|
-
/* @__PURE__ */ (0,
|
|
2614
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: text })
|
|
2432
2615
|
] });
|
|
2433
2616
|
}
|
|
2434
2617
|
case "color":
|
|
2435
|
-
return /* @__PURE__ */ (0,
|
|
2436
|
-
/* @__PURE__ */ (0,
|
|
2437
|
-
/* @__PURE__ */ (0,
|
|
2618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
2619
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "h-4 w-4 shrink-0 rounded border border-border", style: { backgroundColor: text } }),
|
|
2620
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("code", { className: "font-mono text-xs", children: text })
|
|
2438
2621
|
] });
|
|
2439
2622
|
case "tags": {
|
|
2440
2623
|
const items = Array.isArray(raw) ? raw.map(String) : text.split(",").map((s) => s.trim()).filter(Boolean);
|
|
2441
2624
|
if (items.length === 0) return void 0;
|
|
2442
|
-
return /* @__PURE__ */ (0,
|
|
2625
|
+
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}`)) });
|
|
2443
2626
|
}
|
|
2444
2627
|
case "rating":
|
|
2445
|
-
return numberOf(raw) === null ? void 0 : /* @__PURE__ */ (0,
|
|
2628
|
+
return numberOf(raw) === null ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RatingStars, { value: raw, max: format.options?.ratingMax ?? 5 });
|
|
2446
2629
|
default:
|
|
2447
2630
|
return void 0;
|
|
2448
2631
|
}
|
|
@@ -2457,11 +2640,11 @@ function FormattedValue({
|
|
|
2457
2640
|
const score = numberOf(value);
|
|
2458
2641
|
const max = format.options?.ratingMax ?? 5;
|
|
2459
2642
|
if (def?.id === "rating" && onRate && (value === null || value === void 0 || value === "" || score !== null && score >= 0 && score <= max)) {
|
|
2460
|
-
return /* @__PURE__ */ (0,
|
|
2643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, onRate, selectFirst });
|
|
2461
2644
|
}
|
|
2462
2645
|
const result = (0, import_field_formats3.formatFieldValue)(value, format);
|
|
2463
|
-
if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ (0,
|
|
2464
|
-
return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ (0,
|
|
2646
|
+
if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_data_table2.FormattedCell, { result });
|
|
2647
|
+
return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_data_table2.FormattedCell, { result });
|
|
2465
2648
|
}
|
|
2466
2649
|
function formatPhone(raw) {
|
|
2467
2650
|
const text = raw.trim();
|
|
@@ -2485,7 +2668,7 @@ function linkChipText(raw) {
|
|
|
2485
2668
|
}
|
|
2486
2669
|
|
|
2487
2670
|
// src/formatControls.tsx
|
|
2488
|
-
var
|
|
2671
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2489
2672
|
var TYPED_NUMBERS = /* @__PURE__ */ new Set(["currency", "percent", "progress", "decimal", "duration", "file_size", "integer"]);
|
|
2490
2673
|
function scaled(format) {
|
|
2491
2674
|
return (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction";
|
|
@@ -2502,14 +2685,14 @@ function keptValue(format, raw) {
|
|
|
2502
2685
|
return parsed;
|
|
2503
2686
|
}
|
|
2504
2687
|
function NumberInFormat({ format, value, onChange, disabled, id }) {
|
|
2505
|
-
const [text, setText] = (0,
|
|
2506
|
-
const lastSent = (0,
|
|
2507
|
-
(0,
|
|
2688
|
+
const [text, setText] = (0, import_react20.useState)(() => typedText(format, value));
|
|
2689
|
+
const lastSent = (0, import_react20.useRef)(void 0);
|
|
2690
|
+
(0, import_react20.useEffect)(() => {
|
|
2508
2691
|
if (value === lastSent.current) return;
|
|
2509
2692
|
setText(typedText(format, value));
|
|
2510
2693
|
}, [value, format]);
|
|
2511
|
-
return /* @__PURE__ */ (0,
|
|
2512
|
-
|
|
2694
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2695
|
+
import_design_system12.BasicInput,
|
|
2513
2696
|
{
|
|
2514
2697
|
id,
|
|
2515
2698
|
inputMode: "decimal",
|
|
@@ -2533,17 +2716,17 @@ function formatControl(args) {
|
|
|
2533
2716
|
const text = value === null || value === void 0 ? "" : String(value);
|
|
2534
2717
|
const commit = (raw) => onChange(raw === "" ? null : (0, import_field_formats4.parseFieldInput)(raw, format));
|
|
2535
2718
|
if (def.id === "rating") {
|
|
2536
|
-
return disabled ? /* @__PURE__ */ (0,
|
|
2719
|
+
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) }) });
|
|
2537
2720
|
}
|
|
2538
|
-
if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ (0,
|
|
2721
|
+
if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NumberInFormat, { ...args });
|
|
2539
2722
|
switch (def.editor) {
|
|
2540
2723
|
// A TIME OF DAY is not this file's: `FieldControl` draws the typed box and its helper
|
|
2541
2724
|
// (`TypedWordsControl`), never the browser's time control (grids review 3, 2026-09-30).
|
|
2542
2725
|
case "email":
|
|
2543
2726
|
case "url":
|
|
2544
2727
|
case "tel":
|
|
2545
|
-
return /* @__PURE__ */ (0,
|
|
2546
|
-
|
|
2728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2729
|
+
import_design_system12.BasicInput,
|
|
2547
2730
|
{
|
|
2548
2731
|
id,
|
|
2549
2732
|
type: def.editor,
|
|
@@ -2554,9 +2737,9 @@ function formatControl(args) {
|
|
|
2554
2737
|
}
|
|
2555
2738
|
);
|
|
2556
2739
|
case "color":
|
|
2557
|
-
return /* @__PURE__ */ (0,
|
|
2558
|
-
/* @__PURE__ */ (0,
|
|
2559
|
-
|
|
2740
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
2741
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2742
|
+
import_design_system12.BasicInput,
|
|
2560
2743
|
{
|
|
2561
2744
|
id: `${id}-swatch`,
|
|
2562
2745
|
type: "color",
|
|
@@ -2567,20 +2750,20 @@ function formatControl(args) {
|
|
|
2567
2750
|
onChange: (e) => commit(e.target.value)
|
|
2568
2751
|
}
|
|
2569
2752
|
),
|
|
2570
|
-
/* @__PURE__ */ (0,
|
|
2753
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system12.BasicInput, { id, value: text, placeholder: "#3b82f6", disabled, onChange: (e) => commit(e.target.value) })
|
|
2571
2754
|
] });
|
|
2572
2755
|
case "textarea":
|
|
2573
|
-
return /* @__PURE__ */ (0,
|
|
2756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system12.BasicTextarea, { id, rows: 4, value: text, disabled, onChange: (e) => commit(e.target.value) });
|
|
2574
2757
|
default:
|
|
2575
2758
|
return null;
|
|
2576
2759
|
}
|
|
2577
2760
|
}
|
|
2578
2761
|
|
|
2579
2762
|
// src/typedDateHelper.tsx
|
|
2580
|
-
var
|
|
2581
|
-
var
|
|
2763
|
+
var import_react21 = require("react");
|
|
2764
|
+
var import_design_system13 = require("@ai-matrx/design-system");
|
|
2582
2765
|
var import_records9 = require("@ai-matrx/records");
|
|
2583
|
-
var
|
|
2766
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2584
2767
|
var WEEK = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
2585
2768
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
2586
2769
|
function pad(n) {
|
|
@@ -2609,23 +2792,23 @@ function wordsFor(kind, day, time) {
|
|
|
2609
2792
|
}
|
|
2610
2793
|
var keepFocus = { onMouseDown: (e) => e.preventDefault(), tabIndex: -1 };
|
|
2611
2794
|
function CalendarGlyph() {
|
|
2612
|
-
return /* @__PURE__ */ (0,
|
|
2613
|
-
/* @__PURE__ */ (0,
|
|
2614
|
-
/* @__PURE__ */ (0,
|
|
2795
|
+
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: [
|
|
2796
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
|
|
2797
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M16 2v4M8 2v4M3 10h18" })
|
|
2615
2798
|
] });
|
|
2616
2799
|
}
|
|
2617
2800
|
function ClockGlyph() {
|
|
2618
|
-
return /* @__PURE__ */ (0,
|
|
2619
|
-
/* @__PURE__ */ (0,
|
|
2620
|
-
/* @__PURE__ */ (0,
|
|
2801
|
+
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: [
|
|
2802
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2803
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M12 6v6l4 2" })
|
|
2621
2804
|
] });
|
|
2622
2805
|
}
|
|
2623
2806
|
function TypedDateHelper({ kind, text, onText, label }) {
|
|
2624
|
-
const [open, setOpen] = (0,
|
|
2807
|
+
const [open, setOpen] = (0, import_react21.useState)(false);
|
|
2625
2808
|
const held = readBox(text, kind);
|
|
2626
2809
|
const today = /* @__PURE__ */ new Date();
|
|
2627
2810
|
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);
|
|
2628
|
-
const [month, setMonth] = (0,
|
|
2811
|
+
const [month, setMonth] = (0, import_react21.useState)(null);
|
|
2629
2812
|
const shown2 = month ?? { y: start.getFullYear(), m: start.getMonth() };
|
|
2630
2813
|
const first = new Date(shown2.y, shown2.m, 1).getDay();
|
|
2631
2814
|
const days = new Date(shown2.y, shown2.m + 1, 0).getDate();
|
|
@@ -2646,8 +2829,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2646
2829
|
const at = new Date(shown2.y, shown2.m + by, 1);
|
|
2647
2830
|
setMonth({ y: at.getFullYear(), m: at.getMonth() });
|
|
2648
2831
|
};
|
|
2649
|
-
return /* @__PURE__ */ (0,
|
|
2650
|
-
/* @__PURE__ */ (0,
|
|
2832
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system13.Popover, { open, onOpenChange: setOpen, children: [
|
|
2833
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2651
2834
|
"button",
|
|
2652
2835
|
{
|
|
2653
2836
|
type: "button",
|
|
@@ -2656,11 +2839,11 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2656
2839
|
"aria-label": kind === "time" ? `Pick a time for ${label}` : `Pick a date for ${label}`,
|
|
2657
2840
|
title: kind === "time" ? "Pick a time" : "Pick a date",
|
|
2658
2841
|
className: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
2659
|
-
children: kind === "time" ? /* @__PURE__ */ (0,
|
|
2842
|
+
children: kind === "time" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ClockGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CalendarGlyph, {})
|
|
2660
2843
|
}
|
|
2661
2844
|
) }),
|
|
2662
|
-
/* @__PURE__ */ (0,
|
|
2663
|
-
|
|
2845
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2846
|
+
import_design_system13.PopoverContent,
|
|
2664
2847
|
{
|
|
2665
2848
|
sizing: "content",
|
|
2666
2849
|
align: "start",
|
|
@@ -2669,29 +2852,29 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2669
2852
|
"data-records-date-helper-panel": "",
|
|
2670
2853
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
2671
2854
|
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
2672
|
-
children: /* @__PURE__ */ (0,
|
|
2673
|
-
kind === "time" ? null : /* @__PURE__ */ (0,
|
|
2674
|
-
/* @__PURE__ */ (0,
|
|
2675
|
-
/* @__PURE__ */ (0,
|
|
2676
|
-
/* @__PURE__ */ (0,
|
|
2855
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex gap-2", children: [
|
|
2856
|
+
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: [
|
|
2857
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center justify-between text-xs font-medium", children: [
|
|
2858
|
+
/* @__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" }),
|
|
2859
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
|
|
2677
2860
|
MONTHS[shown2.m],
|
|
2678
2861
|
" ",
|
|
2679
2862
|
shown2.y
|
|
2680
2863
|
] }),
|
|
2681
|
-
/* @__PURE__ */ (0,
|
|
2864
|
+
/* @__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" })
|
|
2682
2865
|
] }),
|
|
2683
|
-
/* @__PURE__ */ (0,
|
|
2684
|
-
WEEK.map((w) => /* @__PURE__ */ (0,
|
|
2866
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "grid grid-cols-7 gap-0.5 text-center text-[11px]", children: [
|
|
2867
|
+
WEEK.map((w) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-muted-foreground", children: w }, w)),
|
|
2685
2868
|
cells.map((d, i) => {
|
|
2686
|
-
if (d === null) return /* @__PURE__ */ (0,
|
|
2869
|
+
if (d === null) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", {}, `blank-${i}`);
|
|
2687
2870
|
const key = `${shown2.y}-${pad(shown2.m + 1)}-${pad(d)}`;
|
|
2688
|
-
return /* @__PURE__ */ (0,
|
|
2871
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2689
2872
|
"button",
|
|
2690
2873
|
{
|
|
2691
2874
|
type: "button",
|
|
2692
2875
|
...keepFocus,
|
|
2693
2876
|
"data-records-date-helper-day": key,
|
|
2694
|
-
className: (0,
|
|
2877
|
+
className: (0, import_design_system13.cn)(
|
|
2695
2878
|
"h-6 w-6 rounded tabular-nums hover:bg-muted",
|
|
2696
2879
|
key === held.day ? "bg-primary text-primary-foreground hover:bg-primary" : "",
|
|
2697
2880
|
key === todayKey && key !== held.day ? "ring-1 ring-ring" : ""
|
|
@@ -2704,13 +2887,13 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2704
2887
|
})
|
|
2705
2888
|
] })
|
|
2706
2889
|
] }),
|
|
2707
|
-
kind === "date" ? null : /* @__PURE__ */ (0,
|
|
2890
|
+
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)(
|
|
2708
2891
|
"button",
|
|
2709
2892
|
{
|
|
2710
2893
|
type: "button",
|
|
2711
2894
|
...keepFocus,
|
|
2712
2895
|
"data-records-date-helper-time": `${pad(t.h)}:${pad(t.m)}`,
|
|
2713
|
-
className: (0,
|
|
2896
|
+
className: (0, import_design_system13.cn)(
|
|
2714
2897
|
"whitespace-nowrap rounded px-2 py-0.5 text-left tabular-nums hover:bg-muted",
|
|
2715
2898
|
held.time && held.time.h === t.h && held.time.m === t.m ? "bg-primary text-primary-foreground" : ""
|
|
2716
2899
|
),
|
|
@@ -2726,8 +2909,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
|
|
|
2726
2909
|
}
|
|
2727
2910
|
|
|
2728
2911
|
// src/choiceNudge.ts
|
|
2729
|
-
var
|
|
2730
|
-
var
|
|
2912
|
+
var import_react22 = require("react");
|
|
2913
|
+
var import_react23 = require("@ai-matrx/records/react");
|
|
2731
2914
|
var asked = /* @__PURE__ */ new WeakMap();
|
|
2732
2915
|
function choiceNudgeOf(client) {
|
|
2733
2916
|
let answer = asked.get(client);
|
|
@@ -2741,9 +2924,9 @@ function choiceNudgeOf(client) {
|
|
|
2741
2924
|
return answer;
|
|
2742
2925
|
}
|
|
2743
2926
|
function useChoiceNudge(enabled = true) {
|
|
2744
|
-
const client = (0,
|
|
2745
|
-
const [nudge, setNudge] = (0,
|
|
2746
|
-
(0,
|
|
2927
|
+
const client = (0, import_react23.useOptionalRecordsClient)();
|
|
2928
|
+
const [nudge, setNudge] = (0, import_react22.useState)(null);
|
|
2929
|
+
(0, import_react22.useEffect)(() => {
|
|
2747
2930
|
if (!enabled || !client) return;
|
|
2748
2931
|
let live = true;
|
|
2749
2932
|
void choiceNudgeOf(client).then((answer) => {
|
|
@@ -2811,7 +2994,7 @@ function choiceChipLookOf(field, ...words) {
|
|
|
2811
2994
|
}
|
|
2812
2995
|
|
|
2813
2996
|
// src/editors.tsx
|
|
2814
|
-
var
|
|
2997
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2815
2998
|
var CHOICE_EDITOR_ADDS_WHAT_IS_TYPED = true;
|
|
2816
2999
|
function isChoiceAddition(value) {
|
|
2817
3000
|
return typeof value === "object" && value !== null && value.addingChoices === true;
|
|
@@ -2841,12 +3024,12 @@ function ChoiceAskButtons({
|
|
|
2841
3024
|
onCancel,
|
|
2842
3025
|
busy
|
|
2843
3026
|
}) {
|
|
2844
|
-
return /* @__PURE__ */ (0,
|
|
2845
|
-
/* @__PURE__ */ (0,
|
|
2846
|
-
/* @__PURE__ */ (0,
|
|
2847
|
-
/* @__PURE__ */ (0,
|
|
2848
|
-
keepOffered ? /* @__PURE__ */ (0,
|
|
2849
|
-
/* @__PURE__ */ (0,
|
|
3027
|
+
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: [
|
|
3028
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field, words) }),
|
|
3029
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-wrap items-center gap-1", children: [
|
|
3030
|
+
/* @__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" }),
|
|
3031
|
+
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,
|
|
3032
|
+
/* @__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" })
|
|
2850
3033
|
] })
|
|
2851
3034
|
] });
|
|
2852
3035
|
}
|
|
@@ -2929,12 +3112,12 @@ function openingText(field, value) {
|
|
|
2929
3112
|
return format ? typedText(format, value) : String(value);
|
|
2930
3113
|
}
|
|
2931
3114
|
function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCancel }) {
|
|
2932
|
-
const client = (0,
|
|
3115
|
+
const client = (0, import_react25.useOptionalRecordsClient)();
|
|
2933
3116
|
const kind = String(editorKindFor(field));
|
|
2934
3117
|
const needsChoices = kind === "select" || kind === "multi_select";
|
|
2935
3118
|
const nudge = useChoiceNudge(needsChoices);
|
|
2936
|
-
const [choices, setChoices] = (0,
|
|
2937
|
-
(0,
|
|
3119
|
+
const [choices, setChoices] = (0, import_react24.useState)(null);
|
|
3120
|
+
(0, import_react24.useEffect)(() => {
|
|
2938
3121
|
if (!needsChoices || !client) return;
|
|
2939
3122
|
let cancelled = false;
|
|
2940
3123
|
void client.fieldOptions({ field_id: field.id }).then((result) => {
|
|
@@ -2944,7 +3127,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2944
3127
|
cancelled = true;
|
|
2945
3128
|
};
|
|
2946
3129
|
}, [client, field.id, needsChoices]);
|
|
2947
|
-
(0,
|
|
3130
|
+
(0, import_react24.useEffect)(() => {
|
|
2948
3131
|
if (choices && nudge && value.judged === null) onChange({ ...value, judged: judgeTyped(field, value.text, choices, nudge) });
|
|
2949
3132
|
}, [choices, nudge, value, field, onChange]);
|
|
2950
3133
|
const judged = value.judged;
|
|
@@ -2956,8 +3139,8 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2956
3139
|
judged: judgeTyped(field, text, needsChoices ? choices : void 0, needsChoices ? nudge : void 0),
|
|
2957
3140
|
...value.openedAs !== void 0 ? { openedAs: value.openedAs } : {}
|
|
2958
3141
|
});
|
|
2959
|
-
const box = /* @__PURE__ */ (0,
|
|
2960
|
-
|
|
3142
|
+
const box = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3143
|
+
import_design_system14.BasicInput,
|
|
2961
3144
|
{
|
|
2962
3145
|
id,
|
|
2963
3146
|
value: value.text,
|
|
@@ -2968,16 +3151,16 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2968
3151
|
onChange: (e) => retype(e.target.value)
|
|
2969
3152
|
}
|
|
2970
3153
|
);
|
|
2971
|
-
return /* @__PURE__ */ (0,
|
|
2972
|
-
helper && !disabled ? /* @__PURE__ */ (0,
|
|
3154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col gap-0.5", children: [
|
|
3155
|
+
helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex min-w-0 items-center gap-0.5", children: [
|
|
2973
3156
|
box,
|
|
2974
|
-
/* @__PURE__ */ (0,
|
|
3157
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field) })
|
|
2975
3158
|
] }) : box,
|
|
2976
|
-
judged === null ? /* @__PURE__ */ (0,
|
|
3159
|
+
judged === null ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
2977
3160
|
"Reading ",
|
|
2978
3161
|
fieldName(field),
|
|
2979
3162
|
"'s choices\u2026"
|
|
2980
|
-
] }) : "ask" in judged ? /* @__PURE__ */ (0,
|
|
3163
|
+
] }) : "ask" in judged ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2981
3164
|
ChoiceAskButtons,
|
|
2982
3165
|
{
|
|
2983
3166
|
field,
|
|
@@ -2993,10 +3176,10 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
2993
3176
|
},
|
|
2994
3177
|
onCancel: () => onCancel?.()
|
|
2995
3178
|
}
|
|
2996
|
-
) : "refusal" in judged ? /* @__PURE__ */ (0,
|
|
2997
|
-
/* @__PURE__ */ (0,
|
|
2998
|
-
judged.cancelOnly && onCancel ? /* @__PURE__ */ (0,
|
|
2999
|
-
] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ (0,
|
|
3179
|
+
) : "refusal" in judged ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col gap-1", children: [
|
|
3180
|
+
/* @__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 }),
|
|
3181
|
+
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
|
|
3182
|
+
] }) : 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: [
|
|
3000
3183
|
isChoiceAddition(judged.value) ? `Adds ${quoted(judged.value.add)} to the choices for ${fieldName(field)}. ` : null,
|
|
3001
3184
|
"Reads as",
|
|
3002
3185
|
" ",
|
|
@@ -3007,7 +3190,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
|
|
|
3007
3190
|
}).join(", ")
|
|
3008
3191
|
) : (() => {
|
|
3009
3192
|
const shown2 = format ?? (kind === "datetime" ? { id: carriesTimeOfDay(field, judged.value) ? "datetime" : "date" } : void 0);
|
|
3010
|
-
return shown2 ? /* @__PURE__ */ (0,
|
|
3193
|
+
return shown2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FormattedValue, { value: judged.value, format: shown2 }) : String(judged.value);
|
|
3011
3194
|
})()
|
|
3012
3195
|
] })
|
|
3013
3196
|
] });
|
|
@@ -3020,13 +3203,13 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3020
3203
|
const host = useRecordsUi();
|
|
3021
3204
|
const kind = editorKindFor(field);
|
|
3022
3205
|
const inputId = id ?? `field-${field.key}`;
|
|
3023
|
-
const ownDetails = (0,
|
|
3024
|
-
if (isTypedDraft(value)) return /* @__PURE__ */ (0,
|
|
3025
|
-
if (isSignatureField(field)) return /* @__PURE__ */ (0,
|
|
3206
|
+
const ownDetails = (0, import_react25.useOptionalRecordsClient)() === null;
|
|
3207
|
+
if (isTypedDraft(value)) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedTextControl, { field, value, onChange, disabled, id: inputId, onCommit, onCancel });
|
|
3208
|
+
if (isSignatureField(field)) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SignaturePad, { id: inputId, value, onChange, disabled });
|
|
3026
3209
|
const newerControl = newerKindControl({ field, value, onChange, disabled, id: inputId });
|
|
3027
3210
|
if (newerControl !== void 0) return newerControl;
|
|
3028
3211
|
const format = formatForField(field);
|
|
3029
|
-
if (format && format.id === "time") return /* @__PURE__ */ (0,
|
|
3212
|
+
if (format && format.id === "time") return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
|
|
3030
3213
|
if (format && !FORMAT_BLIND_KINDS.has(String(kind))) {
|
|
3031
3214
|
const own3 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field), ownDetails });
|
|
3032
3215
|
if (own3) return own3;
|
|
@@ -3035,18 +3218,18 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3035
3218
|
case "formula":
|
|
3036
3219
|
case "lookup":
|
|
3037
3220
|
case "rollup":
|
|
3038
|
-
return /* @__PURE__ */ (0,
|
|
3221
|
+
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: [
|
|
3039
3222
|
value === null || value === void 0 ? "\u2014" : String(value),
|
|
3040
|
-
/* @__PURE__ */ (0,
|
|
3223
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "ml-2 italic", children: [
|
|
3041
3224
|
fieldName(field),
|
|
3042
3225
|
" is worked out by the system, so it cannot be typed in"
|
|
3043
3226
|
] })
|
|
3044
3227
|
] });
|
|
3045
3228
|
case "json":
|
|
3046
|
-
return /* @__PURE__ */ (0,
|
|
3229
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(JsonControl, { field, value, onChange, disabled, id: inputId });
|
|
3047
3230
|
case "long_text":
|
|
3048
|
-
return /* @__PURE__ */ (0,
|
|
3049
|
-
|
|
3231
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3232
|
+
import_design_system14.BasicTextarea,
|
|
3050
3233
|
{
|
|
3051
3234
|
id: inputId,
|
|
3052
3235
|
rows: 3,
|
|
@@ -3058,8 +3241,8 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3058
3241
|
case "number":
|
|
3059
3242
|
case "currency":
|
|
3060
3243
|
case "percent":
|
|
3061
|
-
return /* @__PURE__ */ (0,
|
|
3062
|
-
|
|
3244
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3245
|
+
import_design_system14.BasicInput,
|
|
3063
3246
|
{
|
|
3064
3247
|
id: inputId,
|
|
3065
3248
|
type: "number",
|
|
@@ -3071,12 +3254,12 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3071
3254
|
}
|
|
3072
3255
|
);
|
|
3073
3256
|
case "datetime":
|
|
3074
|
-
return /* @__PURE__ */ (0,
|
|
3257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
|
|
3075
3258
|
case "email":
|
|
3076
3259
|
case "phone":
|
|
3077
3260
|
case "url":
|
|
3078
|
-
return /* @__PURE__ */ (0,
|
|
3079
|
-
|
|
3261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3262
|
+
import_design_system14.BasicInput,
|
|
3080
3263
|
{
|
|
3081
3264
|
id: inputId,
|
|
3082
3265
|
type: kind === "email" ? "email" : kind === "phone" ? "tel" : "url",
|
|
@@ -3087,25 +3270,25 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3087
3270
|
}
|
|
3088
3271
|
);
|
|
3089
3272
|
case "checkbox":
|
|
3090
|
-
return /* @__PURE__ */ (0,
|
|
3273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CheckboxControl, { field, value, onChange, disabled, id: inputId });
|
|
3091
3274
|
case "select":
|
|
3092
3275
|
case "multi_select":
|
|
3093
|
-
return /* @__PURE__ */ (0,
|
|
3276
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(OptionControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
|
|
3094
3277
|
case "member":
|
|
3095
|
-
return /* @__PURE__ */ (0,
|
|
3278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PersonPicker, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
|
|
3096
3279
|
case "entity_reference":
|
|
3097
|
-
return /* @__PURE__ */ (0,
|
|
3280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(EntityReferenceControl, { field, value, onChange, disabled, id: inputId });
|
|
3098
3281
|
case "attachment":
|
|
3099
3282
|
if (hostTakesFiles(host)) {
|
|
3100
|
-
return /* @__PURE__ */ (0,
|
|
3283
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AttachmentControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose });
|
|
3101
3284
|
}
|
|
3102
|
-
return /* @__PURE__ */ (0,
|
|
3285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
|
|
3103
3286
|
case "relation":
|
|
3104
|
-
return /* @__PURE__ */ (0,
|
|
3287
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
|
|
3105
3288
|
default:
|
|
3106
3289
|
if (typeof value === "boolean" || field.config?.["kind"] === "boolean") {
|
|
3107
|
-
return /* @__PURE__ */ (0,
|
|
3108
|
-
|
|
3290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3291
|
+
import_design_system14.Checkbox,
|
|
3109
3292
|
{
|
|
3110
3293
|
id: inputId,
|
|
3111
3294
|
checked: value === true,
|
|
@@ -3114,8 +3297,8 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3114
3297
|
}
|
|
3115
3298
|
);
|
|
3116
3299
|
}
|
|
3117
|
-
return /* @__PURE__ */ (0,
|
|
3118
|
-
|
|
3300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3301
|
+
import_design_system14.BasicInput,
|
|
3119
3302
|
{
|
|
3120
3303
|
id: inputId,
|
|
3121
3304
|
...ownDetails && isPersonsName(field) ? { autoComplete: "name" } : {},
|
|
@@ -3127,10 +3310,10 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
|
|
|
3127
3310
|
}
|
|
3128
3311
|
}
|
|
3129
3312
|
function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
3130
|
-
const [text, setText] = (0,
|
|
3131
|
-
const [refusal2, setRefusal] = (0,
|
|
3132
|
-
const sent = (0,
|
|
3133
|
-
(0,
|
|
3313
|
+
const [text, setText] = (0, import_react24.useState)(() => openingText(field, value));
|
|
3314
|
+
const [refusal2, setRefusal] = (0, import_react24.useState)(null);
|
|
3315
|
+
const sent = (0, import_react24.useRef)(value);
|
|
3316
|
+
(0, import_react24.useEffect)(() => {
|
|
3134
3317
|
if (value === sent.current) return;
|
|
3135
3318
|
sent.current = value;
|
|
3136
3319
|
setText(openingText(field, value));
|
|
@@ -3148,10 +3331,10 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
|
3148
3331
|
setRefusal(judged.refusal);
|
|
3149
3332
|
}
|
|
3150
3333
|
};
|
|
3151
|
-
return /* @__PURE__ */ (0,
|
|
3152
|
-
/* @__PURE__ */ (0,
|
|
3153
|
-
/* @__PURE__ */ (0,
|
|
3154
|
-
|
|
3334
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col gap-0.5", children: [
|
|
3335
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex min-w-0 items-center gap-0.5", children: [
|
|
3336
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3337
|
+
import_design_system14.BasicInput,
|
|
3155
3338
|
{
|
|
3156
3339
|
id,
|
|
3157
3340
|
value: text,
|
|
@@ -3167,16 +3350,16 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
|
|
|
3167
3350
|
}
|
|
3168
3351
|
}
|
|
3169
3352
|
),
|
|
3170
|
-
helper && !disabled ? /* @__PURE__ */ (0,
|
|
3353
|
+
helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field) }) : null
|
|
3171
3354
|
] }),
|
|
3172
|
-
refusal2 ? /* @__PURE__ */ (0,
|
|
3355
|
+
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
|
|
3173
3356
|
] });
|
|
3174
3357
|
}
|
|
3175
3358
|
function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
3176
3359
|
const unanswered = value === null || value === void 0;
|
|
3177
|
-
return /* @__PURE__ */ (0,
|
|
3178
|
-
/* @__PURE__ */ (0,
|
|
3179
|
-
|
|
3360
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3361
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3362
|
+
import_design_system14.Checkbox,
|
|
3180
3363
|
{
|
|
3181
3364
|
id,
|
|
3182
3365
|
checked: value === true,
|
|
@@ -3185,10 +3368,10 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
|
3185
3368
|
onCheckedChange: (next) => onChange(next === true)
|
|
3186
3369
|
}
|
|
3187
3370
|
),
|
|
3188
|
-
unanswered ? /* @__PURE__ */ (0,
|
|
3189
|
-
/* @__PURE__ */ (0,
|
|
3190
|
-
field.required ? null : /* @__PURE__ */ (0,
|
|
3191
|
-
|
|
3371
|
+
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: [
|
|
3372
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-xs text-muted-foreground", children: value === true ? "Yes" : "No" }),
|
|
3373
|
+
field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3374
|
+
import_design_system14.Button,
|
|
3192
3375
|
{
|
|
3193
3376
|
size: "sm",
|
|
3194
3377
|
variant: "ghost",
|
|
@@ -3203,11 +3386,11 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
|
|
|
3203
3386
|
}
|
|
3204
3387
|
function JsonControl({ field, value, onChange, disabled, id }) {
|
|
3205
3388
|
const initial = value === null || value === void 0 ? "" : typeof value === "string" ? value : JSON.stringify(value, null, 2);
|
|
3206
|
-
const [text, setText] = (0,
|
|
3207
|
-
const [broken, setBroken] = (0,
|
|
3208
|
-
return /* @__PURE__ */ (0,
|
|
3209
|
-
/* @__PURE__ */ (0,
|
|
3210
|
-
|
|
3389
|
+
const [text, setText] = (0, import_react24.useState)(initial);
|
|
3390
|
+
const [broken, setBroken] = (0, import_react24.useState)(null);
|
|
3391
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3392
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3393
|
+
import_design_system14.BasicTextarea,
|
|
3211
3394
|
{
|
|
3212
3395
|
id,
|
|
3213
3396
|
rows: 4,
|
|
@@ -3240,7 +3423,7 @@ function JsonControl({ field, value, onChange, disabled, id }) {
|
|
|
3240
3423
|
),
|
|
3241
3424
|
broken ? (
|
|
3242
3425
|
// The typed text is still in the box: the notice owns the two doors out.
|
|
3243
|
-
/* @__PURE__ */ (0,
|
|
3426
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3244
3427
|
RefusalNotice,
|
|
3245
3428
|
{
|
|
3246
3429
|
error: broken,
|
|
@@ -3264,11 +3447,11 @@ function inTheStoresOrder(options) {
|
|
|
3264
3447
|
return [...options].sort((a, b) => position(a) - position(b) || made(a).localeCompare(made(b)));
|
|
3265
3448
|
}
|
|
3266
3449
|
function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose, addsChoices, initialSearch, asForm }) {
|
|
3267
|
-
const client = (0,
|
|
3268
|
-
const [options, setOptions] = (0,
|
|
3269
|
-
const [refusal2, setRefusal] = (0,
|
|
3270
|
-
const [reread, setReread] = (0,
|
|
3271
|
-
(0,
|
|
3450
|
+
const client = (0, import_react25.useOptionalRecordsClient)();
|
|
3451
|
+
const [options, setOptions] = (0, import_react24.useState)(null);
|
|
3452
|
+
const [refusal2, setRefusal] = (0, import_react24.useState)(null);
|
|
3453
|
+
const [reread, setReread] = (0, import_react24.useState)(0);
|
|
3454
|
+
(0, import_react24.useEffect)(() => {
|
|
3272
3455
|
if (!client) return;
|
|
3273
3456
|
let cancelled = false;
|
|
3274
3457
|
void client.fieldOptions({ field_id: field.id }).then((result) => {
|
|
@@ -3282,12 +3465,12 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3282
3465
|
}, [client, field.id, reread]);
|
|
3283
3466
|
const handed = publicChoicesOf(field);
|
|
3284
3467
|
if (!client && handed.length > 0) {
|
|
3285
|
-
return /* @__PURE__ */ (0,
|
|
3468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChoiceAnswer, { field, choices: handed, value, onChange, disabled, id });
|
|
3286
3469
|
}
|
|
3287
3470
|
if (!client) {
|
|
3288
|
-
return /* @__PURE__ */ (0,
|
|
3289
|
-
/* @__PURE__ */ (0,
|
|
3290
|
-
|
|
3471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3472
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3473
|
+
import_design_system14.BasicInput,
|
|
3291
3474
|
{
|
|
3292
3475
|
id,
|
|
3293
3476
|
value: value === null || value === void 0 ? "" : String(value),
|
|
@@ -3295,15 +3478,15 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3295
3478
|
onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
|
|
3296
3479
|
}
|
|
3297
3480
|
),
|
|
3298
|
-
/* @__PURE__ */ (0,
|
|
3481
|
+
/* @__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." })
|
|
3299
3482
|
] });
|
|
3300
3483
|
}
|
|
3301
3484
|
if (refusal2)
|
|
3302
|
-
return /* @__PURE__ */ (0,
|
|
3303
|
-
if (!options) return /* @__PURE__ */ (0,
|
|
3485
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { id, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RefusalLine, { error: refusal2 }) });
|
|
3486
|
+
if (!options) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
|
|
3304
3487
|
if (asForm && options.length > 0) {
|
|
3305
3488
|
const titled = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3306
|
-
return /* @__PURE__ */ (0,
|
|
3489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3307
3490
|
ChoiceAnswer,
|
|
3308
3491
|
{
|
|
3309
3492
|
field,
|
|
@@ -3320,7 +3503,7 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3320
3503
|
);
|
|
3321
3504
|
}
|
|
3322
3505
|
if (CHOICE_EDITOR_ADDS_WHAT_IS_TYPED) {
|
|
3323
|
-
return /* @__PURE__ */ (0,
|
|
3506
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3324
3507
|
OpenChoicePicker,
|
|
3325
3508
|
{
|
|
3326
3509
|
field,
|
|
@@ -3339,14 +3522,14 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3339
3522
|
);
|
|
3340
3523
|
}
|
|
3341
3524
|
if (options.length === 0) {
|
|
3342
|
-
return /* @__PURE__ */ (0,
|
|
3525
|
+
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.` });
|
|
3343
3526
|
}
|
|
3344
3527
|
const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3345
3528
|
if (field.multi) {
|
|
3346
3529
|
const chosen = options.filter((option) => (0, import_records10.choiceValuesOf)(value).some((v) => (0, import_records10.isTheChosen)(option, v)));
|
|
3347
3530
|
const picked = new Set(chosen.map((option) => (0, import_records10.optionKey)(option)));
|
|
3348
|
-
const toggles = /* @__PURE__ */ (0,
|
|
3349
|
-
|
|
3531
|
+
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)(
|
|
3532
|
+
import_design_system14.Button,
|
|
3350
3533
|
{
|
|
3351
3534
|
type: "button",
|
|
3352
3535
|
size: "sm",
|
|
@@ -3363,23 +3546,23 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3363
3546
|
option.id
|
|
3364
3547
|
)) });
|
|
3365
3548
|
if (!autoOpen) return toggles;
|
|
3366
|
-
return /* @__PURE__ */ (0,
|
|
3367
|
-
|
|
3549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3550
|
+
import_design_system14.Popover,
|
|
3368
3551
|
{
|
|
3369
3552
|
defaultOpen: true,
|
|
3370
3553
|
onOpenChange: (open) => {
|
|
3371
3554
|
if (!open) onClose?.();
|
|
3372
3555
|
},
|
|
3373
3556
|
children: [
|
|
3374
|
-
/* @__PURE__ */ (0,
|
|
3375
|
-
/* @__PURE__ */ (0,
|
|
3557
|
+
/* @__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(", ") }) }),
|
|
3558
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.PopoverContent, { sizing: "content", className: "max-w-[20rem] p-2", align: "start", children: toggles })
|
|
3376
3559
|
]
|
|
3377
3560
|
}
|
|
3378
3561
|
);
|
|
3379
3562
|
}
|
|
3380
3563
|
const current = options.find((option) => (0, import_records10.isTheChosen)(option, value));
|
|
3381
|
-
return /* @__PURE__ */ (0,
|
|
3382
|
-
|
|
3564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3565
|
+
import_design_system14.Select,
|
|
3383
3566
|
{
|
|
3384
3567
|
value: current ? (0, import_records10.optionKey)(current) : "",
|
|
3385
3568
|
disabled: disabled ?? false,
|
|
@@ -3392,8 +3575,8 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
|
|
|
3392
3575
|
}
|
|
3393
3576
|
} : {},
|
|
3394
3577
|
children: [
|
|
3395
|
-
/* @__PURE__ */ (0,
|
|
3396
|
-
/* @__PURE__ */ (0,
|
|
3578
|
+
/* @__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" }) }),
|
|
3579
|
+
/* @__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)) })
|
|
3397
3580
|
]
|
|
3398
3581
|
}
|
|
3399
3582
|
);
|
|
@@ -3412,18 +3595,18 @@ function OpenChoicePicker({
|
|
|
3412
3595
|
allowOther = true,
|
|
3413
3596
|
onChoicesChanged
|
|
3414
3597
|
}) {
|
|
3415
|
-
const client = (0,
|
|
3598
|
+
const client = (0, import_react25.useOptionalRecordsClient)();
|
|
3416
3599
|
const nudge = useChoiceNudge();
|
|
3417
|
-
const [open, setOpenState] = (0,
|
|
3418
|
-
const onCloseRef = (0,
|
|
3600
|
+
const [open, setOpenState] = (0, import_react24.useState)(autoOpen === true);
|
|
3601
|
+
const onCloseRef = (0, import_react24.useRef)(onClose);
|
|
3419
3602
|
onCloseRef.current = onClose;
|
|
3420
|
-
const setOpen = (0,
|
|
3603
|
+
const setOpen = (0, import_react24.useCallback)((next) => {
|
|
3421
3604
|
setOpenState(next);
|
|
3422
3605
|
if (!next) onCloseRef.current?.();
|
|
3423
3606
|
}, []);
|
|
3424
|
-
const [search, setSearch] = (0,
|
|
3425
|
-
const [adding, setAdding] = (0,
|
|
3426
|
-
const [addRefused, setAddRefused] = (0,
|
|
3607
|
+
const [search, setSearch] = (0, import_react24.useState)(initialSearch ?? "");
|
|
3608
|
+
const [adding, setAdding] = (0, import_react24.useState)(false);
|
|
3609
|
+
const [addRefused, setAddRefused] = (0, import_react24.useState)(null);
|
|
3427
3610
|
const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
|
|
3428
3611
|
const held = withoutAddition(value);
|
|
3429
3612
|
const current = (0, import_records10.choiceValuesOf)(held.value);
|
|
@@ -3475,7 +3658,7 @@ function OpenChoicePicker({
|
|
|
3475
3658
|
});
|
|
3476
3659
|
};
|
|
3477
3660
|
const offList = q !== "" && decided.decision !== "chosen" && decided.decision !== "empty";
|
|
3478
|
-
const foot = offList && decided.decision === "ask" ? /* @__PURE__ */ (0,
|
|
3661
|
+
const foot = offList && decided.decision === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3479
3662
|
ChoiceAskButtons,
|
|
3480
3663
|
{
|
|
3481
3664
|
field,
|
|
@@ -3492,14 +3675,14 @@ function OpenChoicePicker({
|
|
|
3492
3675
|
}
|
|
3493
3676
|
) : null;
|
|
3494
3677
|
const add = offList && decided.decision === "add" ? { label: `Add \u201C${q}\u201D to the choices`, onAdd: addTyped, disabled: adding } : offList && decided.decision === "keep_as_typed" ? { label: `Keep \u201C${q}\u201D as typed`, onAdd: () => choose(q) } : null;
|
|
3495
|
-
return /* @__PURE__ */ (0,
|
|
3678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { id, className: "flex flex-wrap items-center gap-1", children: [
|
|
3496
3679
|
pickedWords.map((word, i) => {
|
|
3497
3680
|
const chip = chipOf(options.find((o) => (0, import_records10.isTheChosen)(o, current[i])), word);
|
|
3498
|
-
return /* @__PURE__ */ (0,
|
|
3681
|
+
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);
|
|
3499
3682
|
}),
|
|
3500
3683
|
disabled ? null : (
|
|
3501
3684
|
// THE ONE "PICK OR ADD" BUILDER (PickOrAdd.tsx) — the relation picker draws the same one.
|
|
3502
|
-
/* @__PURE__ */ (0,
|
|
3685
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3503
3686
|
PickOrAdd,
|
|
3504
3687
|
{
|
|
3505
3688
|
triggerLabel: `Pick for ${fieldName(field)}`,
|
|
@@ -3521,15 +3704,15 @@ function OpenChoicePicker({
|
|
|
3521
3704
|
const option = options.find((o) => o.id === optionId);
|
|
3522
3705
|
if (option) choose((0, import_records10.optionKey)(option));
|
|
3523
3706
|
},
|
|
3524
|
-
empty: q === "" ? /* @__PURE__ */ (0,
|
|
3707
|
+
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,
|
|
3525
3708
|
add,
|
|
3526
3709
|
foot,
|
|
3527
3710
|
...offList && decided.decision === "ask" && !adding ? { onEnterWithNoMatch: addTyped } : {},
|
|
3528
|
-
footNote: addRefused ? /* @__PURE__ */ (0,
|
|
3711
|
+
footNote: addRefused ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RefusalLine, { error: addRefused }) : offList && decided.decision === "not_a_choice" ? (
|
|
3529
3712
|
// never_add on a column that takes only its choices: said, never a silent nothing.
|
|
3530
|
-
/* @__PURE__ */ (0,
|
|
3531
|
-
/* @__PURE__ */ (0,
|
|
3532
|
-
autoOpen ? /* @__PURE__ */ (0,
|
|
3713
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3714
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { "data-records-typed-refusal": "", className: "p-2 text-xs text-muted-foreground", children: notAChoiceSentence(field, [q]) }),
|
|
3715
|
+
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
|
|
3533
3716
|
] })
|
|
3534
3717
|
) : null
|
|
3535
3718
|
}
|
|
@@ -3548,9 +3731,9 @@ function RecordChip({
|
|
|
3548
3731
|
// name. So it caps at its container and ends in an ellipsis with the whole name in
|
|
3549
3732
|
// its tooltip, rather than being cut mid-word by whatever box it landed in
|
|
3550
3733
|
// (lane FIX-14, 2026-09-22).
|
|
3551
|
-
/* @__PURE__ */ (0,
|
|
3552
|
-
/* @__PURE__ */ (0,
|
|
3553
|
-
onRemove ? /* @__PURE__ */ (0,
|
|
3734
|
+
/* @__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: [
|
|
3735
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate", children: title }),
|
|
3736
|
+
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
|
|
3554
3737
|
] })
|
|
3555
3738
|
);
|
|
3556
3739
|
}
|
|
@@ -3562,7 +3745,8 @@ function publicChoicesOf(field) {
|
|
|
3562
3745
|
return typeof o.key === "string" && typeof o.label === "string" ? [{ key: o.key, label: o.label }] : [];
|
|
3563
3746
|
});
|
|
3564
3747
|
}
|
|
3565
|
-
var
|
|
3748
|
+
var FORM_SEARCH_AFTER = 8;
|
|
3749
|
+
var CHOICE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
3566
3750
|
function ChoiceAnswer({
|
|
3567
3751
|
field,
|
|
3568
3752
|
choices,
|
|
@@ -3572,7 +3756,7 @@ function ChoiceAnswer({
|
|
|
3572
3756
|
id,
|
|
3573
3757
|
isChosen
|
|
3574
3758
|
}) {
|
|
3575
|
-
const [search, setSearch] = (0,
|
|
3759
|
+
const [search, setSearch] = (0, import_react24.useState)("");
|
|
3576
3760
|
const held = field.multi ? (0, import_records10.choiceValuesOf)(value) : value === null || value === void 0 || value === "" ? [] : [value];
|
|
3577
3761
|
const on = (choice) => held.some((v) => isChosen ? isChosen(choice, v) : String(v) === choice.key || String(v) === choice.label);
|
|
3578
3762
|
const press = (choice) => {
|
|
@@ -3583,71 +3767,90 @@ function ChoiceAnswer({
|
|
|
3583
3767
|
const keys = choices.filter((c) => c.key === choice.key ? !on(c) : on(c)).map((c) => c.key);
|
|
3584
3768
|
onChange(keys.length === 0 ? null : keys);
|
|
3585
3769
|
};
|
|
3586
|
-
const
|
|
3770
|
+
const lettered = choices.length <= CHOICE_LETTERS.length;
|
|
3771
|
+
const option = (choice) => {
|
|
3587
3772
|
const chosen = on(choice);
|
|
3588
|
-
const
|
|
3589
|
-
return /* @__PURE__ */ (0,
|
|
3773
|
+
const letter = lettered ? CHOICE_LETTERS[choices.indexOf(choice)] : null;
|
|
3774
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3590
3775
|
"button",
|
|
3591
3776
|
{
|
|
3592
3777
|
type: "button",
|
|
3593
3778
|
role: field.multi ? "checkbox" : "radio",
|
|
3594
3779
|
"aria-checked": chosen,
|
|
3780
|
+
"aria-label": choice.label,
|
|
3595
3781
|
disabled,
|
|
3596
3782
|
onClick: () => press(choice),
|
|
3597
|
-
"data-records-choice-chip": "",
|
|
3598
3783
|
"data-records-choice-answer": choice.key,
|
|
3599
|
-
className: (0,
|
|
3600
|
-
"
|
|
3601
|
-
|
|
3602
|
-
chosen ? "ring-2 ring-ring ring-offset-1" : "opacity-80 hover:opacity-100"
|
|
3784
|
+
className: (0, import_design_system14.cn)(
|
|
3785
|
+
"flex min-h-11 w-full items-center gap-3 rounded-md border px-3 py-2 text-left text-base font-medium text-foreground transition-colors sm:min-h-10 sm:text-sm",
|
|
3786
|
+
chosen ? "border-primary bg-primary/10" : "border-primary/30 bg-primary/[0.03] hover:bg-primary/10"
|
|
3603
3787
|
),
|
|
3604
3788
|
children: [
|
|
3605
|
-
|
|
3606
|
-
|
|
3789
|
+
letter ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3790
|
+
"kbd",
|
|
3791
|
+
{
|
|
3792
|
+
"aria-hidden": "true",
|
|
3793
|
+
className: (0, import_design_system14.cn)(
|
|
3794
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border font-sans text-xs font-semibold",
|
|
3795
|
+
chosen ? "border-primary bg-primary text-primary-foreground" : "border-primary/40 text-primary"
|
|
3796
|
+
),
|
|
3797
|
+
children: letter
|
|
3798
|
+
}
|
|
3799
|
+
) : null,
|
|
3800
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 flex-1 break-words", children: choice.label }),
|
|
3801
|
+
chosen ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "aria-hidden": "true", className: "shrink-0 text-primary", children: "\u2713" }) : null
|
|
3607
3802
|
]
|
|
3608
3803
|
},
|
|
3609
3804
|
choice.key
|
|
3610
3805
|
);
|
|
3611
3806
|
};
|
|
3612
|
-
const
|
|
3613
|
-
|
|
3614
|
-
|
|
3807
|
+
const onKeyDown = (event) => {
|
|
3808
|
+
if (!lettered || disabled || event.metaKey || event.ctrlKey || event.altKey) return;
|
|
3809
|
+
if (event.target.tagName === "INPUT") return;
|
|
3810
|
+
const at = CHOICE_LETTERS.indexOf(event.key.toUpperCase());
|
|
3811
|
+
if (event.key.length !== 1 || at < 0 || at >= choices.length) return;
|
|
3812
|
+
event.preventDefault();
|
|
3813
|
+
press(choices[at]);
|
|
3814
|
+
};
|
|
3815
|
+
const group = { role: field.multi ? "group" : "radiogroup", "aria-label": fieldName(field), onKeyDown };
|
|
3816
|
+
if (choices.length <= FORM_SEARCH_AFTER) {
|
|
3817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { id, className: "flex w-full flex-col gap-2", ...group, children: choices.map(option) });
|
|
3615
3818
|
}
|
|
3616
3819
|
const q = search.trim().toLowerCase();
|
|
3617
3820
|
const shown2 = q === "" ? choices : choices.filter((c) => c.label.toLowerCase().includes(q));
|
|
3618
|
-
return /* @__PURE__ */ (0,
|
|
3619
|
-
/* @__PURE__ */ (0,
|
|
3620
|
-
|
|
3821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { id, className: "flex w-full flex-col gap-2", onKeyDown, children: [
|
|
3822
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3823
|
+
import_design_system14.BasicInput,
|
|
3621
3824
|
{
|
|
3622
3825
|
value: search,
|
|
3623
3826
|
onChange: (e) => setSearch(e.target.value),
|
|
3624
3827
|
placeholder: "Search",
|
|
3625
3828
|
"aria-label": `Search \u2014 ${fieldName(field)}`,
|
|
3626
3829
|
autoComplete: "off",
|
|
3627
|
-
className: "h-11 text-base sm:h-
|
|
3830
|
+
className: "h-11 text-base sm:h-9 sm:text-sm"
|
|
3628
3831
|
}
|
|
3629
3832
|
),
|
|
3630
|
-
/* @__PURE__ */ (0,
|
|
3631
|
-
shown2.map(
|
|
3632
|
-
shown2.length === 0 ? /* @__PURE__ */ (0,
|
|
3833
|
+
/* @__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: [
|
|
3834
|
+
shown2.map(option),
|
|
3835
|
+
shown2.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-muted-foreground", children: "No match" }) : null
|
|
3633
3836
|
] })
|
|
3634
3837
|
] });
|
|
3635
3838
|
}
|
|
3636
3839
|
|
|
3637
3840
|
// src/RecordsMount.tsx
|
|
3638
|
-
var
|
|
3639
|
-
var
|
|
3640
|
-
var
|
|
3841
|
+
var import_react26 = require("react");
|
|
3842
|
+
var import_react27 = require("@ai-matrx/records/react");
|
|
3843
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3641
3844
|
function personActor(userId) {
|
|
3642
3845
|
return userId ? { actor: "user", user_id: userId } : { actor: "user" };
|
|
3643
3846
|
}
|
|
3644
3847
|
|
|
3645
3848
|
// src/tablePicking.tsx
|
|
3646
|
-
var
|
|
3849
|
+
var import_react28 = require("react");
|
|
3647
3850
|
var import_records11 = require("@ai-matrx/records");
|
|
3648
|
-
var
|
|
3649
|
-
var
|
|
3650
|
-
var
|
|
3851
|
+
var import_react29 = require("@ai-matrx/records/react");
|
|
3852
|
+
var import_design_system15 = require("@ai-matrx/design-system");
|
|
3853
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3651
3854
|
var APP_TABLE_PREFIX = "records_ui_";
|
|
3652
3855
|
function isValueSet(table) {
|
|
3653
3856
|
if (table.kept_for === "choices") return true;
|
|
@@ -3690,10 +3893,10 @@ function madeOn(stamp) {
|
|
|
3690
3893
|
}
|
|
3691
3894
|
|
|
3692
3895
|
// src/TablePickers.tsx
|
|
3693
|
-
var
|
|
3896
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3694
3897
|
function useTablesAnywhere(dataSource) {
|
|
3695
|
-
const [state, setState] = (0,
|
|
3696
|
-
(0,
|
|
3898
|
+
const [state, setState] = (0, import_react30.useState)({ loading: true, error: null, rows: [] });
|
|
3899
|
+
(0, import_react30.useEffect)(() => {
|
|
3697
3900
|
let live = true;
|
|
3698
3901
|
void Promise.resolve(dataSource.rpc("data_home_tables", {}, { schema: "custom" })).then(
|
|
3699
3902
|
({ data, error }) => {
|
|
@@ -3730,9 +3933,9 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
|
|
|
3730
3933
|
keywords: t.organization_name
|
|
3731
3934
|
}));
|
|
3732
3935
|
const missing = Boolean(value) && !list.loading && !list.error && !list.rows.some((t) => t.table_id === value);
|
|
3733
|
-
return /* @__PURE__ */ (0,
|
|
3734
|
-
/* @__PURE__ */ (0,
|
|
3735
|
-
|
|
3936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3937
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3938
|
+
import_design_system16.CreatablePicker,
|
|
3736
3939
|
{
|
|
3737
3940
|
value: value || null,
|
|
3738
3941
|
options,
|
|
@@ -3745,23 +3948,23 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
|
|
|
3745
3948
|
ariaLabel: "Table"
|
|
3746
3949
|
}
|
|
3747
3950
|
),
|
|
3748
|
-
list.error && /* @__PURE__ */ (0,
|
|
3749
|
-
missing && /* @__PURE__ */ (0,
|
|
3951
|
+
list.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefusalLine, { error: refusal("door", list.error, "Try again in a moment.") }),
|
|
3952
|
+
missing && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-[11px] text-destructive", children: "This table is archived or not shared with you." })
|
|
3750
3953
|
] });
|
|
3751
3954
|
}
|
|
3752
3955
|
function TableScope({ dataSource, userId, tableId, children, fallback = null, tables }) {
|
|
3753
3956
|
const own3 = useTablesAnywhere(dataSource);
|
|
3754
3957
|
const list = tables ?? own3;
|
|
3755
3958
|
const organizationId = list.rows.find((t) => t.table_id === tableId)?.organization_id ?? null;
|
|
3756
|
-
if (!tableId || !organizationId) return /* @__PURE__ */ (0,
|
|
3757
|
-
return /* @__PURE__ */ (0,
|
|
3959
|
+
if (!tableId || !organizationId) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: fallback });
|
|
3960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react31.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children });
|
|
3758
3961
|
}
|
|
3759
3962
|
function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
3760
|
-
const fields = (0,
|
|
3761
|
-
const all = (0,
|
|
3762
|
-
const byKey = (0,
|
|
3963
|
+
const fields = (0, import_react31.useFields)(tableId);
|
|
3964
|
+
const all = (0, import_react30.useMemo)(() => fields.data ?? [], [fields.data]);
|
|
3965
|
+
const byKey = (0, import_react30.useMemo)(() => new Map(all.map((f) => [f.key, f])), [all]);
|
|
3763
3966
|
const keys = Object.keys(value);
|
|
3764
|
-
const [adding, setAdding] = (0,
|
|
3967
|
+
const [adding, setAdding] = (0, import_react30.useState)(false);
|
|
3765
3968
|
const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
|
|
3766
3969
|
const rename = (from, to) => {
|
|
3767
3970
|
if (from === to) return;
|
|
@@ -3774,11 +3977,11 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3774
3977
|
void _gone;
|
|
3775
3978
|
onChange(rest);
|
|
3776
3979
|
};
|
|
3777
|
-
return /* @__PURE__ */ (0,
|
|
3778
|
-
fields.error && /* @__PURE__ */ (0,
|
|
3980
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
3981
|
+
fields.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefusalLine, { error: fields.error }),
|
|
3779
3982
|
keys.map((key) => {
|
|
3780
3983
|
const field = byKey.get(key);
|
|
3781
|
-
return /* @__PURE__ */ (0,
|
|
3984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3782
3985
|
ColumnValueRow,
|
|
3783
3986
|
{
|
|
3784
3987
|
columnKey: key,
|
|
@@ -3794,7 +3997,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3794
3997
|
key
|
|
3795
3998
|
);
|
|
3796
3999
|
}),
|
|
3797
|
-
adding && /* @__PURE__ */ (0,
|
|
4000
|
+
adding && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3798
4001
|
ColumnValueRow,
|
|
3799
4002
|
{
|
|
3800
4003
|
columnKey: null,
|
|
@@ -3811,7 +4014,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
|
3811
4014
|
onRemove: () => setAdding(false)
|
|
3812
4015
|
}
|
|
3813
4016
|
),
|
|
3814
|
-
!disabled && !adding && keys.length < all.length && /* @__PURE__ */ (0,
|
|
4017
|
+
!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 })
|
|
3815
4018
|
] });
|
|
3816
4019
|
}
|
|
3817
4020
|
function ColumnValueRow({
|
|
@@ -3827,10 +4030,10 @@ function ColumnValueRow({
|
|
|
3827
4030
|
}) {
|
|
3828
4031
|
const orphan = columnKey !== null && !loading && field === void 0;
|
|
3829
4032
|
const shown2 = orphan ? [{ value: columnKey, label: columnKey, hint: "Not a column" }, ...options] : options;
|
|
3830
|
-
return /* @__PURE__ */ (0,
|
|
3831
|
-
/* @__PURE__ */ (0,
|
|
3832
|
-
/* @__PURE__ */ (0,
|
|
3833
|
-
|
|
4033
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1 rounded-md border border-border/60 p-2", children: [
|
|
4034
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4035
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4036
|
+
import_design_system16.CreatablePicker,
|
|
3834
4037
|
{
|
|
3835
4038
|
value: columnKey,
|
|
3836
4039
|
options: shown2,
|
|
@@ -3843,23 +4046,23 @@ function ColumnValueRow({
|
|
|
3843
4046
|
ariaLabel: "Column"
|
|
3844
4047
|
}
|
|
3845
4048
|
) }),
|
|
3846
|
-
!disabled && /* @__PURE__ */ (0,
|
|
4049
|
+
!disabled && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_design_system16.Button, { type: "button", variant: "ghost", size: "sm", "aria-label": "Remove", onClick: onRemove, children: "\u2715" })
|
|
3847
4050
|
] }),
|
|
3848
|
-
field ? /* @__PURE__ */ (0,
|
|
4051
|
+
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
|
|
3849
4052
|
] });
|
|
3850
4053
|
}
|
|
3851
4054
|
function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
3852
|
-
const table = (0,
|
|
3853
|
-
const records = (0,
|
|
4055
|
+
const table = (0, import_react31.useTable)(tableId);
|
|
4056
|
+
const records = (0, import_react31.useRecords)(tableId, { pageSize: 200 });
|
|
3854
4057
|
const rows = records.data?.rows ?? [];
|
|
3855
4058
|
const options = rows.map((row) => ({
|
|
3856
4059
|
value: row.id,
|
|
3857
4060
|
label: rowNameIn(table.data ?? null, row)
|
|
3858
4061
|
}));
|
|
3859
4062
|
const missing = Boolean(value) && !records.loading && !records.error && !rows.some((r) => r.id === value);
|
|
3860
|
-
return /* @__PURE__ */ (0,
|
|
3861
|
-
/* @__PURE__ */ (0,
|
|
3862
|
-
|
|
4063
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
4064
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4065
|
+
import_design_system16.CreatablePicker,
|
|
3863
4066
|
{
|
|
3864
4067
|
value: value || null,
|
|
3865
4068
|
options,
|
|
@@ -3872,16 +4075,16 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
|
|
|
3872
4075
|
ariaLabel: "Record"
|
|
3873
4076
|
}
|
|
3874
4077
|
),
|
|
3875
|
-
records.error && /* @__PURE__ */ (0,
|
|
4078
|
+
records.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefusalLine, { error: records.error })
|
|
3876
4079
|
] });
|
|
3877
4080
|
}
|
|
3878
4081
|
|
|
3879
4082
|
// src/DataBindingPicker.tsx
|
|
3880
|
-
var
|
|
4083
|
+
var import_react32 = require("react");
|
|
3881
4084
|
var import_records12 = require("@ai-matrx/records");
|
|
3882
|
-
var
|
|
3883
|
-
var
|
|
3884
|
-
var
|
|
4085
|
+
var import_react33 = require("@ai-matrx/records/react");
|
|
4086
|
+
var import_design_system17 = require("@ai-matrx/design-system");
|
|
4087
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3885
4088
|
var DATA_BINDING_SHAPES = [
|
|
3886
4089
|
{ value: "collection", label: "The whole table" },
|
|
3887
4090
|
{ value: "reference", label: "One record" },
|
|
@@ -3948,9 +4151,9 @@ function DataBindingPicker({ dataSource, userId, binding, onChange, disabled, de
|
|
|
3948
4151
|
...binding.semantic_type === "collection" && defaultRowLimit ? { limit: defaultRowLimit } : {}
|
|
3949
4152
|
});
|
|
3950
4153
|
};
|
|
3951
|
-
return /* @__PURE__ */ (0,
|
|
3952
|
-
/* @__PURE__ */ (0,
|
|
3953
|
-
/* @__PURE__ */ (0,
|
|
4154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
4155
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TablePicker, { dataSource, value: tableId, onChange: selectTable, disabled: Boolean(disabled), tables }),
|
|
4156
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TableScope, { dataSource, userId, tableId, tables, children: tableId && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3954
4157
|
BindingDetails,
|
|
3955
4158
|
{
|
|
3956
4159
|
tableId,
|
|
@@ -3969,11 +4172,11 @@ function BindingDetails({
|
|
|
3969
4172
|
disabled,
|
|
3970
4173
|
defaultRowLimit
|
|
3971
4174
|
}) {
|
|
3972
|
-
const table = (0,
|
|
3973
|
-
const fields = (0,
|
|
3974
|
-
const fieldList = (0,
|
|
4175
|
+
const table = (0, import_react33.useTable)(tableId);
|
|
4176
|
+
const fields = (0, import_react33.useFields)(tableId);
|
|
4177
|
+
const fieldList = (0, import_react32.useMemo)(() => fields.data ?? [], [fields.data]);
|
|
3975
4178
|
const shape = binding.semantic_type;
|
|
3976
|
-
(0,
|
|
4179
|
+
(0, import_react32.useEffect)(() => {
|
|
3977
4180
|
if (disabled || shape === "value" || binding.transform || fields.loading || fieldList.length === 0) return;
|
|
3978
4181
|
onChange({
|
|
3979
4182
|
...binding,
|
|
@@ -4014,9 +4217,9 @@ function BindingDetails({
|
|
|
4014
4217
|
const fieldOptions = fieldList.map((f) => ({ value: f.key, label: fieldName(f) }));
|
|
4015
4218
|
const template = binding.transform?.template ?? "";
|
|
4016
4219
|
const setTemplate = (next) => onChange({ ...binding, transform: { join: "\n", ...binding.transform, name: "list", template: next } });
|
|
4017
|
-
return /* @__PURE__ */ (0,
|
|
4018
|
-
/* @__PURE__ */ (0,
|
|
4019
|
-
|
|
4220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
4221
|
+
/* @__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)(
|
|
4222
|
+
import_design_system17.Button,
|
|
4020
4223
|
{
|
|
4021
4224
|
type: "button",
|
|
4022
4225
|
size: "sm",
|
|
@@ -4029,7 +4232,7 @@ function BindingDetails({
|
|
|
4029
4232
|
},
|
|
4030
4233
|
s.value
|
|
4031
4234
|
)) }),
|
|
4032
|
-
shape !== "collection" && /* @__PURE__ */ (0,
|
|
4235
|
+
shape !== "collection" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4033
4236
|
RecordPicker,
|
|
4034
4237
|
{
|
|
4035
4238
|
tableId,
|
|
@@ -4038,8 +4241,8 @@ function BindingDetails({
|
|
|
4038
4241
|
disabled: Boolean(disabled)
|
|
4039
4242
|
}
|
|
4040
4243
|
),
|
|
4041
|
-
shape === "value" && /* @__PURE__ */ (0,
|
|
4042
|
-
|
|
4244
|
+
shape === "value" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4245
|
+
import_design_system17.CreatablePicker,
|
|
4043
4246
|
{
|
|
4044
4247
|
value: binding.field_key ?? null,
|
|
4045
4248
|
options: fieldOptions,
|
|
@@ -4052,11 +4255,11 @@ function BindingDetails({
|
|
|
4052
4255
|
ariaLabel: "Column"
|
|
4053
4256
|
}
|
|
4054
4257
|
),
|
|
4055
|
-
shape !== "value" && /* @__PURE__ */ (0,
|
|
4056
|
-
/* @__PURE__ */ (0,
|
|
4258
|
+
shape !== "value" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
4259
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4057
4260
|
"textarea",
|
|
4058
4261
|
{
|
|
4059
|
-
className: (0,
|
|
4262
|
+
className: (0, import_design_system17.cn)(
|
|
4060
4263
|
"min-h-[3.5rem] w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs"
|
|
4061
4264
|
),
|
|
4062
4265
|
"aria-label": "Each row reads as",
|
|
@@ -4065,8 +4268,8 @@ function BindingDetails({
|
|
|
4065
4268
|
onChange: (e) => setTemplate(e.target.value)
|
|
4066
4269
|
}
|
|
4067
4270
|
),
|
|
4068
|
-
!disabled && /* @__PURE__ */ (0,
|
|
4069
|
-
|
|
4271
|
+
!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)(
|
|
4272
|
+
import_design_system17.Button,
|
|
4070
4273
|
{
|
|
4071
4274
|
type: "button",
|
|
4072
4275
|
size: "sm",
|
|
@@ -4078,10 +4281,10 @@ function BindingDetails({
|
|
|
4078
4281
|
p.token
|
|
4079
4282
|
)) })
|
|
4080
4283
|
] }),
|
|
4081
|
-
shape === "collection" && /* @__PURE__ */ (0,
|
|
4284
|
+
shape === "collection" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
4082
4285
|
"Up to",
|
|
4083
|
-
/* @__PURE__ */ (0,
|
|
4084
|
-
|
|
4286
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4287
|
+
import_design_system17.BasicInput,
|
|
4085
4288
|
{
|
|
4086
4289
|
type: "number",
|
|
4087
4290
|
min: 1,
|
|
@@ -4097,10 +4300,10 @@ function BindingDetails({
|
|
|
4097
4300
|
),
|
|
4098
4301
|
"rows"
|
|
4099
4302
|
] }),
|
|
4100
|
-
/* @__PURE__ */ (0,
|
|
4101
|
-
/* @__PURE__ */ (0,
|
|
4102
|
-
DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ (0,
|
|
4103
|
-
|
|
4303
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "radiogroup", "aria-label": "If nothing is found", children: [
|
|
4304
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: "If nothing is found" }),
|
|
4305
|
+
DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4306
|
+
import_design_system17.Button,
|
|
4104
4307
|
{
|
|
4105
4308
|
type: "button",
|
|
4106
4309
|
size: "sm",
|
|
@@ -4118,12 +4321,12 @@ function BindingDetails({
|
|
|
4118
4321
|
}
|
|
4119
4322
|
|
|
4120
4323
|
// src/PickedSummaries.tsx
|
|
4121
|
-
var
|
|
4324
|
+
var import_react35 = require("@ai-matrx/records/react");
|
|
4122
4325
|
|
|
4123
4326
|
// src/values.tsx
|
|
4124
4327
|
var import_data_table4 = require("@ai-matrx/design-system/data-table");
|
|
4125
4328
|
var import_field_formats5 = require("@ai-matrx/design-system/field-formats");
|
|
4126
|
-
var
|
|
4329
|
+
var import_design_system20 = require("@ai-matrx/design-system");
|
|
4127
4330
|
|
|
4128
4331
|
// src/enumLabels.ts
|
|
4129
4332
|
function exhaustiveValuesOf() {
|
|
@@ -4160,10 +4363,10 @@ var ABSENCE_WORD_LABEL = {
|
|
|
4160
4363
|
var import_core2 = require("@ai-matrx/records/core");
|
|
4161
4364
|
|
|
4162
4365
|
// src/WholeValue.tsx
|
|
4163
|
-
var
|
|
4366
|
+
var import_react34 = require("react");
|
|
4164
4367
|
var import_core = require("@ai-matrx/records/core");
|
|
4165
|
-
var
|
|
4166
|
-
var
|
|
4368
|
+
var import_design_system18 = require("@ai-matrx/design-system");
|
|
4369
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4167
4370
|
var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
|
|
4168
4371
|
function wholeValueLine(pointer) {
|
|
4169
4372
|
return `Open the whole text (${(0, import_core.wholeValueSize)(pointer)})`;
|
|
@@ -4172,18 +4375,18 @@ function WholeValueCell({ words, pointer }) {
|
|
|
4172
4375
|
const host = useRecordsUi();
|
|
4173
4376
|
const href = host.hrefForFile?.({ fileId: pointer.file_id });
|
|
4174
4377
|
const line = wholeValueLine(pointer);
|
|
4175
|
-
return /* @__PURE__ */ (0,
|
|
4176
|
-
/* @__PURE__ */ (0,
|
|
4378
|
+
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: [
|
|
4379
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "truncate", title: `The first ${pointer.shown_chars} of ${pointer.chars} characters`, children: [
|
|
4177
4380
|
words,
|
|
4178
4381
|
"\u2026"
|
|
4179
4382
|
] }),
|
|
4180
|
-
href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0,
|
|
4383
|
+
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` })
|
|
4181
4384
|
] });
|
|
4182
4385
|
}
|
|
4183
4386
|
|
|
4184
4387
|
// src/ReferenceChips.tsx
|
|
4185
4388
|
var import_records13 = require("@ai-matrx/records");
|
|
4186
|
-
var
|
|
4389
|
+
var import_design_system19 = require("@ai-matrx/design-system");
|
|
4187
4390
|
|
|
4188
4391
|
// src/kindValues.ts
|
|
4189
4392
|
var import_directives = require("@ai-matrx/content-ir/directives");
|
|
@@ -4237,7 +4440,7 @@ function kindLabel(kind) {
|
|
|
4237
4440
|
}
|
|
4238
4441
|
|
|
4239
4442
|
// src/ReferenceChips.tsx
|
|
4240
|
-
var
|
|
4443
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4241
4444
|
function referencesOf(field, value, kind, labels) {
|
|
4242
4445
|
if (kind === "entity_reference") {
|
|
4243
4446
|
return (0, import_records13.entityRefsOf)(value).map((r) => ({ token: r.token, id: r.id, label: r.label }));
|
|
@@ -4258,11 +4461,11 @@ function ReferenceChip({ reference, waiting }) {
|
|
|
4258
4461
|
const host = useRecordsUi();
|
|
4259
4462
|
const words = reference.label ?? (reference.token === "record" ? waiting ?? "Loading\u2026" : WITHHELD_ENTITY_LABEL);
|
|
4260
4463
|
const drawn = host.renderReference ? host.renderReference({ ...reference, label: reference.label ?? words }) : null;
|
|
4261
|
-
return /* @__PURE__ */ (0,
|
|
4262
|
-
|
|
4464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4465
|
+
import_design_system19.Badge,
|
|
4263
4466
|
{
|
|
4264
4467
|
variant: "secondary",
|
|
4265
|
-
className: (0,
|
|
4468
|
+
className: (0, import_design_system19.cn)(
|
|
4266
4469
|
"max-w-full min-w-0 gap-1 px-1.5 py-0 text-[11px] font-normal",
|
|
4267
4470
|
reference.archived && "opacity-70"
|
|
4268
4471
|
),
|
|
@@ -4270,15 +4473,15 @@ function ReferenceChip({ reference, waiting }) {
|
|
|
4270
4473
|
"data-records-reference-archived": reference.archived ? "" : void 0,
|
|
4271
4474
|
title: reference.archived ? ARCHIVED_REFERENCE_TIP : words,
|
|
4272
4475
|
children: [
|
|
4273
|
-
drawn ?? /* @__PURE__ */ (0,
|
|
4274
|
-
reference.archived ? /* @__PURE__ */ (0,
|
|
4476
|
+
drawn ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate", children: words }),
|
|
4477
|
+
reference.archived ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
|
|
4275
4478
|
]
|
|
4276
4479
|
}
|
|
4277
4480
|
);
|
|
4278
4481
|
}
|
|
4279
4482
|
function ReferenceChips({ refs, waiting }) {
|
|
4280
|
-
if (refs.length === 0) return /* @__PURE__ */ (0,
|
|
4281
|
-
return /* @__PURE__ */ (0,
|
|
4483
|
+
if (refs.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
4484
|
+
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}`)) });
|
|
4282
4485
|
}
|
|
4283
4486
|
function KindValueCell({
|
|
4284
4487
|
kv,
|
|
@@ -4287,18 +4490,18 @@ function KindValueCell({
|
|
|
4287
4490
|
}) {
|
|
4288
4491
|
const host = useRecordsUi();
|
|
4289
4492
|
if (host.renderKind) {
|
|
4290
|
-
return /* @__PURE__ */ (0,
|
|
4493
|
+
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 }) });
|
|
4291
4494
|
}
|
|
4292
4495
|
const named = kv.items.map(kindItemWords).filter((w) => w !== null);
|
|
4293
|
-
return /* @__PURE__ */ (0,
|
|
4496
|
+
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) }) });
|
|
4294
4497
|
}
|
|
4295
4498
|
|
|
4296
4499
|
// src/values.tsx
|
|
4297
4500
|
var import_records14 = require("@ai-matrx/records");
|
|
4298
|
-
var
|
|
4299
|
-
function statusMark(field, item) {
|
|
4300
|
-
const mark = statusMarkOf(field, item);
|
|
4301
|
-
return mark ? /* @__PURE__ */ (0,
|
|
4501
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4502
|
+
function statusMark(field, item, document2) {
|
|
4503
|
+
const mark = statusMarkOf(field, item, document2);
|
|
4504
|
+
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;
|
|
4302
4505
|
}
|
|
4303
4506
|
function envelopeFor(document2, key) {
|
|
4304
4507
|
const block = document2?._values;
|
|
@@ -4342,32 +4545,32 @@ var ABSENCE_WORDS = ABSENCE_WORD_LABEL;
|
|
|
4342
4545
|
function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
4343
4546
|
const envelope = envelopeFor(document2, field.key);
|
|
4344
4547
|
if (envelope?.absent) {
|
|
4345
|
-
return /* @__PURE__ */ (0,
|
|
4548
|
+
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) });
|
|
4346
4549
|
}
|
|
4347
4550
|
if (value === null || value === void 0 || value === "") {
|
|
4348
4551
|
const gone = unresolvedFor(document2, field.key);
|
|
4349
4552
|
if (gone) {
|
|
4350
|
-
return /* @__PURE__ */ (0,
|
|
4553
|
+
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" });
|
|
4351
4554
|
}
|
|
4352
4555
|
const computed = computedEmptyOf(field, document2);
|
|
4353
|
-
if (computed?.sentence) return /* @__PURE__ */ (0,
|
|
4354
|
-
if (computed?.words) return /* @__PURE__ */ (0,
|
|
4556
|
+
if (computed?.sentence) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs italic text-muted-foreground", children: computed.sentence });
|
|
4557
|
+
if (computed?.words) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "data-records-empty-why": computed.kind, children: computed.words });
|
|
4355
4558
|
if (computed?.why) {
|
|
4356
|
-
return /* @__PURE__ */ (0,
|
|
4559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-muted-foreground", title: computed.why, "data-records-empty-why": computed.kind, children: "\u2014" });
|
|
4357
4560
|
}
|
|
4358
|
-
return /* @__PURE__ */ (0,
|
|
4561
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
4359
4562
|
}
|
|
4360
|
-
if (isSignatureField(field)) return /* @__PURE__ */ (0,
|
|
4563
|
+
if (isSignatureField(field)) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SignatureValue, { value, fieldKey: field.key, document: document2 });
|
|
4361
4564
|
const newer = newerKindValue(field, value);
|
|
4362
4565
|
if (newer !== void 0) return newer;
|
|
4363
4566
|
const whole = typeof value === "string" ? (0, import_core2.wholeValueOf)(document2, field.key) : null;
|
|
4364
|
-
if (whole) return /* @__PURE__ */ (0,
|
|
4567
|
+
if (whole) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(WholeValueCell, { words: value, pointer: whole });
|
|
4365
4568
|
const kind = editorKindFor(field);
|
|
4366
4569
|
if (kind === "relation" || kind === "entity_reference") {
|
|
4367
|
-
return /* @__PURE__ */ (0,
|
|
4570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReferenceChips, { refs: referencesOf(field, value, kind, labels), waiting: stillWaitingFor });
|
|
4368
4571
|
}
|
|
4369
4572
|
const kv = kind === "attachment" || kind === "member" ? null : kindValueOf(value);
|
|
4370
|
-
if (kv) return /* @__PURE__ */ (0,
|
|
4573
|
+
if (kv) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(KindValueCell, { kv, where: "cell", title: field.label });
|
|
4371
4574
|
const chosen = kind === "select" || kind === "multi_select";
|
|
4372
4575
|
const chipOf = (item) => {
|
|
4373
4576
|
const look = choiceChipLookOf(field, item, scalarText(field, item, labels));
|
|
@@ -4375,17 +4578,17 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4375
4578
|
};
|
|
4376
4579
|
if (chosen) {
|
|
4377
4580
|
const items = Array.isArray(value) ? value : [value];
|
|
4378
|
-
return /* @__PURE__ */ (0,
|
|
4581
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "flex flex-wrap gap-1", "data-records-choice-chips": "", children: items.map((item, i) => {
|
|
4379
4582
|
const chip = chipOf(item);
|
|
4380
|
-
return /* @__PURE__ */ (0,
|
|
4381
|
-
|
|
4583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
4584
|
+
import_design_system20.Badge,
|
|
4382
4585
|
{
|
|
4383
4586
|
variant: "outline",
|
|
4384
|
-
className: (0,
|
|
4587
|
+
className: (0, import_design_system20.cn)("text-[11px]", chip.className),
|
|
4385
4588
|
"data-records-choice-chip": "",
|
|
4386
4589
|
...chip.tinted ? { "data-records-choice-tint": "" } : {},
|
|
4387
4590
|
children: [
|
|
4388
|
-
statusMark(field, item),
|
|
4591
|
+
statusMark(field, item, Array.isArray(value) ? void 0 : document2),
|
|
4389
4592
|
scalarText(field, item, labels, Array.isArray(value) ? void 0 : stillWaitingFor)
|
|
4390
4593
|
]
|
|
4391
4594
|
},
|
|
@@ -4393,13 +4596,13 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4393
4596
|
);
|
|
4394
4597
|
}) });
|
|
4395
4598
|
}
|
|
4396
|
-
if (kind === "attachment") return /* @__PURE__ */ (0,
|
|
4599
|
+
if (kind === "attachment") return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AttachmentChips, { value });
|
|
4397
4600
|
if (Array.isArray(value)) {
|
|
4398
|
-
return /* @__PURE__ */ (0,
|
|
4601
|
+
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}`)) });
|
|
4399
4602
|
}
|
|
4400
4603
|
if (kind === "url" && typeof value === "string") {
|
|
4401
4604
|
const href = value.includes("://") ? value : `https://${value}`;
|
|
4402
|
-
return /* @__PURE__ */ (0,
|
|
4605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
4403
4606
|
"a",
|
|
4404
4607
|
{
|
|
4405
4608
|
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",
|
|
@@ -4410,14 +4613,14 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4410
4613
|
"data-records-link-chip": "",
|
|
4411
4614
|
onClick: (event) => event.stopPropagation(),
|
|
4412
4615
|
children: [
|
|
4413
|
-
/* @__PURE__ */ (0,
|
|
4414
|
-
/* @__PURE__ */ (0,
|
|
4616
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2197" }),
|
|
4617
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate", children: linkChipText(value) })
|
|
4415
4618
|
]
|
|
4416
4619
|
}
|
|
4417
4620
|
);
|
|
4418
4621
|
}
|
|
4419
4622
|
if (kind === "phone" && typeof value === "string" && value.trim() !== "") {
|
|
4420
|
-
return /* @__PURE__ */ (0,
|
|
4623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4421
4624
|
"a",
|
|
4422
4625
|
{
|
|
4423
4626
|
className: "truncate tabular-nums text-primary underline-offset-2 hover:underline",
|
|
@@ -4430,12 +4633,12 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
|
|
|
4430
4633
|
);
|
|
4431
4634
|
}
|
|
4432
4635
|
if (kind === "email" && typeof value === "string") {
|
|
4433
|
-
return /* @__PURE__ */ (0,
|
|
4636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("a", { className: "truncate text-primary underline-offset-2 hover:underline", href: `mailto:${value}`, children: value });
|
|
4434
4637
|
}
|
|
4435
4638
|
if (typeof value === "boolean") {
|
|
4436
|
-
return /* @__PURE__ */ (0,
|
|
4639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: kind === "checkbox" ? "text-sm" : "", title: value ? "Yes" : "No", children: value ? "\u2713" : "\u2014" });
|
|
4437
4640
|
}
|
|
4438
|
-
return /* @__PURE__ */ (0,
|
|
4641
|
+
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) });
|
|
4439
4642
|
}
|
|
4440
4643
|
function scalarText(field, value, labels, stillWaitingFor) {
|
|
4441
4644
|
if (value === null || value === void 0) return "\u2014";
|
|
@@ -4476,12 +4679,13 @@ function scalarText(field, value, labels, stillWaitingFor) {
|
|
|
4476
4679
|
}
|
|
4477
4680
|
|
|
4478
4681
|
// src/PickedSummaries.tsx
|
|
4479
|
-
var
|
|
4682
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4480
4683
|
function TableNameText({ dataSource, tableId }) {
|
|
4481
4684
|
const tables = useTablesAnywhere(dataSource);
|
|
4482
|
-
if (!tableId) return /* @__PURE__ */ (0,
|
|
4483
|
-
if (tables.loading) return /* @__PURE__ */ (0,
|
|
4484
|
-
return /* @__PURE__ */ (0,
|
|
4685
|
+
if (!tableId) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
|
|
4686
|
+
if (tables.loading) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" });
|
|
4687
|
+
if (tables.error) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load the table's name" });
|
|
4688
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: tables.rows.find((t) => t.table_id === tableId)?.table_name ?? "\u2014" });
|
|
4485
4689
|
}
|
|
4486
4690
|
function ColumnValuesText({
|
|
4487
4691
|
dataSource,
|
|
@@ -4489,26 +4693,28 @@ function ColumnValuesText({
|
|
|
4489
4693
|
tableId,
|
|
4490
4694
|
value
|
|
4491
4695
|
}) {
|
|
4492
|
-
if (!tableId) return /* @__PURE__ */ (0,
|
|
4493
|
-
return /* @__PURE__ */ (0,
|
|
4696
|
+
if (!tableId) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
|
|
4697
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TableScope, { dataSource, userId, tableId, fallback: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" }), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RecordLabelProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ColumnValuesWords, { tableId, value }) }) });
|
|
4494
4698
|
}
|
|
4495
4699
|
function ColumnValuesWords({ tableId, value }) {
|
|
4496
|
-
const fields = (0,
|
|
4700
|
+
const fields = (0, import_react35.useFields)(tableId);
|
|
4497
4701
|
const labels = useRecordLabels(fields.data ?? void 0);
|
|
4498
|
-
if (fields.loading) return /* @__PURE__ */ (0,
|
|
4702
|
+
if (fields.loading) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" });
|
|
4703
|
+
if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this table's columns" });
|
|
4499
4704
|
const parts = [];
|
|
4500
4705
|
for (const [key, stored] of Object.entries(value)) {
|
|
4706
|
+
if (key.startsWith("_")) continue;
|
|
4501
4707
|
const field = (fields.data ?? []).find((f) => f.key === key);
|
|
4502
|
-
if (parts.length) parts.push(/* @__PURE__ */ (0,
|
|
4708
|
+
if (parts.length) parts.push(/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: ", " }, `${key}-sep`));
|
|
4503
4709
|
parts.push(
|
|
4504
|
-
/* @__PURE__ */ (0,
|
|
4710
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { children: [
|
|
4505
4711
|
field ? fieldName(field) : "A removed column",
|
|
4506
4712
|
" is ",
|
|
4507
4713
|
field ? renderValue(field, stored, void 0, labels) : "\u2014"
|
|
4508
4714
|
] }, key)
|
|
4509
4715
|
);
|
|
4510
4716
|
}
|
|
4511
|
-
return parts.length ? /* @__PURE__ */ (0,
|
|
4717
|
+
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" });
|
|
4512
4718
|
}
|
|
4513
4719
|
function RecordNameText({
|
|
4514
4720
|
dataSource,
|
|
@@ -4516,14 +4722,60 @@ function RecordNameText({
|
|
|
4516
4722
|
tableId,
|
|
4517
4723
|
recordId
|
|
4518
4724
|
}) {
|
|
4519
|
-
if (!tableId || !recordId) return /* @__PURE__ */ (0,
|
|
4520
|
-
return /* @__PURE__ */ (0,
|
|
4725
|
+
if (!tableId || !recordId) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
|
|
4726
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TableScope, { dataSource, userId, tableId, fallback: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" }), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RecordNameWords, { tableId, recordId }) });
|
|
4521
4727
|
}
|
|
4522
4728
|
function RecordNameWords({ tableId, recordId }) {
|
|
4523
|
-
const table = (0,
|
|
4524
|
-
const record = (0,
|
|
4525
|
-
if (record.loading || table.loading) return /* @__PURE__ */ (0,
|
|
4526
|
-
if (
|
|
4527
|
-
return /* @__PURE__ */ (0,
|
|
4729
|
+
const table = (0, import_react35.useTable)(tableId);
|
|
4730
|
+
const record = (0, import_react35.useRecord)(recordId);
|
|
4731
|
+
if (record.loading || table.loading) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" });
|
|
4732
|
+
if (record.error) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this record" });
|
|
4733
|
+
if (!record.data) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "A record you cannot open" });
|
|
4734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: recordName(record.data.document, table.data?.title_field ?? null) });
|
|
4735
|
+
}
|
|
4736
|
+
|
|
4737
|
+
// src/HeldChangeDecision.tsx
|
|
4738
|
+
var import_react36 = require("react");
|
|
4739
|
+
var import_react37 = require("@ai-matrx/records/react");
|
|
4740
|
+
var import_design_system21 = require("@ai-matrx/design-system");
|
|
4741
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4742
|
+
function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, onDecided }) {
|
|
4743
|
+
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 }) });
|
|
4744
|
+
}
|
|
4745
|
+
function Decision({ approvalId, onDecided }) {
|
|
4746
|
+
const client = (0, import_react37.useRecordsClient)();
|
|
4747
|
+
const [may, setMay] = (0, import_react36.useState)(null);
|
|
4748
|
+
const [busy, setBusy] = (0, import_react36.useState)(null);
|
|
4749
|
+
const [error, setError] = (0, import_react36.useState)(null);
|
|
4750
|
+
(0, import_react36.useEffect)(() => {
|
|
4751
|
+
let live = true;
|
|
4752
|
+
void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
|
|
4753
|
+
if (!live) return;
|
|
4754
|
+
if (res.ok) setMay(res.data);
|
|
4755
|
+
else {
|
|
4756
|
+
setMay(false);
|
|
4757
|
+
setError(res.error);
|
|
4758
|
+
}
|
|
4759
|
+
});
|
|
4760
|
+
return () => {
|
|
4761
|
+
live = false;
|
|
4762
|
+
};
|
|
4763
|
+
}, [client, approvalId]);
|
|
4764
|
+
const decide = async (approve) => {
|
|
4765
|
+
setBusy(approve ? "approve" : "refuse");
|
|
4766
|
+
setError(null);
|
|
4767
|
+
const res = await client.workApprovalDecide({ approval_id: approvalId, approve });
|
|
4768
|
+
setBusy(null);
|
|
4769
|
+
if (res.ok) onDecided(approve);
|
|
4770
|
+
else setError(res.error);
|
|
4771
|
+
};
|
|
4772
|
+
if (may === null) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: "Checking who can decide\u2026" });
|
|
4773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
4774
|
+
may ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-2", children: [
|
|
4775
|
+
/* @__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" }),
|
|
4776
|
+
/* @__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" })
|
|
4777
|
+
] }) : !error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: "An owner or admin of this organization decides this." }),
|
|
4778
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(RefusalLine, { error }) : null
|
|
4779
|
+
] });
|
|
4528
4780
|
}
|
|
4529
4781
|
//# sourceMappingURL=pickers.cjs.map
|