@ai-matrx/records-ui 0.102.0 → 0.102.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/index.cjs +2278 -1550
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1043 -311
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1880,7 +1880,7 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
|
|
|
1880
1880
|
const client = useOptionalRecordsClient();
|
|
1881
1881
|
const [rows, setRows] = useState5(null);
|
|
1882
1882
|
const [words2, setWords] = useState5({});
|
|
1883
|
-
const [
|
|
1883
|
+
const [refusal4, setRefusal] = useState5(null);
|
|
1884
1884
|
const [search, setSearch] = useState5("");
|
|
1885
1885
|
const [open, setOpen] = useState5(false);
|
|
1886
1886
|
const [target, setTarget] = useState5(null);
|
|
@@ -2051,8 +2051,8 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
|
|
|
2051
2051
|
})),
|
|
2052
2052
|
onPick: toggle,
|
|
2053
2053
|
notice: /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
2054
|
-
|
|
2055
|
-
!rows && !
|
|
2054
|
+
refusal4 ? /* @__PURE__ */ jsx7(RefusalLine, { error: refusal4, className: "p-2" }) : null,
|
|
2055
|
+
!rows && !refusal4 ? /* @__PURE__ */ jsx7("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading\u2026" }) : null,
|
|
2056
2056
|
full ? /* @__PURE__ */ jsxs6("p", { className: "p-2 text-xs text-muted-foreground", children: [
|
|
2057
2057
|
fieldName(field2),
|
|
2058
2058
|
" can point at ",
|
|
@@ -4242,7 +4242,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
|
|
|
4242
4242
|
}
|
|
4243
4243
|
function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
|
|
4244
4244
|
const [text, setText] = useState15(() => openingText(field2, value));
|
|
4245
|
-
const [
|
|
4245
|
+
const [refusal4, setRefusal] = useState15(null);
|
|
4246
4246
|
const sent = useRef8(value);
|
|
4247
4247
|
useEffect10(() => {
|
|
4248
4248
|
if (value === sent.current) return;
|
|
@@ -4271,11 +4271,11 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
|
|
|
4271
4271
|
value: text,
|
|
4272
4272
|
disabled,
|
|
4273
4273
|
autoComplete: "off",
|
|
4274
|
-
"aria-invalid":
|
|
4274
|
+
"aria-invalid": refusal4 ? true : void 0,
|
|
4275
4275
|
placeholder: helper === "time" ? "2:30 PM" : helper === "datetime" ? `${typedDateText2("2026-10-03")} 2:30 PM` : helper ? typedDateText2("2026-10-03") : void 0,
|
|
4276
4276
|
onChange: (e) => retype(e.target.value),
|
|
4277
4277
|
onBlur: () => {
|
|
4278
|
-
if (!
|
|
4278
|
+
if (!refusal4) return;
|
|
4279
4279
|
setText(openingText(field2, sent.current));
|
|
4280
4280
|
setRefusal(null);
|
|
4281
4281
|
}
|
|
@@ -4283,7 +4283,7 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
|
|
|
4283
4283
|
),
|
|
4284
4284
|
helper && !disabled ? /* @__PURE__ */ jsx17(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field2) }) : null
|
|
4285
4285
|
] }),
|
|
4286
|
-
|
|
4286
|
+
refusal4 ? /* @__PURE__ */ jsx17("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal4 }) : null
|
|
4287
4287
|
] });
|
|
4288
4288
|
}
|
|
4289
4289
|
function CheckboxControl({ field: field2, value, onChange, disabled, id }) {
|
|
@@ -4380,7 +4380,7 @@ function inTheStoresOrder(options) {
|
|
|
4380
4380
|
function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, addsChoices, initialSearch, asForm }) {
|
|
4381
4381
|
const client = useOptionalRecordsClient6();
|
|
4382
4382
|
const [options, setOptions] = useState15(null);
|
|
4383
|
-
const [
|
|
4383
|
+
const [refusal4, setRefusal] = useState15(null);
|
|
4384
4384
|
const [reread, setReread] = useState15(0);
|
|
4385
4385
|
useEffect10(() => {
|
|
4386
4386
|
if (!client) return;
|
|
@@ -4412,8 +4412,8 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
|
|
|
4412
4412
|
/* @__PURE__ */ jsx17("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." })
|
|
4413
4413
|
] });
|
|
4414
4414
|
}
|
|
4415
|
-
if (
|
|
4416
|
-
return /* @__PURE__ */ jsx17("div", { id, children: /* @__PURE__ */ jsx17(RefusalLine, { error:
|
|
4415
|
+
if (refusal4)
|
|
4416
|
+
return /* @__PURE__ */ jsx17("div", { id, children: /* @__PURE__ */ jsx17(RefusalLine, { error: refusal4 }) });
|
|
4417
4417
|
if (!options) return /* @__PURE__ */ jsx17("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
|
|
4418
4418
|
if (asForm && options.length > 0) {
|
|
4419
4419
|
const titled = (option) => recordName(option.data, null, "Unnamed choice");
|
|
@@ -6031,7 +6031,7 @@ function RetiredValues({
|
|
|
6031
6031
|
}) {
|
|
6032
6032
|
const client = useRecordsClient5();
|
|
6033
6033
|
const [busy, setBusy] = useState20(null);
|
|
6034
|
-
const [
|
|
6034
|
+
const [refusal4, setRefusal] = useState20(null);
|
|
6035
6035
|
const [said, setSaid] = useState20(null);
|
|
6036
6036
|
const [missing, setMissing] = useState20(null);
|
|
6037
6037
|
const kept = retiredValuesOf(document2);
|
|
@@ -6080,7 +6080,7 @@ function RetiredValues({
|
|
|
6080
6080
|
mayWrite ? /* @__PURE__ */ jsx24(Button10, { size: "sm", variant: "outline", className: "h-6 px-2 text-xs", disabled: busy !== null, onClick: () => void restore(entry, index), "data-records-retired-restore": "", children: busy === id ? "Restoring\u2026" : "Restore" }) : null
|
|
6081
6081
|
] }),
|
|
6082
6082
|
entry.reason ? /* @__PURE__ */ jsx24("p", { className: "text-[11px] text-muted-foreground", children: entry.reason }) : null,
|
|
6083
|
-
|
|
6083
|
+
refusal4?.key === id ? /* @__PURE__ */ jsx24(RefusalNotice, { error: refusal4.error }) : null,
|
|
6084
6084
|
missing === id ? /* @__PURE__ */ jsxs20("p", { className: "text-[11px] text-muted-foreground", children: [
|
|
6085
6085
|
"No earlier version of ",
|
|
6086
6086
|
name,
|
|
@@ -7025,7 +7025,7 @@ function GridCell({
|
|
|
7025
7025
|
};
|
|
7026
7026
|
const value = editing ? editing.valueFor(row, field2) : row.document?.[field2.key];
|
|
7027
7027
|
const state = editing ? editing.stateOf(row.id, field2.key) : null;
|
|
7028
|
-
const
|
|
7028
|
+
const refusal4 = editing ? editing.refusalOf(row.id, field2.key) : null;
|
|
7029
7029
|
const editable = Boolean(editing) && canWrite && fieldIsEditable(field2);
|
|
7030
7030
|
if (open && editing) {
|
|
7031
7031
|
return /* @__PURE__ */ jsx27(
|
|
@@ -7043,10 +7043,10 @@ function GridCell({
|
|
|
7043
7043
|
// state they are in, so only Discard is offered. It is INSIDE the open
|
|
7044
7044
|
// cell, so pressing Discard is not "focus left the cell" — which would
|
|
7045
7045
|
// commit the refused value one more time on its way out.
|
|
7046
|
-
|
|
7046
|
+
refusal4 && !refusal4.conflict ? /* @__PURE__ */ jsx27(
|
|
7047
7047
|
RefusalNotice,
|
|
7048
7048
|
{
|
|
7049
|
-
error:
|
|
7049
|
+
error: refusal4.error,
|
|
7050
7050
|
className: "py-1.5 text-left",
|
|
7051
7051
|
onDiscard: () => editing.discard(row.id, field2.key)
|
|
7052
7052
|
}
|
|
@@ -7070,14 +7070,14 @@ function GridCell({
|
|
|
7070
7070
|
}
|
|
7071
7071
|
),
|
|
7072
7072
|
answered ? null : /* @__PURE__ */ jsx27("span", { className: "text-xs text-muted-foreground", title: "nobody has answered this yet", children: "\u2014" }),
|
|
7073
|
-
|
|
7073
|
+
refusal4 ? /* @__PURE__ */ jsx27(CellRefusalNotice, { refusal: refusal4, field: field2, row, editing, typed: false }) : null
|
|
7074
7074
|
] });
|
|
7075
7075
|
}
|
|
7076
7076
|
if (editable && format?.id === "rating") {
|
|
7077
7077
|
return /* @__PURE__ */ jsxs22("span", { "data-matrx-cell-control": "", className: "flex w-full flex-wrap items-center gap-1.5", children: [
|
|
7078
7078
|
/* @__PURE__ */ jsx27(FormattedValue, { value, format, onRate: (next) => editing?.setCell(row.id, field2.key, next), selectFirst: true }),
|
|
7079
7079
|
state === "saving" ? /* @__PURE__ */ jsx27("span", { className: "text-[10px] text-muted-foreground", children: "Saving\u2026" }) : null,
|
|
7080
|
-
|
|
7080
|
+
refusal4 ? /* @__PURE__ */ jsx27(CellRefusalNotice, { refusal: refusal4, field: field2, row, editing, typed: false }) : null
|
|
7081
7081
|
] });
|
|
7082
7082
|
}
|
|
7083
7083
|
const openThisCell = (event) => {
|
|
@@ -7190,30 +7190,30 @@ function GridCell({
|
|
|
7190
7190
|
) : null
|
|
7191
7191
|
] }),
|
|
7192
7192
|
state === "saving" ? /* @__PURE__ */ jsx27("span", { className: "px-1 text-[10px] text-muted-foreground", children: "Saving\u2026" }) : null,
|
|
7193
|
-
|
|
7193
|
+
refusal4 ? /* @__PURE__ */ jsx27(CellRefusalNotice, { refusal: refusal4, field: field2, row, editing, typed: true }) : null
|
|
7194
7194
|
]
|
|
7195
7195
|
}
|
|
7196
7196
|
)
|
|
7197
7197
|
);
|
|
7198
7198
|
}
|
|
7199
7199
|
function CellRefusalNotice({
|
|
7200
|
-
refusal:
|
|
7200
|
+
refusal: refusal4,
|
|
7201
7201
|
field: field2,
|
|
7202
7202
|
row,
|
|
7203
7203
|
editing,
|
|
7204
7204
|
typed: typed2
|
|
7205
7205
|
}) {
|
|
7206
7206
|
const [open, setOpen] = useState21(true);
|
|
7207
|
-
const line = refusalLineForAPerson(
|
|
7208
|
-
const notice =
|
|
7207
|
+
const line = refusalLineForAPerson(refusal4.error);
|
|
7208
|
+
const notice = refusal4.conflict ? /* @__PURE__ */ jsx27(
|
|
7209
7209
|
RefusalNotice,
|
|
7210
7210
|
{
|
|
7211
|
-
error:
|
|
7211
|
+
error: refusal4.error,
|
|
7212
7212
|
className: "py-1.5 text-left",
|
|
7213
7213
|
actions: /* @__PURE__ */ jsxs22("span", { className: "flex flex-col gap-1", "data-refusal-conflict": "", children: [
|
|
7214
7214
|
/* @__PURE__ */ jsxs22("span", { className: "text-[11px]", children: [
|
|
7215
7215
|
"Theirs: ",
|
|
7216
|
-
/* @__PURE__ */ jsx27("strong", { children: formatTheirs(
|
|
7216
|
+
/* @__PURE__ */ jsx27("strong", { children: formatTheirs(refusal4.conflict, field2.key) })
|
|
7217
7217
|
] }),
|
|
7218
7218
|
/* @__PURE__ */ jsxs22("span", { className: "flex flex-wrap gap-1", children: [
|
|
7219
7219
|
/* @__PURE__ */ jsx27(Button11, { size: "sm", variant: "outline", onClick: () => editing?.retry(row.id, field2.key), children: "Try again" }),
|
|
@@ -7224,7 +7224,7 @@ function CellRefusalNotice({
|
|
|
7224
7224
|
) : /* @__PURE__ */ jsx27(
|
|
7225
7225
|
RefusalNotice,
|
|
7226
7226
|
{
|
|
7227
|
-
error:
|
|
7227
|
+
error: refusal4.error,
|
|
7228
7228
|
className: "py-1.5 text-left",
|
|
7229
7229
|
...typed2 ? { onKeepEditing: () => editing?.keepEditing(row.id, field2.key) } : {},
|
|
7230
7230
|
onDiscard: () => editing?.discard(row.id, field2.key)
|
|
@@ -8571,7 +8571,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
|
|
|
8571
8571
|
const [to, setTo] = useState28(null);
|
|
8572
8572
|
const [preview, setPreview] = useState28(null);
|
|
8573
8573
|
const [asking, setAsking] = useState28(false);
|
|
8574
|
-
const [
|
|
8574
|
+
const [refusal4, setRefusal] = useState28(null);
|
|
8575
8575
|
const [busy, setBusy] = useState28(false);
|
|
8576
8576
|
const [said, setSaid] = useState28(null);
|
|
8577
8577
|
const name = fieldName(field2);
|
|
@@ -8669,7 +8669,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
|
|
|
8669
8669
|
preview.keptAside > 0 ? `; ${preview.keptAside} ${preview.keptAside === 1 ? "value does" : "values do"} not fit and will be kept aside with ${preview.keptAside === 1 ? "its record" : "their records"}, with the reason \u2014 nothing is deleted` + (preview.examples.length > 0 ? ` (for example ${preview.examples.map((e) => `\u201C${e}\u201D`).join(", ")})` : "") : "",
|
|
8670
8670
|
preview.partial ? ". Counted over the first 1,000 different values." : "."
|
|
8671
8671
|
] }) : null,
|
|
8672
|
-
|
|
8672
|
+
refusal4 ? /* @__PURE__ */ jsx33(RefusalNotice, { error: refusal4 }) : null,
|
|
8673
8673
|
said ? /* @__PURE__ */ jsx33("p", { role: "status", className: "text-[11px] text-muted-foreground", "data-records-retype-done": "", children: said }) : null
|
|
8674
8674
|
] });
|
|
8675
8675
|
}
|
|
@@ -8697,7 +8697,7 @@ function groupValue(value, numbers) {
|
|
|
8697
8697
|
function FieldRulePreview({ field: field2, tableId, rules }) {
|
|
8698
8698
|
const client = useRecordsClient12();
|
|
8699
8699
|
const [preview, setPreview] = useState29(null);
|
|
8700
|
-
const [
|
|
8700
|
+
const [refusal4, setRefusal] = useState29(null);
|
|
8701
8701
|
const key = useMemo13(() => ruleWords(rules), [rules]);
|
|
8702
8702
|
const latest = useRef16(rules);
|
|
8703
8703
|
latest.current = rules;
|
|
@@ -8723,7 +8723,7 @@ function FieldRulePreview({ field: field2, tableId, rules }) {
|
|
|
8723
8723
|
clearTimeout(timer);
|
|
8724
8724
|
};
|
|
8725
8725
|
}, [client, tableId, field2.key, key]);
|
|
8726
|
-
if (
|
|
8726
|
+
if (refusal4) return /* @__PURE__ */ jsx34(RefusalNotice, { error: refusal4 });
|
|
8727
8727
|
if (!preview) {
|
|
8728
8728
|
return /* @__PURE__ */ jsxs29("p", { className: "text-[11px] text-muted-foreground", "data-records-rule-preview": "counting", children: [
|
|
8729
8729
|
"Counting ",
|
|
@@ -11105,7 +11105,7 @@ function MergeRecordDialog({ tableId, record, open, onOpenChange, onMerged }) {
|
|
|
11105
11105
|
const records = useRecords3(tableId, { pageSize: 200 });
|
|
11106
11106
|
const [other, setOther] = useState32(null);
|
|
11107
11107
|
const [busy, setBusy] = useState32(false);
|
|
11108
|
-
const [
|
|
11108
|
+
const [refusal4, setRefusal] = useState32(null);
|
|
11109
11109
|
const options = useMemo15(
|
|
11110
11110
|
() => (records.data?.rows ?? []).filter((row) => row.id !== record.id).map((row) => ({ value: row.id, label: rowNameIn(table.data ?? null, row) })),
|
|
11111
11111
|
[records.data, record.id, table.data]
|
|
@@ -11175,7 +11175,7 @@ function MergeRecordDialog({ tableId, record, open, onOpenChange, onMerged }) {
|
|
|
11175
11175
|
ariaLabel: "Record to merge"
|
|
11176
11176
|
}
|
|
11177
11177
|
),
|
|
11178
|
-
|
|
11178
|
+
refusal4 ? /* @__PURE__ */ jsx39(RefusalNotice, { error: refusal4 }) : null,
|
|
11179
11179
|
/* @__PURE__ */ jsxs34(DialogFooter, { children: [
|
|
11180
11180
|
/* @__PURE__ */ jsx39(Button19, { variant: "ghost", size: "sm", onClick: () => close(false), disabled: busy, children: "Cancel" }),
|
|
11181
11181
|
/* @__PURE__ */ jsx39(Button19, { size: "sm", onClick: () => void merge(), disabled: !other || busy, "data-records-merge-go": "", children: busy ? "Merging\u2026" : "Merge" })
|
|
@@ -11359,7 +11359,7 @@ function useGridColours(args) {
|
|
|
11359
11359
|
[client, tableId, decorations, notify]
|
|
11360
11360
|
);
|
|
11361
11361
|
const idOf = useCallback12((key) => fields.find((f) => f.key === key), [fields]);
|
|
11362
|
-
const
|
|
11362
|
+
const refusal4 = mayColour ? void 0 : whyNot;
|
|
11363
11363
|
const headerItem = useCallback12(
|
|
11364
11364
|
(columnKey) => {
|
|
11365
11365
|
if (!enabled) return null;
|
|
@@ -11374,7 +11374,7 @@ function useGridColours(args) {
|
|
|
11374
11374
|
id: "col-colour",
|
|
11375
11375
|
label: "Colour by\u2026",
|
|
11376
11376
|
icon: "palette",
|
|
11377
|
-
disabledReason:
|
|
11377
|
+
disabledReason: refusal4,
|
|
11378
11378
|
submenu: [
|
|
11379
11379
|
byThis ? {
|
|
11380
11380
|
id: "col-colour-off",
|
|
@@ -11410,7 +11410,7 @@ function useGridColours(args) {
|
|
|
11410
11410
|
]
|
|
11411
11411
|
};
|
|
11412
11412
|
},
|
|
11413
|
-
[enabled, idOf, decorations.data,
|
|
11413
|
+
[enabled, idOf, decorations.data, refusal4, write]
|
|
11414
11414
|
);
|
|
11415
11415
|
const cellItem = useCallback12(
|
|
11416
11416
|
(rowId, columnKey) => {
|
|
@@ -11422,7 +11422,7 @@ function useGridColours(args) {
|
|
|
11422
11422
|
id: "cell-highlight",
|
|
11423
11423
|
label: "Highlight cell",
|
|
11424
11424
|
icon: "palette",
|
|
11425
|
-
disabledReason:
|
|
11425
|
+
disabledReason: refusal4,
|
|
11426
11426
|
submenu: swatches(
|
|
11427
11427
|
"cell-highlight",
|
|
11428
11428
|
current,
|
|
@@ -11430,7 +11430,7 @@ function useGridColours(args) {
|
|
|
11430
11430
|
)
|
|
11431
11431
|
};
|
|
11432
11432
|
},
|
|
11433
|
-
[enabled, idOf, decorations.data,
|
|
11433
|
+
[enabled, idOf, decorations.data, refusal4, write]
|
|
11434
11434
|
);
|
|
11435
11435
|
const cellsItem = useCallback12(
|
|
11436
11436
|
(cells) => {
|
|
@@ -11440,7 +11440,7 @@ function useGridColours(args) {
|
|
|
11440
11440
|
id: "sel-highlight",
|
|
11441
11441
|
label: `Highlight ${n} cells`,
|
|
11442
11442
|
icon: "palette",
|
|
11443
|
-
disabledReason:
|
|
11443
|
+
disabledReason: refusal4,
|
|
11444
11444
|
submenu: swatches("sel-highlight", void 0, (color) => {
|
|
11445
11445
|
void (async () => {
|
|
11446
11446
|
let kept = 0;
|
|
@@ -11460,7 +11460,7 @@ function useGridColours(args) {
|
|
|
11460
11460
|
})
|
|
11461
11461
|
};
|
|
11462
11462
|
},
|
|
11463
|
-
[enabled, idOf,
|
|
11463
|
+
[enabled, idOf, refusal4, client, tableId, decorations, notify]
|
|
11464
11464
|
);
|
|
11465
11465
|
const rowItem = useCallback12(
|
|
11466
11466
|
(rowId) => {
|
|
@@ -11470,7 +11470,7 @@ function useGridColours(args) {
|
|
|
11470
11470
|
id: "row-highlight",
|
|
11471
11471
|
label: "Highlight row",
|
|
11472
11472
|
icon: "palette",
|
|
11473
|
-
disabledReason:
|
|
11473
|
+
disabledReason: refusal4,
|
|
11474
11474
|
submenu: swatches(
|
|
11475
11475
|
"row-highlight",
|
|
11476
11476
|
current,
|
|
@@ -11478,7 +11478,7 @@ function useGridColours(args) {
|
|
|
11478
11478
|
)
|
|
11479
11479
|
};
|
|
11480
11480
|
},
|
|
11481
|
-
[enabled, decorations.data,
|
|
11481
|
+
[enabled, decorations.data, refusal4, write]
|
|
11482
11482
|
);
|
|
11483
11483
|
const dialogs = enabled ? /* @__PURE__ */ jsx40(
|
|
11484
11484
|
ColourRulesDialog,
|
|
@@ -12483,19 +12483,19 @@ function planPastedBlock(args) {
|
|
|
12483
12483
|
accepted[key] = judged.value;
|
|
12484
12484
|
}
|
|
12485
12485
|
const predicted = predictValueRefusals(args.fields, accepted);
|
|
12486
|
-
for (const
|
|
12487
|
-
const key =
|
|
12486
|
+
for (const refusal4 of predicted) {
|
|
12487
|
+
const key = refusal4.field_key;
|
|
12488
12488
|
if (key === void 0) continue;
|
|
12489
12489
|
const cell = built.find((b) => b.key === key && b.refusal === null);
|
|
12490
12490
|
if (!cell) continue;
|
|
12491
|
-
cell.refusal =
|
|
12491
|
+
cell.refusal = refusal4.message;
|
|
12492
12492
|
cell.value = null;
|
|
12493
12493
|
delete accepted[key];
|
|
12494
12494
|
refusals.push({
|
|
12495
12495
|
fromLine,
|
|
12496
12496
|
column: fieldName(byKey.get(key) ?? { key }),
|
|
12497
12497
|
raw: cell.raw,
|
|
12498
|
-
why:
|
|
12498
|
+
why: refusal4.message
|
|
12499
12499
|
});
|
|
12500
12500
|
}
|
|
12501
12501
|
cells += Object.keys(accepted).length;
|
|
@@ -15736,10 +15736,10 @@ function PastePreview({
|
|
|
15736
15736
|
/* @__PURE__ */ jsx54(PlanTable, { plan }),
|
|
15737
15737
|
plan.refusals.length > 0 ? /* @__PURE__ */ jsxs49("div", { "data-matrx-paste-refusals": true, className: "flex flex-col gap-1", children: [
|
|
15738
15738
|
/* @__PURE__ */ jsx54("p", { className: "text-xs font-medium", children: plan.refusals.length === 1 ? "One cell will be left alone:" : `${plan.refusals.length} cells will be left alone:` }),
|
|
15739
|
-
/* @__PURE__ */ jsx54("ul", { className: "flex flex-col gap-1", children: plan.refusals.slice(0, 12).map((
|
|
15740
|
-
/* @__PURE__ */ jsx54("span", { className: "font-medium", children:
|
|
15739
|
+
/* @__PURE__ */ jsx54("ul", { className: "flex flex-col gap-1", children: plan.refusals.slice(0, 12).map((refusal4, index) => /* @__PURE__ */ jsxs49("li", { className: "text-xs text-muted-foreground", children: [
|
|
15740
|
+
/* @__PURE__ */ jsx54("span", { className: "font-medium", children: refusal4.fromLine > 0 ? `Row ${refusal4.fromLine}, ${refusal4.column}` : refusal4.column }),
|
|
15741
15741
|
" \u2014 ",
|
|
15742
|
-
|
|
15742
|
+
refusal4.why
|
|
15743
15743
|
] }, index)) }),
|
|
15744
15744
|
plan.refusals.length > 12 ? /* @__PURE__ */ jsxs49("p", { className: "text-xs text-muted-foreground", children: [
|
|
15745
15745
|
plan.refusals.length - 12,
|
|
@@ -19683,35 +19683,35 @@ function useGridUndo(args) {
|
|
|
19683
19683
|
if (!step2) return;
|
|
19684
19684
|
setBusy(true);
|
|
19685
19685
|
const changes = changesFor(step2, direction, known.current);
|
|
19686
|
-
let
|
|
19686
|
+
let refusal4 = null;
|
|
19687
19687
|
if (direction === "redo" && (step2.created?.length ?? 0) > 0) {
|
|
19688
19688
|
const answers = await Promise.all((step2.created ?? []).map((id) => client.recordRestore({ record_id: id })));
|
|
19689
19689
|
const failed = answers.find((a) => !a.ok);
|
|
19690
|
-
if (failed && !failed.ok)
|
|
19690
|
+
if (failed && !failed.ok) refusal4 = failed.error;
|
|
19691
19691
|
}
|
|
19692
|
-
if (!
|
|
19692
|
+
if (!refusal4 && step2.retiredField) {
|
|
19693
19693
|
const fieldId = step2.retiredField.fieldId;
|
|
19694
19694
|
const done = direction === "undo" ? await client.fieldRestore({ field_id: fieldId }) : await client.fieldRetire({ field_id: fieldId });
|
|
19695
|
-
if (!done.ok)
|
|
19695
|
+
if (!done.ok) refusal4 = done.error;
|
|
19696
19696
|
else tableShapeChanged5(tableId);
|
|
19697
19697
|
}
|
|
19698
|
-
if (!
|
|
19698
|
+
if (!refusal4 && changes.length > 0) {
|
|
19699
19699
|
const done = await changeRecordsAt(client, { table_id: tableId, changes });
|
|
19700
|
-
if (!done.ok)
|
|
19700
|
+
if (!done.ok) refusal4 = done.error;
|
|
19701
19701
|
else {
|
|
19702
19702
|
for (const result of done.data ?? []) if (result.op === "update") known.current.set(result.id, result.version);
|
|
19703
19703
|
onVersions?.((done.data ?? []).flatMap((r) => r.op === "update" ? [{ id: r.id, version: r.version }] : []));
|
|
19704
19704
|
}
|
|
19705
19705
|
}
|
|
19706
|
-
if (!
|
|
19706
|
+
if (!refusal4 && direction === "undo" && (step2.archived?.length ?? 0) > 0) {
|
|
19707
19707
|
const answers = await Promise.all((step2.archived ?? []).map((id) => client.recordRestore({ record_id: id })));
|
|
19708
19708
|
const failed = answers.find((a) => !a.ok);
|
|
19709
|
-
if (failed && !failed.ok)
|
|
19709
|
+
if (failed && !failed.ok) refusal4 = failed.error;
|
|
19710
19710
|
}
|
|
19711
19711
|
setBusy(false);
|
|
19712
|
-
if (
|
|
19713
|
-
setNotice({ says: `${direction === "undo" ? "Undo" : "Redo"} changed nothing: ${refusalSentence(
|
|
19714
|
-
if (isChangedElsewhere(
|
|
19712
|
+
if (refusal4) {
|
|
19713
|
+
setNotice({ says: `${direction === "undo" ? "Undo" : "Redo"} changed nothing: ${refusalSentence(refusal4)}`, refusal: refusal4, canUndo: false });
|
|
19714
|
+
if (isChangedElsewhere(refusal4)) reload();
|
|
19715
19715
|
return;
|
|
19716
19716
|
}
|
|
19717
19717
|
forget(step2.cells.map((c) => ({ rowId: c.rowId, key: c.key })));
|
|
@@ -19862,7 +19862,7 @@ function undoKey(event) {
|
|
|
19862
19862
|
// src/gridAssist.tsx
|
|
19863
19863
|
import { useCallback as useCallback23, useEffect as useEffect45, useMemo as useMemo32, useRef as useRef27, useState as useState56 } from "react";
|
|
19864
19864
|
import { tableKindSlug, wholeValueOf as wholeValueOf4 } from "@ai-matrx/records/core";
|
|
19865
|
-
import { useContentTransferCapabilities } from "@ai-matrx/
|
|
19865
|
+
import { useContentTransferCapabilities } from "@ai-matrx/alchemy/react/workspace";
|
|
19866
19866
|
|
|
19867
19867
|
// src/gridAgentContext.ts
|
|
19868
19868
|
function recordOf(table, row) {
|
|
@@ -20202,7 +20202,7 @@ function useGridBulk(args) {
|
|
|
20202
20202
|
const client = useRecordsClient35();
|
|
20203
20203
|
const { tableId, rows, fields, noun, nounPlural, reload, forget, pushUndo: pushUndo2, versions } = args;
|
|
20204
20204
|
const [busy, setBusy] = useState57(false);
|
|
20205
|
-
const [
|
|
20205
|
+
const [refusal4, setRefusal] = useState57(null);
|
|
20206
20206
|
const send = useCallback24(
|
|
20207
20207
|
async (changes) => {
|
|
20208
20208
|
setBusy(true);
|
|
@@ -20266,7 +20266,7 @@ function useGridBulk(args) {
|
|
|
20266
20266
|
},
|
|
20267
20267
|
[send, rows, pushUndo2, reload, noun, nounPlural]
|
|
20268
20268
|
);
|
|
20269
|
-
return { busy, refusal:
|
|
20269
|
+
return { busy, refusal: refusal4, clearRefusal: () => setRefusal(null), apply, duplicate, archive };
|
|
20270
20270
|
}
|
|
20271
20271
|
function BulkActions({
|
|
20272
20272
|
ids,
|
|
@@ -23163,17 +23163,749 @@ import { Button as Button43 } from "@ai-matrx/design-system";
|
|
|
23163
23163
|
import { useFields as useFields9, useOptionalRecordsClient as useOptionalRecordsClient9, useTable as useTable7 } from "@ai-matrx/records/react";
|
|
23164
23164
|
|
|
23165
23165
|
// src/entityTable.tsx
|
|
23166
|
-
import { useId as useId2, useMemo as
|
|
23166
|
+
import { useId as useId2, useMemo as useMemo37 } from "react";
|
|
23167
23167
|
import { MatrxDataTable as MatrxDataTable2 } from "@ai-matrx/design-system/data-table";
|
|
23168
23168
|
import { useRecordsClient as useRecordsClient38 } from "@ai-matrx/records/react";
|
|
23169
|
+
|
|
23170
|
+
// ../entity-data/src/react/index.tsx
|
|
23171
|
+
import { createContext as createContext7, createElement, useContext as useContext7, useMemo as useMemo36, useRef as useRef30 } from "react";
|
|
23172
|
+
import { useQuery } from "@tanstack/react-query";
|
|
23169
23173
|
import {
|
|
23170
|
-
|
|
23171
|
-
|
|
23172
|
-
|
|
23173
|
-
|
|
23174
|
-
|
|
23175
|
-
|
|
23176
|
-
|
|
23174
|
+
dataKeys,
|
|
23175
|
+
hostEvents,
|
|
23176
|
+
useRecordsQueryClient,
|
|
23177
|
+
useDataColumns,
|
|
23178
|
+
useDataMutations,
|
|
23179
|
+
useDataRow,
|
|
23180
|
+
useDataRows
|
|
23181
|
+
} from "@ai-matrx/records/data/react";
|
|
23182
|
+
|
|
23183
|
+
// ../entity-data/src/core/client.ts
|
|
23184
|
+
import { asRecordsDataSource } from "@ai-matrx/records/core";
|
|
23185
|
+
|
|
23186
|
+
// ../entity-data/src/core/errors.ts
|
|
23187
|
+
import { mapPgError as mapPgError2 } from "@ai-matrx/records/core";
|
|
23188
|
+
var ENTITY_REFUSALS = {
|
|
23189
|
+
/** conflict_version: somebody else's write won. */
|
|
23190
|
+
MX001: "stale_write",
|
|
23191
|
+
/** organization_required: the call needs an organization and carried none. */
|
|
23192
|
+
MX002: "organization_required",
|
|
23193
|
+
/** forbidden. */
|
|
23194
|
+
MX003: "door",
|
|
23195
|
+
/** not_found (also: not visible to this person). */
|
|
23196
|
+
MX004: "not_found",
|
|
23197
|
+
/** validation_refused (detail.reason required / bad_value / ambiguous_word / constraint; `not_supported` is read apart below). */
|
|
23198
|
+
MX005: "invalid_argument",
|
|
23199
|
+
/** system_column: a write named a column the store owns. */
|
|
23200
|
+
MX008: "invalid_argument",
|
|
23201
|
+
/** unknown_identifier: a column that is not there or not usable here. */
|
|
23202
|
+
MX012: "invalid_argument",
|
|
23203
|
+
/** cursor_invalid: the page cursor belongs to another list; the engine restarts the page. */
|
|
23204
|
+
MX013: "invalid_argument",
|
|
23205
|
+
/** view_not_offered. */
|
|
23206
|
+
MX015: "invalid_argument",
|
|
23207
|
+
/** invalid_argument: a parameter the door refuses by name. */
|
|
23208
|
+
MX016: "invalid_argument"
|
|
23209
|
+
};
|
|
23210
|
+
function mapEntityError(error, where) {
|
|
23211
|
+
const mapped = mapPgError2(error, where);
|
|
23212
|
+
const state = mapped.sqlstate;
|
|
23213
|
+
if (state && /^MX\d{3}$/.test(state)) {
|
|
23214
|
+
const code = ENTITY_REFUSALS[state];
|
|
23215
|
+
if (code) {
|
|
23216
|
+
const reason = mapped.detail?.reason;
|
|
23217
|
+
const known = { ...mapped, code: state === "MX005" && reason === "not_supported" ? "not_supported" : code };
|
|
23218
|
+
delete known.unmapped;
|
|
23219
|
+
delete known.diagnostic;
|
|
23220
|
+
return known;
|
|
23221
|
+
}
|
|
23222
|
+
}
|
|
23223
|
+
return mapped;
|
|
23224
|
+
}
|
|
23225
|
+
function refusal2(code, message, hint) {
|
|
23226
|
+
return { ok: false, error: { code, message, ...hint ? { hint } : {} } };
|
|
23227
|
+
}
|
|
23228
|
+
|
|
23229
|
+
// ../entity-data/src/core/client.ts
|
|
23230
|
+
var OP_ID_HEADER = "x-matrx-op-id";
|
|
23231
|
+
var ENTITY_DOOR_SCHEMA = "platform";
|
|
23232
|
+
function createEntityClient(options) {
|
|
23233
|
+
const source = asRecordsDataSource(options.dataSource ?? options.supabase);
|
|
23234
|
+
let warnedHeaderless = false;
|
|
23235
|
+
function withHeaders(pending, headers) {
|
|
23236
|
+
if (!headers) return;
|
|
23237
|
+
const builder = pending;
|
|
23238
|
+
if (typeof builder.setHeader === "function") {
|
|
23239
|
+
for (const [name, value] of Object.entries(headers)) builder.setHeader(name, value);
|
|
23240
|
+
return;
|
|
23241
|
+
}
|
|
23242
|
+
if (!warnedHeaderless) {
|
|
23243
|
+
warnedHeaderless = true;
|
|
23244
|
+
console.warn(
|
|
23245
|
+
`[@ai-matrx/entity-data] This data source cannot carry a per-call header (${Object.keys(headers).join(", ")}), so this browser re-reads the notice of its own writes once.`
|
|
23246
|
+
);
|
|
23247
|
+
}
|
|
23248
|
+
}
|
|
23249
|
+
async function call(fn, args, schema = ENTITY_DOOR_SCHEMA, headers) {
|
|
23250
|
+
try {
|
|
23251
|
+
const pending = source.rpc(fn, args, { schema });
|
|
23252
|
+
withHeaders(pending, headers);
|
|
23253
|
+
const answer = await pending;
|
|
23254
|
+
if (answer.error) return { ok: false, error: mapEntityError(answer.error, `${schema}.${fn}`) };
|
|
23255
|
+
return { ok: true, data: answer.data };
|
|
23256
|
+
} catch (thrown) {
|
|
23257
|
+
return {
|
|
23258
|
+
ok: false,
|
|
23259
|
+
error: mapEntityError({ code: "", message: thrown instanceof Error ? thrown.message : String(thrown) }, `${schema}.${fn}`)
|
|
23260
|
+
};
|
|
23261
|
+
}
|
|
23262
|
+
}
|
|
23263
|
+
return {
|
|
23264
|
+
list(request) {
|
|
23265
|
+
const args = {
|
|
23266
|
+
p_entity_type: request.token,
|
|
23267
|
+
p_scope: request.scope ?? null,
|
|
23268
|
+
p_filter: request.filter ?? {},
|
|
23269
|
+
p_search: request.search ?? null,
|
|
23270
|
+
p_sort: request.sort ?? null,
|
|
23271
|
+
p_archived: request.archived ?? "active",
|
|
23272
|
+
p_page_size: request.pageSize ?? null,
|
|
23273
|
+
p_after: request.after ?? null,
|
|
23274
|
+
p_with_total: request.withTotal ?? true
|
|
23275
|
+
};
|
|
23276
|
+
return call("entity_list_scoped", args);
|
|
23277
|
+
},
|
|
23278
|
+
get(request) {
|
|
23279
|
+
return call("entity_get", { p_entity_type: request.token, p_ids: [...request.ids] });
|
|
23280
|
+
},
|
|
23281
|
+
columns(request) {
|
|
23282
|
+
return call("entity_columns", { p_organization_id: request.organizationId ?? null, p_token: request.token });
|
|
23283
|
+
},
|
|
23284
|
+
insert(request) {
|
|
23285
|
+
return call(
|
|
23286
|
+
"entity_insert",
|
|
23287
|
+
{ p_entity_type: request.token, p_organization_id: request.organizationId, p_rows: request.rows.map((r) => ({ ...r })) },
|
|
23288
|
+
ENTITY_DOOR_SCHEMA,
|
|
23289
|
+
opHeader(request.opId)
|
|
23290
|
+
);
|
|
23291
|
+
},
|
|
23292
|
+
update(request) {
|
|
23293
|
+
return call(
|
|
23294
|
+
"entity_update",
|
|
23295
|
+
{ p_entity_type: request.token, p_id: request.id, p_base_version: request.baseVersion, p_patch: request.patch },
|
|
23296
|
+
ENTITY_DOOR_SCHEMA,
|
|
23297
|
+
opHeader(request.opId)
|
|
23298
|
+
);
|
|
23299
|
+
},
|
|
23300
|
+
archive(request) {
|
|
23301
|
+
return call("entity_archive", { p_entity_type: request.token, p_ids: [...request.ids] }, ENTITY_DOOR_SCHEMA, opHeader(request.opId));
|
|
23302
|
+
},
|
|
23303
|
+
unarchive(request) {
|
|
23304
|
+
return call("entity_unarchive", { p_entity_type: request.token, p_ids: [...request.ids] }, ENTITY_DOOR_SCHEMA, opHeader(request.opId));
|
|
23305
|
+
},
|
|
23306
|
+
knob(request) {
|
|
23307
|
+
return call("knob_resolve", { p_feature: "entity_data", p_key: request.key, p_organization_id: request.organizationId ?? null });
|
|
23308
|
+
},
|
|
23309
|
+
async memberOrganizations() {
|
|
23310
|
+
const answer = await call("my_orgs", {}, "iam");
|
|
23311
|
+
if (!answer.ok) return answer;
|
|
23312
|
+
const rows = Array.isArray(answer.data) ? answer.data : [];
|
|
23313
|
+
const ids = rows.map((row) => typeof row === "string" ? row : row && typeof row === "object" ? Object.values(row)[0] : null).filter((id) => typeof id === "string");
|
|
23314
|
+
return { ok: true, data: ids };
|
|
23315
|
+
}
|
|
23316
|
+
};
|
|
23317
|
+
}
|
|
23318
|
+
function opHeader(opId) {
|
|
23319
|
+
return opId ? { [OP_ID_HEADER]: opId } : void 0;
|
|
23320
|
+
}
|
|
23321
|
+
|
|
23322
|
+
// ../entity-data/src/core/realtime.ts
|
|
23323
|
+
import {
|
|
23324
|
+
defineChannelNamespace,
|
|
23325
|
+
subscribeToRealtimeManager
|
|
23326
|
+
} from "@ai-matrx/realtime";
|
|
23327
|
+
import { isOwnOp } from "@ai-matrx/records";
|
|
23328
|
+
var entityOrgChannel = defineChannelNamespace({
|
|
23329
|
+
namespace: "entity-org",
|
|
23330
|
+
foreignTopic: "mx:entity-org",
|
|
23331
|
+
parts: ["organizationId", "token"],
|
|
23332
|
+
description: "One organization's changes to one platform type (contacts, deals, projects, tasks, employees). Carries NOTICES written by platform.entity_org_notice_stmt \u2014 which ids moved, never a value. Admitted by the one RLS policy on realtime.messages to members of that organization."
|
|
23333
|
+
});
|
|
23334
|
+
var ENTITY_NOTICE_EVENT = "entity_bump";
|
|
23335
|
+
var DEFAULT_BATCH_MS = 150;
|
|
23336
|
+
var DEFAULT_MAX_WAIT_MS = 1e3;
|
|
23337
|
+
var DEFAULT_MAX_ORG_TOPICS = 20;
|
|
23338
|
+
function entityNoticeKey(notice) {
|
|
23339
|
+
return notice.id ?? (notice.at ? `${notice.organization_id ?? ""}:${notice.entity_type ?? ""}:${notice.at}` : void 0);
|
|
23340
|
+
}
|
|
23341
|
+
function entityOrgTopic(organizationId, token) {
|
|
23342
|
+
return entityOrgChannel.topic({ organizationId, token });
|
|
23343
|
+
}
|
|
23344
|
+
function entityOrgChannelSpec(organizationId, token, onNotice, onBackfill) {
|
|
23345
|
+
return {
|
|
23346
|
+
topic: entityOrgTopic(organizationId, token),
|
|
23347
|
+
// Database Broadcast is authorized by RLS on realtime.messages; the manager awaits setAuth() first.
|
|
23348
|
+
private: true,
|
|
23349
|
+
// The sender is Postgres: no Matrx envelope. Our own write is known by the op id it carried.
|
|
23350
|
+
wire: { mode: "raw", isOwnMessage: (payload) => isOwnOp(payload?.op_id) },
|
|
23351
|
+
eventKey: (_source, payload) => entityNoticeKey(payload ?? {}),
|
|
23352
|
+
broadcast: [
|
|
23353
|
+
{
|
|
23354
|
+
event: ENTITY_NOTICE_EVENT,
|
|
23355
|
+
onMessage: (message) => {
|
|
23356
|
+
const notice = message.data ?? {};
|
|
23357
|
+
if (isOwnOp(notice.op_id)) return;
|
|
23358
|
+
onNotice(notice);
|
|
23359
|
+
}
|
|
23360
|
+
}
|
|
23361
|
+
],
|
|
23362
|
+
// Realtime has no replay: a channel back from a gap re-reads.
|
|
23363
|
+
onBackfill: () => onBackfill()
|
|
23364
|
+
};
|
|
23365
|
+
}
|
|
23366
|
+
function orderOrganizationTopics(input) {
|
|
23367
|
+
const members = input.members ? new Set(input.members) : null;
|
|
23368
|
+
const out = [];
|
|
23369
|
+
const push = (org) => {
|
|
23370
|
+
if (!org || out.includes(org)) return;
|
|
23371
|
+
if (members && !members.has(org)) return;
|
|
23372
|
+
out.push(org);
|
|
23373
|
+
};
|
|
23374
|
+
push(input.active);
|
|
23375
|
+
push(input.filter);
|
|
23376
|
+
const held = [...(input.held ?? /* @__PURE__ */ new Map()).entries()].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
|
|
23377
|
+
for (const [org] of held) push(org);
|
|
23378
|
+
for (const org of [...input.members ?? []].sort()) push(org);
|
|
23379
|
+
return out.slice(0, Math.max(0, input.max));
|
|
23380
|
+
}
|
|
23381
|
+
function createEntityRealtime(options = {}) {
|
|
23382
|
+
const batchMs = options.batchMs ?? DEFAULT_BATCH_MS;
|
|
23383
|
+
const maxWaitMs = options.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;
|
|
23384
|
+
const channels = /* @__PURE__ */ new Map();
|
|
23385
|
+
const open = (organizationId, token) => {
|
|
23386
|
+
const channel = { listeners: /* @__PURE__ */ new Set(), stop: null };
|
|
23387
|
+
const spec = entityOrgChannelSpec(
|
|
23388
|
+
organizationId,
|
|
23389
|
+
token,
|
|
23390
|
+
(notice) => {
|
|
23391
|
+
for (const listener of channel.listeners) listener.notice(notice);
|
|
23392
|
+
},
|
|
23393
|
+
() => {
|
|
23394
|
+
for (const listener of channel.listeners) listener.backfill();
|
|
23395
|
+
}
|
|
23396
|
+
);
|
|
23397
|
+
if (options.manager) {
|
|
23398
|
+
const handle = options.manager.open(spec);
|
|
23399
|
+
channel.stop = () => handle.close();
|
|
23400
|
+
} else {
|
|
23401
|
+
channel.stop = subscribeToRealtimeManager(() => spec);
|
|
23402
|
+
}
|
|
23403
|
+
return channel;
|
|
23404
|
+
};
|
|
23405
|
+
return {
|
|
23406
|
+
subscribe({ token, organizationIds }, sink) {
|
|
23407
|
+
let timer = null;
|
|
23408
|
+
let firstAt = 0;
|
|
23409
|
+
let pending = /* @__PURE__ */ new Set();
|
|
23410
|
+
let wholeList = false;
|
|
23411
|
+
const flush = () => {
|
|
23412
|
+
if (timer !== null) clearTimeout(timer);
|
|
23413
|
+
timer = null;
|
|
23414
|
+
const ids = [...pending];
|
|
23415
|
+
const all = wholeList;
|
|
23416
|
+
pending = /* @__PURE__ */ new Set();
|
|
23417
|
+
wholeList = false;
|
|
23418
|
+
if (all) sink.rows(null);
|
|
23419
|
+
else if (ids.length > 0) sink.rows(ids);
|
|
23420
|
+
};
|
|
23421
|
+
const nudge = () => {
|
|
23422
|
+
const now = Date.now();
|
|
23423
|
+
if (timer === null) firstAt = now;
|
|
23424
|
+
else clearTimeout(timer);
|
|
23425
|
+
const wait = Math.max(0, Math.min(batchMs, firstAt + maxWaitMs - now));
|
|
23426
|
+
timer = setTimeout(flush, wait);
|
|
23427
|
+
};
|
|
23428
|
+
const listener = {
|
|
23429
|
+
notice(notice) {
|
|
23430
|
+
if (notice.entity_type && notice.entity_type !== token) return;
|
|
23431
|
+
if (notice.ids == null) wholeList = true;
|
|
23432
|
+
else for (const id of notice.ids) pending.add(id);
|
|
23433
|
+
nudge();
|
|
23434
|
+
},
|
|
23435
|
+
backfill() {
|
|
23436
|
+
wholeList = true;
|
|
23437
|
+
flush();
|
|
23438
|
+
}
|
|
23439
|
+
};
|
|
23440
|
+
const keys = [...new Set(organizationIds)].map((org) => {
|
|
23441
|
+
const key = entityOrgTopic(org, token);
|
|
23442
|
+
const channel = channels.get(key) ?? open(org, token);
|
|
23443
|
+
channels.set(key, channel);
|
|
23444
|
+
channel.listeners.add(listener);
|
|
23445
|
+
return key;
|
|
23446
|
+
});
|
|
23447
|
+
return () => {
|
|
23448
|
+
if (timer !== null) clearTimeout(timer);
|
|
23449
|
+
for (const key of keys) {
|
|
23450
|
+
const channel = channels.get(key);
|
|
23451
|
+
if (!channel) continue;
|
|
23452
|
+
channel.listeners.delete(listener);
|
|
23453
|
+
if (channel.listeners.size > 0) continue;
|
|
23454
|
+
channel.stop?.();
|
|
23455
|
+
channels.delete(key);
|
|
23456
|
+
}
|
|
23457
|
+
};
|
|
23458
|
+
}
|
|
23459
|
+
};
|
|
23460
|
+
}
|
|
23461
|
+
|
|
23462
|
+
// ../entity-data/src/port/port.ts
|
|
23463
|
+
import { mintOpId } from "@ai-matrx/records";
|
|
23464
|
+
|
|
23465
|
+
// ../entity-data/src/core/wire.ts
|
|
23466
|
+
var IDENTITY = {
|
|
23467
|
+
_id: "id",
|
|
23468
|
+
_version: "version",
|
|
23469
|
+
_organization_id: "organization_id"
|
|
23470
|
+
};
|
|
23471
|
+
var CUSTOM_PREFIX = "_custom.";
|
|
23472
|
+
function wireColumn(column, customKeys) {
|
|
23473
|
+
const identity = IDENTITY[column];
|
|
23474
|
+
if (identity) return identity;
|
|
23475
|
+
if (column.startsWith(CUSTOM_PREFIX)) return column;
|
|
23476
|
+
return customKeys.has(column) ? `${CUSTOM_PREFIX}${column}` : column;
|
|
23477
|
+
}
|
|
23478
|
+
function predicate(clause, customKeys) {
|
|
23479
|
+
const column = wireColumn(clause.column, customKeys);
|
|
23480
|
+
const v = clause.value;
|
|
23481
|
+
switch (clause.op) {
|
|
23482
|
+
case "eq":
|
|
23483
|
+
return v === null || v === void 0 ? { column, op: "empty" } : { column, op: "eq", value: v };
|
|
23484
|
+
case "neq":
|
|
23485
|
+
return v === null || v === void 0 ? { column, op: "empty", negated: true } : { column, op: "neq", value: v };
|
|
23486
|
+
case "lt":
|
|
23487
|
+
case "lte":
|
|
23488
|
+
case "gt":
|
|
23489
|
+
case "gte":
|
|
23490
|
+
return { column, op: clause.op, value: v };
|
|
23491
|
+
case "in":
|
|
23492
|
+
return { column, op: "in", values: Array.isArray(v) ? v : [] };
|
|
23493
|
+
case "empty":
|
|
23494
|
+
return v === false ? { column, op: "empty", negated: true } : { column, op: "empty" };
|
|
23495
|
+
case "contains":
|
|
23496
|
+
return { column, op: "contains", value: v };
|
|
23497
|
+
default:
|
|
23498
|
+
return { column, op: String(clause.op), value: v };
|
|
23499
|
+
}
|
|
23500
|
+
}
|
|
23501
|
+
function toWire(query, customKeys = /* @__PURE__ */ new Set()) {
|
|
23502
|
+
const q = query ?? {};
|
|
23503
|
+
const out = {};
|
|
23504
|
+
const scope = {};
|
|
23505
|
+
if (q.lane) scope.kind = q.lane;
|
|
23506
|
+
if (q.org && q.org !== "all") scope.organization_id = q.org;
|
|
23507
|
+
if (scope.kind || scope.organization_id) out.scope = scope;
|
|
23508
|
+
if (q.where && q.where.length > 0) out.filter = { all: q.where.map((c) => predicate(c, customKeys)) };
|
|
23509
|
+
const search = q.search?.trim();
|
|
23510
|
+
if (search) out.search = search;
|
|
23511
|
+
if (q.sort && q.sort.length > 0) {
|
|
23512
|
+
out.sort = q.sort.map((s) => ({
|
|
23513
|
+
column: wireColumn(s.column, customKeys),
|
|
23514
|
+
dir: s.direction === "desc" ? "desc" : "asc",
|
|
23515
|
+
nulls: "last"
|
|
23516
|
+
}));
|
|
23517
|
+
}
|
|
23518
|
+
if (typeof q.pageSize === "number" && Number.isFinite(q.pageSize)) out.pageSize = Math.max(1, Math.floor(q.pageSize));
|
|
23519
|
+
return out;
|
|
23520
|
+
}
|
|
23521
|
+
|
|
23522
|
+
// ../entity-data/src/port/rows.ts
|
|
23523
|
+
var IDENTITY_COLUMNS = /* @__PURE__ */ new Set(["id", "version", "organization_id"]);
|
|
23524
|
+
var PRESENTATION_KEYS = /* @__PURE__ */ new Set(["_state", "_k"]);
|
|
23525
|
+
function isRefList(value) {
|
|
23526
|
+
return Array.isArray(value) && value.length > 0 && value.every((item) => item !== null && typeof item === "object" && typeof item.token === "string" && typeof item.id === "string");
|
|
23527
|
+
}
|
|
23528
|
+
function toRefs(value) {
|
|
23529
|
+
if (!isRefList(value)) return [];
|
|
23530
|
+
return value.map((item) => ({ token: item.token, id: item.id, label: typeof item.label === "string" ? item.label : null }));
|
|
23531
|
+
}
|
|
23532
|
+
function toRow(wire) {
|
|
23533
|
+
const row = {
|
|
23534
|
+
_id: wire.id,
|
|
23535
|
+
_version: wire.version,
|
|
23536
|
+
_organization_id: wire.organization_id,
|
|
23537
|
+
_custom: wire._custom && typeof wire._custom === "object" ? { ...wire._custom } : {}
|
|
23538
|
+
};
|
|
23539
|
+
for (const [key, value] of Object.entries(wire)) {
|
|
23540
|
+
if (IDENTITY_COLUMNS.has(key) || PRESENTATION_KEYS.has(key) || key === "_custom") continue;
|
|
23541
|
+
row[key] = isRefList(value) ? toRefs(value) : value === void 0 ? null : value;
|
|
23542
|
+
}
|
|
23543
|
+
return row;
|
|
23544
|
+
}
|
|
23545
|
+
function toColumn(wire) {
|
|
23546
|
+
const column = {
|
|
23547
|
+
key: wire.key,
|
|
23548
|
+
label: wire.label || wire.key,
|
|
23549
|
+
type: wire.type,
|
|
23550
|
+
origin: wire.origin === "custom" ? "custom" : "platform",
|
|
23551
|
+
required: Boolean(wire.required),
|
|
23552
|
+
readOnly: Boolean(wire.readOnly)
|
|
23553
|
+
};
|
|
23554
|
+
if (wire.choices && wire.choices.length > 0) column.choices = [...wire.choices];
|
|
23555
|
+
if (wire.linksTo && wire.linksTo.length > 0) column.linksTo = [...wire.linksTo];
|
|
23556
|
+
return column;
|
|
23557
|
+
}
|
|
23558
|
+
function toColumns(wire) {
|
|
23559
|
+
return wire.filter((c) => !IDENTITY_COLUMNS.has(c.key)).map(toColumn);
|
|
23560
|
+
}
|
|
23561
|
+
|
|
23562
|
+
// ../entity-data/src/port/port.ts
|
|
23563
|
+
var UUID_SHAPE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
23564
|
+
var isUuidShape3 = (value) => typeof value === "string" && UUID_SHAPE.test(value);
|
|
23565
|
+
function toWireValue(value) {
|
|
23566
|
+
if (isRef(value)) return value.id;
|
|
23567
|
+
if (Array.isArray(value) && value.length > 0 && value.every(isRef)) {
|
|
23568
|
+
return value.length === 1 ? value[0].id : value.map((ref) => ref.id);
|
|
23569
|
+
}
|
|
23570
|
+
return value;
|
|
23571
|
+
}
|
|
23572
|
+
function isRef(value) {
|
|
23573
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.token === "string" && typeof value.id === "string";
|
|
23574
|
+
}
|
|
23575
|
+
function toWireValues(values) {
|
|
23576
|
+
const out = {};
|
|
23577
|
+
for (const [key, value] of Object.entries(values)) {
|
|
23578
|
+
if (value === void 0) continue;
|
|
23579
|
+
if (key === "_custom" && value && typeof value === "object" && !Array.isArray(value)) {
|
|
23580
|
+
out._custom = Object.fromEntries(Object.entries(value).filter(([, v]) => v !== void 0).map(([k, v]) => [k, toWireValue(v)]));
|
|
23581
|
+
continue;
|
|
23582
|
+
}
|
|
23583
|
+
out[key] = Array.isArray(value) && value.length === 0 && key !== "_custom" ? null : toWireValue(value);
|
|
23584
|
+
}
|
|
23585
|
+
return out;
|
|
23586
|
+
}
|
|
23587
|
+
function createEntityDataPort(options) {
|
|
23588
|
+
const client = options.client ?? createEntityClient({ dataSource: options.dataSource });
|
|
23589
|
+
const activeOrganization = () => (options.activeOrganizationId ? options.activeOrganizationId() : options.organization) ?? null;
|
|
23590
|
+
const gets = /* @__PURE__ */ new Map();
|
|
23591
|
+
const aliases = options.aliases;
|
|
23592
|
+
const shapes = /* @__PURE__ */ new Map();
|
|
23593
|
+
let warnedNotLive = false;
|
|
23594
|
+
const held = /* @__PURE__ */ new Map();
|
|
23595
|
+
const replans = /* @__PURE__ */ new Map();
|
|
23596
|
+
let memberships = null;
|
|
23597
|
+
let maxOrgTopics = null;
|
|
23598
|
+
function hold(alias, rows) {
|
|
23599
|
+
const byId = held.get(alias) ?? /* @__PURE__ */ new Map();
|
|
23600
|
+
held.set(alias, byId);
|
|
23601
|
+
const before = new Set(byId.values());
|
|
23602
|
+
for (const r of rows) {
|
|
23603
|
+
if (typeof r.id === "string" && typeof r.organization_id === "string") byId.set(r.id, r.organization_id);
|
|
23604
|
+
}
|
|
23605
|
+
if ([...byId.values()].some((org) => !before.has(org))) for (const replan of replans.get(alias) ?? []) replan();
|
|
23606
|
+
}
|
|
23607
|
+
function heldCounts(alias) {
|
|
23608
|
+
const counts = /* @__PURE__ */ new Map();
|
|
23609
|
+
for (const org of held.get(alias)?.values() ?? []) counts.set(org, (counts.get(org) ?? 0) + 1);
|
|
23610
|
+
return counts;
|
|
23611
|
+
}
|
|
23612
|
+
function membershipsOnce() {
|
|
23613
|
+
memberships ??= client.memberOrganizations().then((answer) => {
|
|
23614
|
+
if (answer.ok) return answer.data;
|
|
23615
|
+
memberships = null;
|
|
23616
|
+
console.warn(`[@ai-matrx/entity-data] Could not read your organizations for live updates: ${answer.error.message}`);
|
|
23617
|
+
return null;
|
|
23618
|
+
});
|
|
23619
|
+
return memberships;
|
|
23620
|
+
}
|
|
23621
|
+
function maxOrgTopicsOnce() {
|
|
23622
|
+
maxOrgTopics ??= client.knob({ key: "realtime_max_org_topics", organizationId: activeOrganization() }).then((answer) => {
|
|
23623
|
+
const value = answer.ok ? Number(answer.data) : Number.NaN;
|
|
23624
|
+
if (Number.isFinite(value) && value >= 0) return value;
|
|
23625
|
+
console.warn(`[@ai-matrx/entity-data] knob entity_data.realtime_max_org_topics did not resolve; joining at most ${DEFAULT_MAX_ORG_TOPICS} organizations.`);
|
|
23626
|
+
return DEFAULT_MAX_ORG_TOPICS;
|
|
23627
|
+
});
|
|
23628
|
+
return maxOrgTopics;
|
|
23629
|
+
}
|
|
23630
|
+
const tokenBindings = /* @__PURE__ */ new Map();
|
|
23631
|
+
function bindingOf(alias) {
|
|
23632
|
+
if (Object.prototype.hasOwnProperty.call(aliases, alias)) return aliases[alias];
|
|
23633
|
+
if (!options.tokensAreAliases || !/^[a-z][a-z0-9_]*$/.test(alias)) return null;
|
|
23634
|
+
let bound2 = tokenBindings.get(alias);
|
|
23635
|
+
if (!bound2) {
|
|
23636
|
+
bound2 = { kind: "entity", token: alias };
|
|
23637
|
+
tokenBindings.set(alias, bound2);
|
|
23638
|
+
}
|
|
23639
|
+
return bound2;
|
|
23640
|
+
}
|
|
23641
|
+
function noSuchAlias(alias) {
|
|
23642
|
+
return refusal2("not_found", `This Applet has no data source called "${alias}".`, "Use one of the aliases sources() lists.");
|
|
23643
|
+
}
|
|
23644
|
+
function shapeOf(alias, binding) {
|
|
23645
|
+
let held2 = shapes.get(alias);
|
|
23646
|
+
if (!held2) {
|
|
23647
|
+
held2 = client.columns({ token: binding.token, organizationId: binding.organizationId ?? null }).then((answer) => {
|
|
23648
|
+
if (!answer.ok) shapes.delete(alias);
|
|
23649
|
+
return answer;
|
|
23650
|
+
});
|
|
23651
|
+
shapes.set(alias, held2);
|
|
23652
|
+
}
|
|
23653
|
+
return held2;
|
|
23654
|
+
}
|
|
23655
|
+
function getCoalesced(alias, token, id) {
|
|
23656
|
+
return new Promise((resolve) => {
|
|
23657
|
+
let batch = gets.get(alias);
|
|
23658
|
+
if (!batch) {
|
|
23659
|
+
batch = /* @__PURE__ */ new Map();
|
|
23660
|
+
gets.set(alias, batch);
|
|
23661
|
+
const asked3 = batch;
|
|
23662
|
+
queueMicrotask(() => {
|
|
23663
|
+
gets.delete(alias);
|
|
23664
|
+
void flushGets(alias, token, asked3);
|
|
23665
|
+
});
|
|
23666
|
+
}
|
|
23667
|
+
const waiting = batch.get(id) ?? [];
|
|
23668
|
+
waiting.push(resolve);
|
|
23669
|
+
batch.set(id, waiting);
|
|
23670
|
+
});
|
|
23671
|
+
}
|
|
23672
|
+
async function flushGets(alias, token, asked3) {
|
|
23673
|
+
const answer = await client.get({ token, ids: [...asked3.keys()] });
|
|
23674
|
+
if (answer.ok) hold(alias, answer.data.rows);
|
|
23675
|
+
const byId = new Map(answer.ok ? answer.data.rows.map((r) => [r.id, r]) : []);
|
|
23676
|
+
for (const [id, waiting] of asked3) {
|
|
23677
|
+
const found = byId.get(id);
|
|
23678
|
+
const wire = found && found["_state"]?.archived === true ? void 0 : found;
|
|
23679
|
+
const result = answer.ok ? { ok: true, data: wire ? toRow(wire) : null } : answer;
|
|
23680
|
+
for (const resolve of waiting) resolve(result);
|
|
23681
|
+
}
|
|
23682
|
+
}
|
|
23683
|
+
function readBack(alias, answer, what) {
|
|
23684
|
+
if (!answer.ok) return answer;
|
|
23685
|
+
hold(alias, answer.data.rows);
|
|
23686
|
+
const wire = answer.data.rows[0];
|
|
23687
|
+
if (!wire) {
|
|
23688
|
+
return refusal2(
|
|
23689
|
+
"not_found",
|
|
23690
|
+
`${what} was saved, but you cannot open it now, so it is not shown here.`,
|
|
23691
|
+
"The row is in the store; who may open it decides whether it appears in this list."
|
|
23692
|
+
);
|
|
23693
|
+
}
|
|
23694
|
+
return { ok: true, data: toRow(wire) };
|
|
23695
|
+
}
|
|
23696
|
+
function done(answer) {
|
|
23697
|
+
return answer.ok ? { ok: true, data: void 0 } : answer;
|
|
23698
|
+
}
|
|
23699
|
+
return {
|
|
23700
|
+
async sources() {
|
|
23701
|
+
const out = [];
|
|
23702
|
+
for (const [alias, binding] of Object.entries(aliases)) {
|
|
23703
|
+
const shape = await shapeOf(alias, binding);
|
|
23704
|
+
if (!shape.ok) return shape;
|
|
23705
|
+
out.push({
|
|
23706
|
+
alias,
|
|
23707
|
+
label: binding.label ?? shape.data.label ?? alias,
|
|
23708
|
+
kind: "entity",
|
|
23709
|
+
canCreate: Boolean(shape.data.can_create),
|
|
23710
|
+
canUpdate: Boolean(shape.data.can_update)
|
|
23711
|
+
});
|
|
23712
|
+
}
|
|
23713
|
+
return { ok: true, data: out };
|
|
23714
|
+
},
|
|
23715
|
+
async describe(alias) {
|
|
23716
|
+
const binding = bindingOf(alias);
|
|
23717
|
+
if (!binding) return noSuchAlias(alias);
|
|
23718
|
+
const shape = await shapeOf(alias, binding);
|
|
23719
|
+
if (!shape.ok) return shape;
|
|
23720
|
+
return {
|
|
23721
|
+
ok: true,
|
|
23722
|
+
data: {
|
|
23723
|
+
token: binding.token,
|
|
23724
|
+
label: binding.label ?? shape.data.label ?? binding.token,
|
|
23725
|
+
canCreate: Boolean(shape.data.can_create),
|
|
23726
|
+
canUpdate: Boolean(shape.data.can_update)
|
|
23727
|
+
}
|
|
23728
|
+
};
|
|
23729
|
+
},
|
|
23730
|
+
async columns(alias) {
|
|
23731
|
+
const binding = bindingOf(alias);
|
|
23732
|
+
if (!binding) return noSuchAlias(alias);
|
|
23733
|
+
const shape = await shapeOf(alias, binding);
|
|
23734
|
+
return shape.ok ? { ok: true, data: toColumns(shape.data.columns) } : shape;
|
|
23735
|
+
},
|
|
23736
|
+
async list(alias, q = {}, cursor) {
|
|
23737
|
+
const binding = bindingOf(alias);
|
|
23738
|
+
if (!binding) return noSuchAlias(alias);
|
|
23739
|
+
let customKeys = /* @__PURE__ */ new Set();
|
|
23740
|
+
if (q.where && q.where.length > 0 || q.sort && q.sort.length > 0) {
|
|
23741
|
+
const shape = await shapeOf(alias, binding);
|
|
23742
|
+
if (!shape.ok) return shape;
|
|
23743
|
+
customKeys = new Set(shape.data.columns.filter((c) => c.origin === "custom").map((c) => c.key));
|
|
23744
|
+
}
|
|
23745
|
+
const wire = toWire(q, customKeys);
|
|
23746
|
+
const answer = await client.list({ token: binding.token, ...wire, after: cursor ?? null });
|
|
23747
|
+
if (!answer.ok) return answer;
|
|
23748
|
+
const { data } = answer;
|
|
23749
|
+
if (data.sort_ignored.length > 0) {
|
|
23750
|
+
console.warn(`[@ai-matrx/entity-data] "${alias}" sorts by one column for now; ignored: ${data.sort_ignored.join(", ")}.`);
|
|
23751
|
+
}
|
|
23752
|
+
hold(alias, data.rows);
|
|
23753
|
+
const page = {
|
|
23754
|
+
rows: data.rows.map(toRow),
|
|
23755
|
+
// A count that stopped at the store's cap is a floor, not a count: unknown beats a wrong number.
|
|
23756
|
+
total: data.total === null || data.total === void 0 || data.total_is_capped ? null : data.total,
|
|
23757
|
+
cursor: data.has_more ? data.next_after : null
|
|
23758
|
+
};
|
|
23759
|
+
return { ok: true, data: page };
|
|
23760
|
+
},
|
|
23761
|
+
async get(alias, id) {
|
|
23762
|
+
const binding = bindingOf(alias);
|
|
23763
|
+
if (!binding) return noSuchAlias(alias);
|
|
23764
|
+
if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
|
|
23765
|
+
return getCoalesced(alias, binding.token, id);
|
|
23766
|
+
},
|
|
23767
|
+
async create(alias, values) {
|
|
23768
|
+
const binding = bindingOf(alias);
|
|
23769
|
+
if (!binding) return noSuchAlias(alias);
|
|
23770
|
+
const organizationId = activeOrganization();
|
|
23771
|
+
if (!organizationId) {
|
|
23772
|
+
return refusal2(
|
|
23773
|
+
"organization_required",
|
|
23774
|
+
"Choose the organization this new record belongs to.",
|
|
23775
|
+
"Pick an organization, then add the row again. Nothing was saved."
|
|
23776
|
+
);
|
|
23777
|
+
}
|
|
23778
|
+
const answer = await client.insert({ token: binding.token, organizationId, rows: [toWireValues(values)], opId: mintOpId() });
|
|
23779
|
+
return readBack(alias, answer, "The new row");
|
|
23780
|
+
},
|
|
23781
|
+
async update(alias, id, patch, baseVersion) {
|
|
23782
|
+
const binding = bindingOf(alias);
|
|
23783
|
+
if (!binding) return noSuchAlias(alias);
|
|
23784
|
+
if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
|
|
23785
|
+
const answer = await client.update({ token: binding.token, id, baseVersion, patch: toWireValues(patch), opId: mintOpId() });
|
|
23786
|
+
return readBack(alias, answer, "The change");
|
|
23787
|
+
},
|
|
23788
|
+
async archive(alias, id) {
|
|
23789
|
+
const binding = bindingOf(alias);
|
|
23790
|
+
if (!binding) return noSuchAlias(alias);
|
|
23791
|
+
if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
|
|
23792
|
+
return done(await client.archive({ token: binding.token, ids: [id], opId: mintOpId() }));
|
|
23793
|
+
},
|
|
23794
|
+
async restore(alias, id) {
|
|
23795
|
+
const binding = bindingOf(alias);
|
|
23796
|
+
if (!binding) return noSuchAlias(alias);
|
|
23797
|
+
if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
|
|
23798
|
+
return done(await client.unarchive({ token: binding.token, ids: [id], opId: mintOpId() }));
|
|
23799
|
+
},
|
|
23800
|
+
subscribe(event, listener) {
|
|
23801
|
+
const alias = event.startsWith("rows:") ? event.slice(5) : null;
|
|
23802
|
+
const binding = alias ? bindingOf(alias) : null;
|
|
23803
|
+
if (!alias || !binding) {
|
|
23804
|
+
throw new Error(`DataPort.subscribe: "${event}" is not an event this Applet's port carries. Use rows:<alias>.`);
|
|
23805
|
+
}
|
|
23806
|
+
const realtime = options.realtime;
|
|
23807
|
+
if (!realtime) {
|
|
23808
|
+
if (!warnedNotLive) {
|
|
23809
|
+
warnedNotLive = true;
|
|
23810
|
+
console.warn("[@ai-matrx/entity-data] This host bound no realtime layer, so other people's changes appear on the next read.");
|
|
23811
|
+
}
|
|
23812
|
+
return () => {
|
|
23813
|
+
};
|
|
23814
|
+
}
|
|
23815
|
+
let stopped = false;
|
|
23816
|
+
let joined = [];
|
|
23817
|
+
let stopLive = null;
|
|
23818
|
+
const sink = { rows: (ids) => listener({ ids: ids === null ? null : [...ids] }) };
|
|
23819
|
+
const plan = async () => {
|
|
23820
|
+
const organizationIds = binding.organizationId ? [binding.organizationId] : orderOrganizationTopics({
|
|
23821
|
+
active: activeOrganization(),
|
|
23822
|
+
held: heldCounts(alias),
|
|
23823
|
+
members: await membershipsOnce(),
|
|
23824
|
+
max: await maxOrgTopicsOnce()
|
|
23825
|
+
});
|
|
23826
|
+
if (stopped) return;
|
|
23827
|
+
if (organizationIds.length === joined.length && organizationIds.every((org, i) => org === joined[i])) return;
|
|
23828
|
+
const previous = stopLive;
|
|
23829
|
+
joined = organizationIds;
|
|
23830
|
+
stopLive = realtime.subscribe({ token: binding.token, organizationIds }, sink);
|
|
23831
|
+
previous?.();
|
|
23832
|
+
};
|
|
23833
|
+
const replan = () => void plan();
|
|
23834
|
+
const set = replans.get(alias) ?? /* @__PURE__ */ new Set();
|
|
23835
|
+
replans.set(alias, set);
|
|
23836
|
+
set.add(replan);
|
|
23837
|
+
replan();
|
|
23838
|
+
return () => {
|
|
23839
|
+
stopped = true;
|
|
23840
|
+
set.delete(replan);
|
|
23841
|
+
stopLive?.();
|
|
23842
|
+
stopLive = null;
|
|
23843
|
+
};
|
|
23844
|
+
}
|
|
23845
|
+
};
|
|
23846
|
+
}
|
|
23847
|
+
|
|
23848
|
+
// ../entity-data/src/react/index.tsx
|
|
23849
|
+
var ENTITY_PORT_KEY = "entity-data";
|
|
23850
|
+
var EntityScopeContext = createContext7(null);
|
|
23851
|
+
function EntityDataProvider({ dataSource, client, activeOrganizationId, realtime, portKey = ENTITY_PORT_KEY, children }) {
|
|
23852
|
+
const active = useRef30(activeOrganizationId);
|
|
23853
|
+
active.current = activeOrganizationId;
|
|
23854
|
+
const scope = useMemo36(() => {
|
|
23855
|
+
const bound2 = client ?? createEntityClient({ dataSource });
|
|
23856
|
+
const live = realtime === false ? void 0 : realtime ?? createEntityRealtime();
|
|
23857
|
+
const port = createEntityDataPort({
|
|
23858
|
+
client: bound2,
|
|
23859
|
+
aliases: {},
|
|
23860
|
+
tokensAreAliases: true,
|
|
23861
|
+
activeOrganizationId: () => active.current,
|
|
23862
|
+
...live ? { realtime: live } : {}
|
|
23863
|
+
});
|
|
23864
|
+
return { port, portKey, events: hostEvents(port) };
|
|
23865
|
+
}, [client, dataSource, realtime, portKey]);
|
|
23866
|
+
return createElement(EntityScopeContext.Provider, { value: scope }, children);
|
|
23867
|
+
}
|
|
23868
|
+
function useOptionalEntityScope() {
|
|
23869
|
+
return useContext7(EntityScopeContext);
|
|
23870
|
+
}
|
|
23871
|
+
function useEntityScope() {
|
|
23872
|
+
const scope = useContext7(EntityScopeContext);
|
|
23873
|
+
if (!scope) {
|
|
23874
|
+
throw new Error(
|
|
23875
|
+
"An entity hook was called outside <EntityDataProvider>. Mount it once, high, with the supabase client that carries this person's session and the active organization."
|
|
23876
|
+
);
|
|
23877
|
+
}
|
|
23878
|
+
return scope;
|
|
23879
|
+
}
|
|
23880
|
+
function useEntityList(token, query = {}) {
|
|
23881
|
+
return useDataRows(token, query, useEntityScope());
|
|
23882
|
+
}
|
|
23883
|
+
function useEntityColumns(token) {
|
|
23884
|
+
return useDataColumns(token, useEntityScope());
|
|
23885
|
+
}
|
|
23886
|
+
function useEntityType(token) {
|
|
23887
|
+
const scope = useEntityScope();
|
|
23888
|
+
const qc = useRecordsQueryClient();
|
|
23889
|
+
const q = useQuery(
|
|
23890
|
+
{
|
|
23891
|
+
queryKey: [...dataKeys.alias(scope.portKey, token), "type"],
|
|
23892
|
+
queryFn: async () => {
|
|
23893
|
+
const answer = await scope.port.describe(token);
|
|
23894
|
+
if (!answer.ok) throw Object.assign(new Error(answer.error.message), { error: answer.error });
|
|
23895
|
+
return answer.data;
|
|
23896
|
+
},
|
|
23897
|
+
retry: false
|
|
23898
|
+
},
|
|
23899
|
+
qc
|
|
23900
|
+
);
|
|
23901
|
+
const failed = q.error;
|
|
23902
|
+
return { data: q.data, loading: q.isPending, error: failed ? failed.error ?? { code: "internal", message: failed.message } : null, refresh: () => void q.refetch() };
|
|
23903
|
+
}
|
|
23904
|
+
function useEntityWrite(token) {
|
|
23905
|
+
return useDataMutations(token, useEntityScope());
|
|
23906
|
+
}
|
|
23907
|
+
|
|
23908
|
+
// src/entityTable.tsx
|
|
23177
23909
|
import { Fragment as Fragment24, jsx as jsx69 } from "react/jsx-runtime";
|
|
23178
23910
|
function EntityDataScope({ children }) {
|
|
23179
23911
|
const above = useOptionalEntityScope();
|
|
@@ -23189,12 +23921,12 @@ function entityShownColumns(columns) {
|
|
|
23189
23921
|
function entityCellValue(row, column) {
|
|
23190
23922
|
return column.origin === "custom" ? row._custom?.[column.key] ?? null : row[column.key] ?? null;
|
|
23191
23923
|
}
|
|
23192
|
-
function
|
|
23924
|
+
function isRefList2(value) {
|
|
23193
23925
|
return Array.isArray(value) && value.every((v) => v !== null && typeof v === "object" && typeof v.id === "string");
|
|
23194
23926
|
}
|
|
23195
23927
|
function entityValueText(column, v) {
|
|
23196
23928
|
if (v === null || v === void 0 || v === "") return "";
|
|
23197
|
-
if (
|
|
23929
|
+
if (isRefList2(v)) return v.map((ref) => typeof ref.label === "string" ? ref.label : "").filter(Boolean).join(", ");
|
|
23198
23930
|
if (typeof v === "number") return v.toLocaleString();
|
|
23199
23931
|
if (typeof v === "boolean") return v ? "Yes" : "No";
|
|
23200
23932
|
if (column.type !== "date" && column.type !== "datetime" && column.type !== "timestamp") return typeof v === "object" ? JSON.stringify(v) : String(v);
|
|
@@ -23228,7 +23960,7 @@ function useEntityTable(token, options = {}) {
|
|
|
23228
23960
|
const columns = useEntityColumns(token);
|
|
23229
23961
|
const list = useEntityList(token, { ...options.pageSize ? { pageSize: options.pageSize } : {}, ...search ? { search } : {} });
|
|
23230
23962
|
const write = useEntityWrite(token);
|
|
23231
|
-
const shown4 =
|
|
23963
|
+
const shown4 = useMemo37(() => entityShownColumns(columns.data ?? []), [columns.data]);
|
|
23232
23964
|
const refused = list.error ?? columns.error ?? type.error;
|
|
23233
23965
|
const name = entityNameColumn(shown4);
|
|
23234
23966
|
return {
|
|
@@ -23268,7 +24000,7 @@ function entityTableColumns(columns, editable) {
|
|
|
23268
24000
|
// A link or a choice reads (and is edited) as its words; anything else as stored.
|
|
23269
24001
|
accessorFn: (row) => {
|
|
23270
24002
|
const v = entityCellValue(row, c);
|
|
23271
|
-
return
|
|
24003
|
+
return isRefList2(v) ? entityValueText(c, v) : v;
|
|
23272
24004
|
},
|
|
23273
24005
|
cell: (row) => entityValueText(c, entityCellValue(row, c)),
|
|
23274
24006
|
sortable: !c.linksTo,
|
|
@@ -23286,8 +24018,8 @@ function EntityGrid({
|
|
|
23286
24018
|
editable = true
|
|
23287
24019
|
}) {
|
|
23288
24020
|
const canEdit = editable && entity.canUpdate;
|
|
23289
|
-
const columns =
|
|
23290
|
-
const byId =
|
|
24021
|
+
const columns = useMemo37(() => entityTableColumns(entity.columns, canEdit), [entity.columns, canEdit]);
|
|
24022
|
+
const byId = useMemo37(() => new Map(entity.columns.map((c) => [columnId(c), c])), [entity.columns]);
|
|
23291
24023
|
return /* @__PURE__ */ jsx69(
|
|
23292
24024
|
MatrxDataTable2,
|
|
23293
24025
|
{
|
|
@@ -23616,7 +24348,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
|
|
|
23616
24348
|
}
|
|
23617
24349
|
|
|
23618
24350
|
// src/ImportNotice.tsx
|
|
23619
|
-
import { useCallback as useCallback26, useEffect as useEffect49, useMemo as
|
|
24351
|
+
import { useCallback as useCallback26, useEffect as useEffect49, useMemo as useMemo38, useState as useState61 } from "react";
|
|
23620
24352
|
import { useRecordsClient as useRecordsClient40 } from "@ai-matrx/records/react";
|
|
23621
24353
|
import { Button as Button45, cn as cn36 } from "@ai-matrx/design-system";
|
|
23622
24354
|
import { jsx as jsx72, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
@@ -23660,7 +24392,7 @@ function ImportNotice({ tableId, onOpenImport, epoch = 0, className }) {
|
|
|
23660
24392
|
live = false;
|
|
23661
24393
|
};
|
|
23662
24394
|
}, [client, tableId, epoch]);
|
|
23663
|
-
const run =
|
|
24395
|
+
const run = useMemo38(() => runs ? runToNotice(runs) : null, [runs]);
|
|
23664
24396
|
const shown4 = run && !wasDismissed(run.import_id) && dismissed !== run.import_id ? run : null;
|
|
23665
24397
|
useEffect49(() => {
|
|
23666
24398
|
if (!shown4 || report?.import_id === shown4.import_id) return;
|
|
@@ -23720,7 +24452,7 @@ function ImportNotice({ tableId, onOpenImport, epoch = 0, className }) {
|
|
|
23720
24452
|
}
|
|
23721
24453
|
|
|
23722
24454
|
// src/SaveToTable.tsx
|
|
23723
|
-
import { useMemo as
|
|
24455
|
+
import { useMemo as useMemo41, useState as useState67 } from "react";
|
|
23724
24456
|
import { useRecordsClient as useRecordsClient46, useMyLevels as useMyLevels3, useTables as useTables3 } from "@ai-matrx/records/react";
|
|
23725
24457
|
import {
|
|
23726
24458
|
Button as Button52,
|
|
@@ -23919,14 +24651,14 @@ function fieldsForNewColumns(columns) {
|
|
|
23919
24651
|
}
|
|
23920
24652
|
|
|
23921
24653
|
// src/BookingSlots.tsx
|
|
23922
|
-
import { useCallback as useCallback29, useEffect as useEffect52, useMemo as
|
|
24654
|
+
import { useCallback as useCallback29, useEffect as useEffect52, useMemo as useMemo40, useState as useState64 } from "react";
|
|
23923
24655
|
import { useRecordsClient as useRecordsClient43, useMyLevels as useMyLevels2 } from "@ai-matrx/records/react";
|
|
23924
24656
|
import { bookingPath as bookingPath2 } from "@ai-matrx/records";
|
|
23925
24657
|
import { Badge as Badge11, Button as Button49, Skeleton as Skeleton5, cn as cn39 } from "@ai-matrx/design-system";
|
|
23926
24658
|
|
|
23927
24659
|
// src/BookingBuilder.tsx
|
|
23928
24660
|
import { ErrorBox as ErrorBox3 } from "@ai-matrx/design-system";
|
|
23929
|
-
import { useCallback as useCallback27, useEffect as useEffect50, useMemo as
|
|
24661
|
+
import { useCallback as useCallback27, useEffect as useEffect50, useMemo as useMemo39, useRef as useRef31, useState as useState62 } from "react";
|
|
23930
24662
|
import { useFields as useFields11, useRecordsClient as useRecordsClient41, useTable as useTable9 } from "@ai-matrx/records/react";
|
|
23931
24663
|
import { formatDurationMinutes } from "@ai-matrx/kit/format";
|
|
23932
24664
|
import {
|
|
@@ -24063,14 +24795,14 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
|
|
|
24063
24795
|
const [confirmation, setConfirmation] = useState62("");
|
|
24064
24796
|
const [offer, setOffer] = useState62(null);
|
|
24065
24797
|
const [formId, setFormId] = useState62(bookingId ?? null);
|
|
24066
|
-
const madeRef =
|
|
24798
|
+
const madeRef = useRef31(null);
|
|
24067
24799
|
const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
|
|
24068
|
-
const askable =
|
|
24800
|
+
const askable = useMemo39(
|
|
24069
24801
|
() => askableFields(fields.data ?? [], STORE_ANSWERS_THESE),
|
|
24070
24802
|
[fields.data]
|
|
24071
24803
|
);
|
|
24072
24804
|
const unfillable = requiredLeftUnasked(fields.data ?? [], asked3, STORE_ANSWERS_THESE);
|
|
24073
|
-
const leftOut =
|
|
24805
|
+
const leftOut = useMemo39(
|
|
24074
24806
|
() => whyNotAskable(fields.data ?? [], STORE_ANSWERS_THESE),
|
|
24075
24807
|
[fields.data]
|
|
24076
24808
|
);
|
|
@@ -24133,7 +24865,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
|
|
|
24133
24865
|
}),
|
|
24134
24866
|
[timezone, minutes, buffer, lead, perDay, days, windows]
|
|
24135
24867
|
);
|
|
24136
|
-
const startedAsking =
|
|
24868
|
+
const startedAsking = useRef31(false);
|
|
24137
24869
|
useEffect50(() => {
|
|
24138
24870
|
if (startedAsking.current || !loaded || existing || formId || !fields.data) return;
|
|
24139
24871
|
startedAsking.current = true;
|
|
@@ -24879,7 +25611,7 @@ function ArchivedBuiltOn({ tableId, onRestored }) {
|
|
|
24879
25611
|
const [things, setThings] = useState63(null);
|
|
24880
25612
|
const [error, setError] = useState63(null);
|
|
24881
25613
|
const [restoring, setRestoring] = useState63(null);
|
|
24882
|
-
const [
|
|
25614
|
+
const [refusal4, setRefusal] = useState63(null);
|
|
24883
25615
|
const [said, setSaid] = useState63(null);
|
|
24884
25616
|
const read = useCallback28(async () => {
|
|
24885
25617
|
const [forms, checklists] = await Promise.all([
|
|
@@ -24932,7 +25664,7 @@ function ArchivedBuiltOn({ tableId, onRestored }) {
|
|
|
24932
25664
|
" \xB7 archived ",
|
|
24933
25665
|
archivedWhen(thing.archivedAt)
|
|
24934
25666
|
] }),
|
|
24935
|
-
|
|
25667
|
+
refusal4 && refusal4.id === thing.id ? /* @__PURE__ */ jsx78(RefusalNotice, { error: refusal4.error, className: "mt-2" }) : null
|
|
24936
25668
|
] }),
|
|
24937
25669
|
thing.whyNot ? /* @__PURE__ */ jsx78("span", { className: "text-xs text-muted-foreground", children: thing.whyNot }) : /* @__PURE__ */ jsx78(
|
|
24938
25670
|
Button48,
|
|
@@ -24986,7 +25718,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
|
|
|
24986
25718
|
useEffect52(() => {
|
|
24987
25719
|
void load();
|
|
24988
25720
|
}, [load]);
|
|
24989
|
-
const subjectIds =
|
|
25721
|
+
const subjectIds = useMemo40(
|
|
24990
25722
|
() => Array.from(
|
|
24991
25723
|
/* @__PURE__ */ new Set([
|
|
24992
25724
|
...(pages ?? []).map((p) => p.table_id),
|
|
@@ -25802,7 +26534,7 @@ function typeWord2(t) {
|
|
|
25802
26534
|
}
|
|
25803
26535
|
function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, className }) {
|
|
25804
26536
|
const client = useRecordsClient46();
|
|
25805
|
-
const shapes =
|
|
26537
|
+
const shapes = useMemo41(() => shapesOfSource(source), [source]);
|
|
25806
26538
|
const [which, setWhich] = useState67(() => Math.min(Math.max(0, shapeIndex), Math.max(0, shapes.length - 1)));
|
|
25807
26539
|
const shape = shapes[which] ?? null;
|
|
25808
26540
|
const [split, setSplit] = useState67("");
|
|
@@ -25830,8 +26562,8 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
|
|
|
25830
26562
|
const [phase, setPhase] = useState67("ready");
|
|
25831
26563
|
const [made, setMade] = useState67(null);
|
|
25832
26564
|
const sourceName = source.title?.trim() || shape?.name || "the rows above";
|
|
25833
|
-
const sourceText =
|
|
25834
|
-
const wizardSource =
|
|
26565
|
+
const sourceText = useMemo41(() => JSON.stringify({ headers, rows }), [headers, rows]);
|
|
26566
|
+
const wizardSource = useMemo41(
|
|
25835
26567
|
() => ({ name: sourceName, parsed: { headers, rows }, text: sourceText }),
|
|
25836
26568
|
[sourceName, headers, rows, sourceText]
|
|
25837
26569
|
);
|
|
@@ -26185,7 +26917,7 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
|
|
|
26185
26917
|
}
|
|
26186
26918
|
|
|
26187
26919
|
// src/StageRules.tsx
|
|
26188
|
-
import { useCallback as useCallback31, useEffect as useEffect55, useMemo as
|
|
26920
|
+
import { useCallback as useCallback31, useEffect as useEffect55, useMemo as useMemo42, useState as useState68 } from "react";
|
|
26189
26921
|
import { useFields as useFields12, useRecordsClient as useRecordsClient47, useTable as useTable10 } from "@ai-matrx/records/react";
|
|
26190
26922
|
import { BasicInput as BasicInput18, BasicTextarea as BasicTextarea8, Button as Button53, Separator as Separator7, Skeleton as Skeleton7, cn as cn42 } from "@ai-matrx/design-system";
|
|
26191
26923
|
import { jsx as jsx83, jsxs as jsxs74 } from "react/jsx-runtime";
|
|
@@ -26246,8 +26978,8 @@ function StageRulesSection({ tableId, stage, className }) {
|
|
|
26246
26978
|
const stages = pipeline?.stages ?? [];
|
|
26247
26979
|
const stageKey = chosen ?? stages.find((s) => !s.retired)?.key ?? null;
|
|
26248
26980
|
const stageLabel = stages.find((s) => s.key === stageKey)?.label ?? stageKey ?? "";
|
|
26249
|
-
const gates =
|
|
26250
|
-
const conditionFields =
|
|
26981
|
+
const gates = useMemo42(() => stageKey ? gatesOf(pipeline, stageKey) : [], [pipeline, stageKey]);
|
|
26982
|
+
const conditionFields = useMemo42(
|
|
26251
26983
|
() => (fields.data ?? []).map((f) => ({ id: String(f.id), key: f.key, label: fieldName(f), field: f })),
|
|
26252
26984
|
[fields.data]
|
|
26253
26985
|
);
|
|
@@ -26473,7 +27205,7 @@ function Clause({
|
|
|
26473
27205
|
}
|
|
26474
27206
|
|
|
26475
27207
|
// src/TableRename.tsx
|
|
26476
|
-
import { useCallback as useCallback32, useEffect as useEffect56, useRef as
|
|
27208
|
+
import { useCallback as useCallback32, useEffect as useEffect56, useRef as useRef32, useState as useState69 } from "react";
|
|
26477
27209
|
import { tableShapeChanged as tableShapeChanged6, useRecordsClient as useRecordsClient48 } from "@ai-matrx/records/react";
|
|
26478
27210
|
import {
|
|
26479
27211
|
Button as Button54,
|
|
@@ -26495,7 +27227,7 @@ function tableNameProblem(typed2) {
|
|
|
26495
27227
|
}
|
|
26496
27228
|
function useRenameFromMenu() {
|
|
26497
27229
|
const [open, setOpen] = useState69(false);
|
|
26498
|
-
const asked3 =
|
|
27230
|
+
const asked3 = useRef32(false);
|
|
26499
27231
|
const ask = useCallback32(() => {
|
|
26500
27232
|
asked3.current = true;
|
|
26501
27233
|
window.setTimeout(() => setOpen(true), 0);
|
|
@@ -26521,8 +27253,8 @@ function TableRenameDialog({
|
|
|
26521
27253
|
const [typed2, setTyped] = useState69(name);
|
|
26522
27254
|
const [busy, setBusy] = useState69(false);
|
|
26523
27255
|
const [refused, setRefused] = useState69(null);
|
|
26524
|
-
const box =
|
|
26525
|
-
const openedAt =
|
|
27256
|
+
const box = useRef32(null);
|
|
27257
|
+
const openedAt = useRef32(null);
|
|
26526
27258
|
useEffect56(() => {
|
|
26527
27259
|
if (!open) return;
|
|
26528
27260
|
openedAt.current = readTableVersionNow(client, tableId);
|
|
@@ -26614,7 +27346,7 @@ function TableRenameDialog({
|
|
|
26614
27346
|
}
|
|
26615
27347
|
|
|
26616
27348
|
// src/TableSettings.tsx
|
|
26617
|
-
import { useEffect as useEffect61, useRef as
|
|
27349
|
+
import { useEffect as useEffect61, useRef as useRef33, useState as useState75 } from "react";
|
|
26618
27350
|
|
|
26619
27351
|
// src/ArchiveDeliberately.tsx
|
|
26620
27352
|
import { useState as useState70 } from "react";
|
|
@@ -26708,11 +27440,11 @@ import { Badge as Badge13, Button as Button59, Separator as Separator8, cn as cn
|
|
|
26708
27440
|
var TableRestoreRefused = class extends Error {
|
|
26709
27441
|
refusal;
|
|
26710
27442
|
sentence;
|
|
26711
|
-
constructor(
|
|
26712
|
-
const sentence2 = refusalSentence(
|
|
27443
|
+
constructor(refusal4) {
|
|
27444
|
+
const sentence2 = refusalSentence(refusal4);
|
|
26713
27445
|
super(sentence2);
|
|
26714
27446
|
this.name = "TableRestoreRefused";
|
|
26715
|
-
this.refusal =
|
|
27447
|
+
this.refusal = refusal4;
|
|
26716
27448
|
this.sentence = sentence2;
|
|
26717
27449
|
}
|
|
26718
27450
|
};
|
|
@@ -26963,7 +27695,7 @@ function RowShownTo({ recordId }) {
|
|
|
26963
27695
|
}
|
|
26964
27696
|
|
|
26965
27697
|
// src/TableDetails.tsx
|
|
26966
|
-
import { useEffect as useEffect59, useMemo as
|
|
27698
|
+
import { useEffect as useEffect59, useMemo as useMemo43, useState as useState73 } from "react";
|
|
26967
27699
|
import { tableShapeChanged as tableShapeChanged8, useRecordsClient as useRecordsClient52 } from "@ai-matrx/records/react";
|
|
26968
27700
|
import { Button as Button57, Textarea as Textarea4 } from "@ai-matrx/design-system";
|
|
26969
27701
|
import { jsx as jsx88, jsxs as jsxs79 } from "react/jsx-runtime";
|
|
@@ -26989,7 +27721,7 @@ function TableDetails({
|
|
|
26989
27721
|
const [busy, setBusy] = useState73(false);
|
|
26990
27722
|
const [refused, setRefused] = useState73(null);
|
|
26991
27723
|
useEffect59(() => setText(kept), [kept]);
|
|
26992
|
-
const choices =
|
|
27724
|
+
const choices = useMemo43(() => rowLabelChoices(fields), [fields]);
|
|
26993
27725
|
const write = async (patch, base) => {
|
|
26994
27726
|
setBusy(true);
|
|
26995
27727
|
setRefused(null);
|
|
@@ -27052,7 +27784,7 @@ function TableDetails({
|
|
|
27052
27784
|
}
|
|
27053
27785
|
|
|
27054
27786
|
// src/ColumnsAtOnce.tsx
|
|
27055
|
-
import { useEffect as useEffect60, useMemo as
|
|
27787
|
+
import { useEffect as useEffect60, useMemo as useMemo44, useState as useState74 } from "react";
|
|
27056
27788
|
import { useFieldMutation as useFieldMutation3 } from "@ai-matrx/records/react";
|
|
27057
27789
|
import { Badge as Badge12, BasicInput as BasicInput19, Button as Button58, Checkbox as Checkbox10, cn as cn43 } from "@ai-matrx/design-system";
|
|
27058
27790
|
import { jsx as jsx89, jsxs as jsxs80 } from "react/jsx-runtime";
|
|
@@ -27092,7 +27824,7 @@ function ColumnsAtOnce({
|
|
|
27092
27824
|
useEffect60(() => setHidden([...look?.hidden ?? []]), [hiddenSignature]);
|
|
27093
27825
|
const [dragging, setDragging] = useState74(null);
|
|
27094
27826
|
const [saving, setSaving] = useState74(false);
|
|
27095
|
-
const byId =
|
|
27827
|
+
const byId = useMemo44(() => new Map(rows.map((f) => [f.id, f])), [rows]);
|
|
27096
27828
|
const batch = columnsBatch(rows, draft);
|
|
27097
27829
|
const orderMoved = rows.some((f, i) => f.id !== draft[i]?.id);
|
|
27098
27830
|
const hiddenChanged = look ? JSON.stringify([...hidden].sort()) !== JSON.stringify([...look.hidden].sort()) : false;
|
|
@@ -27259,8 +27991,8 @@ function TableSettings({
|
|
|
27259
27991
|
live = false;
|
|
27260
27992
|
};
|
|
27261
27993
|
}, [tableId]);
|
|
27262
|
-
const askToArchiveRef =
|
|
27263
|
-
const archiveAskedSeen =
|
|
27994
|
+
const askToArchiveRef = useRef33(null);
|
|
27995
|
+
const archiveAskedSeen = useRef33(0);
|
|
27264
27996
|
const panelReady = Boolean(table.data && fields.data && rights.structure);
|
|
27265
27997
|
useEffect61(() => {
|
|
27266
27998
|
const ask = askToArchiveRef.current;
|
|
@@ -27451,7 +28183,7 @@ import { useFields as useFields15, useRecord as useRecord3, useRecordsClient as
|
|
|
27451
28183
|
import { AlchemyMenu as AlchemyMenu2 } from "@ai-matrx/alchemy/react";
|
|
27452
28184
|
|
|
27453
28185
|
// src/RecordChat.tsx
|
|
27454
|
-
import { useEffect as useEffect62, useMemo as
|
|
28186
|
+
import { useEffect as useEffect62, useMemo as useMemo45, useState as useState76 } from "react";
|
|
27455
28187
|
import { useRecordsClient as useRecordsClient54 } from "@ai-matrx/records/react";
|
|
27456
28188
|
import { Skeleton as Skeleton8, cn as cn45 } from "@ai-matrx/design-system";
|
|
27457
28189
|
import { jsx as jsx91, jsxs as jsxs82 } from "react/jsx-runtime";
|
|
@@ -27477,7 +28209,7 @@ function RecordChat({ tableId, recordId, className }) {
|
|
|
27477
28209
|
cancelled = true;
|
|
27478
28210
|
};
|
|
27479
28211
|
}, [client, recordId]);
|
|
27480
|
-
const context =
|
|
28212
|
+
const context = useMemo45(() => {
|
|
27481
28213
|
if (!scope) return null;
|
|
27482
28214
|
return {
|
|
27483
28215
|
surfaceKey: `records-ui:record-chat:${recordId}`,
|
|
@@ -27666,7 +28398,7 @@ function ShareForSomebodyElse({
|
|
|
27666
28398
|
}
|
|
27667
28399
|
|
|
27668
28400
|
// src/RecordBody.tsx
|
|
27669
|
-
import { useEffect as useEffect64, useRef as
|
|
28401
|
+
import { useEffect as useEffect64, useRef as useRef34, useState as useState78 } from "react";
|
|
27670
28402
|
import { Button as Button61, cn as cn46 } from "@ai-matrx/design-system";
|
|
27671
28403
|
import { newerKindOf as newerKindOf5 } from "@ai-matrx/records";
|
|
27672
28404
|
import { tableShapeChanged as tableShapeChanged10, useFieldMutation as useFieldMutation5, useFields as useFields14, useRecord as useRecord2, useRecordsClient as useRecordsClient55, useTable as useTable12 } from "@ai-matrx/records/react";
|
|
@@ -27703,9 +28435,9 @@ function BodyEditor({ tableId, recordId, field: field2 }) {
|
|
|
27703
28435
|
const raw = record.data?.document?.[field2.key];
|
|
27704
28436
|
const stored = typeof raw === "string" ? raw : "";
|
|
27705
28437
|
const [saving, setSaving] = useState78({ phase: "idle" });
|
|
27706
|
-
const lastSaved =
|
|
27707
|
-
const waiting =
|
|
27708
|
-
const timer =
|
|
28438
|
+
const lastSaved = useRef34(null);
|
|
28439
|
+
const waiting = useRef34(null);
|
|
28440
|
+
const timer = useRef34(null);
|
|
27709
28441
|
if (lastSaved.current === null && record.data) lastSaved.current = stored;
|
|
27710
28442
|
const write = async () => {
|
|
27711
28443
|
if (timer.current) clearTimeout(timer.current);
|
|
@@ -27726,7 +28458,7 @@ function BodyEditor({ tableId, recordId, field: field2 }) {
|
|
|
27726
28458
|
setSaving({ phase: "refused", error: answered.error });
|
|
27727
28459
|
}
|
|
27728
28460
|
};
|
|
27729
|
-
const writeRef =
|
|
28461
|
+
const writeRef = useRef34(write);
|
|
27730
28462
|
writeRef.current = write;
|
|
27731
28463
|
useEffect64(
|
|
27732
28464
|
() => () => {
|
|
@@ -27895,7 +28627,7 @@ function computedInPlainWords(row, field2) {
|
|
|
27895
28627
|
}
|
|
27896
28628
|
|
|
27897
28629
|
// src/systemTable.ts
|
|
27898
|
-
import { useEffect as useEffect65, useMemo as
|
|
28630
|
+
import { useEffect as useEffect65, useMemo as useMemo46, useState as useState80 } from "react";
|
|
27899
28631
|
import { useRecordsClient as useRecordsClient57 } from "@ai-matrx/records/react";
|
|
27900
28632
|
var inFlight = /* @__PURE__ */ new Map();
|
|
27901
28633
|
async function ensureSystemTable(client, spec) {
|
|
@@ -28027,7 +28759,7 @@ function useSystemTable(spec) {
|
|
|
28027
28759
|
const client = useRecordsClient57();
|
|
28028
28760
|
const [state, setState] = useState80({ tableId: null, loading: true, error: null });
|
|
28029
28761
|
const slug = spec.slug;
|
|
28030
|
-
const stable =
|
|
28762
|
+
const stable = useMemo46(() => spec, [slug]);
|
|
28031
28763
|
useEffect65(() => {
|
|
28032
28764
|
let cancelled = false;
|
|
28033
28765
|
setState({ tableId: null, loading: true, error: null });
|
|
@@ -28131,7 +28863,7 @@ var LOOK_WORDS = {
|
|
|
28131
28863
|
};
|
|
28132
28864
|
|
|
28133
28865
|
// src/ViewSwitcher.tsx
|
|
28134
|
-
import { useEffect as useEffect72, useMemo as
|
|
28866
|
+
import { useEffect as useEffect72, useMemo as useMemo54, useState as useState88 } from "react";
|
|
28135
28867
|
import { mayDrag as mayDrag4, useFields as useFields18, useRecordPage as useRecordPage2, useRecordsClient as useRecordsClient62, useTable as useTable16 } from "@ai-matrx/records/react";
|
|
28136
28868
|
import { stableFilterKey as stableFilterKey4 } from "@ai-matrx/records";
|
|
28137
28869
|
import { Button as Button68, Select as Select16, SelectContent as SelectContent16, SelectItem as SelectItem16, SelectTrigger as SelectTrigger16, SelectValue as SelectValue16, Skeleton as Skeleton11, cn as cn53 } from "@ai-matrx/design-system";
|
|
@@ -28145,7 +28877,7 @@ import {
|
|
|
28145
28877
|
import { formatCount as formatCount3 } from "@ai-matrx/kit/format";
|
|
28146
28878
|
|
|
28147
28879
|
// src/Pipeline.tsx
|
|
28148
|
-
import { useCallback as useCallback35, useEffect as useEffect66, useMemo as
|
|
28880
|
+
import { useCallback as useCallback35, useEffect as useEffect66, useMemo as useMemo48, useRef as useRef35, useState as useState82 } from "react";
|
|
28149
28881
|
import {
|
|
28150
28882
|
mayDrag,
|
|
28151
28883
|
useFields as useFields17,
|
|
@@ -28206,7 +28938,7 @@ function CardDates({ record, fields }) {
|
|
|
28206
28938
|
}
|
|
28207
28939
|
|
|
28208
28940
|
// src/RecordActionMenu.tsx
|
|
28209
|
-
import { useCallback as useCallback34, useMemo as
|
|
28941
|
+
import { useCallback as useCallback34, useMemo as useMemo47, useState as useState81 } from "react";
|
|
28210
28942
|
import { useFields as useFields16, useRecordsClient as useRecordsClient58, useTable as useTable14 } from "@ai-matrx/records/react";
|
|
28211
28943
|
import {
|
|
28212
28944
|
ContextMenu,
|
|
@@ -28301,7 +29033,7 @@ function useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge })
|
|
|
28301
29033
|
const linkRecord = host.linkRecord;
|
|
28302
29034
|
const href = host.hrefForRecord && table.data ? host.hrefForRecord({ table: table.data, recordId: row.id }) : void 0;
|
|
28303
29035
|
const fieldList = fields.data;
|
|
28304
|
-
return
|
|
29036
|
+
return useMemo47(() => {
|
|
28305
29037
|
const said = (sentence2) => notify?.success(sentence2);
|
|
28306
29038
|
return {
|
|
28307
29039
|
...typeof window !== "undefined" ? { origin: window.location.origin } : {},
|
|
@@ -28403,8 +29135,8 @@ function RecordActionMenu({ tableId, row, name, onOpenRecord, onChanged, childre
|
|
|
28403
29135
|
const [merging, setMerging] = useState81(false);
|
|
28404
29136
|
const openMerge = useCallback34(() => setMerging(true), []);
|
|
28405
29137
|
const actionHost = useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge: openMerge });
|
|
28406
|
-
const rights =
|
|
28407
|
-
const actions =
|
|
29138
|
+
const rights = useMemo47(() => whatYouMayDo(row.level || null, true), [row.level]);
|
|
29139
|
+
const actions = useMemo47(
|
|
28408
29140
|
() => recordActions({ record: { id: row.id, tableId, name }, rights, host: actionHost }),
|
|
28409
29141
|
[row.id, tableId, name, rights, actionHost]
|
|
28410
29142
|
);
|
|
@@ -28484,7 +29216,7 @@ function PipelineBoard({
|
|
|
28484
29216
|
const client = useRecordsClient59();
|
|
28485
29217
|
const fields = useFields17(tableId);
|
|
28486
29218
|
const ownDecorations = useTableDecorations(style ? null : tableId);
|
|
28487
|
-
const cardStyle =
|
|
29219
|
+
const cardStyle = useMemo48(
|
|
28488
29220
|
() => style ?? resolveTableStyle(ownDecorations.data, fields.data ?? [], void 0),
|
|
28489
29221
|
[style, ownDecorations.data, fields.data]
|
|
28490
29222
|
);
|
|
@@ -28496,9 +29228,9 @@ function PipelineBoard({
|
|
|
28496
29228
|
const [waiting, setWaiting] = useState82(/* @__PURE__ */ new Map());
|
|
28497
29229
|
const [dragging, setDragging] = useState82(null);
|
|
28498
29230
|
const [over, setOver] = useState82(null);
|
|
28499
|
-
const alive =
|
|
29231
|
+
const alive = useRef35(true);
|
|
28500
29232
|
const [selected, setSelected] = useState82(/* @__PURE__ */ new Set());
|
|
28501
|
-
const anchor =
|
|
29233
|
+
const anchor = useRef35(null);
|
|
28502
29234
|
const [batch, setBatch] = useState82(/* @__PURE__ */ new Map());
|
|
28503
29235
|
const [batchSaid, setBatchSaid] = useState82(null);
|
|
28504
29236
|
const [batchError, setBatchError] = useState82(null);
|
|
@@ -28532,11 +29264,11 @@ function PipelineBoard({
|
|
|
28532
29264
|
void reload();
|
|
28533
29265
|
}, [reload]);
|
|
28534
29266
|
const versions = useRecordVersions(client, rows, (r) => mayDrag(r.level));
|
|
28535
|
-
const versionsRef =
|
|
29267
|
+
const versionsRef = useRef35(versions);
|
|
28536
29268
|
versionsRef.current = versions;
|
|
28537
29269
|
const drawnVersion = (id) => versionsRef.current.seen(id);
|
|
28538
29270
|
const stageKey = definition?.stage_field ?? null;
|
|
28539
|
-
const cardsByStage =
|
|
29271
|
+
const cardsByStage = useMemo48(() => {
|
|
28540
29272
|
const map = /* @__PURE__ */ new Map();
|
|
28541
29273
|
if (!stageKey) return map;
|
|
28542
29274
|
for (const row of rows) {
|
|
@@ -28547,12 +29279,12 @@ function PipelineBoard({
|
|
|
28547
29279
|
}, [rows, stageKey, definition?.stages]);
|
|
28548
29280
|
const unplaced = cardsByStage.get(UNPLACED) ?? [];
|
|
28549
29281
|
const all = fields.data ?? [];
|
|
28550
|
-
const titleField =
|
|
29282
|
+
const titleField = useMemo48(
|
|
28551
29283
|
() => cardTitleField(all, titleKey ?? null, [stageKey]),
|
|
28552
29284
|
[all, stageKey, titleKey]
|
|
28553
29285
|
);
|
|
28554
29286
|
const unplacedLabels = useRecordLabels(titleField ? [titleField] : []);
|
|
28555
|
-
const measurable =
|
|
29287
|
+
const measurable = useMemo48(
|
|
28556
29288
|
() => all.filter((f) => ["number", "currency", "percentage"].includes(String(f.type ?? ""))),
|
|
28557
29289
|
[all]
|
|
28558
29290
|
);
|
|
@@ -29121,13 +29853,13 @@ function batchSentence(moved, waiting, notMoved, label) {
|
|
|
29121
29853
|
}
|
|
29122
29854
|
|
|
29123
29855
|
// src/CalendarView.tsx
|
|
29124
|
-
import { useEffect as useEffect68, useMemo as
|
|
29856
|
+
import { useEffect as useEffect68, useMemo as useMemo51, useRef as useRef37, useState as useState84 } from "react";
|
|
29125
29857
|
import { mayDrag as mayDrag2 } from "@ai-matrx/records/react";
|
|
29126
29858
|
import { Button as Button65, Select as Select13, SelectContent as SelectContent13, SelectItem as SelectItem13, SelectTrigger as SelectTrigger13, SelectValue as SelectValue13, cn as cn50 } from "@ai-matrx/design-system";
|
|
29127
29859
|
import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS2 } from "@ai-matrx/design-system/data-table";
|
|
29128
29860
|
|
|
29129
29861
|
// src/recordMoves.tsx
|
|
29130
|
-
import { useCallback as useCallback36, useEffect as useEffect67, useMemo as
|
|
29862
|
+
import { useCallback as useCallback36, useEffect as useEffect67, useMemo as useMemo49, useRef as useRef36, useState as useState83 } from "react";
|
|
29131
29863
|
import { useRecordsClient as useRecordsClient60 } from "@ai-matrx/records/react";
|
|
29132
29864
|
import { Button as Button64 } from "@ai-matrx/design-system";
|
|
29133
29865
|
import { Fragment as Fragment38, jsx as jsx98, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
@@ -29206,7 +29938,7 @@ function useRecordMoves({
|
|
|
29206
29938
|
[client, undo, onMoved]
|
|
29207
29939
|
);
|
|
29208
29940
|
const offering = Boolean(undo.notice);
|
|
29209
|
-
const undoRef =
|
|
29941
|
+
const undoRef = useRef36(undo);
|
|
29210
29942
|
undoRef.current = undo;
|
|
29211
29943
|
useEffect67(() => {
|
|
29212
29944
|
if (!offering || typeof document === "undefined") return;
|
|
@@ -29255,7 +29987,7 @@ function useRecordMoves({
|
|
|
29255
29987
|
}
|
|
29256
29988
|
) : null
|
|
29257
29989
|
] });
|
|
29258
|
-
return
|
|
29990
|
+
return useMemo49(
|
|
29259
29991
|
() => ({ move, create, refused, say: (says, sticky) => undo.say(says, sticky), undo, onKeyDown, notice }),
|
|
29260
29992
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
29261
29993
|
[move, create, refused, undo, onKeyDown, stale, reloadStale]
|
|
@@ -29274,12 +30006,12 @@ function MoveRefusedBadge({ refused }) {
|
|
|
29274
30006
|
}
|
|
29275
30007
|
|
|
29276
30008
|
// src/rowColorBy.tsx
|
|
29277
|
-
import { useMemo as
|
|
30009
|
+
import { useMemo as useMemo50 } from "react";
|
|
29278
30010
|
import { EMPTY_TABLE_STYLE, resolveRowColor as resolveRowColor2 } from "@ai-matrx/design-system/data-table";
|
|
29279
30011
|
function useRowColorBy(all, colorKey, style) {
|
|
29280
30012
|
const colorField = all.find((f) => f.key === colorKey);
|
|
29281
30013
|
const options = useChoiceOptions(all, colorField && isChoiceField(colorField) ? [colorField.key] : []);
|
|
29282
|
-
return
|
|
30014
|
+
return useMemo50(() => {
|
|
29283
30015
|
const lookup = (key, value) => {
|
|
29284
30016
|
const first = Array.isArray(value) ? value[0] : value;
|
|
29285
30017
|
return optionFor(options.get(key), first)?.color ?? (colorField ? storedChoiceColor(colorField, first) : void 0) ?? colorFromTheValue(key, first);
|
|
@@ -29595,12 +30327,12 @@ function CalendarView({
|
|
|
29595
30327
|
const [mode, setMode] = useState84(initialMode ?? (narrow ? "list" : "month"));
|
|
29596
30328
|
const [anchor, setAnchor] = useState84(initialDate ?? dayKey(/* @__PURE__ */ new Date()));
|
|
29597
30329
|
const [openDay, setOpenDay] = useState84(null);
|
|
29598
|
-
const titleFields =
|
|
30330
|
+
const titleFields = useMemo51(() => titleField ? [titleField] : [], [titleField]);
|
|
29599
30331
|
const labels = useRecordLabels(titleFields);
|
|
29600
30332
|
const all = fields ?? [];
|
|
29601
30333
|
const moments = holdsMoments(dateField);
|
|
29602
30334
|
const snap = (minutes) => snapTo(minutes, snapMinutes);
|
|
29603
|
-
const otherDates =
|
|
30335
|
+
const otherDates = useMemo51(
|
|
29604
30336
|
() => eligibleFieldFor("date", all, null, { far: farFields }).eligible.filter((f) => f.key !== dateField.key),
|
|
29605
30337
|
[all, farFields, dateField.key]
|
|
29606
30338
|
);
|
|
@@ -29612,7 +30344,7 @@ function CalendarView({
|
|
|
29612
30344
|
const endWorkedOut = isComputedField(endField);
|
|
29613
30345
|
const canMove = (row) => mayDrag2(row.level) && !startWorkedOut;
|
|
29614
30346
|
const creates = canCreate && !startWorkedOut;
|
|
29615
|
-
const choiceFields =
|
|
30347
|
+
const choiceFields = useMemo51(() => eligibleFieldFor("choice", all).eligible.filter(isChoiceField), [all]);
|
|
29616
30348
|
const [colorPick, setColorPick] = useState84(void 0);
|
|
29617
30349
|
const colorKey = colorPick !== void 0 ? colorPick : style?.colorBy?.field ?? choiceFields[0]?.key ?? null;
|
|
29618
30350
|
const colorOf = useRowColorBy(all, colorKey, style);
|
|
@@ -29624,7 +30356,7 @@ function CalendarView({
|
|
|
29624
30356
|
}, [undoneCount]);
|
|
29625
30357
|
const startOf = (row) => placedOver.has(row.id) ? placedOver.get(row.id).start : (row.document ?? {})[dateField.key];
|
|
29626
30358
|
const endOf = (row) => endField ? placedOver.has(row.id) ? placedOver.get(row.id).end : (row.document ?? {})[endField.key] : null;
|
|
29627
|
-
const { placed, undated } =
|
|
30359
|
+
const { placed, undated } = useMemo51(() => {
|
|
29628
30360
|
const out = [];
|
|
29629
30361
|
const without = [];
|
|
29630
30362
|
for (const row of rows) {
|
|
@@ -29646,7 +30378,7 @@ function CalendarView({
|
|
|
29646
30378
|
}, [rows, dateField.key, endField?.key, placedOver, defaultMinutes]);
|
|
29647
30379
|
const titleOf = (row) => cardWords(row, titleField, labels).text;
|
|
29648
30380
|
const rowById = (id) => rows.find((r) => r.id === id);
|
|
29649
|
-
const frame =
|
|
30381
|
+
const frame = useRef37(null);
|
|
29650
30382
|
const [focusOn, setFocusOn] = useState84(null);
|
|
29651
30383
|
useEffect68(() => {
|
|
29652
30384
|
if (!focusOn) return;
|
|
@@ -29695,7 +30427,7 @@ function CalendarView({
|
|
|
29695
30427
|
const made = await moves.create({ tableId, data, label: `New record on ${where}` });
|
|
29696
30428
|
if (made) onOpenRecord?.(made);
|
|
29697
30429
|
};
|
|
29698
|
-
const grabOffset =
|
|
30430
|
+
const grabOffset = useRef37(0);
|
|
29699
30431
|
const [resizing, setResizing] = useState84(null);
|
|
29700
30432
|
const [ghost, setGhost] = useState84(null);
|
|
29701
30433
|
useEffect68(() => {
|
|
@@ -30244,7 +30976,7 @@ function WeekHours({
|
|
|
30244
30976
|
render,
|
|
30245
30977
|
overlay
|
|
30246
30978
|
}) {
|
|
30247
|
-
const frame =
|
|
30979
|
+
const frame = useRef37(null);
|
|
30248
30980
|
useEffect68(() => {
|
|
30249
30981
|
if (frame.current) frame.current.scrollTop = 7 * HOUR_PX;
|
|
30250
30982
|
}, []);
|
|
@@ -30291,7 +31023,7 @@ function weekHeading(first) {
|
|
|
30291
31023
|
}
|
|
30292
31024
|
|
|
30293
31025
|
// src/TimelineView.tsx
|
|
30294
|
-
import { useEffect as useEffect69, useMemo as
|
|
31026
|
+
import { useEffect as useEffect69, useMemo as useMemo52, useRef as useRef38, useState as useState85 } from "react";
|
|
30295
31027
|
import { mayDrag as mayDrag3 } from "@ai-matrx/records/react";
|
|
30296
31028
|
import { Button as Button66, Select as Select14, SelectContent as SelectContent14, SelectItem as SelectItem14, SelectTrigger as SelectTrigger14, SelectValue as SelectValue14, cn as cn51 } from "@ai-matrx/design-system";
|
|
30297
31029
|
import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS3 } from "@ai-matrx/design-system/data-table";
|
|
@@ -30411,21 +31143,21 @@ function TimelineView({
|
|
|
30411
31143
|
const [zoom, setZoom] = useState85(initialZoom);
|
|
30412
31144
|
const today = dayKeyOf(/* @__PURE__ */ new Date());
|
|
30413
31145
|
const [anchor, setAnchor] = useState85(initialDate ?? today);
|
|
30414
|
-
const dates =
|
|
31146
|
+
const dates = useMemo52(() => offerableFields(fields, "date", { far: farFields }), [fields, farFields]);
|
|
30415
31147
|
const has = (list, key) => key && list.some((f) => f.key === key) ? key : null;
|
|
30416
31148
|
const [picked, setPicked] = useState85({});
|
|
30417
31149
|
useEffect69(() => setPicked({}), [startKey, endKey, groupKey, colorKey]);
|
|
30418
31150
|
const named = (key) => key && fields.some((f) => f.key === key) ? key : null;
|
|
30419
31151
|
const startChosen = "startKey" in picked ? picked.startKey ?? null : has(dates, startKey) ?? named(startKey) ?? onlyCandidate(dates);
|
|
30420
|
-
const endCandidates =
|
|
30421
|
-
const endAuto =
|
|
31152
|
+
const endCandidates = useMemo52(() => dates.filter((f) => f.key !== startChosen), [dates, startChosen]);
|
|
31153
|
+
const endAuto = useMemo52(() => {
|
|
30422
31154
|
const only = onlyCandidate(endCandidates);
|
|
30423
31155
|
return only && startChosen && endFollowsStart(rows, startChosen, only) ? only : null;
|
|
30424
31156
|
}, [endCandidates, rows, startChosen]);
|
|
30425
31157
|
const endChosen = "endKey" in picked ? picked.endKey ?? null : has(endCandidates, endKey) ?? (endKey !== startChosen ? named(endKey) : null) ?? (endKey === void 0 ? endAuto : null);
|
|
30426
|
-
const groupCandidates =
|
|
31158
|
+
const groupCandidates = useMemo52(() => groupableFields(fields), [fields]);
|
|
30427
31159
|
const groupChosen = "groupKey" in picked ? picked.groupKey ?? null : has(groupCandidates, groupKey);
|
|
30428
|
-
const choiceFields =
|
|
31160
|
+
const choiceFields = useMemo52(() => fields.filter(isChoiceField), [fields]);
|
|
30429
31161
|
const colorChosen = "colorKey" in picked ? picked.colorKey ?? null : has(choiceFields, colorKey) ?? (colorKey === void 0 ? has(choiceFields, style?.colorBy?.field) ?? onlyCandidate(choiceFields) : null);
|
|
30430
31162
|
const setting = (patch) => {
|
|
30431
31163
|
setPicked((held) => ({ ...held, ...patch }));
|
|
@@ -30438,7 +31170,7 @@ function TimelineView({
|
|
|
30438
31170
|
const endWorkedOut = isComputedField(endField);
|
|
30439
31171
|
const canMove = (row) => mayDrag3(row.level) && !startWorkedOut;
|
|
30440
31172
|
const colorOf = useRowColorBy(fields, colorChosen, style);
|
|
30441
|
-
const labelFields =
|
|
31173
|
+
const labelFields = useMemo52(() => [titleField, groupField].filter((f) => Boolean(f)), [titleField, groupField]);
|
|
30442
31174
|
const labels = useRecordLabels(labelFields);
|
|
30443
31175
|
const titleOf = (row) => cardWords(row, titleField, labels).text;
|
|
30444
31176
|
const groupOptions = useChoiceOptions(fields, groupField && isChoiceField(groupField) ? [groupField.key] : []).get(groupField?.key ?? "");
|
|
@@ -30451,7 +31183,7 @@ function TimelineView({
|
|
|
30451
31183
|
const startOf = (row) => placedOver.has(row.id) ? placedOver.get(row.id).start : startField ? (row.document ?? {})[startField.key] : null;
|
|
30452
31184
|
const endOf = (row) => !endField ? null : placedOver.has(row.id) ? placedOver.get(row.id).end : (row.document ?? {})[endField.key];
|
|
30453
31185
|
const [dragging, setDragging] = useState85(null);
|
|
30454
|
-
const { placed, unscheduled } =
|
|
31186
|
+
const { placed, unscheduled } = useMemo52(() => {
|
|
30455
31187
|
const out = [];
|
|
30456
31188
|
const without = [];
|
|
30457
31189
|
for (const row of rows) {
|
|
@@ -30542,12 +31274,12 @@ function TimelineView({
|
|
|
30542
31274
|
const from = windowStart(anchor, zoom);
|
|
30543
31275
|
const days = WINDOW[zoom].days;
|
|
30544
31276
|
const width = days * px;
|
|
30545
|
-
const scale =
|
|
31277
|
+
const scale = useMemo52(() => scaleOf(from, days, zoom), [from, days, zoom]);
|
|
30546
31278
|
const xOf = (day) => daysBetween(from, day) * px;
|
|
30547
|
-
const scroller =
|
|
31279
|
+
const scroller = useRef38(null);
|
|
30548
31280
|
const grouped = Boolean(groupField);
|
|
30549
31281
|
const [scrollX, setScrollX] = useState85(0);
|
|
30550
|
-
const frame =
|
|
31282
|
+
const frame = useRef38(null);
|
|
30551
31283
|
const onScroll = () => {
|
|
30552
31284
|
if (frame.current !== null) return;
|
|
30553
31285
|
frame.current = requestAnimationFrame(() => {
|
|
@@ -30562,7 +31294,7 @@ function TimelineView({
|
|
|
30562
31294
|
el.scrollLeft = Math.max(0, xOf(anchor) - (el.clientWidth - label) / 4);
|
|
30563
31295
|
setScrollX(el.scrollLeft);
|
|
30564
31296
|
}, [anchor, zoom, grouped]);
|
|
30565
|
-
const lanes =
|
|
31297
|
+
const lanes = useMemo52(() => {
|
|
30566
31298
|
if (!groupField) return [{ key: "all", label: "", color: void 0, bars: placed }];
|
|
30567
31299
|
const order = (groupOptions ?? []).map((o) => o.label);
|
|
30568
31300
|
const map = new Map(order.map((name) => [name, []]));
|
|
@@ -30581,14 +31313,14 @@ function TimelineView({
|
|
|
30581
31313
|
}, [groupField, groupOptions, placed, labels]);
|
|
30582
31314
|
const laneChangeAllowed = Boolean(groupField && fieldIsEditable(groupField));
|
|
30583
31315
|
const laneLocked = groupField && !laneChangeAllowed ? `${fieldName(groupField)} is worked out, so a bar keeps its row.` : null;
|
|
30584
|
-
const holdsKeys =
|
|
31316
|
+
const holdsKeys = useMemo52(
|
|
30585
31317
|
() => Boolean(groupField) && (groupOptions ?? []).length > 0 && rows.some((row) => {
|
|
30586
31318
|
const v = (row.document ?? {})[groupField.key];
|
|
30587
31319
|
return (Array.isArray(v) ? v : [v]).some((x) => (groupOptions ?? []).some((o) => o.key === x && o.id !== x));
|
|
30588
31320
|
}),
|
|
30589
31321
|
[rows, groupOptions, groupField]
|
|
30590
31322
|
);
|
|
30591
|
-
const heldIn =
|
|
31323
|
+
const heldIn = useMemo52(() => {
|
|
30592
31324
|
const out = /* @__PURE__ */ new Map();
|
|
30593
31325
|
if (!groupField) return out;
|
|
30594
31326
|
for (const row of rows) {
|
|
@@ -31168,7 +31900,7 @@ function CardFieldsPicker({
|
|
|
31168
31900
|
}
|
|
31169
31901
|
|
|
31170
31902
|
// src/ListView.tsx
|
|
31171
|
-
import { useMemo as
|
|
31903
|
+
import { useMemo as useMemo53 } from "react";
|
|
31172
31904
|
import { Select as Select15, SelectContent as SelectContent15, SelectItem as SelectItem15, SelectTrigger as SelectTrigger15, SelectValue as SelectValue15, cn as cn52 } from "@ai-matrx/design-system";
|
|
31173
31905
|
import { resolveRowColor as resolveRowColor3, ROW_TINT_CLASS as ROW_TINT_CLASS2 } from "@ai-matrx/design-system/data-table";
|
|
31174
31906
|
import { jsx as jsx104, jsxs as jsxs94 } from "react/jsx-runtime";
|
|
@@ -31208,7 +31940,7 @@ function ListView({
|
|
|
31208
31940
|
}) {
|
|
31209
31941
|
const groupField = grouping?.field ? fields.find((f) => f.key === grouping.field) : void 0;
|
|
31210
31942
|
const groupKey = groupField?.key ?? null;
|
|
31211
|
-
const groups =
|
|
31943
|
+
const groups = useMemo53(() => listGroups(rows, groupKey), [rows, groupKey]);
|
|
31212
31944
|
const shown4 = cardFieldsShown(fields, hiddenFields, [titleField?.key, groupKey]);
|
|
31213
31945
|
const chose = hiddenFields !== void 0;
|
|
31214
31946
|
const moves = useRecordMoves({ tableId, rows, ...onMoved ? { onMoved } : {} });
|
|
@@ -31306,7 +32038,7 @@ function ListRow({
|
|
|
31306
32038
|
style,
|
|
31307
32039
|
onOpenRecord
|
|
31308
32040
|
}) {
|
|
31309
|
-
const wanted =
|
|
32041
|
+
const wanted = useMemo53(() => titleField && pointsAtRecords(titleField) ? [titleField] : NO_FIELDS, [titleField]);
|
|
31310
32042
|
const labels = useRecordLabels(wanted);
|
|
31311
32043
|
const { text: title, withheld } = cardWords(row, titleField, labels);
|
|
31312
32044
|
const doc = row.document ?? {};
|
|
@@ -31353,7 +32085,7 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
|
|
|
31353
32085
|
useEffect72(() => {
|
|
31354
32086
|
setLimit(pageSize);
|
|
31355
32087
|
}, [questionKey, pageSize]);
|
|
31356
|
-
const storeSort =
|
|
32088
|
+
const storeSort = useMemo54(
|
|
31357
32089
|
() => (view.sorts ?? []).map((s) => ({ field: s.field, direction: s.direction })),
|
|
31358
32090
|
[view.sorts]
|
|
31359
32091
|
);
|
|
@@ -31384,7 +32116,7 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
|
|
|
31384
32116
|
}, [client, ruleId, pageSize]);
|
|
31385
32117
|
const asked3 = stableFilterKey4(filter ?? null);
|
|
31386
32118
|
const fromView = asked3 !== "{}" && (asked3 === stableFilterKey4(view.where ?? null) || asked3 === stableFilterKey4(view.filters ?? null));
|
|
31387
|
-
const tableRows =
|
|
32119
|
+
const tableRows = useMemo54(() => table.data?.rows ?? [], [table.data]);
|
|
31388
32120
|
const manual = view.order === "manual" && Boolean(viewId) && !ruleId;
|
|
31389
32121
|
const hand = useHandOrderRows({
|
|
31390
32122
|
viewId: viewId ?? null,
|
|
@@ -31397,7 +32129,7 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
|
|
|
31397
32129
|
const rows = ruleId ? ruled.rows : manual ? hand.rows ?? NO_ROWS2 : tableRows;
|
|
31398
32130
|
const total = ruleId || manual ? null : table.data?.total ?? null;
|
|
31399
32131
|
const sortsKey = JSON.stringify(view.sorts ?? []);
|
|
31400
|
-
const shown4 =
|
|
32132
|
+
const shown4 = useMemo54(
|
|
31401
32133
|
() => manual || !ruleId ? rows : sortRows(rows, JSON.parse(sortsKey)),
|
|
31402
32134
|
[rows, manual, ruleId, sortsKey]
|
|
31403
32135
|
);
|
|
@@ -31681,7 +32413,7 @@ function Board({
|
|
|
31681
32413
|
const records = useViewRecords(view, pageSize, filter, viewId ?? null);
|
|
31682
32414
|
const stage = useStageField(view.subject);
|
|
31683
32415
|
const decorations = useTableDecorations(view.subject);
|
|
31684
|
-
const style =
|
|
32416
|
+
const style = useMemo54(
|
|
31685
32417
|
() => resolveTableStyle(decorations.data, fields.data ?? [], view.presentation?.style),
|
|
31686
32418
|
[decorations.data, fields.data, view.presentation?.style]
|
|
31687
32419
|
);
|
|
@@ -32046,10 +32778,10 @@ function Kanban({
|
|
|
32046
32778
|
canAdd = false
|
|
32047
32779
|
}) {
|
|
32048
32780
|
const client = useRecordsClient62();
|
|
32049
|
-
const groupFields =
|
|
32781
|
+
const groupFields = useMemo54(() => [groupField], [groupField]);
|
|
32050
32782
|
const labels = useRecordLabels(groupFields);
|
|
32051
32783
|
const options = useChoiceOptions(groupFields, isChoiceField(groupField) ? [groupField.key] : []).get(groupField.key);
|
|
32052
|
-
const columns =
|
|
32784
|
+
const columns = useMemo54(() => {
|
|
32053
32785
|
const map = /* @__PURE__ */ new Map();
|
|
32054
32786
|
const order = (options ?? []).map((o) => o.label);
|
|
32055
32787
|
for (const label of order) map.set(label, []);
|
|
@@ -32063,14 +32795,14 @@ function Kanban({
|
|
|
32063
32795
|
return [...map.entries()].sort((a, b) => rank(a[0]) - rank(b[0]) || a[0].localeCompare(b[0]));
|
|
32064
32796
|
}, [rows, groupField, labels, options]);
|
|
32065
32797
|
const moves = useRecordMoves({ tableId, rows, onMoved });
|
|
32066
|
-
const holdsKeys =
|
|
32798
|
+
const holdsKeys = useMemo54(
|
|
32067
32799
|
() => (options ?? []).length > 0 && rows.some((row) => {
|
|
32068
32800
|
const v = (row.document ?? {})[groupField.key];
|
|
32069
32801
|
return (Array.isArray(v) ? v : [v]).some((x) => (options ?? []).some((o) => o.key === x && o.id !== x));
|
|
32070
32802
|
}),
|
|
32071
32803
|
[rows, options, groupField.key]
|
|
32072
32804
|
);
|
|
32073
|
-
const heldIn =
|
|
32805
|
+
const heldIn = useMemo54(() => {
|
|
32074
32806
|
const out = /* @__PURE__ */ new Map();
|
|
32075
32807
|
for (const row of rows) {
|
|
32076
32808
|
const raw = (row.document ?? {})[groupField.key];
|
|
@@ -32274,7 +33006,7 @@ function Gallery({
|
|
|
32274
33006
|
onNew,
|
|
32275
33007
|
newLabel
|
|
32276
33008
|
}) {
|
|
32277
|
-
const hidden =
|
|
33009
|
+
const hidden = useMemo54(() => new Set(hiddenFields ?? []), [hiddenFields]);
|
|
32278
33010
|
const imageField = imageKey ? fields.find((field2) => field2.key === imageKey) : void 0;
|
|
32279
33011
|
const shown4 = fields.filter((field2) => !hidden.has(field2.key) && field2.key !== imageKey);
|
|
32280
33012
|
const chose = hiddenFields !== void 0;
|
|
@@ -32374,7 +33106,7 @@ function RecordCard({
|
|
|
32374
33106
|
fields
|
|
32375
33107
|
}) {
|
|
32376
33108
|
const host = useRecordsUi();
|
|
32377
|
-
const wanted =
|
|
33109
|
+
const wanted = useMemo54(
|
|
32378
33110
|
() => field2 && pointsAtRecords(field2) ? [field2] : NO_FIELDS2,
|
|
32379
33111
|
[field2]
|
|
32380
33112
|
);
|
|
@@ -32454,7 +33186,7 @@ function ArchivedView({
|
|
|
32454
33186
|
const [loading, setLoading] = useState89(true);
|
|
32455
33187
|
const [error, setError] = useState89(null);
|
|
32456
33188
|
const [restoring, setRestoring] = useState89(null);
|
|
32457
|
-
const [
|
|
33189
|
+
const [refusal4, setRefusal] = useState89(null);
|
|
32458
33190
|
useEffect73(() => {
|
|
32459
33191
|
if (laneFromHost) setLane(laneFromHost);
|
|
32460
33192
|
}, [laneFromHost]);
|
|
@@ -32531,7 +33263,7 @@ function ArchivedView({
|
|
|
32531
33263
|
/* @__PURE__ */ jsxs96("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
32532
33264
|
/* @__PURE__ */ jsx106("span", { className: "truncate text-sm", children: recordName(row.document, titleKey) }),
|
|
32533
33265
|
/* @__PURE__ */ jsx106("span", { className: "truncate text-xs text-muted-foreground", "data-testid": "archived-who", children: archivedByLine(row) }),
|
|
32534
|
-
|
|
33266
|
+
refusal4 && refusal4.recordId === row.id ? /* @__PURE__ */ jsx106(RefusalNotice, { error: refusal4.error, className: "mt-2" }) : null
|
|
32535
33267
|
] }),
|
|
32536
33268
|
mayRestore ? /* @__PURE__ */ jsx106(
|
|
32537
33269
|
Button69,
|
|
@@ -32560,7 +33292,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
|
|
|
32560
33292
|
const [rows, setRows] = useState89(null);
|
|
32561
33293
|
const [error, setError] = useState89(null);
|
|
32562
33294
|
const [restoring, setRestoring] = useState89(null);
|
|
32563
|
-
const [
|
|
33295
|
+
const [refusal4, setRefusal] = useState89(null);
|
|
32564
33296
|
const read = useCallback37(async () => {
|
|
32565
33297
|
const answer = await client.fieldsRetired({ table_id: tableId });
|
|
32566
33298
|
if (answer.ok) {
|
|
@@ -32604,7 +33336,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
|
|
|
32604
33336
|
/* @__PURE__ */ jsxs96("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
32605
33337
|
/* @__PURE__ */ jsx106("span", { className: "truncate text-sm", children: name }),
|
|
32606
33338
|
/* @__PURE__ */ jsx106("span", { className: "truncate text-xs text-muted-foreground", children: retiredColumnLine(row) }),
|
|
32607
|
-
|
|
33339
|
+
refusal4 && refusal4.fieldId === row.id ? /* @__PURE__ */ jsx106(RefusalNotice, { error: refusal4.error, className: "mt-2" }) : null
|
|
32608
33340
|
] }),
|
|
32609
33341
|
mayRestore ? /* @__PURE__ */ jsx106(Button69, { size: "sm", variant: "outline", disabled: restoring === row.id, onClick: () => void restore(row.id), children: restoring === row.id ? "Bringing it back\u2026" : "Restore" }) : null
|
|
32610
33342
|
]
|
|
@@ -32673,7 +33405,7 @@ function ArchivedPortals({
|
|
|
32673
33405
|
const [confirming, setConfirming] = useState90(null);
|
|
32674
33406
|
const [typed2, setTyped] = useState90("");
|
|
32675
33407
|
const [restoring, setRestoring] = useState90(null);
|
|
32676
|
-
const [
|
|
33408
|
+
const [refusal4, setRefusal] = useState90(null);
|
|
32677
33409
|
const [said, setSaid] = useState90(null);
|
|
32678
33410
|
const read = useCallback38(async () => {
|
|
32679
33411
|
const answered = await client.listPortals({ archived: "archived" });
|
|
@@ -32789,7 +33521,7 @@ function ArchivedPortals({
|
|
|
32789
33521
|
)
|
|
32790
33522
|
] })
|
|
32791
33523
|
] }) : null,
|
|
32792
|
-
|
|
33524
|
+
refusal4 && refusal4.portalId === portal.portal_id ? /* @__PURE__ */ jsx107(RefusalNotice, { error: refusal4.error }) : null
|
|
32793
33525
|
]
|
|
32794
33526
|
},
|
|
32795
33527
|
portal.portal_id
|
|
@@ -32806,9 +33538,9 @@ import { useRecordsClient as useRecordsClient65 } from "@ai-matrx/records/react"
|
|
|
32806
33538
|
import { Badge as Badge14, Button as Button71, Input as Input6, Popover as Popover11, PopoverContent as PopoverContent11, PopoverTrigger as PopoverTrigger11, Skeleton as Skeleton14, cn as cn56 } from "@ai-matrx/design-system";
|
|
32807
33539
|
|
|
32808
33540
|
// src/seedOnce.ts
|
|
32809
|
-
import { useCallback as useCallback39, useRef as
|
|
33541
|
+
import { useCallback as useCallback39, useRef as useRef39 } from "react";
|
|
32810
33542
|
function useSeedGuard() {
|
|
32811
|
-
const claimed =
|
|
33543
|
+
const claimed = useRef39(/* @__PURE__ */ new Set());
|
|
32812
33544
|
return useCallback39((name) => {
|
|
32813
33545
|
if (claimed.current.has(name)) return false;
|
|
32814
33546
|
claimed.current.add(name);
|
|
@@ -33126,7 +33858,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
|
|
|
33126
33858
|
}
|
|
33127
33859
|
|
|
33128
33860
|
// src/ProposalRow.tsx
|
|
33129
|
-
import { useEffect as useEffect76, useRef as
|
|
33861
|
+
import { useEffect as useEffect76, useRef as useRef40, useState as useState92 } from "react";
|
|
33130
33862
|
import { useRecordsClient as useRecordsClient66 } from "@ai-matrx/records/react";
|
|
33131
33863
|
import { Badge as Badge15, Button as Button72, cn as cn57 } from "@ai-matrx/design-system";
|
|
33132
33864
|
import { jsx as jsx109, jsxs as jsxs99 } from "react/jsx-runtime";
|
|
@@ -33144,7 +33876,7 @@ function ProposalRow({
|
|
|
33144
33876
|
const [settled, setSettled] = useState92(outcome ?? null);
|
|
33145
33877
|
const [busy, setBusy] = useState92(false);
|
|
33146
33878
|
const [confirming, setConfirming] = useState92(false);
|
|
33147
|
-
const drawnVersion =
|
|
33879
|
+
const drawnVersion = useRef40(null);
|
|
33148
33880
|
const needsVersion = change.act === "update" && Boolean(change.record) && change.version === void 0 && !onApply && !settled;
|
|
33149
33881
|
useEffect76(() => {
|
|
33150
33882
|
if (needsVersion && change.record && !drawnVersion.current) drawnVersion.current = readVersionNow(client, change.record);
|
|
@@ -33234,14 +33966,14 @@ function ProposalRow({
|
|
|
33234
33966
|
}
|
|
33235
33967
|
|
|
33236
33968
|
// src/ActionInbox.tsx
|
|
33237
|
-
import { useCallback as useCallback42, useEffect as useEffect78, useMemo as
|
|
33969
|
+
import { useCallback as useCallback42, useEffect as useEffect78, useMemo as useMemo56, useRef as useRef41, useState as useState94 } from "react";
|
|
33238
33970
|
import { useRecordsClient as useRecordsClient68 } from "@ai-matrx/records/react";
|
|
33239
33971
|
import { Badge as Badge17, Button as Button74, Checkbox as Checkbox11, Skeleton as Skeleton16, cn as cn59 } from "@ai-matrx/design-system";
|
|
33240
33972
|
import { toggleSelection as toggleSelection2 } from "@ai-matrx/design-system/data-table";
|
|
33241
33973
|
import { formatAbsoluteDate, formatDurationMs } from "@ai-matrx/kit/format";
|
|
33242
33974
|
|
|
33243
33975
|
// src/ChecklistRunner.tsx
|
|
33244
|
-
import { useCallback as useCallback41, useEffect as useEffect77, useMemo as
|
|
33976
|
+
import { useCallback as useCallback41, useEffect as useEffect77, useMemo as useMemo55, useState as useState93 } from "react";
|
|
33245
33977
|
import { useRecordsClient as useRecordsClient67, useTable as useTable19 } from "@ai-matrx/records/react";
|
|
33246
33978
|
import { Badge as Badge16, BasicInput as BasicInput22, BasicTextarea as BasicTextarea9, Button as Button73, Skeleton as Skeleton15, cn as cn58 } from "@ai-matrx/design-system";
|
|
33247
33979
|
import { humanizeIdentifier as humanizeIdentifier12 } from "@ai-matrx/kit/text-case";
|
|
@@ -33375,7 +34107,7 @@ function ChecklistRunner({
|
|
|
33375
34107
|
},
|
|
33376
34108
|
[client, loadSteps]
|
|
33377
34109
|
);
|
|
33378
|
-
const active =
|
|
34110
|
+
const active = useMemo55(
|
|
33379
34111
|
() => runs?.find((r) => r.run_id === activeId) ?? null,
|
|
33380
34112
|
[runs, activeId]
|
|
33381
34113
|
);
|
|
@@ -33603,7 +34335,7 @@ function MyChecklistSteps({
|
|
|
33603
34335
|
}, [held, onSteps]);
|
|
33604
34336
|
const steps = onlyIds ? held.filter((s) => onlyIds.has(s.step_id)) : held;
|
|
33605
34337
|
const [busy, setBusy] = useState93(null);
|
|
33606
|
-
const [
|
|
34338
|
+
const [refusal4, setRefusal] = useState93(null);
|
|
33607
34339
|
const complete = useCallback41(
|
|
33608
34340
|
async (step2, evidence) => {
|
|
33609
34341
|
setBusy(step2.step_id);
|
|
@@ -33626,7 +34358,7 @@ function MyChecklistSteps({
|
|
|
33626
34358
|
/* @__PURE__ */ jsx110("span", { className: "tabular-nums", children: steps.length })
|
|
33627
34359
|
] }),
|
|
33628
34360
|
error ? /* @__PURE__ */ jsx110(RefusalNotice, { error }) : null,
|
|
33629
|
-
|
|
34361
|
+
refusal4 ? /* @__PURE__ */ jsx110(RefusalNotice, { error: refusal4 }) : null,
|
|
33630
34362
|
/* @__PURE__ */ jsx110("ol", { className: "flex flex-col gap-1.5", children: steps.map(
|
|
33631
34363
|
(step2) => actions ? /* @__PURE__ */ jsxs100("div", { className: "flex flex-col gap-0.5", "data-step-row": step2.step_id, children: [
|
|
33632
34364
|
/* @__PURE__ */ jsx110(StepRow, { step: step2, busy: busy === step2.step_id, onComplete: (evidence) => void complete(step2, evidence) }),
|
|
@@ -33827,7 +34559,7 @@ function ChecklistTemplateEditor({
|
|
|
33827
34559
|
const [saved, setSaved] = useState93(false);
|
|
33828
34560
|
const [name, setName] = useState93("");
|
|
33829
34561
|
const [rows, setRows] = useState93([{ ...EMPTY_ROW }]);
|
|
33830
|
-
const [
|
|
34562
|
+
const [refusal4, setRefusal] = useState93(null);
|
|
33831
34563
|
const [error, setError] = useState93(null);
|
|
33832
34564
|
const [busy, setBusy] = useState93(false);
|
|
33833
34565
|
const [loading, setLoading] = useState93(Boolean(templateId));
|
|
@@ -33859,7 +34591,7 @@ function ChecklistTemplateEditor({
|
|
|
33859
34591
|
cancelled = true;
|
|
33860
34592
|
};
|
|
33861
34593
|
}, [client, templateId]);
|
|
33862
|
-
const spec =
|
|
34594
|
+
const spec = useMemo55(
|
|
33863
34595
|
() => ({
|
|
33864
34596
|
name: name.trim(),
|
|
33865
34597
|
about_table_id: aboutTableId,
|
|
@@ -34003,10 +34735,10 @@ function ChecklistTemplateEditor({
|
|
|
34003
34735
|
] }, index)) }),
|
|
34004
34736
|
/* @__PURE__ */ jsxs100("div", { className: "flex items-center gap-1.5", children: [
|
|
34005
34737
|
/* @__PURE__ */ jsx110(Button73, { size: "sm", variant: "outline", onClick: () => setRows((held) => [...held, { ...EMPTY_ROW }]), children: "Add a step" }),
|
|
34006
|
-
/* @__PURE__ */ jsx110(Button73, { size: "sm", disabled: busy ||
|
|
34738
|
+
/* @__PURE__ */ jsx110(Button73, { size: "sm", disabled: busy || refusal4 !== null || spec.steps.length === 0, onClick: () => void save(), children: busy ? "\u2026" : "Save" }),
|
|
34007
34739
|
saved && !busy ? /* @__PURE__ */ jsx110("span", { className: "text-xs text-muted-foreground", "data-testid": "checklist-editor-saved", role: "status", children: "Saved" }) : null
|
|
34008
34740
|
] }),
|
|
34009
|
-
|
|
34741
|
+
refusal4 ? /* @__PURE__ */ jsx110("p", { className: "text-xs text-muted-foreground", "data-testid": "checklist-editor-refusal", children: refusal4 }) : null
|
|
34010
34742
|
] });
|
|
34011
34743
|
}
|
|
34012
34744
|
function toStepSpec(row, index) {
|
|
@@ -34139,9 +34871,9 @@ function ActionInbox({
|
|
|
34139
34871
|
const [outcome, setOutcome] = useState94({});
|
|
34140
34872
|
const [busy, setBusy] = useState94(null);
|
|
34141
34873
|
const [cursor, setCursor] = useState94(0);
|
|
34142
|
-
const listRef =
|
|
34874
|
+
const listRef = useRef41(null);
|
|
34143
34875
|
const [selected, setSelected] = useState94(/* @__PURE__ */ new Set());
|
|
34144
|
-
const anchor =
|
|
34876
|
+
const anchor = useRef41(null);
|
|
34145
34877
|
const [deciding, setDeciding] = useState94(false);
|
|
34146
34878
|
const [batchSaid, setBatchSaid] = useState94(null);
|
|
34147
34879
|
const [view, setView] = useState94("inbox");
|
|
@@ -34168,17 +34900,17 @@ function ActionInbox({
|
|
|
34168
34900
|
useEffect78(() => {
|
|
34169
34901
|
void load();
|
|
34170
34902
|
}, [load]);
|
|
34171
|
-
const narrowed =
|
|
34903
|
+
const narrowed = useMemo56(() => {
|
|
34172
34904
|
const all = (items ?? []).filter((i) => !(view === "inbox" && i.kind === "assignment" && stepIds.has(i.item_id)));
|
|
34173
34905
|
if (!tableId || everyTable) return all;
|
|
34174
34906
|
return all.filter((i) => i.table_id === tableId);
|
|
34175
34907
|
}, [items, tableId, everyTable, view, stepIds]);
|
|
34176
|
-
const waitingIds =
|
|
34908
|
+
const waitingIds = useMemo56(
|
|
34177
34909
|
() => new Set((items ?? []).filter((i) => i.kind === "assignment").map((i) => i.item_id)),
|
|
34178
34910
|
[items]
|
|
34179
34911
|
);
|
|
34180
|
-
const groups =
|
|
34181
|
-
const shown4 =
|
|
34912
|
+
const groups = useMemo56(() => groupInbox(narrowed, groupBy), [narrowed, groupBy]);
|
|
34913
|
+
const shown4 = useMemo56(() => groups.flatMap((g) => g.items), [groups]);
|
|
34182
34914
|
const elsewhere = (items?.length ?? 0) - narrowed.length;
|
|
34183
34915
|
useEffect78(() => {
|
|
34184
34916
|
if (cursor >= shown4.length) setCursor(Math.max(0, shown4.length - 1));
|
|
@@ -34205,9 +34937,9 @@ function ActionInbox({
|
|
|
34205
34937
|
[client, load]
|
|
34206
34938
|
);
|
|
34207
34939
|
const [held, setHeld] = useState94({});
|
|
34208
|
-
const holds2 =
|
|
34209
|
-
const lastHold =
|
|
34210
|
-
const holdSeq =
|
|
34940
|
+
const holds2 = useRef41(/* @__PURE__ */ new Map());
|
|
34941
|
+
const lastHold = useRef41(null);
|
|
34942
|
+
const holdSeq = useRef41(0);
|
|
34211
34943
|
const [, tick] = useState94(0);
|
|
34212
34944
|
useEffect78(() => {
|
|
34213
34945
|
if (Object.keys(held).length === 0) return;
|
|
@@ -34264,7 +34996,7 @@ function ActionInbox({
|
|
|
34264
34996
|
flush();
|
|
34265
34997
|
};
|
|
34266
34998
|
}, []);
|
|
34267
|
-
const resumed =
|
|
34999
|
+
const resumed = useRef41(false);
|
|
34268
35000
|
useEffect78(() => {
|
|
34269
35001
|
if (resumed.current || items === null || view !== "inbox") return;
|
|
34270
35002
|
resumed.current = true;
|
|
@@ -34885,7 +35617,7 @@ function ActionInbox({
|
|
|
34885
35617
|
}
|
|
34886
35618
|
|
|
34887
35619
|
// src/HistoryPanel.tsx
|
|
34888
|
-
import { useCallback as useCallback43, useEffect as useEffect79, useRef as
|
|
35620
|
+
import { useCallback as useCallback43, useEffect as useEffect79, useRef as useRef42, useState as useState95 } from "react";
|
|
34889
35621
|
import {
|
|
34890
35622
|
useFields as useFields20,
|
|
34891
35623
|
useRecordChangeRevision,
|
|
@@ -34905,9 +35637,9 @@ function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
|
|
|
34905
35637
|
const [error, setError] = useState95(null);
|
|
34906
35638
|
const [open, setOpen] = useState95(null);
|
|
34907
35639
|
const [pending, setPending] = useState95({ phase: "idle" });
|
|
34908
|
-
const seenAtPreview =
|
|
35640
|
+
const seenAtPreview = useRef42(null);
|
|
34909
35641
|
const [said, setSaid] = useState95(null);
|
|
34910
|
-
const listRef =
|
|
35642
|
+
const listRef = useRef42(null);
|
|
34911
35643
|
const changed = useRecordChangeRevision(recordId);
|
|
34912
35644
|
const load = useCallback43(async () => {
|
|
34913
35645
|
const answered = await client.recordHistory({ record_id: recordId });
|
|
@@ -35200,7 +35932,7 @@ function say(value, field2) {
|
|
|
35200
35932
|
}
|
|
35201
35933
|
|
|
35202
35934
|
// src/CommentThread.tsx
|
|
35203
|
-
import { useCallback as useCallback44, useEffect as useEffect80, useMemo as
|
|
35935
|
+
import { useCallback as useCallback44, useEffect as useEffect80, useMemo as useMemo57, useRef as useRef43, useState as useState96 } from "react";
|
|
35204
35936
|
import {
|
|
35205
35937
|
useFields as useFields21,
|
|
35206
35938
|
useRecordsClient as useRecordsClient70,
|
|
@@ -35224,7 +35956,7 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
|
|
|
35224
35956
|
const [people, setPeople] = useState96([]);
|
|
35225
35957
|
const [mentionQuery, setMentionQuery] = useState96(null);
|
|
35226
35958
|
const [picked, setPicked] = useState96([]);
|
|
35227
|
-
const box =
|
|
35959
|
+
const box = useRef43(null);
|
|
35228
35960
|
const load = useCallback44(async () => {
|
|
35229
35961
|
const answered = await client.commentThread({ record_id: recordId, include_resolved: showResolved });
|
|
35230
35962
|
if (!answered.ok) {
|
|
@@ -35258,7 +35990,7 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
|
|
|
35258
35990
|
alive = false;
|
|
35259
35991
|
};
|
|
35260
35992
|
}, [host]);
|
|
35261
|
-
const candidates =
|
|
35993
|
+
const candidates = useMemo57(() => {
|
|
35262
35994
|
if (mentionQuery === null) return [];
|
|
35263
35995
|
const q = mentionQuery.trim().toLowerCase();
|
|
35264
35996
|
return people.filter((p) => !picked.some((already) => already.userId === p.userId)).filter((p) => q === "" || (p.name ?? p.email ?? "").toLowerCase().includes(q)).slice(0, 6);
|
|
@@ -35444,7 +36176,7 @@ function Line({
|
|
|
35444
36176
|
}
|
|
35445
36177
|
|
|
35446
36178
|
// src/FieldHistoryPanel.tsx
|
|
35447
|
-
import { useCallback as useCallback45, useEffect as useEffect81, useRef as
|
|
36179
|
+
import { useCallback as useCallback45, useEffect as useEffect81, useRef as useRef44, useState as useState97 } from "react";
|
|
35448
36180
|
import {
|
|
35449
36181
|
useFields as useFields22,
|
|
35450
36182
|
useRecordsClient as useRecordsClient71,
|
|
@@ -35468,7 +36200,7 @@ function FieldHistoryPanel({
|
|
|
35468
36200
|
const [rows, setRows] = useState97(null);
|
|
35469
36201
|
const [error, setError] = useState97(null);
|
|
35470
36202
|
const [pending, setPending] = useState97({ phase: "idle" });
|
|
35471
|
-
const seenAtPreview =
|
|
36203
|
+
const seenAtPreview = useRef44(null);
|
|
35472
36204
|
const [said, setSaid] = useState97(null);
|
|
35473
36205
|
const load = useCallback45(async () => {
|
|
35474
36206
|
const answered = await client.fieldHistory(
|
|
@@ -35716,7 +36448,7 @@ function submissionStamp(args) {
|
|
|
35716
36448
|
}
|
|
35717
36449
|
|
|
35718
36450
|
// src/PortalBuilder.tsx
|
|
35719
|
-
import { useCallback as useCallback46, useEffect as useEffect82, useMemo as
|
|
36451
|
+
import { useCallback as useCallback46, useEffect as useEffect82, useMemo as useMemo58, useRef as useRef45, useState as useState98 } from "react";
|
|
35720
36452
|
import { useRecordsClient as useRecordsClient72, useTables as useTables4 } from "@ai-matrx/records/react";
|
|
35721
36453
|
import { BasicInput as BasicInput23, Button as Button78, Checkbox as Checkbox12, Label as Label18, Separator as Separator10, Skeleton as Skeleton20, cn as cn63 } from "@ai-matrx/design-system";
|
|
35722
36454
|
import { Fragment as Fragment46, jsx as jsx115, jsxs as jsxs105 } from "react/jsx-runtime";
|
|
@@ -35784,7 +36516,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
|
|
|
35784
36516
|
return rest;
|
|
35785
36517
|
});
|
|
35786
36518
|
}, [tableId, portalId, clientTableId, cameFromPeople]);
|
|
35787
|
-
const ticked =
|
|
36519
|
+
const ticked = useMemo58(() => Object.values(exposures).filter((e) => e.on), [exposures]);
|
|
35788
36520
|
const tiesTo = useCallback46(
|
|
35789
36521
|
(id) => (fieldsByTable[id] ?? []).filter(
|
|
35790
36522
|
(f) => f.type === "relation" && f.relation_target === clientTableId
|
|
@@ -35806,7 +36538,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
|
|
|
35806
36538
|
if (on) void loadFields(t.id);
|
|
35807
36539
|
}
|
|
35808
36540
|
const [linking, setLinking] = useState98(null);
|
|
35809
|
-
const linkingNow =
|
|
36541
|
+
const linkingNow = useRef45(null);
|
|
35810
36542
|
async function addLinkBack(id) {
|
|
35811
36543
|
const clients = (tables.data ?? []).find((t) => t.id === clientTableId);
|
|
35812
36544
|
if (!clientTableId || !clients) return;
|
|
@@ -35833,7 +36565,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
|
|
|
35833
36565
|
linkingNow.current = null;
|
|
35834
36566
|
setLinking(null);
|
|
35835
36567
|
}
|
|
35836
|
-
const autoLinked =
|
|
36568
|
+
const autoLinked = useRef45(/* @__PURE__ */ new Set());
|
|
35837
36569
|
useEffect82(() => {
|
|
35838
36570
|
if (linking !== null || !clientTableId) return;
|
|
35839
36571
|
for (const e of Object.values(exposures)) {
|
|
@@ -35870,7 +36602,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
|
|
|
35870
36602
|
setSavedId(answered.data);
|
|
35871
36603
|
onSaved?.(answered.data);
|
|
35872
36604
|
}
|
|
35873
|
-
const inviteField =
|
|
36605
|
+
const inviteField = useMemo58(() => {
|
|
35874
36606
|
for (const e of ticked) {
|
|
35875
36607
|
const tie = tiesTo(e.tableId)[0];
|
|
35876
36608
|
if (tie) return tie;
|
|
@@ -36107,7 +36839,7 @@ function clientNoun(table) {
|
|
|
36107
36839
|
}
|
|
36108
36840
|
|
|
36109
36841
|
// src/PortalsPanel.tsx
|
|
36110
|
-
import { useCallback as useCallback47, useEffect as useEffect84, useMemo as
|
|
36842
|
+
import { useCallback as useCallback47, useEffect as useEffect84, useMemo as useMemo60, useState as useState100 } from "react";
|
|
36111
36843
|
import { useRecordsClient as useRecordsClient74 } from "@ai-matrx/records/react";
|
|
36112
36844
|
import {
|
|
36113
36845
|
portalArchiveConsequence,
|
|
@@ -36118,7 +36850,7 @@ import {
|
|
|
36118
36850
|
import { Badge as Badge21, BasicInput as BasicInput25, Button as Button80, Separator as Separator11, Skeleton as Skeleton21, cn as cn67 } from "@ai-matrx/design-system";
|
|
36119
36851
|
|
|
36120
36852
|
// src/PortalLookEditor.tsx
|
|
36121
|
-
import { useEffect as useEffect83, useMemo as
|
|
36853
|
+
import { useEffect as useEffect83, useMemo as useMemo59, useState as useState99 } from "react";
|
|
36122
36854
|
import { useRecordsClient as useRecordsClient73 } from "@ai-matrx/records/react";
|
|
36123
36855
|
import { BasicInput as BasicInput24, Button as Button79, cn as cn66 } from "@ai-matrx/design-system";
|
|
36124
36856
|
|
|
@@ -36263,7 +36995,7 @@ function PortalLookEditor({ card, onSaved, className }) {
|
|
|
36263
36995
|
cancelled = true;
|
|
36264
36996
|
};
|
|
36265
36997
|
}, [card, client]);
|
|
36266
|
-
const orgName =
|
|
36998
|
+
const orgName = useMemo59(
|
|
36267
36999
|
() => card.style.from_organization.includes("display_name") ? card.style.display_name : null,
|
|
36268
37000
|
[card.style]
|
|
36269
37001
|
);
|
|
@@ -37059,7 +37791,7 @@ function Invite({ card, onInvited }) {
|
|
|
37059
37791
|
cancelled = true;
|
|
37060
37792
|
};
|
|
37061
37793
|
}, [client, card.client_table_id]);
|
|
37062
|
-
const options =
|
|
37794
|
+
const options = useMemo60(() => {
|
|
37063
37795
|
const all = (rows ?? []).map((row) => ({ id: row.id, name: rowNameIn(clientTable, row) }));
|
|
37064
37796
|
const needle = search.trim().toLowerCase();
|
|
37065
37797
|
return needle === "" ? all.slice(0, 25) : all.filter((o) => o.name.toLowerCase().includes(needle)).slice(0, 25);
|
|
@@ -37252,7 +37984,7 @@ function FormLookFrame({ look, title, children, contained = false, className })
|
|
|
37252
37984
|
}
|
|
37253
37985
|
|
|
37254
37986
|
// src/DigestScheduler.tsx
|
|
37255
|
-
import { useCallback as useCallback48, useEffect as useEffect85, useMemo as
|
|
37987
|
+
import { useCallback as useCallback48, useEffect as useEffect85, useMemo as useMemo61, useState as useState101 } from "react";
|
|
37256
37988
|
import { useRecordsClient as useRecordsClient75, useTable as useTable23 } from "@ai-matrx/records/react";
|
|
37257
37989
|
import { hasQuietHours } from "@ai-matrx/records";
|
|
37258
37990
|
import { BasicInput as BasicInput26, Button as Button81, Checkbox as Checkbox13, Label as Label19, Separator as Separator12, Skeleton as Skeleton22, cn as cn69 } from "@ai-matrx/design-system";
|
|
@@ -37372,12 +38104,12 @@ function DigestScheduler({
|
|
|
37372
38104
|
useEffect85(() => {
|
|
37373
38105
|
void load();
|
|
37374
38106
|
}, [load]);
|
|
37375
|
-
const schedule =
|
|
38107
|
+
const schedule = useMemo61(() => {
|
|
37376
38108
|
if (cadence === "weekly") return `${weekday} ${time}`;
|
|
37377
38109
|
if (cadence === "daily") return time;
|
|
37378
38110
|
return null;
|
|
37379
38111
|
}, [cadence, weekday, time]);
|
|
37380
|
-
const quietHours =
|
|
38112
|
+
const quietHours = useMemo61(
|
|
37381
38113
|
() => quiet2 ? { start: quietFrom, end: quietTo, tz: timezone } : { tz: timezone },
|
|
37382
38114
|
[quiet2, quietFrom, quietTo, timezone]
|
|
37383
38115
|
);
|
|
@@ -38054,7 +38786,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
|
|
|
38054
38786
|
|
|
38055
38787
|
// src/FormBuilder.tsx
|
|
38056
38788
|
import { ErrorBox as ErrorBox7 } from "@ai-matrx/design-system";
|
|
38057
|
-
import { useCallback as useCallback53, useEffect as useEffect90, useMemo as
|
|
38789
|
+
import { useCallback as useCallback53, useEffect as useEffect90, useMemo as useMemo63, useRef as useRef47, useState as useState106 } from "react";
|
|
38058
38790
|
import { useFields as useFields24, useRecordsClient as useRecordsClient79, useTable as useTable26 } from "@ai-matrx/records/react";
|
|
38059
38791
|
import { publicFormPath } from "@ai-matrx/records";
|
|
38060
38792
|
import {
|
|
@@ -38068,7 +38800,7 @@ import {
|
|
|
38068
38800
|
} from "@ai-matrx/design-system";
|
|
38069
38801
|
|
|
38070
38802
|
// src/FormRunner.tsx
|
|
38071
|
-
import { useCallback as useCallback51, useEffect as useEffect88, useMemo as
|
|
38803
|
+
import { useCallback as useCallback51, useEffect as useEffect88, useMemo as useMemo62, useRef as useRef46, useState as useState104 } from "react";
|
|
38072
38804
|
import { useFields as useFields23, useOptionalRecordsClient as useOptionalRecordsClient11 } from "@ai-matrx/records/react";
|
|
38073
38805
|
import { Button as Button84, Progress, Skeleton as Skeleton25, cn as cn72 } from "@ai-matrx/design-system";
|
|
38074
38806
|
import { humanizeIdentifier as humanizeIdentifier16 } from "@ai-matrx/kit/text-case";
|
|
@@ -38165,13 +38897,13 @@ function FormStage({
|
|
|
38165
38897
|
const [answers, setAnswers] = useState104(() => ({ ...initialAnswers ?? {} }));
|
|
38166
38898
|
const [at, setAt] = useState104(0);
|
|
38167
38899
|
const [error, setError] = useState104(null);
|
|
38168
|
-
const [
|
|
38900
|
+
const [refusal4, setRefusal] = useState104(null);
|
|
38169
38901
|
const [writing, setWriting] = useState104(false);
|
|
38170
38902
|
const [done, setDone] = useState104(null);
|
|
38171
38903
|
const [hidden, setHidden] = useState104({});
|
|
38172
|
-
const decoy =
|
|
38173
|
-
const stage =
|
|
38174
|
-
const questions =
|
|
38904
|
+
const decoy = useRef46("");
|
|
38905
|
+
const stage = useRef46(null);
|
|
38906
|
+
const questions = useMemo62(() => {
|
|
38175
38907
|
const byKey = new Map((fields ?? []).map((f) => [f.key, f]));
|
|
38176
38908
|
return (form.questions ?? []).map((q) => {
|
|
38177
38909
|
const field2 = byKey.get(q.field) ?? null;
|
|
@@ -38231,13 +38963,13 @@ function FormStage({
|
|
|
38231
38963
|
};
|
|
38232
38964
|
}, [whichAsked, questions, answers]);
|
|
38233
38965
|
const live = questions.filter((q) => !hidden[q.key]);
|
|
38234
|
-
const told =
|
|
38966
|
+
const told = useRef46(answers);
|
|
38235
38967
|
useEffect88(() => {
|
|
38236
38968
|
if (told.current === answers) return;
|
|
38237
38969
|
told.current = answers;
|
|
38238
38970
|
onAnswersChange?.(answers);
|
|
38239
38971
|
}, [answers, onAnswersChange]);
|
|
38240
|
-
const resumeAt =
|
|
38972
|
+
const resumeAt = useRef46(
|
|
38241
38973
|
resumed && initialAnswers && Object.keys(initialAnswers).length > 0 ? questions.find((q) => {
|
|
38242
38974
|
const v = initialAnswers[q.key];
|
|
38243
38975
|
return v === void 0 || v === null || v === "";
|
|
@@ -38359,10 +39091,10 @@ function FormStage({
|
|
|
38359
39091
|
] }) : null,
|
|
38360
39092
|
form.intro && index === 0 ? /* @__PURE__ */ jsx124("p", { className: "text-sm text-muted-foreground", children: authored(host, form.intro, "form-intro") }) : null,
|
|
38361
39093
|
error ? /* @__PURE__ */ jsx124(RefusalNotice, { error, className: "text-left" }) : null,
|
|
38362
|
-
|
|
39094
|
+
refusal4 ? /* @__PURE__ */ jsx124(
|
|
38363
39095
|
RefusalNotice,
|
|
38364
39096
|
{
|
|
38365
|
-
error:
|
|
39097
|
+
error: refusal4,
|
|
38366
39098
|
className: "text-left",
|
|
38367
39099
|
onKeepEditing: () => {
|
|
38368
39100
|
setRefusal(null);
|
|
@@ -38830,7 +39562,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
|
|
|
38830
39562
|
const [lookUnread, setLookUnread] = useState106(null);
|
|
38831
39563
|
const [restoredAt, setRestoredAt] = useState106(null);
|
|
38832
39564
|
const [adding, setAdding] = useState106(false);
|
|
38833
|
-
const keysBeforeAdd =
|
|
39565
|
+
const keysBeforeAdd = useRef47(null);
|
|
38834
39566
|
const [makeOnMount, setMakeOnMount] = useState106("waiting");
|
|
38835
39567
|
const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
|
|
38836
39568
|
const load = useCallback53(async () => {
|
|
@@ -38880,8 +39612,8 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
|
|
|
38880
39612
|
}
|
|
38881
39613
|
onActiveForm?.(chosen);
|
|
38882
39614
|
}, [forms, activeFormId, makeOnMount]);
|
|
38883
|
-
const byKey =
|
|
38884
|
-
const stored =
|
|
39615
|
+
const byKey = useMemo63(() => new Map((fields.data ?? []).map((f) => [f.key, f])), [fields.data]);
|
|
39616
|
+
const stored = useMemo63(() => draft ? (forms ?? []).find((f) => f.id === draft.id) ?? null : null, [draft, forms]);
|
|
38885
39617
|
const dirty = Boolean(draft && stored && !sameForm(draft, stored));
|
|
38886
39618
|
useEffect90(() => {
|
|
38887
39619
|
if (!draft || !stored) return;
|
|
@@ -39649,13 +40381,13 @@ function bucketWindow2(groupKey, value) {
|
|
|
39649
40381
|
import {
|
|
39650
40382
|
useEffect as useEffect91,
|
|
39651
40383
|
useId as useId4,
|
|
39652
|
-
useRef as
|
|
40384
|
+
useRef as useRef48,
|
|
39653
40385
|
useState as useState107
|
|
39654
40386
|
} from "react";
|
|
39655
40387
|
import { cn as cn75 } from "@ai-matrx/design-system";
|
|
39656
40388
|
import { jsx as jsx127, jsxs as jsxs117 } from "react/jsx-runtime";
|
|
39657
40389
|
function useMeasuredWidth(fallback = 480) {
|
|
39658
|
-
const ref =
|
|
40390
|
+
const ref = useRef48(null);
|
|
39659
40391
|
const [width, setWidth] = useState107(fallback);
|
|
39660
40392
|
useEffect91(() => {
|
|
39661
40393
|
const node = ref.current;
|
|
@@ -39943,7 +40675,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
|
|
|
39943
40675
|
}
|
|
39944
40676
|
|
|
39945
40677
|
// src/DocRender.tsx
|
|
39946
|
-
import { useCallback as useCallback55, useEffect as useEffect93, useRef as
|
|
40678
|
+
import { useCallback as useCallback55, useEffect as useEffect93, useRef as useRef49, useState as useState109 } from "react";
|
|
39947
40679
|
import { useRecordsClient as useRecordsClient81 } from "@ai-matrx/records/react";
|
|
39948
40680
|
import { Button as Button88, Skeleton as Skeleton29, cn as cn77 } from "@ai-matrx/design-system";
|
|
39949
40681
|
import { jsx as jsx129, jsxs as jsxs119 } from "react/jsx-runtime";
|
|
@@ -39954,7 +40686,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
|
|
|
39954
40686
|
const [showing, setShowing] = useState109(null);
|
|
39955
40687
|
const [error, setError] = useState109(null);
|
|
39956
40688
|
const [busy, setBusy] = useState109(null);
|
|
39957
|
-
const paper =
|
|
40689
|
+
const paper = useRef49(null);
|
|
39958
40690
|
const load = useCallback55(async () => {
|
|
39959
40691
|
const [body, held] = await Promise.all([
|
|
39960
40692
|
client.docRenderBody({ template_id: templateId, record_id: recordId }),
|
|
@@ -40207,7 +40939,7 @@ function SignBlock({ tableId, recordId, render, className }) {
|
|
|
40207
40939
|
}
|
|
40208
40940
|
|
|
40209
40941
|
// src/ChartBlock.tsx
|
|
40210
|
-
import { useMemo as
|
|
40942
|
+
import { useMemo as useMemo65 } from "react";
|
|
40211
40943
|
import {
|
|
40212
40944
|
Bar,
|
|
40213
40945
|
BarChart,
|
|
@@ -40226,12 +40958,12 @@ import {
|
|
|
40226
40958
|
import {
|
|
40227
40959
|
measureKey as measureKey3
|
|
40228
40960
|
} from "@ai-matrx/records";
|
|
40229
|
-
import { mapPgError as
|
|
40961
|
+
import { mapPgError as mapPgError3 } from "@ai-matrx/records/core";
|
|
40230
40962
|
import { cn as cn79 } from "@ai-matrx/design-system";
|
|
40231
40963
|
import { formatCount as formatCount4 } from "@ai-matrx/kit/format";
|
|
40232
40964
|
|
|
40233
40965
|
// src/linkWords.ts
|
|
40234
|
-
import { useEffect as useEffect95, useMemo as
|
|
40966
|
+
import { useEffect as useEffect95, useMemo as useMemo64, useState as useState111 } from "react";
|
|
40235
40967
|
import { useOptionalRecordsClient as useOptionalRecordsClient12 } from "@ai-matrx/records/react";
|
|
40236
40968
|
function useLinkGroupNamer(block, tableId) {
|
|
40237
40969
|
const client = useOptionalRecordsClient12();
|
|
@@ -40269,7 +41001,7 @@ function useLinkGroupNamer(block, tableId) {
|
|
|
40269
41001
|
cancelled = true;
|
|
40270
41002
|
};
|
|
40271
41003
|
}, [client, ask]);
|
|
40272
|
-
return
|
|
41004
|
+
return useMemo64(() => {
|
|
40273
41005
|
if (Object.keys(named).length === 0 && choices.length === 0) return void 0;
|
|
40274
41006
|
return (key, value) => {
|
|
40275
41007
|
const choice = choices.find((f) => f.key === key);
|
|
@@ -40339,7 +41071,7 @@ function pretty(n) {
|
|
|
40339
41071
|
return Number.isInteger(n) ? n.toLocaleString() : n.toLocaleString(void 0, { maximumFractionDigits: 2 });
|
|
40340
41072
|
}
|
|
40341
41073
|
function asRefusal2(block) {
|
|
40342
|
-
return
|
|
41074
|
+
return mapPgError3(
|
|
40343
41075
|
{
|
|
40344
41076
|
message: block.refused ?? "",
|
|
40345
41077
|
...block.sqlstate ? { code: block.sqlstate } : {}
|
|
@@ -40361,7 +41093,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
|
|
|
40361
41093
|
const series = compared ? [primary, priorKey(primary)] : [primary];
|
|
40362
41094
|
const target = kind === "stuck" ? null : block.target ?? null;
|
|
40363
41095
|
const named = useLinkGroupNamer(source ? NO_GROUPS : block, tableId);
|
|
40364
|
-
const points =
|
|
41096
|
+
const points = useMemo65(() => {
|
|
40365
41097
|
if (kind === "stuck") return [];
|
|
40366
41098
|
const rows = block.rows ?? [];
|
|
40367
41099
|
return rows.map((row, index) => {
|
|
@@ -40385,7 +41117,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
|
|
|
40385
41117
|
};
|
|
40386
41118
|
});
|
|
40387
41119
|
}, [block.rows, kind, primary, compared, grain, windows, named]);
|
|
40388
|
-
const config =
|
|
41120
|
+
const config = useMemo65(() => {
|
|
40389
41121
|
const out = {};
|
|
40390
41122
|
out[primary] = {
|
|
40391
41123
|
label: windows ? windowName(windows.window, windows.period) : primary.replace("_", " of "),
|
|
@@ -40743,7 +41475,7 @@ function onlyWholeNumbers(rows) {
|
|
|
40743
41475
|
}
|
|
40744
41476
|
|
|
40745
41477
|
// src/DashboardCanvas.tsx
|
|
40746
|
-
import { useCallback as useCallback57, useEffect as useEffect97, useMemo as
|
|
41478
|
+
import { useCallback as useCallback57, useEffect as useEffect97, useMemo as useMemo68, useState as useState114 } from "react";
|
|
40747
41479
|
import { useFields as useFields29, useRecordsClient as useRecordsClient84, useTable as useTable30 } from "@ai-matrx/records/react";
|
|
40748
41480
|
import {
|
|
40749
41481
|
BasicInput as BasicInput31,
|
|
@@ -40908,7 +41640,7 @@ function GridCell2({
|
|
|
40908
41640
|
}
|
|
40909
41641
|
|
|
40910
41642
|
// src/AddChart.tsx
|
|
40911
|
-
import { useMemo as
|
|
41643
|
+
import { useMemo as useMemo67, useState as useState113 } from "react";
|
|
40912
41644
|
import { useFields as useFields28, useRecordsClient as useRecordsClient83 } from "@ai-matrx/records/react";
|
|
40913
41645
|
import {
|
|
40914
41646
|
Button as Button91,
|
|
@@ -40920,12 +41652,12 @@ import {
|
|
|
40920
41652
|
} from "@ai-matrx/design-system";
|
|
40921
41653
|
|
|
40922
41654
|
// src/TablePickers.tsx
|
|
40923
|
-
import { useEffect as useEffect96, useMemo as
|
|
41655
|
+
import { useEffect as useEffect96, useMemo as useMemo66, useState as useState112 } from "react";
|
|
40924
41656
|
import { RecordsProvider as RecordsProvider2, useFields as useFields27, useRecords as useRecords7, useTable as useTable29 } from "@ai-matrx/records/react";
|
|
40925
41657
|
import { Button as Button90, CreatablePicker as CreatablePicker2 } from "@ai-matrx/design-system";
|
|
40926
41658
|
|
|
40927
41659
|
// src/RecordsMount.tsx
|
|
40928
|
-
import { useRef as
|
|
41660
|
+
import { useRef as useRef50 } from "react";
|
|
40929
41661
|
import { RecordsProvider } from "@ai-matrx/records/react";
|
|
40930
41662
|
import { jsx as jsx133 } from "react/jsx-runtime";
|
|
40931
41663
|
var STORE_DECIDES_REASON = "This host offers exactly what the record store says this person may do: the level comes back with the table on the read door, so a control they cannot use is never drawn in the first place.";
|
|
@@ -40943,7 +41675,7 @@ function RecordsMount({
|
|
|
40943
41675
|
return /* @__PURE__ */ jsx133(RecordsProvider, { config, children: /* @__PURE__ */ jsx133(RecordsUiProvider, { value: bound2, children: /* @__PURE__ */ jsx133(RecordLabelProvider, { children }) }) });
|
|
40944
41676
|
}
|
|
40945
41677
|
function useShallowStableHost(host) {
|
|
40946
|
-
const held =
|
|
41678
|
+
const held = useRef50(null);
|
|
40947
41679
|
const next = host ?? {};
|
|
40948
41680
|
const previous = held.current;
|
|
40949
41681
|
if (previous !== null && sameParts(previous, next)) return previous;
|
|
@@ -41113,8 +41845,8 @@ function TableScope({ dataSource, userId, tableId, children, fallback = null, un
|
|
|
41113
41845
|
}
|
|
41114
41846
|
function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
|
|
41115
41847
|
const fields = useFields27(tableId);
|
|
41116
|
-
const all =
|
|
41117
|
-
const byKey =
|
|
41848
|
+
const all = useMemo66(() => fields.data ?? [], [fields.data]);
|
|
41849
|
+
const byKey = useMemo66(() => new Map(all.map((f) => [f.key, f])), [all]);
|
|
41118
41850
|
const keys = Object.keys(value);
|
|
41119
41851
|
const [adding, setAdding] = useState112(false);
|
|
41120
41852
|
const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
|
|
@@ -41274,7 +42006,7 @@ function AddChart({ subject, onAdd, onClose }) {
|
|
|
41274
42006
|
const client = useRecordsClient83();
|
|
41275
42007
|
const [tableId, setTableId] = useState113(subject);
|
|
41276
42008
|
const fields = useFields28(tableId);
|
|
41277
|
-
const all =
|
|
42009
|
+
const all = useMemo67(() => onePerKey(fields.data ?? []), [fields.data]);
|
|
41278
42010
|
const labels = useRecordLabels(all);
|
|
41279
42011
|
const wordsFor2 = (key, value) => {
|
|
41280
42012
|
const field2 = all.find((f) => f.key === key);
|
|
@@ -41472,7 +42204,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
|
|
|
41472
42204
|
const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
|
|
41473
42205
|
if (chosen.id !== activeId) setActiveId(chosen.id);
|
|
41474
42206
|
}, [boards, activeDashboardId, madeOnMount]);
|
|
41475
|
-
const board =
|
|
42207
|
+
const board = useMemo68(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
|
|
41476
42208
|
const filterKey = JSON.stringify(filter ?? {});
|
|
41477
42209
|
useEffect97(() => {
|
|
41478
42210
|
if (!activeId) {
|
|
@@ -42037,13 +42769,13 @@ function TargetControl({
|
|
|
42037
42769
|
}
|
|
42038
42770
|
|
|
42039
42771
|
// src/QuestionPanel.tsx
|
|
42040
|
-
import { useEffect as useEffect98, useMemo as
|
|
42772
|
+
import { useEffect as useEffect98, useMemo as useMemo69, useRef as useRef51, useState as useState115 } from "react";
|
|
42041
42773
|
import { Badge as Badge23, BasicInput as BasicInput32, Button as Button93, Checkbox as Checkbox16, Label as Label23, Skeleton as Skeleton32, cn as cn82 } from "@ai-matrx/design-system";
|
|
42042
42774
|
import { useFields as useFields30, useRecordsClient as useRecordsClient85 } from "@ai-matrx/records/react";
|
|
42043
42775
|
|
|
42044
42776
|
// src/question.ts
|
|
42045
42777
|
import { measureKey as measureKey4 } from "@ai-matrx/records";
|
|
42046
|
-
import { mapPgError as
|
|
42778
|
+
import { mapPgError as mapPgError4 } from "@ai-matrx/records/core";
|
|
42047
42779
|
var QUESTION_OPS = ["count", "sum", "avg", "min", "max"];
|
|
42048
42780
|
var QUESTION_LIMIT_DEFAULT = 25;
|
|
42049
42781
|
var QUESTION_GROUP_CEILING = 200;
|
|
@@ -42068,7 +42800,7 @@ function questionFromDefinition(definition) {
|
|
|
42068
42800
|
show: ["table", "bar", "column", "line", "donut", "number"].includes(raw.show) ? raw.show : base.show
|
|
42069
42801
|
};
|
|
42070
42802
|
}
|
|
42071
|
-
function
|
|
42803
|
+
function refusal3(message, hint) {
|
|
42072
42804
|
return { ok: false, error: { code: "invalid_argument", message, ...hint ? { hint } : {} } };
|
|
42073
42805
|
}
|
|
42074
42806
|
function fieldById(fields, id) {
|
|
@@ -42119,7 +42851,7 @@ function sortAndCut(rows, spec, keys) {
|
|
|
42119
42851
|
async function askQuestion(client, tableId, spec, fields) {
|
|
42120
42852
|
const measures = spec.measures.length > 0 ? spec.measures : [{ op: "count" }];
|
|
42121
42853
|
for (const m of measures) {
|
|
42122
|
-
if (m.op !== "count" && !m.key) return
|
|
42854
|
+
if (m.op !== "count" && !m.key) return refusal3(`Pick the column to ${m.op === "avg" ? "average" : m.op}.`);
|
|
42123
42855
|
}
|
|
42124
42856
|
const keys = measures.map((m) => measureKey4({ op: m.op, ...m.key ? { key: m.key } : {} }));
|
|
42125
42857
|
const group = spec.group;
|
|
@@ -42128,7 +42860,7 @@ async function askQuestion(client, tableId, spec, fields) {
|
|
|
42128
42860
|
if (spec.through.length > 0) {
|
|
42129
42861
|
const flat = flatWhere(spec.where, fields);
|
|
42130
42862
|
if (flat === null) {
|
|
42131
|
-
return
|
|
42863
|
+
return refusal3(
|
|
42132
42864
|
"A condition on a related table can only be joined with \u201Cis\u201D conditions, all of them true.",
|
|
42133
42865
|
"Simplify the other conditions, or move them to the related table."
|
|
42134
42866
|
);
|
|
@@ -42198,10 +42930,10 @@ async function askQuestion(client, tableId, spec, fields) {
|
|
|
42198
42930
|
async function askThrough(client, tableId, spec, fields, measures, keys, filter) {
|
|
42199
42931
|
const group = spec.group;
|
|
42200
42932
|
const rel = fields.find((f) => f.key === group.relation);
|
|
42201
|
-
if (!rel || !rel.relation_target) return
|
|
42933
|
+
if (!rel || !rel.relation_target) return refusal3(`\u201C${group.relation}\u201D is not a relation of this table.`);
|
|
42202
42934
|
const flat = filter && !filter.op ? filter : flatWhere(filter, fields);
|
|
42203
42935
|
if (flat === null) {
|
|
42204
|
-
return
|
|
42936
|
+
return refusal3(
|
|
42205
42937
|
"Summarizing by a related table's column can only be joined with \u201Cis\u201D conditions, all of them true.",
|
|
42206
42938
|
"Simplify the conditions, or summarize by a column of this table."
|
|
42207
42939
|
);
|
|
@@ -42215,7 +42947,7 @@ async function askThrough(client, tableId, spec, fields, measures, keys, filter)
|
|
|
42215
42947
|
if (!values.ok) return values;
|
|
42216
42948
|
const named = values.data.map((r) => (r.groups ?? {})[group.key] ?? null).filter((v) => v !== null && v !== "");
|
|
42217
42949
|
if (named.length > QUESTION_THROUGH_GROUP_CAP) {
|
|
42218
|
-
return
|
|
42950
|
+
return refusal3(
|
|
42219
42951
|
`That column has more than ${QUESTION_THROUGH_GROUP_CAP} values, too many to summarize by.`,
|
|
42220
42952
|
"Add a condition that narrows it, or summarize by a column of this table."
|
|
42221
42953
|
);
|
|
@@ -42258,25 +42990,25 @@ async function askThrough(client, tableId, spec, fields, measures, keys, filter)
|
|
|
42258
42990
|
async function askAsOf(client, tableId, spec, fields, measures, keys) {
|
|
42259
42991
|
const group = spec.group;
|
|
42260
42992
|
if (spec.through.length > 0 || group?.kind === "through") {
|
|
42261
|
-
return
|
|
42993
|
+
return refusal3("\u201CAs of\u201D cannot reach across a relation yet.", "Ask without the related table's column, or without \u201Cas of\u201D.");
|
|
42262
42994
|
}
|
|
42263
42995
|
if (group?.kind === "bucket") {
|
|
42264
|
-
return
|
|
42996
|
+
return refusal3("\u201CAs of\u201D cannot cut dates into periods yet.", "Summarize by the date itself, or ask without \u201Cas of\u201D.");
|
|
42265
42997
|
}
|
|
42266
42998
|
const match = flatWhere(spec.where, fields);
|
|
42267
42999
|
if (match === null) {
|
|
42268
|
-
return
|
|
43000
|
+
return refusal3("\u201CAs of\u201D can only be filtered with \u201Cis\u201D conditions, all of them true.", "Simplify the filter, or ask without \u201Cas of\u201D.");
|
|
42269
43001
|
}
|
|
42270
43002
|
const formula = [...measures.map((m) => m.key), group?.key, ...Object.keys(match)].find((k) => isFormula(fields, k));
|
|
42271
43003
|
if (formula) {
|
|
42272
43004
|
const f = fields.find((x) => x.key === formula);
|
|
42273
|
-
return
|
|
43005
|
+
return refusal3(
|
|
42274
43006
|
`${f?.label || formula} is worked out when a record is read, so it cannot be measured as of a moment.`,
|
|
42275
43007
|
"Measure a stored column, or ask without \u201Cas of\u201D."
|
|
42276
43008
|
);
|
|
42277
43009
|
}
|
|
42278
43010
|
const moment = new Date(spec.asOf);
|
|
42279
|
-
if (Number.isNaN(moment.getTime())) return
|
|
43011
|
+
if (Number.isNaN(moment.getTime())) return refusal3("\u201CAs of\u201D is not a date and time.");
|
|
42280
43012
|
const config = client.config;
|
|
42281
43013
|
const groupKey = group?.kind === "field" ? group.key : null;
|
|
42282
43014
|
const byGroup = /* @__PURE__ */ new Map();
|
|
@@ -42295,11 +43027,11 @@ async function askAsOf(client, tableId, spec, fields, measures, keys) {
|
|
|
42295
43027
|
},
|
|
42296
43028
|
{ schema: config.schema ?? "custom" }
|
|
42297
43029
|
);
|
|
42298
|
-
if (response.error) return { ok: false, error:
|
|
43030
|
+
if (response.error) return { ok: false, error: mapPgError4(response.error, "askQuestion.asOf") };
|
|
42299
43031
|
const rows2 = Array.isArray(response.data) ? response.data : [];
|
|
42300
43032
|
const bad = rows2.find((r) => Number(r.not_numbers ?? 0) > 0);
|
|
42301
43033
|
if (bad && m.op !== "count") {
|
|
42302
|
-
return
|
|
43034
|
+
return refusal3(`${m.key} held \u201C${bad.a_non_number}\u201D then, which is not a number, so its ${m.op} cannot be worked out.`);
|
|
42303
43035
|
}
|
|
42304
43036
|
for (const r of rows2) {
|
|
42305
43037
|
const g = groupKey ? r.bucket ?? null : null;
|
|
@@ -42366,7 +43098,7 @@ function savedOf(row) {
|
|
|
42366
43098
|
}
|
|
42367
43099
|
async function questionsOf(client, tableId) {
|
|
42368
43100
|
const response = await client.config.dataSource.schema("platform").from("saved_view").select("id, name, definition, visibility, version, created_by").eq("surface_key", QUESTION_SURFACE).eq("subject_id", tableId).is("deleted_at", null).order("name", { ascending: true });
|
|
42369
|
-
if (response.error) return { ok: false, error:
|
|
43101
|
+
if (response.error) return { ok: false, error: mapPgError4(response.error, "questionsOf") };
|
|
42370
43102
|
const me = client.config.actor?.user_id ?? null;
|
|
42371
43103
|
return {
|
|
42372
43104
|
ok: true,
|
|
@@ -42375,7 +43107,7 @@ async function questionsOf(client, tableId) {
|
|
|
42375
43107
|
}
|
|
42376
43108
|
async function questionSave(client, args) {
|
|
42377
43109
|
const name = args.name.trim();
|
|
42378
|
-
if (!name) return
|
|
43110
|
+
if (!name) return refusal3("Name the question so the team can find it.");
|
|
42379
43111
|
const response = await client.config.dataSource.rpc(
|
|
42380
43112
|
"saved_view_save",
|
|
42381
43113
|
{
|
|
@@ -42395,7 +43127,7 @@ async function questionSave(client, args) {
|
|
|
42395
43127
|
if (response.error.code === "23505") {
|
|
42396
43128
|
return { ok: false, error: { code: "already_exists", message: `You already have a question called \u201C${name}\u201D.` } };
|
|
42397
43129
|
}
|
|
42398
|
-
return { ok: false, error:
|
|
43130
|
+
return { ok: false, error: mapPgError4(response.error, "questionSave") };
|
|
42399
43131
|
}
|
|
42400
43132
|
return { ok: true, data: response.data ? savedOf(response.data) : null };
|
|
42401
43133
|
}
|
|
@@ -42405,7 +43137,7 @@ async function questionArchive(client, id, version) {
|
|
|
42405
43137
|
{ p_surface_key: QUESTION_SURFACE, p_id: id, ...version !== void 0 ? { p_expected_version: version } : {} },
|
|
42406
43138
|
{ schema: "public" }
|
|
42407
43139
|
);
|
|
42408
|
-
if (response.error) return { ok: false, error:
|
|
43140
|
+
if (response.error) return { ok: false, error: mapPgError4(response.error, "questionArchive") };
|
|
42409
43141
|
return { ok: true, data: response.data !== null };
|
|
42410
43142
|
}
|
|
42411
43143
|
|
|
@@ -42452,7 +43184,7 @@ function fromLocalInput(value) {
|
|
|
42452
43184
|
function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
|
|
42453
43185
|
const client = useRecordsClient85();
|
|
42454
43186
|
const fields = useFields30(tableId);
|
|
42455
|
-
const all =
|
|
43187
|
+
const all = useMemo69(() => fields.data ?? [], [fields.data]);
|
|
42456
43188
|
const me = client.config.actor?.user_id ?? null;
|
|
42457
43189
|
const [hidden, setHidden] = useState115(null);
|
|
42458
43190
|
const [related, setRelated] = useState115({});
|
|
@@ -42479,7 +43211,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
|
|
|
42479
43211
|
live = false;
|
|
42480
43212
|
};
|
|
42481
43213
|
}, [client, tableId, all, fields.loading]);
|
|
42482
|
-
const offered =
|
|
43214
|
+
const offered = useMemo69(() => hidden ? all.filter((f) => !hidden.has(f.key)) : [], [all, hidden]);
|
|
42483
43215
|
const [saved, setSaved] = useState115(null);
|
|
42484
43216
|
const [savedEpoch, setSavedEpoch] = useState115(0);
|
|
42485
43217
|
const [current, setCurrent] = useState115(null);
|
|
@@ -42489,7 +43221,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
|
|
|
42489
43221
|
const [saveError, setSaveError] = useState115(null);
|
|
42490
43222
|
const [saving, setSaving] = useState115(false);
|
|
42491
43223
|
const [linkMissed, setLinkMissed] = useState115(false);
|
|
42492
|
-
const openedFromLink =
|
|
43224
|
+
const openedFromLink = useRef51(false);
|
|
42493
43225
|
useEffect98(() => {
|
|
42494
43226
|
let live = true;
|
|
42495
43227
|
void questionsOf(client, tableId).then((answer2) => {
|
|
@@ -42868,7 +43600,7 @@ function formatValue(key, value, fields) {
|
|
|
42868
43600
|
return new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(value);
|
|
42869
43601
|
}
|
|
42870
43602
|
function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATED }) {
|
|
42871
|
-
const block =
|
|
43603
|
+
const block = useMemo69(
|
|
42872
43604
|
() => ({
|
|
42873
43605
|
kind: "table",
|
|
42874
43606
|
group_by: answer.groupKey && spec.group?.kind === "field" ? [answer.groupKey] : [],
|
|
@@ -43262,7 +43994,7 @@ function TableAsk({ tableId, onOpenInQuestions }) {
|
|
|
43262
43994
|
}
|
|
43263
43995
|
|
|
43264
43996
|
// src/PageScreen.tsx
|
|
43265
|
-
import { useCallback as useCallback58, useEffect as useEffect99, useMemo as
|
|
43997
|
+
import { useCallback as useCallback58, useEffect as useEffect99, useMemo as useMemo70, useState as useState117 } from "react";
|
|
43266
43998
|
import {
|
|
43267
43999
|
useFields as useFields32,
|
|
43268
44000
|
useRecordPage as useRecordPage3,
|
|
@@ -43370,7 +44102,7 @@ function PageScreen({
|
|
|
43370
44102
|
live = false;
|
|
43371
44103
|
};
|
|
43372
44104
|
}, [client, chartKey]);
|
|
43373
|
-
const blocks =
|
|
44105
|
+
const blocks = useMemo70(
|
|
43374
44106
|
() => page ? pageBlocksOf(page.presentation, page.blocks.map((b) => b.id ?? "").filter(Boolean)) : [],
|
|
43375
44107
|
[page]
|
|
43376
44108
|
);
|
|
@@ -43636,7 +44368,7 @@ function ListBlockView({
|
|
|
43636
44368
|
const client = useRecordsClient87();
|
|
43637
44369
|
const table = useTable31(block.table_id);
|
|
43638
44370
|
const fields = useFields32(block.table_id);
|
|
43639
|
-
const all =
|
|
44371
|
+
const all = useMemo70(() => onePerKey3(fields.data ?? []), [fields.data]);
|
|
43640
44372
|
const [view, setView] = useState117(block.view_id ? "reading" : null);
|
|
43641
44373
|
useEffect99(() => {
|
|
43642
44374
|
if (!block.view_id) {
|
|
@@ -44233,12 +44965,12 @@ function FormsPanel({ tableId, activeFormId, className }) {
|
|
|
44233
44965
|
}
|
|
44234
44966
|
|
|
44235
44967
|
// src/CaptureSheet.tsx
|
|
44236
|
-
import { useCallback as useCallback61, useEffect as useEffect102, useRef as
|
|
44968
|
+
import { useCallback as useCallback61, useEffect as useEffect102, useRef as useRef53, useState as useState120 } from "react";
|
|
44237
44969
|
import { useFields as useFields33, useRecordsClient as useRecordsClient90, useTable as useTable33 } from "@ai-matrx/records/react";
|
|
44238
44970
|
import { Button as Button98, Input as Input8, Skeleton as Skeleton37, Textarea as Textarea7, cn as cn86 } from "@ai-matrx/design-system";
|
|
44239
44971
|
|
|
44240
44972
|
// src/CaptureRun.tsx
|
|
44241
|
-
import { useCallback as useCallback60, useEffect as useEffect101, useMemo as
|
|
44973
|
+
import { useCallback as useCallback60, useEffect as useEffect101, useMemo as useMemo71, useRef as useRef52, useState as useState119 } from "react";
|
|
44242
44974
|
import {
|
|
44243
44975
|
coerceTypedAnswer as coerceTypedAnswer3,
|
|
44244
44976
|
coercionLabel,
|
|
@@ -44296,7 +45028,7 @@ function CaptureRun({ sheetId, face: given, className }) {
|
|
|
44296
45028
|
const [items, setItems] = useState119([]);
|
|
44297
45029
|
const [lastSynced, setLastSynced] = useState119(null);
|
|
44298
45030
|
const [sending, setSending] = useState119(false);
|
|
44299
|
-
const queueRef =
|
|
45031
|
+
const queueRef = useRef52(null);
|
|
44300
45032
|
useEffect101(() => {
|
|
44301
45033
|
const q2 = openCaptureQueue({
|
|
44302
45034
|
onChange: (c, all) => {
|
|
@@ -44347,7 +45079,7 @@ function CaptureRun({ sheetId, face: given, className }) {
|
|
|
44347
45079
|
cancelled = true;
|
|
44348
45080
|
};
|
|
44349
45081
|
}, [client, given, sheetId]);
|
|
44350
|
-
const questions =
|
|
45082
|
+
const questions = useMemo71(() => {
|
|
44351
45083
|
const asked3 = face?.presentation?.questions ?? [];
|
|
44352
45084
|
if (asked3.length > 0) return asked3;
|
|
44353
45085
|
return (face?.fields ?? []).map((f) => ({
|
|
@@ -44676,7 +45408,7 @@ function AdHocCaptureSheet({
|
|
|
44676
45408
|
const [error, setError] = useState120(null);
|
|
44677
45409
|
const [uploadError, setUploadError] = useState120(null);
|
|
44678
45410
|
const [flushing, setFlushing] = useState120(false);
|
|
44679
|
-
const queue =
|
|
45411
|
+
const queue = useRef53([]);
|
|
44680
45412
|
const keep = useCallback61(
|
|
44681
45413
|
async (next) => {
|
|
44682
45414
|
queue.current = next;
|
|
@@ -45216,7 +45948,7 @@ function useEmbedHandshake(args) {
|
|
|
45216
45948
|
}
|
|
45217
45949
|
|
|
45218
45950
|
// src/TablePage.tsx
|
|
45219
|
-
import { useCallback as useCallback66, useEffect as useEffect108, useMemo as
|
|
45951
|
+
import { useCallback as useCallback66, useEffect as useEffect108, useMemo as useMemo75, useRef as useRef54, useState as useState130 } from "react";
|
|
45220
45952
|
import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
|
|
45221
45953
|
import { useFields as useFields36, useRecordsClient as useRecordsClient95, useTable as useTable35 } from "@ai-matrx/records/react";
|
|
45222
45954
|
import {
|
|
@@ -45347,7 +46079,7 @@ function RecordAsk({ tableId, recordId }) {
|
|
|
45347
46079
|
}
|
|
45348
46080
|
|
|
45349
46081
|
// src/breakDown.tsx
|
|
45350
|
-
import { useMemo as
|
|
46082
|
+
import { useMemo as useMemo72, useState as useState125 } from "react";
|
|
45351
46083
|
import {
|
|
45352
46084
|
Button as Button102,
|
|
45353
46085
|
Dialog as Dialog14,
|
|
@@ -45384,9 +46116,9 @@ function BreakDownDialog({
|
|
|
45384
46116
|
onOpenChange,
|
|
45385
46117
|
onApply
|
|
45386
46118
|
}) {
|
|
45387
|
-
const source =
|
|
46119
|
+
const source = useMemo72(() => ({ kind: "table", id: tableId }), [tableId]);
|
|
45388
46120
|
const { def } = useDrillDefinition(open ? source : null);
|
|
45389
|
-
const dimensions =
|
|
46121
|
+
const dimensions = useMemo72(() => drillDimensionsOf(def, NO_LABELS), [def]);
|
|
45390
46122
|
const [picked, setPicked] = useState125(null);
|
|
45391
46123
|
const key = picked ?? held?.field ?? dimensions[0]?.key ?? "";
|
|
45392
46124
|
return /* @__PURE__ */ jsx147(Dialog14, { open, onOpenChange, children: /* @__PURE__ */ jsxs136(DialogContent14, { "data-break-down": "", className: "max-w-sm", children: [
|
|
@@ -45413,8 +46145,8 @@ function BreakDownDialog({
|
|
|
45413
46145
|
}
|
|
45414
46146
|
|
|
45415
46147
|
// src/TableReference.tsx
|
|
45416
|
-
import { useCallback as useCallback65, useMemo as
|
|
45417
|
-
import { useContentTransferCapabilities as useContentTransferCapabilities2 } from "@ai-matrx/
|
|
46148
|
+
import { useCallback as useCallback65, useMemo as useMemo73, useState as useState126 } from "react";
|
|
46149
|
+
import { useContentTransferCapabilities as useContentTransferCapabilities2 } from "@ai-matrx/alchemy/react/workspace";
|
|
45418
46150
|
import { Button as Button103, Dialog as Dialog15, DialogContent as DialogContent15, DialogHeader as DialogHeader15, DialogTitle as DialogTitle15 } from "@ai-matrx/design-system";
|
|
45419
46151
|
import { jsx as jsx148, jsxs as jsxs137 } from "react/jsx-runtime";
|
|
45420
46152
|
function tableReferenceChoices(tableId, name) {
|
|
@@ -45442,7 +46174,7 @@ function TableReferenceDialog({
|
|
|
45442
46174
|
const port = useContentTransferCapabilities2().reference;
|
|
45443
46175
|
const notify = useRecordsUi().notify;
|
|
45444
46176
|
const [copied, setCopied] = useState126(null);
|
|
45445
|
-
const choices =
|
|
46177
|
+
const choices = useMemo73(
|
|
45446
46178
|
() => tableReferenceChoices(table.id, tableName(table)).filter((c) => port?.supports(c.reference)),
|
|
45447
46179
|
[table, port]
|
|
45448
46180
|
);
|
|
@@ -45571,7 +46303,7 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
|
|
|
45571
46303
|
}
|
|
45572
46304
|
|
|
45573
46305
|
// src/ViewFilter.tsx
|
|
45574
|
-
import { useEffect as useEffect106, useMemo as
|
|
46306
|
+
import { useEffect as useEffect106, useMemo as useMemo74, useState as useState128 } from "react";
|
|
45575
46307
|
import { Button as Button105, cn as cn90 } from "@ai-matrx/design-system";
|
|
45576
46308
|
import { useFields as useFields35 } from "@ai-matrx/records/react";
|
|
45577
46309
|
import { jsx as jsx150, jsxs as jsxs139 } from "react/jsx-runtime";
|
|
@@ -45592,7 +46324,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
|
|
|
45592
46324
|
useEffect106(() => {
|
|
45593
46325
|
setDraft(saved);
|
|
45594
46326
|
}, [view?.id, savedKey]);
|
|
45595
|
-
const conditionFields =
|
|
46327
|
+
const conditionFields = useMemo74(
|
|
45596
46328
|
() => (fields.data ?? []).map((f) => ({ id: f.id, key: f.key, label: f.label || f.key, field: f })),
|
|
45597
46329
|
[fields.data]
|
|
45598
46330
|
);
|
|
@@ -45934,7 +46666,7 @@ function useSlotScroll(slot) {
|
|
|
45934
46666
|
}
|
|
45935
46667
|
|
|
45936
46668
|
// src/TablePage.tsx
|
|
45937
|
-
import { isUuidShape as
|
|
46669
|
+
import { isUuidShape as isUuidShape4 } from "@ai-matrx/kit/uuid";
|
|
45938
46670
|
import { Fragment as Fragment63, jsx as jsx152, jsxs as jsxs141 } from "react/jsx-runtime";
|
|
45939
46671
|
var RAIL_TITLE = {
|
|
45940
46672
|
settings: "Table settings",
|
|
@@ -46014,7 +46746,7 @@ function TableNotHere({
|
|
|
46014
46746
|
const client = useRecordsClient95();
|
|
46015
46747
|
const [archived, setArchived] = useState130({ phase: "asking" });
|
|
46016
46748
|
const [restoring, setRestoring] = useState130(false);
|
|
46017
|
-
const [
|
|
46749
|
+
const [refusal4, setRefusal] = useState130(null);
|
|
46018
46750
|
useEffect108(() => {
|
|
46019
46751
|
let alive = true;
|
|
46020
46752
|
void client.tableArchived({ table_id: tableId }).then((answered) => {
|
|
@@ -46032,7 +46764,7 @@ function TableNotHere({
|
|
|
46032
46764
|
/* @__PURE__ */ jsx152("p", { className: "text-sm font-medium", children: "This table is archived" }),
|
|
46033
46765
|
/* @__PURE__ */ jsx152("p", { className: "max-w-prose text-xs text-muted-foreground", children: TABLE_IS_ARCHIVED }),
|
|
46034
46766
|
/* @__PURE__ */ jsx152("p", { className: "text-xs text-muted-foreground", children: archivedByLine2(row) }),
|
|
46035
|
-
|
|
46767
|
+
refusal4 ? /* @__PURE__ */ jsx152(RefusalNotice, { error: refusal4 }) : null,
|
|
46036
46768
|
/* @__PURE__ */ jsxs141("div", { className: "flex gap-2", children: [
|
|
46037
46769
|
/* @__PURE__ */ jsx152(
|
|
46038
46770
|
Button106,
|
|
@@ -46149,7 +46881,7 @@ function openingView(activeView, activeDashboardId) {
|
|
|
46149
46881
|
}
|
|
46150
46882
|
function savedViewFromParam(activeView) {
|
|
46151
46883
|
const word = typeof activeView === "string" ? activeView.trim() : "";
|
|
46152
|
-
return
|
|
46884
|
+
return isUuidShape4(word) ? word.toLowerCase() : null;
|
|
46153
46885
|
}
|
|
46154
46886
|
function addressForView(view, layout) {
|
|
46155
46887
|
return view && !view.isDefault ? view.id : layout;
|
|
@@ -46250,7 +46982,7 @@ function TablePage({
|
|
|
46250
46982
|
const [hostLayout, setHostLayout] = useState130(hostFromLink);
|
|
46251
46983
|
const [views, setViews] = useState130(void 0);
|
|
46252
46984
|
const [pickedViewId, setPickedViewId] = useState130(savedFromLink);
|
|
46253
|
-
const viewSeen =
|
|
46985
|
+
const viewSeen = useRef54(null);
|
|
46254
46986
|
const [viewLinkMissed, setViewLinkMissed] = useState130(false);
|
|
46255
46987
|
const [layoutChosen, setLayoutChosen] = useState130(false);
|
|
46256
46988
|
const railAsked = typeof activeRail === "string" ? activeRail.trim() : "";
|
|
@@ -46321,7 +47053,7 @@ function TablePage({
|
|
|
46321
47053
|
lookDiffers: view ? lookDiffers(view, look) : false
|
|
46322
47054
|
};
|
|
46323
47055
|
const shownSignature = JSON.stringify(shownReport);
|
|
46324
|
-
const reportRef =
|
|
47056
|
+
const reportRef = useRef54(onShownViewChange);
|
|
46325
47057
|
reportRef.current = onShownViewChange;
|
|
46326
47058
|
useEffect108(() => {
|
|
46327
47059
|
reportRef.current?.(JSON.parse(shownSignature));
|
|
@@ -46382,18 +47114,18 @@ function TablePage({
|
|
|
46382
47114
|
},
|
|
46383
47115
|
[client, tableId, view, looks]
|
|
46384
47116
|
);
|
|
46385
|
-
const arrival =
|
|
47117
|
+
const arrival = useRef54(viewAddress ?? null);
|
|
46386
47118
|
const [gridQuery, setGridQuery] = useState130(null);
|
|
46387
47119
|
const [addressResetEpoch, setAddressResetEpoch] = useState130(0);
|
|
46388
47120
|
const reportGrid = useCallback66((q) => {
|
|
46389
47121
|
const next = { sort: q.sort, filters: q.filters, search: q.search, page: q.page };
|
|
46390
47122
|
setGridQuery((held) => sameViewAddress(held, next) ? held : next);
|
|
46391
47123
|
}, []);
|
|
46392
|
-
const addressPort =
|
|
47124
|
+
const addressPort = useMemo75(
|
|
46393
47125
|
() => ({ initial: arrival.current, report: reportGrid, resetEpoch: addressResetEpoch }),
|
|
46394
47126
|
[reportGrid, addressResetEpoch]
|
|
46395
47127
|
);
|
|
46396
|
-
const hiddenApplied =
|
|
47128
|
+
const hiddenApplied = useRef54(false);
|
|
46397
47129
|
useEffect108(() => {
|
|
46398
47130
|
const hidden = arrival.current?.hidden;
|
|
46399
47131
|
if (hiddenApplied.current || !view || !looks || !hidden || hidden.length === 0) return;
|
|
@@ -46414,9 +47146,9 @@ function TablePage({
|
|
|
46414
47146
|
const gridPending = !isViewAddressEmpty({ ...arrival.current ?? {}, hidden: [] });
|
|
46415
47147
|
const addressReady = Boolean(view && looks) && (gridQuery !== null || !gridPending);
|
|
46416
47148
|
const addressSignature = JSON.stringify(viewAddressToParams(addressNow));
|
|
46417
|
-
const addressReportRef =
|
|
47149
|
+
const addressReportRef = useRef54(onViewAddressChange);
|
|
46418
47150
|
addressReportRef.current = onViewAddressChange;
|
|
46419
|
-
const addressSent =
|
|
47151
|
+
const addressSent = useRef54(null);
|
|
46420
47152
|
useEffect108(() => {
|
|
46421
47153
|
if (!addressReady) return;
|
|
46422
47154
|
if (addressSent.current === null && addressSignature === JSON.stringify(viewAddressToParams(arrival.current))) {
|
|
@@ -46671,9 +47403,9 @@ function TablePage({
|
|
|
46671
47403
|
}
|
|
46672
47404
|
});
|
|
46673
47405
|
const openedEntry = ACTION_PRESS.find((entry) => entry.press.main !== void 0 && entry.press.main === main) ?? ACTION_PRESS.find((entry) => entry.press.rail !== void 0 && entry.press.rail === rail) ?? null;
|
|
46674
|
-
const actionsRef =
|
|
47406
|
+
const actionsRef = useRef54(actions);
|
|
46675
47407
|
actionsRef.current = actions;
|
|
46676
|
-
const onActionsRef =
|
|
47408
|
+
const onActionsRef = useRef54(onActions);
|
|
46677
47409
|
onActionsRef.current = onActions;
|
|
46678
47410
|
useEffect108(() => {
|
|
46679
47411
|
onActionsRef.current?.(actionsRef.current);
|
|
@@ -47020,7 +47752,7 @@ function TablePage({
|
|
|
47020
47752
|
QuestionPanel,
|
|
47021
47753
|
{
|
|
47022
47754
|
tableId,
|
|
47023
|
-
activeQuestionId: questionsFromLink && activeItemId &&
|
|
47755
|
+
activeQuestionId: questionsFromLink && activeItemId && isUuidShape4(activeItemId) ? activeItemId : null,
|
|
47024
47756
|
draft: questionDraft
|
|
47025
47757
|
}
|
|
47026
47758
|
) : main === "archived" ? (
|
|
@@ -47242,7 +47974,7 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
|
|
|
47242
47974
|
// src/entityViews.tsx
|
|
47243
47975
|
import { TapTargetSearchGroup as TapTargetSearchGroup2, TooltipProvider } from "@ai-matrx/design-system";
|
|
47244
47976
|
import { MatrxTableCardShowMore as MatrxTableCardShowMore3 } from "@ai-matrx/design-system/data-table";
|
|
47245
|
-
import { useEffect as useEffect109, useMemo as
|
|
47977
|
+
import { useEffect as useEffect109, useMemo as useMemo76, useState as useState131 } from "react";
|
|
47246
47978
|
import { Button as Button107, ErrorBox as ErrorBox9, Input as Input12, cn as cn93 } from "@ai-matrx/design-system";
|
|
47247
47979
|
import { useRecordsClient as useRecordsClient96 } from "@ai-matrx/records/react";
|
|
47248
47980
|
import { Fragment as Fragment64, jsx as jsx153, jsxs as jsxs142 } from "react/jsx-runtime";
|
|
@@ -47255,7 +47987,7 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
|
|
|
47255
47987
|
const choiceColumns = entityChoiceColumns(entity.columns);
|
|
47256
47988
|
const column = (groupBy ? choiceColumns.find((c) => c.key === groupBy) : void 0) ?? choiceColumns[0] ?? null;
|
|
47257
47989
|
const title = entityTitleColumn(entity.columns);
|
|
47258
|
-
const extra =
|
|
47990
|
+
const extra = useMemo76(
|
|
47259
47991
|
() => cardFields ? entity.columns.filter((c) => cardFields.includes(c.key)) : entity.columns.filter((c) => c !== title && c !== column && c.type !== "choice").slice(0, 2),
|
|
47260
47992
|
[cardFields, entity.columns, title, column]
|
|
47261
47993
|
);
|
|
@@ -47520,7 +48252,7 @@ function TablePage2(props) {
|
|
|
47520
48252
|
}
|
|
47521
48253
|
|
|
47522
48254
|
// src/DataBindingPicker.tsx
|
|
47523
|
-
import { useEffect as useEffect110, useMemo as
|
|
48255
|
+
import { useEffect as useEffect110, useMemo as useMemo77 } from "react";
|
|
47524
48256
|
import { isEntityReferenceConfig } from "@ai-matrx/records";
|
|
47525
48257
|
import { useFields as useFields37, useTable as useTable36 } from "@ai-matrx/records/react";
|
|
47526
48258
|
import { BasicInput as BasicInput35, Button as Button108, CreatablePicker as CreatablePicker3, cn as cn94 } from "@ai-matrx/design-system";
|
|
@@ -47614,7 +48346,7 @@ function BindingDetails({
|
|
|
47614
48346
|
}) {
|
|
47615
48347
|
const table = useTable36(tableId);
|
|
47616
48348
|
const fields = useFields37(tableId);
|
|
47617
|
-
const fieldList =
|
|
48349
|
+
const fieldList = useMemo77(() => fields.data ?? [], [fields.data]);
|
|
47618
48350
|
const shape = binding.semantic_type;
|
|
47619
48351
|
useEffect110(() => {
|
|
47620
48352
|
if (disabled || shape === "value" || binding.transform || fields.loading || fieldList.length === 0) return;
|
|
@@ -47883,16 +48615,16 @@ function Decision({ approvalId, onDecided }) {
|
|
|
47883
48615
|
}
|
|
47884
48616
|
|
|
47885
48617
|
// src/TemplatePreview.tsx
|
|
47886
|
-
import { useEffect as useEffect112, useMemo as
|
|
48618
|
+
import { useEffect as useEffect112, useMemo as useMemo78, useState as useState133 } from "react";
|
|
47887
48619
|
import { templatePreview } from "@ai-matrx/records/memory";
|
|
47888
48620
|
import { useRecordsClient as useRecordsClient98 } from "@ai-matrx/records/react";
|
|
47889
48621
|
import { jsx as jsx158, jsxs as jsxs146 } from "react/jsx-runtime";
|
|
47890
48622
|
function useTemplatePreview(spec, today) {
|
|
47891
|
-
return
|
|
48623
|
+
return useMemo78(() => templatePreview(spec, today ? { today } : {}), [spec, today]);
|
|
47892
48624
|
}
|
|
47893
48625
|
function TemplatePreview({ spec, today, initialTable, host, aside, booking, className }) {
|
|
47894
48626
|
const preview = useTemplatePreview(spec, today);
|
|
47895
|
-
const bound2 =
|
|
48627
|
+
const bound2 = useMemo78(() => ({ ...host, sayLevelNeeded: false }), [host]);
|
|
47896
48628
|
const first = preview.tables.find((t) => t.token === initialTable) ?? preview.tables[0];
|
|
47897
48629
|
const [active, setActive] = useState133(first?.id ?? null);
|
|
47898
48630
|
const table = preview.tables.find((t) => t.id === active) ?? first;
|