@ai-matrx/records-ui 0.9.0 → 0.10.3
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 +89 -0
- package/dist/index.cjs +166 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -31
- package/dist/index.d.ts +66 -31
- package/dist/index.js +227 -104
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -710,7 +710,7 @@ function PersonPicker({ field, value: value2, onChange, disabled, id, className
|
|
|
710
710
|
}
|
|
711
711
|
|
|
712
712
|
// src/gridEditing.tsx
|
|
713
|
-
import { useCallback as useCallback3, useMemo as useMemo5, useRef as useRef2, useState as useState5 } from "react";
|
|
713
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo5, useRef as useRef2, useState as useState5 } from "react";
|
|
714
714
|
import { asWriteConflict } from "@ai-matrx/records/core";
|
|
715
715
|
import { useRecordsClient as useRecordsClient5 } from "@ai-matrx/records/react";
|
|
716
716
|
import { Button as Button4, cn as cn6 } from "@ai-matrx/design-system";
|
|
@@ -732,27 +732,49 @@ var TITLE = {
|
|
|
732
732
|
store_not_served: "The store is not being served",
|
|
733
733
|
internal: "The store said something this package does not recognise"
|
|
734
734
|
};
|
|
735
|
+
var MACHINE_IDENTITY = [
|
|
736
|
+
/\b[A-Z]{2,4}-\d{1,3}\b/,
|
|
737
|
+
// FLD-11, REC-29, AGT-7
|
|
738
|
+
/\b(?:custom|platform|iam|history|public)\.[a-z_]+/,
|
|
739
|
+
// a database object
|
|
740
|
+
/\b(?:config|data|document|spec)\.[a-z_]+/,
|
|
741
|
+
// a path inside a document
|
|
742
|
+
/\b[a-z]+(?:_[a-z]+)+\b/,
|
|
743
|
+
// any snake_case identifier
|
|
744
|
+
// A SQLSTATE: five characters of digits and capitals, at least one a digit —
|
|
745
|
+
// so `23514` and `PT409` match and an emphatic `NEVER` does not.
|
|
746
|
+
/\b(?=[0-9A-Z]{5}\b)(?=[0-9A-Z]*\d)[0-9A-Z]{5}\b/
|
|
747
|
+
];
|
|
748
|
+
function hintIsMachineIdentity(hint) {
|
|
749
|
+
return MACHINE_IDENTITY.some((shape) => shape.test(hint));
|
|
750
|
+
}
|
|
751
|
+
function hintForAPerson(hint) {
|
|
752
|
+
const said = (hint ?? "").trim();
|
|
753
|
+
if (said === "") return null;
|
|
754
|
+
return hintIsMachineIdentity(said) ? null : said;
|
|
755
|
+
}
|
|
735
756
|
function RefusalNotice({
|
|
736
757
|
error,
|
|
737
758
|
className,
|
|
738
759
|
actions
|
|
739
760
|
}) {
|
|
761
|
+
const hint = hintForAPerson(error.hint);
|
|
762
|
+
const forEngineers = [
|
|
763
|
+
error.sqlstate ? `The store's code for this was ${error.sqlstate}.` : null,
|
|
764
|
+
hint === null && error.hint ? error.hint : null
|
|
765
|
+
].filter(Boolean).join(" ");
|
|
740
766
|
return /* @__PURE__ */ jsxs4(
|
|
741
767
|
Alert,
|
|
742
768
|
{
|
|
743
769
|
variant: "destructive",
|
|
744
770
|
className: cn4("text-xs", className),
|
|
745
|
-
...
|
|
771
|
+
...forEngineers ? { title: forEngineers } : {},
|
|
746
772
|
children: [
|
|
747
773
|
/* @__PURE__ */ jsx5(AlertTitle, { className: "text-xs font-medium", children: TITLE[error.code] ?? "The store refused this" }),
|
|
748
774
|
/* @__PURE__ */ jsxs4(AlertDescription, { className: "space-y-1 text-xs", children: [
|
|
749
775
|
/* @__PURE__ */ jsx5("p", { children: error.message }),
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
"The store's code for this was ",
|
|
753
|
-
error.sqlstate,
|
|
754
|
-
"."
|
|
755
|
-
] }) : null,
|
|
776
|
+
hint ? /* @__PURE__ */ jsx5("p", { className: "opacity-80", children: hint }) : null,
|
|
777
|
+
forEngineers ? /* @__PURE__ */ jsx5("p", { className: "sr-only", ...error.sqlstate ? { "data-sqlstate": error.sqlstate } : {}, children: forEngineers }) : null,
|
|
756
778
|
actions
|
|
757
779
|
] })
|
|
758
780
|
]
|
|
@@ -760,7 +782,14 @@ function RefusalNotice({
|
|
|
760
782
|
);
|
|
761
783
|
}
|
|
762
784
|
function RefusalLine({ error, className }) {
|
|
763
|
-
|
|
785
|
+
const hint = hintForAPerson(error.hint);
|
|
786
|
+
return /* @__PURE__ */ jsxs4("p", { className: cn4("text-xs text-destructive", className), title: error.hint ?? void 0, children: [
|
|
787
|
+
error.message,
|
|
788
|
+
hint ? /* @__PURE__ */ jsxs4("span", { className: "opacity-80", children: [
|
|
789
|
+
" ",
|
|
790
|
+
hint
|
|
791
|
+
] }) : null
|
|
792
|
+
] });
|
|
764
793
|
}
|
|
765
794
|
|
|
766
795
|
// src/values.tsx
|
|
@@ -940,6 +969,8 @@ async function versionOf(client, cache, recordId) {
|
|
|
940
969
|
function useGridEditing({ tableId, fields, rows, reload, canWrite }) {
|
|
941
970
|
const client = useRecordsClient5();
|
|
942
971
|
const [editing, setEditing] = useState5(null);
|
|
972
|
+
const [draft, setDraft] = useState5(null);
|
|
973
|
+
const startedFrom = useRef2(null);
|
|
943
974
|
const [optimistic, setOptimistic] = useState5({});
|
|
944
975
|
const [saving, setSaving] = useState5({});
|
|
945
976
|
const [refusals, setRefusals] = useState5({});
|
|
@@ -971,15 +1002,31 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite }) {
|
|
|
971
1002
|
(rowId, key) => refusals[cellKey(rowId, key)] ?? null,
|
|
972
1003
|
[refusals]
|
|
973
1004
|
);
|
|
1005
|
+
const shownValue = useCallback3(
|
|
1006
|
+
(rowId, key) => {
|
|
1007
|
+
const held = optimistic[cellKey(rowId, key)];
|
|
1008
|
+
if (held !== void 0) return held;
|
|
1009
|
+
return rows.find((r) => r.id === rowId)?.document?.[key];
|
|
1010
|
+
},
|
|
1011
|
+
[optimistic, rows]
|
|
1012
|
+
);
|
|
974
1013
|
const begin = useCallback3(
|
|
975
1014
|
(address) => {
|
|
976
1015
|
if (!canWrite) return;
|
|
1016
|
+
if (editing && editing.rowId === address.rowId && editing.key === address.key) return;
|
|
1017
|
+
const current = shownValue(address.rowId, address.key);
|
|
1018
|
+
startedFrom.current = current;
|
|
1019
|
+
setDraft(current);
|
|
977
1020
|
setEditing(address);
|
|
978
1021
|
void versionOf(client, versions.current, address.rowId);
|
|
979
1022
|
},
|
|
980
|
-
[canWrite, client]
|
|
1023
|
+
[canWrite, client, editing, shownValue]
|
|
981
1024
|
);
|
|
982
|
-
const cancel = useCallback3(() =>
|
|
1025
|
+
const cancel = useCallback3(() => {
|
|
1026
|
+
setEditing(null);
|
|
1027
|
+
setDraft(null);
|
|
1028
|
+
startedFrom.current = null;
|
|
1029
|
+
}, []);
|
|
983
1030
|
const writeCellNow = useCallback3(
|
|
984
1031
|
async (rowId, key, value2) => {
|
|
985
1032
|
const id = cellKey(rowId, key);
|
|
@@ -1041,21 +1088,31 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite }) {
|
|
|
1041
1088
|
[client, reload]
|
|
1042
1089
|
);
|
|
1043
1090
|
const commit = useCallback3(
|
|
1044
|
-
(
|
|
1091
|
+
(move = null) => {
|
|
1045
1092
|
const open = editing;
|
|
1046
1093
|
if (!open) return;
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1049
|
-
if (!unchanged) void writeCell(open.rowId, open.key, value2);
|
|
1094
|
+
const value2 = draft;
|
|
1095
|
+
if (!sameValue(startedFrom.current, value2)) void writeCell(open.rowId, open.key, value2);
|
|
1050
1096
|
if (!move) {
|
|
1051
1097
|
setEditing(null);
|
|
1098
|
+
setDraft(null);
|
|
1099
|
+
startedFrom.current = null;
|
|
1052
1100
|
return;
|
|
1053
1101
|
}
|
|
1054
1102
|
const next = step(open, order, rowIds, move);
|
|
1103
|
+
if (!next) {
|
|
1104
|
+
setEditing(null);
|
|
1105
|
+
setDraft(null);
|
|
1106
|
+
startedFrom.current = null;
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
const starting = shownValue(next.rowId, next.key);
|
|
1110
|
+
startedFrom.current = starting;
|
|
1111
|
+
setDraft(starting);
|
|
1055
1112
|
setEditing(next);
|
|
1056
|
-
|
|
1113
|
+
void versionOf(client, versions.current, next.rowId);
|
|
1057
1114
|
},
|
|
1058
|
-
[editing,
|
|
1115
|
+
[editing, draft, writeCell, order, rowIds, client, shownValue]
|
|
1059
1116
|
);
|
|
1060
1117
|
const retry = useCallback3(
|
|
1061
1118
|
(rowId, key) => {
|
|
@@ -1110,12 +1167,18 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite }) {
|
|
|
1110
1167
|
}
|
|
1111
1168
|
reload();
|
|
1112
1169
|
const first = order[0];
|
|
1113
|
-
if (first)
|
|
1170
|
+
if (first) {
|
|
1171
|
+
startedFrom.current = void 0;
|
|
1172
|
+
setDraft(void 0);
|
|
1173
|
+
setEditing({ rowId: written.data, key: first });
|
|
1174
|
+
}
|
|
1114
1175
|
return null;
|
|
1115
1176
|
}, [client, tableId, reload, order]);
|
|
1116
1177
|
return {
|
|
1117
1178
|
valueFor,
|
|
1118
1179
|
editing,
|
|
1180
|
+
draft,
|
|
1181
|
+
type: setDraft,
|
|
1119
1182
|
stateOf,
|
|
1120
1183
|
refusalOf,
|
|
1121
1184
|
begin,
|
|
@@ -1178,27 +1241,40 @@ function GridCell({
|
|
|
1178
1241
|
OpenCell,
|
|
1179
1242
|
{
|
|
1180
1243
|
field,
|
|
1181
|
-
|
|
1182
|
-
|
|
1244
|
+
draft: editing.draft,
|
|
1245
|
+
onType: editing.type,
|
|
1246
|
+
onCommit: (move) => editing.commit(move),
|
|
1183
1247
|
onCancel: editing.cancel
|
|
1184
1248
|
}
|
|
1185
1249
|
);
|
|
1186
1250
|
}
|
|
1187
|
-
|
|
1251
|
+
const openThisCell = (event) => {
|
|
1252
|
+
event.preventDefault();
|
|
1253
|
+
event.stopPropagation();
|
|
1254
|
+
editing.begin({ rowId: row.id, key: field.key });
|
|
1255
|
+
};
|
|
1256
|
+
return /* @__PURE__ */ jsxs5("span", { "data-matrx-cell-control": "", className: "flex w-full min-w-0 flex-col gap-0.5", children: [
|
|
1188
1257
|
/* @__PURE__ */ jsx8(
|
|
1189
1258
|
"span",
|
|
1190
1259
|
{
|
|
1191
1260
|
role: editable ? "button" : void 0,
|
|
1192
1261
|
tabIndex: editable ? 0 : void 0,
|
|
1193
1262
|
"aria-label": editable ? `Edit ${fieldName(field)}` : void 0,
|
|
1194
|
-
title: editable ? `${fieldName(field)} \u2014 press Enter to edit` :
|
|
1263
|
+
title: editable ? `${fieldName(field)} \u2014 click or press Enter to edit` : `${fieldName(field)} is worked out by the system, so it cannot be typed in`,
|
|
1195
1264
|
className: cn6(
|
|
1196
|
-
|
|
1265
|
+
// `w-full` so the whole cell is the control. A gap beside it is bare
|
|
1266
|
+
// table cell, and a click there is a row click.
|
|
1267
|
+
"block w-full min-w-0 truncate rounded px-1 py-0.5",
|
|
1197
1268
|
editable ? "cursor-text hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" : "",
|
|
1198
1269
|
state === "saving" ? "opacity-60" : "",
|
|
1199
1270
|
state === "refused" ? "ring-1 ring-destructive" : ""
|
|
1200
1271
|
),
|
|
1201
|
-
onClick: editable ?
|
|
1272
|
+
onClick: editable ? openThisCell : void 0,
|
|
1273
|
+
onDoubleClick: (event) => {
|
|
1274
|
+
event.preventDefault();
|
|
1275
|
+
event.stopPropagation();
|
|
1276
|
+
if (editable) editing.begin({ rowId: row.id, key: field.key });
|
|
1277
|
+
},
|
|
1202
1278
|
onKeyDown: editable ? (event) => {
|
|
1203
1279
|
if (event.key === "Enter" || event.key === "F2") {
|
|
1204
1280
|
event.preventDefault();
|
|
@@ -1241,11 +1317,11 @@ function closesOnBlur(field) {
|
|
|
1241
1317
|
}
|
|
1242
1318
|
function OpenCell({
|
|
1243
1319
|
field,
|
|
1244
|
-
|
|
1320
|
+
draft,
|
|
1321
|
+
onType,
|
|
1245
1322
|
onCommit,
|
|
1246
1323
|
onCancel
|
|
1247
1324
|
}) {
|
|
1248
|
-
const [draft, setDraft] = useState5(value2);
|
|
1249
1325
|
const multiline = editorKindFor(field) === "long_text";
|
|
1250
1326
|
const blurCommits = closesOnBlur(field);
|
|
1251
1327
|
const done = useRef2(false);
|
|
@@ -1254,22 +1330,24 @@ function OpenCell({
|
|
|
1254
1330
|
done.current = true;
|
|
1255
1331
|
run();
|
|
1256
1332
|
};
|
|
1333
|
+
const host = useRef2(null);
|
|
1334
|
+
useEffect5(() => {
|
|
1335
|
+
const control = host.current?.querySelector("input, textarea, [role='combobox'], button");
|
|
1336
|
+
if (control && document.activeElement !== control) control.focus();
|
|
1337
|
+
}, [field.id]);
|
|
1257
1338
|
const blur = blurCommits ? {
|
|
1258
1339
|
onBlur: (event) => {
|
|
1259
1340
|
if (event.currentTarget.contains(event.relatedTarget)) return;
|
|
1260
|
-
once(() => onCommit(
|
|
1341
|
+
once(() => onCommit(null));
|
|
1261
1342
|
}
|
|
1262
1343
|
} : {};
|
|
1263
1344
|
return /* @__PURE__ */ jsxs5(
|
|
1264
1345
|
"span",
|
|
1265
1346
|
{
|
|
1347
|
+
ref: host,
|
|
1266
1348
|
"data-matrx-cell-control": "",
|
|
1267
|
-
className: "flex min-w-[10rem] flex-col gap-1",
|
|
1268
|
-
|
|
1269
|
-
if (!node) return;
|
|
1270
|
-
const control = node.querySelector("input, textarea, [role='combobox'], button");
|
|
1271
|
-
if (control && document.activeElement !== control) control.focus();
|
|
1272
|
-
},
|
|
1349
|
+
className: "flex w-full min-w-[10rem] flex-col gap-1",
|
|
1350
|
+
onDoubleClick: (event) => event.stopPropagation(),
|
|
1273
1351
|
onKeyDown: (event) => {
|
|
1274
1352
|
if (event.key === "Escape") {
|
|
1275
1353
|
event.preventDefault();
|
|
@@ -1280,20 +1358,20 @@ function OpenCell({
|
|
|
1280
1358
|
if (event.key === "Tab") {
|
|
1281
1359
|
event.preventDefault();
|
|
1282
1360
|
event.stopPropagation();
|
|
1283
|
-
once(() => onCommit(
|
|
1361
|
+
once(() => onCommit(event.shiftKey ? "previous" : "next"));
|
|
1284
1362
|
return;
|
|
1285
1363
|
}
|
|
1286
1364
|
if (event.key === "Enter" && (!multiline || event.metaKey || event.ctrlKey)) {
|
|
1287
1365
|
event.preventDefault();
|
|
1288
1366
|
event.stopPropagation();
|
|
1289
|
-
once(() => onCommit(
|
|
1367
|
+
once(() => onCommit(null));
|
|
1290
1368
|
}
|
|
1291
1369
|
},
|
|
1292
1370
|
...blur,
|
|
1293
1371
|
children: [
|
|
1294
|
-
/* @__PURE__ */ jsx8(FieldControl, { field, value: draft, onChange:
|
|
1372
|
+
/* @__PURE__ */ jsx8(FieldControl, { field, value: draft, onChange: onType, id: `cell-${field.id}` }),
|
|
1295
1373
|
blurCommits ? /* @__PURE__ */ jsx8("span", { className: "text-[10px] text-muted-foreground", children: multiline ? "\u2318\u23CE saves \xB7 Esc cancels \xB7 Tab next" : "\u23CE saves \xB7 Esc cancels \xB7 Tab next" }) : /* @__PURE__ */ jsxs5("span", { className: "flex items-center gap-1", children: [
|
|
1296
|
-
/* @__PURE__ */ jsx8(Button4, { size: "sm", onClick: () => once(() => onCommit(
|
|
1374
|
+
/* @__PURE__ */ jsx8(Button4, { size: "sm", onClick: () => once(() => onCommit(null)), children: "Save" }),
|
|
1297
1375
|
/* @__PURE__ */ jsx8(Button4, { size: "sm", variant: "ghost", onClick: () => once(onCancel), children: "Cancel" })
|
|
1298
1376
|
] })
|
|
1299
1377
|
]
|
|
@@ -1386,6 +1464,8 @@ function Grid({
|
|
|
1386
1464
|
tableId: `records-grid-${tableId}`,
|
|
1387
1465
|
stickyHeader: true,
|
|
1388
1466
|
pageSize,
|
|
1467
|
+
detail: { enabled: false },
|
|
1468
|
+
window: { enabled: false },
|
|
1389
1469
|
...onOpenRecord ? { onRowOpen: (row) => onOpenRecord(row.id) } : {},
|
|
1390
1470
|
...canWrite ? {
|
|
1391
1471
|
rowActions: (row) => /* @__PURE__ */ jsx9(
|
|
@@ -1727,7 +1807,7 @@ import { useFields as useFields5, useRecord as useRecord2, useTable as useTable3
|
|
|
1727
1807
|
import { Button as Button9, Separator as Separator3, cn as cn11 } from "@ai-matrx/design-system";
|
|
1728
1808
|
|
|
1729
1809
|
// src/RecordForm.tsx
|
|
1730
|
-
import { useEffect as
|
|
1810
|
+
import { useEffect as useEffect7, useMemo as useMemo8, useState as useState10 } from "react";
|
|
1731
1811
|
import {
|
|
1732
1812
|
useFields as useFields4,
|
|
1733
1813
|
useRecord,
|
|
@@ -1737,7 +1817,7 @@ import { predictWriteRefusals } from "@ai-matrx/records/core";
|
|
|
1737
1817
|
import { Button as Button8, Separator as Separator2, cn as cn10 } from "@ai-matrx/design-system";
|
|
1738
1818
|
|
|
1739
1819
|
// src/systemTable.ts
|
|
1740
|
-
import { useEffect as
|
|
1820
|
+
import { useEffect as useEffect6, useMemo as useMemo7, useState as useState9 } from "react";
|
|
1741
1821
|
import { useRecordsClient as useRecordsClient6 } from "@ai-matrx/records/react";
|
|
1742
1822
|
var inFlight = /* @__PURE__ */ new Map();
|
|
1743
1823
|
async function ensureSystemTable(client, spec) {
|
|
@@ -1878,7 +1958,7 @@ function useSystemTable(spec) {
|
|
|
1878
1958
|
const [state, setState] = useState9({ tableId: null, loading: true, error: null });
|
|
1879
1959
|
const slug = spec.slug;
|
|
1880
1960
|
const stable = useMemo7(() => spec, [slug]);
|
|
1881
|
-
|
|
1961
|
+
useEffect6(() => {
|
|
1882
1962
|
let cancelled = false;
|
|
1883
1963
|
setState({ tableId: null, loading: true, error: null });
|
|
1884
1964
|
void ensureSystemTable(client, stable).then((result) => {
|
|
@@ -1896,7 +1976,7 @@ function useSystemTable(spec) {
|
|
|
1896
1976
|
function useRecordVersion(recordId) {
|
|
1897
1977
|
const client = useRecordsClient6();
|
|
1898
1978
|
const [version, setVersion] = useState9(null);
|
|
1899
|
-
|
|
1979
|
+
useEffect6(() => {
|
|
1900
1980
|
let cancelled = false;
|
|
1901
1981
|
setVersion(null);
|
|
1902
1982
|
if (!recordId) return;
|
|
@@ -1933,7 +2013,7 @@ function RecordForm({
|
|
|
1933
2013
|
const [touched, setTouched] = useState10(false);
|
|
1934
2014
|
const loaded = useRecordVersion(recordId ?? null);
|
|
1935
2015
|
const loadedVersion = loaded.version;
|
|
1936
|
-
|
|
2016
|
+
useEffect7(() => {
|
|
1937
2017
|
const document3 = existing.data?.document;
|
|
1938
2018
|
if (document3) setDraft({ ...document3 });
|
|
1939
2019
|
}, [existing.data?.record_id, loadedVersion]);
|
|
@@ -2208,7 +2288,6 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
|
|
|
2208
2288
|
[fields.data, field?.id]
|
|
2209
2289
|
);
|
|
2210
2290
|
const relations = useMemo10(() => others.filter((f) => f.type === "relation"), [others]);
|
|
2211
|
-
const manyRelations = useMemo10(() => relations.filter((f) => f.multi), [relations]);
|
|
2212
2291
|
const choice = fieldTypeChoice(type);
|
|
2213
2292
|
const editing = Boolean(field);
|
|
2214
2293
|
const derivedKey = field?.key ?? keyFor(label);
|
|
@@ -2216,7 +2295,9 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
|
|
|
2216
2295
|
return /* @__PURE__ */ jsx14("p", { className: cn12("text-xs text-muted-foreground", className), children: rights.reason });
|
|
2217
2296
|
}
|
|
2218
2297
|
const options = optionText.split("\n").map((word) => word.trim()).filter((word) => word !== "");
|
|
2298
|
+
const missing = editing ? null : whatIsMissing({ type, label, options, via, pick, agg, of, relations, formulaFields });
|
|
2219
2299
|
const save = async () => {
|
|
2300
|
+
if (missing) return;
|
|
2220
2301
|
if (editing && field) {
|
|
2221
2302
|
const patch = {
|
|
2222
2303
|
label,
|
|
@@ -2322,7 +2403,6 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
|
|
|
2322
2403
|
formulaFields,
|
|
2323
2404
|
setFormulaFields,
|
|
2324
2405
|
relations,
|
|
2325
|
-
manyRelations,
|
|
2326
2406
|
others,
|
|
2327
2407
|
existingOptionsTable: Boolean(field?.options_table_id ?? field?.config?.["options_table_id"])
|
|
2328
2408
|
}
|
|
@@ -2437,8 +2517,17 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
|
|
|
2437
2517
|
] }, `${rule.kind}-${index}`))
|
|
2438
2518
|
] }),
|
|
2439
2519
|
mutation.error ? /* @__PURE__ */ jsx14(RefusalNotice, { error: mutation.error }) : null,
|
|
2520
|
+
missing ? /* @__PURE__ */ jsx14("p", { className: "text-[11px] text-destructive", children: missing }) : null,
|
|
2440
2521
|
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2441
|
-
/* @__PURE__ */ jsx14(
|
|
2522
|
+
/* @__PURE__ */ jsx14(
|
|
2523
|
+
Button10,
|
|
2524
|
+
{
|
|
2525
|
+
size: "sm",
|
|
2526
|
+
disabled: mutation.saving || missing !== null,
|
|
2527
|
+
onClick: () => void save(),
|
|
2528
|
+
children: mutation.saving ? "Saving\u2026" : field ? "Save field" : "Add field"
|
|
2529
|
+
}
|
|
2530
|
+
),
|
|
2442
2531
|
onCancel ? /* @__PURE__ */ jsx14(Button10, { size: "sm", variant: "ghost", onClick: onCancel, children: "Cancel" }) : null,
|
|
2443
2532
|
field ? /* @__PURE__ */ jsx14("div", { className: "ml-auto flex items-center gap-2", children: askingToRemove ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
2444
2533
|
/* @__PURE__ */ jsxs11("span", { className: "text-destructive", children: [
|
|
@@ -2452,6 +2541,34 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
|
|
|
2452
2541
|
] })
|
|
2453
2542
|
] });
|
|
2454
2543
|
}
|
|
2544
|
+
function whatIsMissing(state) {
|
|
2545
|
+
const { type, label, options, via, pick, agg, of, relations, formulaFields } = state;
|
|
2546
|
+
if (label.trim() === "") return "Give the column a name.";
|
|
2547
|
+
if (type === "select" || type === "multi_select") {
|
|
2548
|
+
if (options.length === 0) return "Type the choices this column offers, one per line.";
|
|
2549
|
+
return null;
|
|
2550
|
+
}
|
|
2551
|
+
if (type === "lookup" || type === "rollup") {
|
|
2552
|
+
if (relations.length === 0) {
|
|
2553
|
+
return type === "rollup" ? "A total is worked out across the records a column points at, and this table has no column that points at records yet. Add a Person or File column that can hold more than one, then come back." : "A borrowed value is read from a record a column points at, and this table has no column that points at another record yet. Add a Person or File column, then come back.";
|
|
2554
|
+
}
|
|
2555
|
+
const chosen = relations.find((relation) => relation.key === via);
|
|
2556
|
+
if (!chosen) {
|
|
2557
|
+
return type === "rollup" ? "Choose the column whose records this one adds up." : "Choose the column whose record this one reads from.";
|
|
2558
|
+
}
|
|
2559
|
+
if (type === "rollup" && !chosen.multi) {
|
|
2560
|
+
return `${fieldName(chosen)} points at one record at a time, so there is nothing to total. Tick "Can hold more than one" on ${fieldName(chosen)}, or use Borrowed value to read its one value.`;
|
|
2561
|
+
}
|
|
2562
|
+
if (type === "lookup" && pick.trim() === "") {
|
|
2563
|
+
return `Say which value to read from the record ${fieldName(chosen)} points at.`;
|
|
2564
|
+
}
|
|
2565
|
+
if (type === "rollup" && agg !== "count" && of.trim() === "") {
|
|
2566
|
+
return "Say which value of those records to work out.";
|
|
2567
|
+
}
|
|
2568
|
+
return null;
|
|
2569
|
+
}
|
|
2570
|
+
return null;
|
|
2571
|
+
}
|
|
2455
2572
|
function multiApplies(type) {
|
|
2456
2573
|
return type === "member" || type === "attachment" || type === "text";
|
|
2457
2574
|
}
|
|
@@ -2517,16 +2634,19 @@ function TypeQuestions(props) {
|
|
|
2517
2634
|
] });
|
|
2518
2635
|
}
|
|
2519
2636
|
if (type === "lookup" || type === "rollup") {
|
|
2520
|
-
const usable =
|
|
2637
|
+
const usable = props.relations;
|
|
2521
2638
|
if (usable.length === 0) {
|
|
2522
|
-
return /* @__PURE__ */ jsx14("p", { className: "text-[11px] text-muted-foreground", children: type === "rollup" ? "This kind of column works something out from records
|
|
2639
|
+
return /* @__PURE__ */ jsx14("p", { className: "text-[11px] text-muted-foreground", children: type === "rollup" ? "This kind of column works something out from the records another column points at, and this table has no column that points at records yet. Add a Person or File column that can hold more than one first." : "This kind of column reads a value from a record another column points at, and this table has no column that points at another record yet. Add a Person or File column first." });
|
|
2523
2640
|
}
|
|
2524
2641
|
return /* @__PURE__ */ jsxs11("div", { className: "grid gap-3 sm:grid-cols-2", children: [
|
|
2525
2642
|
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-1", children: [
|
|
2526
2643
|
/* @__PURE__ */ jsx14(Label2, { className: "text-xs", children: type === "rollup" ? "Across the records in" : "Read it from" }),
|
|
2527
2644
|
/* @__PURE__ */ jsxs11(Select2, { value: props.via, onValueChange: props.setVia, children: [
|
|
2528
2645
|
/* @__PURE__ */ jsx14(SelectTrigger2, { size: "sm", "aria-label": type === "rollup" ? "Across the records in" : "Read it from", children: /* @__PURE__ */ jsx14(SelectValue2, { placeholder: "Choose a column" }) }),
|
|
2529
|
-
/* @__PURE__ */ jsx14(SelectContent2, { children: usable.map((f) => /* @__PURE__ */
|
|
2646
|
+
/* @__PURE__ */ jsx14(SelectContent2, { children: usable.map((f) => /* @__PURE__ */ jsxs11(SelectItem2, { value: f.key, children: [
|
|
2647
|
+
fieldName(f),
|
|
2648
|
+
type === "rollup" && !f.multi ? " \u2014 holds one" : ""
|
|
2649
|
+
] }, f.id)) })
|
|
2530
2650
|
] })
|
|
2531
2651
|
] }),
|
|
2532
2652
|
type === "lookup" ? /* @__PURE__ */ jsxs11("label", { className: "flex flex-col gap-1", children: [
|
|
@@ -2978,7 +3098,7 @@ function parseSorts(raw) {
|
|
|
2978
3098
|
}
|
|
2979
3099
|
|
|
2980
3100
|
// src/ViewSwitcher.tsx
|
|
2981
|
-
import { useEffect as
|
|
3101
|
+
import { useEffect as useEffect8, useMemo as useMemo11, useState as useState16 } from "react";
|
|
2982
3102
|
import { useFields as useFields9, useRecords as useRecords3, useRecordsClient as useRecordsClient8 } from "@ai-matrx/records/react";
|
|
2983
3103
|
import { Button as Button14, Skeleton as Skeleton3, cn as cn15 } from "@ai-matrx/design-system";
|
|
2984
3104
|
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
@@ -2991,7 +3111,7 @@ function useViewRecords(view, pageSize = 200) {
|
|
|
2991
3111
|
error: null
|
|
2992
3112
|
});
|
|
2993
3113
|
const ruleId = view.ruleId ?? null;
|
|
2994
|
-
|
|
3114
|
+
useEffect8(() => {
|
|
2995
3115
|
if (!ruleId) return;
|
|
2996
3116
|
let cancelled = false;
|
|
2997
3117
|
setRuled({ rows: [], loading: true, error: null });
|
|
@@ -3041,7 +3161,7 @@ function ViewSwitcher({
|
|
|
3041
3161
|
}) {
|
|
3042
3162
|
const [layout, setLayout] = useState16(view.layout);
|
|
3043
3163
|
const [local, setLocal] = useState16({});
|
|
3044
|
-
|
|
3164
|
+
useEffect8(() => {
|
|
3045
3165
|
setLayout(view.layout);
|
|
3046
3166
|
setLocal({});
|
|
3047
3167
|
}, [view.layout, view.name, view.subject]);
|
|
@@ -3318,7 +3438,7 @@ function Card({
|
|
|
3318
3438
|
}
|
|
3319
3439
|
|
|
3320
3440
|
// src/ViewBar.tsx
|
|
3321
|
-
import { useCallback as useCallback5, useEffect as
|
|
3441
|
+
import { useCallback as useCallback5, useEffect as useEffect9, useState as useState17 } from "react";
|
|
3322
3442
|
import { useRecordsClient as useRecordsClient9 } from "@ai-matrx/records/react";
|
|
3323
3443
|
import { Button as Button15, Input, Skeleton as Skeleton4, cn as cn16 } from "@ai-matrx/design-system";
|
|
3324
3444
|
|
|
@@ -3380,10 +3500,10 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, className }) {
|
|
|
3380
3500
|
setError(null);
|
|
3381
3501
|
setViews(mine);
|
|
3382
3502
|
}, [client, viewTableId, tableId, seed]);
|
|
3383
|
-
|
|
3503
|
+
useEffect9(() => {
|
|
3384
3504
|
void load();
|
|
3385
3505
|
}, [load]);
|
|
3386
|
-
|
|
3506
|
+
useEffect9(() => {
|
|
3387
3507
|
if (!views || views.length === 0) return;
|
|
3388
3508
|
const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? views.find((v) => v.isDefault) ?? views[0];
|
|
3389
3509
|
if (chosen.id !== active) setActive(chosen.id);
|
|
@@ -3561,7 +3681,7 @@ function ProposalRow({
|
|
|
3561
3681
|
}
|
|
3562
3682
|
|
|
3563
3683
|
// src/ActionInbox.tsx
|
|
3564
|
-
import { useCallback as useCallback6, useEffect as
|
|
3684
|
+
import { useCallback as useCallback6, useEffect as useEffect10, useMemo as useMemo12, useState as useState19 } from "react";
|
|
3565
3685
|
import { useRecordsClient as useRecordsClient11 } from "@ai-matrx/records/react";
|
|
3566
3686
|
import { Badge as Badge6, Button as Button17, Skeleton as Skeleton5, cn as cn18 } from "@ai-matrx/design-system";
|
|
3567
3687
|
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
@@ -3640,7 +3760,7 @@ function ActionInbox({ tableId, includeSettled = false, seed, onOpenRecord, clas
|
|
|
3640
3760
|
setError(null);
|
|
3641
3761
|
setActions(held);
|
|
3642
3762
|
}, [client, queueTableId, seed]);
|
|
3643
|
-
|
|
3763
|
+
useEffect10(() => {
|
|
3644
3764
|
void load();
|
|
3645
3765
|
}, [load]);
|
|
3646
3766
|
const shown = useMemo12(() => {
|
|
@@ -3755,7 +3875,7 @@ function parseChanges(raw) {
|
|
|
3755
3875
|
}
|
|
3756
3876
|
|
|
3757
3877
|
// src/HistoryPanel.tsx
|
|
3758
|
-
import { useCallback as useCallback7, useEffect as
|
|
3878
|
+
import { useCallback as useCallback7, useEffect as useEffect11, useState as useState20 } from "react";
|
|
3759
3879
|
import {
|
|
3760
3880
|
useFields as useFields10,
|
|
3761
3881
|
useRecordsClient as useRecordsClient12,
|
|
@@ -3802,7 +3922,7 @@ function HistoryPanel({ tableId, recordId, className }) {
|
|
|
3802
3922
|
);
|
|
3803
3923
|
setRead(read2.ok ? read2.data : { record_id: recordId, document: {}, hidden: {}, computed: [] });
|
|
3804
3924
|
}, [client, recordId]);
|
|
3805
|
-
|
|
3925
|
+
useEffect11(() => {
|
|
3806
3926
|
void load();
|
|
3807
3927
|
}, [load]);
|
|
3808
3928
|
if (error) return /* @__PURE__ */ jsx22(RefusalNotice, { error, className });
|
|
@@ -3862,7 +3982,7 @@ function HistoryPanel({ tableId, recordId, className }) {
|
|
|
3862
3982
|
}
|
|
3863
3983
|
|
|
3864
3984
|
// src/CommentThread.tsx
|
|
3865
|
-
import { useCallback as useCallback8, useEffect as
|
|
3985
|
+
import { useCallback as useCallback8, useEffect as useEffect12, useState as useState21 } from "react";
|
|
3866
3986
|
import { useRecordsClient as useRecordsClient13, useTable as useTable9 } from "@ai-matrx/records/react";
|
|
3867
3987
|
import { Button as Button19, Skeleton as Skeleton7, Textarea, cn as cn20 } from "@ai-matrx/design-system";
|
|
3868
3988
|
import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
@@ -3907,7 +4027,7 @@ function CommentThread({ tableId, recordId, className }) {
|
|
|
3907
4027
|
result.data.rows.filter((row) => row.document?.["subject"] === recordId).map(toComment).sort((a, b) => a.at.localeCompare(b.at))
|
|
3908
4028
|
);
|
|
3909
4029
|
}, [client, commentTableId, recordId]);
|
|
3910
|
-
|
|
4030
|
+
useEffect12(() => {
|
|
3911
4031
|
void load();
|
|
3912
4032
|
}, [load]);
|
|
3913
4033
|
async function post() {
|
|
@@ -4077,7 +4197,7 @@ function submissionStamp(args) {
|
|
|
4077
4197
|
}
|
|
4078
4198
|
|
|
4079
4199
|
// src/FormBuilder.tsx
|
|
4080
|
-
import { useCallback as useCallback10, useEffect as
|
|
4200
|
+
import { useCallback as useCallback10, useEffect as useEffect14, useMemo as useMemo14, useState as useState23 } from "react";
|
|
4081
4201
|
import { useFields as useFields12, useRecordsClient as useRecordsClient15, useTable as useTable10 } from "@ai-matrx/records/react";
|
|
4082
4202
|
import {
|
|
4083
4203
|
BasicInput as BasicInput5,
|
|
@@ -4090,7 +4210,7 @@ import {
|
|
|
4090
4210
|
} from "@ai-matrx/design-system";
|
|
4091
4211
|
|
|
4092
4212
|
// src/FormRunner.tsx
|
|
4093
|
-
import { useCallback as useCallback9, useEffect as
|
|
4213
|
+
import { useCallback as useCallback9, useEffect as useEffect13, useMemo as useMemo13, useRef as useRef4, useState as useState22 } from "react";
|
|
4094
4214
|
import { useFields as useFields11, useRecordsClient as useRecordsClient14 } from "@ai-matrx/records/react";
|
|
4095
4215
|
import { doorExists, DOORS } from "@ai-matrx/records/core";
|
|
4096
4216
|
import { Button as Button20, Progress, Skeleton as Skeleton8, cn as cn21 } from "@ai-matrx/design-system";
|
|
@@ -4120,7 +4240,7 @@ function FormRunner({ form, preview = false, onSubmitted, className }) {
|
|
|
4120
4240
|
};
|
|
4121
4241
|
});
|
|
4122
4242
|
}, [fields.data, form.questions]);
|
|
4123
|
-
|
|
4243
|
+
useEffect13(() => {
|
|
4124
4244
|
let cancelled = false;
|
|
4125
4245
|
const conditional = questions.filter((q) => q.showIf);
|
|
4126
4246
|
if (conditional.length === 0) return;
|
|
@@ -4195,7 +4315,7 @@ function FormRunner({ form, preview = false, onSubmitted, className }) {
|
|
|
4195
4315
|
if (event.shiftKey) retreat();
|
|
4196
4316
|
else advance();
|
|
4197
4317
|
}
|
|
4198
|
-
|
|
4318
|
+
useEffect13(() => {
|
|
4199
4319
|
const input = stage.current?.querySelector("input, textarea, select, [role='combobox']");
|
|
4200
4320
|
input?.focus();
|
|
4201
4321
|
}, [index, done]);
|
|
@@ -4361,10 +4481,10 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
|
4361
4481
|
setError(null);
|
|
4362
4482
|
setForms(mine);
|
|
4363
4483
|
}, [client, formTableId, tableId, seed]);
|
|
4364
|
-
|
|
4484
|
+
useEffect14(() => {
|
|
4365
4485
|
void load();
|
|
4366
4486
|
}, [load]);
|
|
4367
|
-
|
|
4487
|
+
useEffect14(() => {
|
|
4368
4488
|
if (!forms || forms.length === 0) return;
|
|
4369
4489
|
const chosen = forms.find((f) => f.id === (activeFormId ?? activeId)) ?? forms[0];
|
|
4370
4490
|
if (chosen.id !== activeId) setActiveId(chosen.id);
|
|
@@ -4736,7 +4856,7 @@ function isSignatureField(field) {
|
|
|
4736
4856
|
}
|
|
4737
4857
|
|
|
4738
4858
|
// src/DocTemplate.tsx
|
|
4739
|
-
import { useCallback as useCallback11, useEffect as
|
|
4859
|
+
import { useCallback as useCallback11, useEffect as useEffect15, useState as useState24 } from "react";
|
|
4740
4860
|
import { useFields as useFields13, useRecordsClient as useRecordsClient16, useTable as useTable11 } from "@ai-matrx/records/react";
|
|
4741
4861
|
import { BasicInput as BasicInput6, BasicTextarea as BasicTextarea4, Button as Button22, Label as Label4, Skeleton as Skeleton10, cn as cn23 } from "@ai-matrx/design-system";
|
|
4742
4862
|
import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
@@ -4784,10 +4904,10 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
|
|
|
4784
4904
|
setError(null);
|
|
4785
4905
|
setTemplates(rows);
|
|
4786
4906
|
}, [client, tableId, seed, fields.data]);
|
|
4787
|
-
|
|
4907
|
+
useEffect15(() => {
|
|
4788
4908
|
void load();
|
|
4789
4909
|
}, [load]);
|
|
4790
|
-
|
|
4910
|
+
useEffect15(() => {
|
|
4791
4911
|
if (!templates || templates.length === 0) return;
|
|
4792
4912
|
const chosen = templates.find((t) => t.id === (activeTemplateId ?? activeId)) ?? templates[0];
|
|
4793
4913
|
if (chosen.id !== activeId) setActiveId(chosen.id);
|
|
@@ -4795,7 +4915,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
|
|
|
4795
4915
|
setDraftBody(chosen.body);
|
|
4796
4916
|
onActiveTemplate?.(chosen);
|
|
4797
4917
|
}, [templates, activeTemplateId]);
|
|
4798
|
-
|
|
4918
|
+
useEffect15(() => {
|
|
4799
4919
|
let cancelled = false;
|
|
4800
4920
|
if (draftBody.trim() === "") {
|
|
4801
4921
|
setUnresolved([]);
|
|
@@ -4915,7 +5035,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
|
|
|
4915
5035
|
}
|
|
4916
5036
|
|
|
4917
5037
|
// src/DocRender.tsx
|
|
4918
|
-
import { useCallback as useCallback12, useEffect as
|
|
5038
|
+
import { useCallback as useCallback12, useEffect as useEffect16, useRef as useRef5, useState as useState25 } from "react";
|
|
4919
5039
|
import { useRecordsClient as useRecordsClient17 } from "@ai-matrx/records/react";
|
|
4920
5040
|
import { Button as Button23, Skeleton as Skeleton11, cn as cn24 } from "@ai-matrx/design-system";
|
|
4921
5041
|
import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
@@ -4944,7 +5064,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
|
|
|
4944
5064
|
setPreview(body.data);
|
|
4945
5065
|
setRenders(held.data.filter((r) => r.template_id === templateId));
|
|
4946
5066
|
}, [client, templateId, recordId]);
|
|
4947
|
-
|
|
5067
|
+
useEffect16(() => {
|
|
4948
5068
|
void load();
|
|
4949
5069
|
}, [load]);
|
|
4950
5070
|
async function freeze() {
|
|
@@ -5028,7 +5148,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
|
|
|
5028
5148
|
}
|
|
5029
5149
|
|
|
5030
5150
|
// src/SignBlock.tsx
|
|
5031
|
-
import { useCallback as useCallback13, useEffect as
|
|
5151
|
+
import { useCallback as useCallback13, useEffect as useEffect17, useState as useState26 } from "react";
|
|
5032
5152
|
import { useFields as useFields14, useRecordsClient as useRecordsClient18 } from "@ai-matrx/records/react";
|
|
5033
5153
|
import { BasicInput as BasicInput7, Button as Button24, Skeleton as Skeleton12, cn as cn25 } from "@ai-matrx/design-system";
|
|
5034
5154
|
import { useTable as useTable12 } from "@ai-matrx/records/react";
|
|
@@ -5058,7 +5178,7 @@ function SignBlock({ tableId, recordId, render, className }) {
|
|
|
5058
5178
|
}
|
|
5059
5179
|
setVerdicts(answers);
|
|
5060
5180
|
}, [client, recordId]);
|
|
5061
|
-
|
|
5181
|
+
useEffect17(() => {
|
|
5062
5182
|
void load();
|
|
5063
5183
|
}, [load]);
|
|
5064
5184
|
async function sign(field) {
|
|
@@ -5165,7 +5285,7 @@ function SignBlock({ tableId, recordId, render, className }) {
|
|
|
5165
5285
|
}
|
|
5166
5286
|
|
|
5167
5287
|
// src/NotifyRuleEditor.tsx
|
|
5168
|
-
import { useCallback as useCallback14, useEffect as
|
|
5288
|
+
import { useCallback as useCallback14, useEffect as useEffect18, useState as useState27 } from "react";
|
|
5169
5289
|
import { useRecordsClient as useRecordsClient19, useTable as useTable13 } from "@ai-matrx/records/react";
|
|
5170
5290
|
import { Button as Button25, Skeleton as Skeleton13, cn as cn26 } from "@ai-matrx/design-system";
|
|
5171
5291
|
import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
@@ -5196,7 +5316,7 @@ function NotifyRuleEditor({ tableId, seed, className }) {
|
|
|
5196
5316
|
if (host.savedViews) setViews(await host.savedViews());
|
|
5197
5317
|
else setViews(null);
|
|
5198
5318
|
}, [client, host]);
|
|
5199
|
-
|
|
5319
|
+
useEffect18(() => {
|
|
5200
5320
|
void load();
|
|
5201
5321
|
}, [load]);
|
|
5202
5322
|
const write = useCallback14(
|
|
@@ -5231,7 +5351,7 @@ function NotifyRuleEditor({ tableId, seed, className }) {
|
|
|
5231
5351
|
},
|
|
5232
5352
|
[client, tableId]
|
|
5233
5353
|
);
|
|
5234
|
-
|
|
5354
|
+
useEffect18(() => {
|
|
5235
5355
|
if (!subscriptions || !seed || seed.length === 0) return;
|
|
5236
5356
|
const missing = seed.filter((s) => !subscriptions.some((held) => held.name === s.name));
|
|
5237
5357
|
if (missing.length === 0) return;
|
|
@@ -5320,7 +5440,7 @@ function NotifyRuleEditor({ tableId, seed, className }) {
|
|
|
5320
5440
|
}
|
|
5321
5441
|
|
|
5322
5442
|
// src/ChartBlock.tsx
|
|
5323
|
-
import { useEffect as
|
|
5443
|
+
import { useEffect as useEffect19, useState as useState28 } from "react";
|
|
5324
5444
|
import { useRecordsClient as useRecordsClient20 } from "@ai-matrx/records/react";
|
|
5325
5445
|
import { measureKey } from "@ai-matrx/records";
|
|
5326
5446
|
import { Skeleton as Skeleton14, cn as cn27 } from "@ai-matrx/design-system";
|
|
@@ -5341,7 +5461,7 @@ function ChartBlock({ spec, className }) {
|
|
|
5341
5461
|
f: spec.filter ?? {},
|
|
5342
5462
|
l: spec.limit ?? 50
|
|
5343
5463
|
});
|
|
5344
|
-
|
|
5464
|
+
useEffect19(() => {
|
|
5345
5465
|
if (needs) return;
|
|
5346
5466
|
let cancelled = false;
|
|
5347
5467
|
setRows(null);
|
|
@@ -5488,7 +5608,7 @@ function Drawing({ kind, rows, measure }) {
|
|
|
5488
5608
|
}
|
|
5489
5609
|
|
|
5490
5610
|
// src/DashboardCanvas.tsx
|
|
5491
|
-
import { useCallback as useCallback15, useEffect as
|
|
5611
|
+
import { useCallback as useCallback15, useEffect as useEffect20, useState as useState29 } from "react";
|
|
5492
5612
|
import { useFields as useFields15, useRecordsClient as useRecordsClient21, useTable as useTable14 } from "@ai-matrx/records/react";
|
|
5493
5613
|
import { Button as Button26, Skeleton as Skeleton15, cn as cn28 } from "@ai-matrx/design-system";
|
|
5494
5614
|
import { jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
@@ -5535,10 +5655,10 @@ function DashboardCanvas({ tableId, seed, activeDashboardId, className }) {
|
|
|
5535
5655
|
setError(null);
|
|
5536
5656
|
setBoards(mine);
|
|
5537
5657
|
}, [client, boardTableId, tableId, seed]);
|
|
5538
|
-
|
|
5658
|
+
useEffect20(() => {
|
|
5539
5659
|
void load();
|
|
5540
5660
|
}, [load]);
|
|
5541
|
-
|
|
5661
|
+
useEffect20(() => {
|
|
5542
5662
|
if (!boards || boards.length === 0) return;
|
|
5543
5663
|
const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
|
|
5544
5664
|
if (chosen.id !== activeId) setActiveId(chosen.id);
|
|
@@ -5675,7 +5795,7 @@ function DashboardCanvas({ tableId, seed, activeDashboardId, className }) {
|
|
|
5675
5795
|
}
|
|
5676
5796
|
|
|
5677
5797
|
// src/RecordChat.tsx
|
|
5678
|
-
import { useEffect as
|
|
5798
|
+
import { useEffect as useEffect21, useMemo as useMemo15, useState as useState30 } from "react";
|
|
5679
5799
|
import { useFields as useFields16, useRecordsClient as useRecordsClient22, useTable as useTable15 } from "@ai-matrx/records/react";
|
|
5680
5800
|
import { Skeleton as Skeleton16, cn as cn29 } from "@ai-matrx/design-system";
|
|
5681
5801
|
import { jsx as jsx32, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
@@ -5687,7 +5807,7 @@ function RecordChat({ tableId, recordId, className }) {
|
|
|
5687
5807
|
const fields = useFields16(tableId);
|
|
5688
5808
|
const [read, setRead] = useState30(null);
|
|
5689
5809
|
const [error, setError] = useState30(null);
|
|
5690
|
-
|
|
5810
|
+
useEffect21(() => {
|
|
5691
5811
|
let cancelled = false;
|
|
5692
5812
|
setRead(null);
|
|
5693
5813
|
setError(null);
|
|
@@ -5808,7 +5928,7 @@ function noticeText(notice) {
|
|
|
5808
5928
|
}
|
|
5809
5929
|
|
|
5810
5930
|
// src/EnrichPanel.tsx
|
|
5811
|
-
import { useCallback as useCallback16, useEffect as
|
|
5931
|
+
import { useCallback as useCallback16, useEffect as useEffect22, useMemo as useMemo16, useState as useState31 } from "react";
|
|
5812
5932
|
import { useFields as useFields17, useRecordsClient as useRecordsClient23, useTable as useTable16 } from "@ai-matrx/records/react";
|
|
5813
5933
|
import { Badge as Badge8, Button as Button27, Skeleton as Skeleton17, cn as cn30 } from "@ai-matrx/design-system";
|
|
5814
5934
|
import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
@@ -5832,7 +5952,7 @@ function EnrichPanel({ tableId, recordId, className }) {
|
|
|
5832
5952
|
setError(null);
|
|
5833
5953
|
setDocument(answered.data.document);
|
|
5834
5954
|
}, [client, recordId]);
|
|
5835
|
-
|
|
5955
|
+
useEffect22(() => {
|
|
5836
5956
|
void load();
|
|
5837
5957
|
}, [load]);
|
|
5838
5958
|
const agentFields = useMemo16(() => {
|
|
@@ -5971,7 +6091,7 @@ function describe(field, document2) {
|
|
|
5971
6091
|
}
|
|
5972
6092
|
|
|
5973
6093
|
// src/ChecklistRunner.tsx
|
|
5974
|
-
import { useCallback as useCallback17, useEffect as
|
|
6094
|
+
import { useCallback as useCallback17, useEffect as useEffect23, useMemo as useMemo17, useState as useState32 } from "react";
|
|
5975
6095
|
import { useRecordsClient as useRecordsClient24, useTable as useTable17 } from "@ai-matrx/records/react";
|
|
5976
6096
|
import { Badge as Badge9, Button as Button28, Skeleton as Skeleton18, cn as cn31 } from "@ai-matrx/design-system";
|
|
5977
6097
|
import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
@@ -6003,7 +6123,7 @@ function ChecklistRunner({ tableId, seed, className }) {
|
|
|
6003
6123
|
const [busy, setBusy] = useState32(false);
|
|
6004
6124
|
const [note, setNote] = useState32(null);
|
|
6005
6125
|
const runTableId = home.tableId;
|
|
6006
|
-
|
|
6126
|
+
useEffect23(() => {
|
|
6007
6127
|
let cancelled = false;
|
|
6008
6128
|
void client.workStates().then((answered) => {
|
|
6009
6129
|
if (cancelled || !answered.ok) return;
|
|
@@ -6025,10 +6145,10 @@ function ChecklistRunner({ tableId, seed, className }) {
|
|
|
6025
6145
|
setRuns(held);
|
|
6026
6146
|
return held;
|
|
6027
6147
|
}, [client, runTableId, tableId]);
|
|
6028
|
-
|
|
6148
|
+
useEffect23(() => {
|
|
6029
6149
|
void loadRuns();
|
|
6030
6150
|
}, [loadRuns]);
|
|
6031
|
-
|
|
6151
|
+
useEffect23(() => {
|
|
6032
6152
|
let cancelled = false;
|
|
6033
6153
|
if (!runTableId || !seed || seed.length === 0 || runs === null) return;
|
|
6034
6154
|
const missing = seed.filter((spec) => !runs.some((run) => run.name === spec.name));
|
|
@@ -6060,7 +6180,7 @@ function ChecklistRunner({ tableId, seed, className }) {
|
|
|
6060
6180
|
}
|
|
6061
6181
|
setTurns(answered.data);
|
|
6062
6182
|
}, [client, tableId]);
|
|
6063
|
-
|
|
6183
|
+
useEffect23(() => {
|
|
6064
6184
|
void loadTurns();
|
|
6065
6185
|
}, [loadTurns, active?.id, active?.stepIds.length]);
|
|
6066
6186
|
async function move(step2, to) {
|
|
@@ -6209,7 +6329,7 @@ function toRun(row) {
|
|
|
6209
6329
|
}
|
|
6210
6330
|
|
|
6211
6331
|
// src/BookingSlots.tsx
|
|
6212
|
-
import { useCallback as useCallback18, useEffect as
|
|
6332
|
+
import { useCallback as useCallback18, useEffect as useEffect24, useMemo as useMemo18, useState as useState33 } from "react";
|
|
6213
6333
|
import { useRecordsClient as useRecordsClient25, useTable as useTable18 } from "@ai-matrx/records/react";
|
|
6214
6334
|
import { Button as Button29, Skeleton as Skeleton19, cn as cn32 } from "@ai-matrx/design-system";
|
|
6215
6335
|
import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
@@ -6231,7 +6351,7 @@ function BookingSlots({
|
|
|
6231
6351
|
const [refused, setRefused] = useState33(null);
|
|
6232
6352
|
const me = client.config.actor.user_id ?? "anonymous";
|
|
6233
6353
|
const slug = `records_ui_slots_${tableId.replace(/-/g, "").slice(0, 16)}`;
|
|
6234
|
-
|
|
6354
|
+
useEffect24(() => {
|
|
6235
6355
|
let cancelled = false;
|
|
6236
6356
|
void (async () => {
|
|
6237
6357
|
const tables = await client.tableList();
|
|
@@ -6284,7 +6404,7 @@ function BookingSlots({
|
|
|
6284
6404
|
setError(null);
|
|
6285
6405
|
setHolds(answered.data);
|
|
6286
6406
|
}, [client, slotTableId]);
|
|
6287
|
-
|
|
6407
|
+
useEffect24(() => {
|
|
6288
6408
|
void loadHolds();
|
|
6289
6409
|
}, [loadHolds]);
|
|
6290
6410
|
const slots = useMemo18(() => {
|
|
@@ -6416,7 +6536,7 @@ function whenText(at) {
|
|
|
6416
6536
|
}
|
|
6417
6537
|
|
|
6418
6538
|
// src/CaptureSheet.tsx
|
|
6419
|
-
import { useCallback as useCallback19, useEffect as
|
|
6539
|
+
import { useCallback as useCallback19, useEffect as useEffect25, useRef as useRef6, useState as useState34 } from "react";
|
|
6420
6540
|
import { useFields as useFields18, useRecordsClient as useRecordsClient26, useTable as useTable19 } from "@ai-matrx/records/react";
|
|
6421
6541
|
import { Button as Button30, Input as Input2, Skeleton as Skeleton20, Textarea as Textarea2, cn as cn33 } from "@ai-matrx/design-system";
|
|
6422
6542
|
import { Fragment as Fragment10, jsx as jsx36, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
@@ -6460,7 +6580,7 @@ function CaptureSheet({
|
|
|
6460
6580
|
},
|
|
6461
6581
|
[host]
|
|
6462
6582
|
);
|
|
6463
|
-
|
|
6583
|
+
useEffect25(() => {
|
|
6464
6584
|
let cancelled = false;
|
|
6465
6585
|
void (async () => {
|
|
6466
6586
|
const held = host.captureQueue ? await host.captureQueue.load() : [];
|
|
@@ -6639,7 +6759,7 @@ function CaptureSheet({
|
|
|
6639
6759
|
}
|
|
6640
6760
|
|
|
6641
6761
|
// src/PortalShell.tsx
|
|
6642
|
-
import { useCallback as useCallback20, useEffect as
|
|
6762
|
+
import { useCallback as useCallback20, useEffect as useEffect26, useState as useState35 } from "react";
|
|
6643
6763
|
import { useRecordsClient as useRecordsClient27 } from "@ai-matrx/records/react";
|
|
6644
6764
|
import { Button as Button31, Skeleton as Skeleton21, cn as cn34 } from "@ai-matrx/design-system";
|
|
6645
6765
|
import { jsx as jsx37, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
@@ -6665,7 +6785,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
|
|
|
6665
6785
|
}
|
|
6666
6786
|
setReach(reached.data.map((row) => row.resource_id));
|
|
6667
6787
|
}, [client, resourceType]);
|
|
6668
|
-
|
|
6788
|
+
useEffect26(() => {
|
|
6669
6789
|
void load();
|
|
6670
6790
|
}, [load]);
|
|
6671
6791
|
if (error) {
|
|
@@ -6725,7 +6845,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
|
|
|
6725
6845
|
function PortalRow({ tableId, recordId }) {
|
|
6726
6846
|
const client = useRecordsClient27();
|
|
6727
6847
|
const [title, setTitle] = useState35(null);
|
|
6728
|
-
|
|
6848
|
+
useEffect26(() => {
|
|
6729
6849
|
let cancelled = false;
|
|
6730
6850
|
void client.recordRead({ record_id: recordId }).then((answered) => {
|
|
6731
6851
|
if (cancelled) return;
|
|
@@ -6745,7 +6865,7 @@ function PortalRow({ tableId, recordId }) {
|
|
|
6745
6865
|
}
|
|
6746
6866
|
|
|
6747
6867
|
// src/PublicViewPage.tsx
|
|
6748
|
-
import { useCallback as useCallback21, useEffect as
|
|
6868
|
+
import { useCallback as useCallback21, useEffect as useEffect27, useState as useState36 } from "react";
|
|
6749
6869
|
import { useRecordsClient as useRecordsClient28 } from "@ai-matrx/records/react";
|
|
6750
6870
|
import { Skeleton as Skeleton22, cn as cn35 } from "@ai-matrx/design-system";
|
|
6751
6871
|
import { jsx as jsx38, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
@@ -6789,7 +6909,7 @@ function PublicViewPage({ slug, className }) {
|
|
|
6789
6909
|
}
|
|
6790
6910
|
setRows([{ id: found.resource_id, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
|
|
6791
6911
|
}, [client, slug]);
|
|
6792
|
-
|
|
6912
|
+
useEffect27(() => {
|
|
6793
6913
|
void load();
|
|
6794
6914
|
}, [load]);
|
|
6795
6915
|
if (error) return /* @__PURE__ */ jsx38(RefusalNotice, { error, className });
|
|
@@ -6826,7 +6946,7 @@ function PublicRow({ row, fields }) {
|
|
|
6826
6946
|
}
|
|
6827
6947
|
|
|
6828
6948
|
// src/EmbedFrame.tsx
|
|
6829
|
-
import { useCallback as useCallback22, useEffect as
|
|
6949
|
+
import { useCallback as useCallback22, useEffect as useEffect28, useState as useState37 } from "react";
|
|
6830
6950
|
import { useRecordsClient as useRecordsClient29 } from "@ai-matrx/records/react";
|
|
6831
6951
|
import { Button as Button32, Input as Input3, Skeleton as Skeleton23, Textarea as Textarea3, cn as cn36 } from "@ai-matrx/design-system";
|
|
6832
6952
|
import { useTable as useTable20 } from "@ai-matrx/records/react";
|
|
@@ -6939,7 +7059,7 @@ function useEmbedHandshake(args) {
|
|
|
6939
7059
|
const [loading, setLoading] = useState37(true);
|
|
6940
7060
|
const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
|
|
6941
7061
|
const { secret, requiredMode } = args;
|
|
6942
|
-
|
|
7062
|
+
useEffect28(() => {
|
|
6943
7063
|
let cancelled = false;
|
|
6944
7064
|
setLoading(true);
|
|
6945
7065
|
setError(null);
|
|
@@ -7447,6 +7567,8 @@ export {
|
|
|
7447
7567
|
formDocument,
|
|
7448
7568
|
formFromRecord,
|
|
7449
7569
|
groupLabel,
|
|
7570
|
+
hintForAPerson,
|
|
7571
|
+
hintIsMachineIdentity,
|
|
7450
7572
|
humanize,
|
|
7451
7573
|
idsOf,
|
|
7452
7574
|
isId,
|
|
@@ -7479,6 +7601,7 @@ export {
|
|
|
7479
7601
|
useViewRecords,
|
|
7480
7602
|
viewDocument,
|
|
7481
7603
|
viewFromRecord,
|
|
7482
|
-
viewPatchDocument
|
|
7604
|
+
viewPatchDocument,
|
|
7605
|
+
whatIsMissing
|
|
7483
7606
|
};
|
|
7484
7607
|
//# sourceMappingURL=index.js.map
|