@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/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 [refusal3, setRefusal] = useState5(null);
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
- refusal3 ? /* @__PURE__ */ jsx7(RefusalLine, { error: refusal3, className: "p-2" }) : null,
2055
- !rows && !refusal3 ? /* @__PURE__ */ jsx7("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading\u2026" }) : null,
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 [refusal3, setRefusal] = useState15(null);
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": refusal3 ? true : void 0,
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 (!refusal3) return;
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
- refusal3 ? /* @__PURE__ */ jsx17("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal3 }) : null
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 [refusal3, setRefusal] = useState15(null);
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 (refusal3)
4416
- return /* @__PURE__ */ jsx17("div", { id, children: /* @__PURE__ */ jsx17(RefusalLine, { error: refusal3 }) });
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 [refusal3, setRefusal] = useState20(null);
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
- refusal3?.key === id ? /* @__PURE__ */ jsx24(RefusalNotice, { error: refusal3.error }) : null,
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 refusal3 = editing ? editing.refusalOf(row.id, field2.key) : null;
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
- refusal3 && !refusal3.conflict ? /* @__PURE__ */ jsx27(
7046
+ refusal4 && !refusal4.conflict ? /* @__PURE__ */ jsx27(
7047
7047
  RefusalNotice,
7048
7048
  {
7049
- error: refusal3.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
- refusal3 ? /* @__PURE__ */ jsx27(CellRefusalNotice, { refusal: refusal3, field: field2, row, editing, typed: false }) : null
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
- refusal3 ? /* @__PURE__ */ jsx27(CellRefusalNotice, { refusal: refusal3, field: field2, row, editing, typed: false }) : null
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
- refusal3 ? /* @__PURE__ */ jsx27(CellRefusalNotice, { refusal: refusal3, field: field2, row, editing, typed: true }) : null
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: refusal3,
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(refusal3.error);
7208
- const notice = refusal3.conflict ? /* @__PURE__ */ jsx27(
7207
+ const line = refusalLineForAPerson(refusal4.error);
7208
+ const notice = refusal4.conflict ? /* @__PURE__ */ jsx27(
7209
7209
  RefusalNotice,
7210
7210
  {
7211
- error: refusal3.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(refusal3.conflict, field2.key) })
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: refusal3.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 [refusal3, setRefusal] = useState28(null);
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
- refusal3 ? /* @__PURE__ */ jsx33(RefusalNotice, { error: refusal3 }) : null,
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 [refusal3, setRefusal] = useState29(null);
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 (refusal3) return /* @__PURE__ */ jsx34(RefusalNotice, { error: refusal3 });
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 [refusal3, setRefusal] = useState32(null);
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
- refusal3 ? /* @__PURE__ */ jsx39(RefusalNotice, { error: refusal3 }) : null,
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 refusal3 = mayColour ? void 0 : whyNot;
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: refusal3,
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, refusal3, write]
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: refusal3,
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, refusal3, write]
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: refusal3,
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, refusal3, client, tableId, decorations, notify]
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: refusal3,
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, refusal3, write]
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 refusal3 of predicted) {
12487
- const key = refusal3.field_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 = refusal3.message;
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: refusal3.message
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((refusal3, index) => /* @__PURE__ */ jsxs49("li", { className: "text-xs text-muted-foreground", children: [
15740
- /* @__PURE__ */ jsx54("span", { className: "font-medium", children: refusal3.fromLine > 0 ? `Row ${refusal3.fromLine}, ${refusal3.column}` : refusal3.column }),
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
- refusal3.why
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 refusal3 = null;
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) refusal3 = failed.error;
19690
+ if (failed && !failed.ok) refusal4 = failed.error;
19691
19691
  }
19692
- if (!refusal3 && step2.retiredField) {
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) refusal3 = done.error;
19695
+ if (!done.ok) refusal4 = done.error;
19696
19696
  else tableShapeChanged5(tableId);
19697
19697
  }
19698
- if (!refusal3 && changes.length > 0) {
19698
+ if (!refusal4 && changes.length > 0) {
19699
19699
  const done = await changeRecordsAt(client, { table_id: tableId, changes });
19700
- if (!done.ok) refusal3 = done.error;
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 (!refusal3 && direction === "undo" && (step2.archived?.length ?? 0) > 0) {
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) refusal3 = failed.error;
19709
+ if (failed && !failed.ok) refusal4 = failed.error;
19710
19710
  }
19711
19711
  setBusy(false);
19712
- if (refusal3) {
19713
- setNotice({ says: `${direction === "undo" ? "Undo" : "Redo"} changed nothing: ${refusalSentence(refusal3)}`, refusal: refusal3, canUndo: false });
19714
- if (isChangedElsewhere(refusal3)) reload();
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/design-system/content-transfer";
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 [refusal3, setRefusal] = useState57(null);
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: refusal3, clearRefusal: () => setRefusal(null), apply, duplicate, archive };
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 useMemo36 } from "react";
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
- EntityDataProvider,
23171
- useEntityColumns,
23172
- useEntityList,
23173
- useEntityType,
23174
- useEntityWrite,
23175
- useOptionalEntityScope
23176
- } from "@ai-matrx/entity-data/react";
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 isRefList(value) {
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 (isRefList(v)) return v.map((ref) => typeof ref.label === "string" ? ref.label : "").filter(Boolean).join(", ");
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 = useMemo36(() => entityShownColumns(columns.data ?? []), [columns.data]);
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 isRefList(v) ? entityValueText(c, v) : v;
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 = useMemo36(() => entityTableColumns(entity.columns, canEdit), [entity.columns, canEdit]);
23290
- const byId = useMemo36(() => new Map(entity.columns.map((c) => [columnId(c), c])), [entity.columns]);
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 useMemo37, useState as useState61 } from "react";
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 = useMemo37(() => runs ? runToNotice(runs) : null, [runs]);
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 useMemo40, useState as useState67 } from "react";
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 useMemo39, useState as useState64 } from "react";
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 useMemo38, useRef as useRef30, useState as useState62 } from "react";
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 = useRef30(null);
24798
+ const madeRef = useRef31(null);
24067
24799
  const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
24068
- const askable = useMemo38(
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 = useMemo38(
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 = useRef30(false);
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 [refusal3, setRefusal] = useState63(null);
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
- refusal3 && refusal3.id === thing.id ? /* @__PURE__ */ jsx78(RefusalNotice, { error: refusal3.error, className: "mt-2" }) : null
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 = useMemo39(
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 = useMemo40(() => shapesOfSource(source), [source]);
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 = useMemo40(() => JSON.stringify({ headers, rows }), [headers, rows]);
25834
- const wizardSource = useMemo40(
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 useMemo41, useState as useState68 } from "react";
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 = useMemo41(() => stageKey ? gatesOf(pipeline, stageKey) : [], [pipeline, stageKey]);
26250
- const conditionFields = useMemo41(
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 useRef31, useState as useState69 } from "react";
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 = useRef31(false);
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 = useRef31(null);
26525
- const openedAt = useRef31(null);
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 useRef32, useState as useState75 } from "react";
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(refusal3) {
26712
- const sentence2 = refusalSentence(refusal3);
27443
+ constructor(refusal4) {
27444
+ const sentence2 = refusalSentence(refusal4);
26713
27445
  super(sentence2);
26714
27446
  this.name = "TableRestoreRefused";
26715
- this.refusal = refusal3;
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 useMemo42, useState as useState73 } from "react";
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 = useMemo42(() => rowLabelChoices(fields), [fields]);
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 useMemo43, useState as useState74 } from "react";
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 = useMemo43(() => new Map(rows.map((f) => [f.id, f])), [rows]);
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 = useRef32(null);
27263
- const archiveAskedSeen = useRef32(0);
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 useMemo44, useState as useState76 } from "react";
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 = useMemo44(() => {
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 useRef33, useState as useState78 } from "react";
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 = useRef33(null);
27707
- const waiting = useRef33(null);
27708
- const timer = useRef33(null);
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 = useRef33(write);
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 useMemo45, useState as useState80 } from "react";
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 = useMemo45(() => spec, [slug]);
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 useMemo53, useState as useState88 } from "react";
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 useMemo47, useRef as useRef34, useState as useState82 } from "react";
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 useMemo46, useState as useState81 } from "react";
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 useMemo46(() => {
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 = useMemo46(() => whatYouMayDo(row.level || null, true), [row.level]);
28407
- const actions = useMemo46(
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 = useMemo47(
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 = useRef34(true);
29231
+ const alive = useRef35(true);
28500
29232
  const [selected, setSelected] = useState82(/* @__PURE__ */ new Set());
28501
- const anchor = useRef34(null);
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 = useRef34(versions);
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 = useMemo47(() => {
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 = useMemo47(
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 = useMemo47(
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 useMemo50, useRef as useRef36, useState as useState84 } from "react";
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 useMemo48, useRef as useRef35, useState as useState83 } from "react";
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 = useRef35(undo);
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 useMemo48(
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 useMemo49 } from "react";
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 useMemo49(() => {
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 = useMemo50(() => titleField ? [titleField] : [], [titleField]);
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 = useMemo50(
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 = useMemo50(() => eligibleFieldFor("choice", all).eligible.filter(isChoiceField), [all]);
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 } = useMemo50(() => {
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 = useRef36(null);
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 = useRef36(0);
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 = useRef36(null);
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 useMemo51, useRef as useRef37, useState as useState85 } from "react";
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 = useMemo51(() => offerableFields(fields, "date", { far: farFields }), [fields, farFields]);
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 = useMemo51(() => dates.filter((f) => f.key !== startChosen), [dates, startChosen]);
30421
- const endAuto = useMemo51(() => {
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 = useMemo51(() => groupableFields(fields), [fields]);
31158
+ const groupCandidates = useMemo52(() => groupableFields(fields), [fields]);
30427
31159
  const groupChosen = "groupKey" in picked ? picked.groupKey ?? null : has(groupCandidates, groupKey);
30428
- const choiceFields = useMemo51(() => fields.filter(isChoiceField), [fields]);
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 = useMemo51(() => [titleField, groupField].filter((f) => Boolean(f)), [titleField, groupField]);
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 } = useMemo51(() => {
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 = useMemo51(() => scaleOf(from, days, zoom), [from, days, zoom]);
31277
+ const scale = useMemo52(() => scaleOf(from, days, zoom), [from, days, zoom]);
30546
31278
  const xOf = (day) => daysBetween(from, day) * px;
30547
- const scroller = useRef37(null);
31279
+ const scroller = useRef38(null);
30548
31280
  const grouped = Boolean(groupField);
30549
31281
  const [scrollX, setScrollX] = useState85(0);
30550
- const frame = useRef37(null);
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 = useMemo51(() => {
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 = useMemo51(
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 = useMemo51(() => {
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 useMemo52 } from "react";
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 = useMemo52(() => listGroups(rows, groupKey), [rows, groupKey]);
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 = useMemo52(() => titleField && pointsAtRecords(titleField) ? [titleField] : NO_FIELDS, [titleField]);
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 = useMemo53(
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 = useMemo53(() => table.data?.rows ?? [], [table.data]);
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 = useMemo53(
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 = useMemo53(
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 = useMemo53(() => [groupField], [groupField]);
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 = useMemo53(() => {
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 = useMemo53(
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 = useMemo53(() => {
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 = useMemo53(() => new Set(hiddenFields ?? []), [hiddenFields]);
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 = useMemo53(
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 [refusal3, setRefusal] = useState89(null);
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
- refusal3 && refusal3.recordId === row.id ? /* @__PURE__ */ jsx106(RefusalNotice, { error: refusal3.error, className: "mt-2" }) : null
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 [refusal3, setRefusal] = useState89(null);
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
- refusal3 && refusal3.fieldId === row.id ? /* @__PURE__ */ jsx106(RefusalNotice, { error: refusal3.error, className: "mt-2" }) : null
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 [refusal3, setRefusal] = useState90(null);
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
- refusal3 && refusal3.portalId === portal.portal_id ? /* @__PURE__ */ jsx107(RefusalNotice, { error: refusal3.error }) : null
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 useRef38 } from "react";
33541
+ import { useCallback as useCallback39, useRef as useRef39 } from "react";
32810
33542
  function useSeedGuard() {
32811
- const claimed = useRef38(/* @__PURE__ */ new Set());
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 useRef39, useState as useState92 } from "react";
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 = useRef39(null);
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 useMemo55, useRef as useRef40, useState as useState94 } from "react";
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 useMemo54, useState as useState93 } from "react";
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 = useMemo54(
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 [refusal3, setRefusal] = useState93(null);
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
- refusal3 ? /* @__PURE__ */ jsx110(RefusalNotice, { error: refusal3 }) : null,
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 [refusal3, setRefusal] = useState93(null);
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 = useMemo54(
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 || refusal3 !== null || spec.steps.length === 0, onClick: () => void save(), children: busy ? "\u2026" : "Save" }),
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
- refusal3 ? /* @__PURE__ */ jsx110("p", { className: "text-xs text-muted-foreground", "data-testid": "checklist-editor-refusal", children: refusal3 }) : null
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 = useRef40(null);
34874
+ const listRef = useRef41(null);
34143
34875
  const [selected, setSelected] = useState94(/* @__PURE__ */ new Set());
34144
- const anchor = useRef40(null);
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 = useMemo55(() => {
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 = useMemo55(
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 = useMemo55(() => groupInbox(narrowed, groupBy), [narrowed, groupBy]);
34181
- const shown4 = useMemo55(() => groups.flatMap((g) => g.items), [groups]);
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 = useRef40(/* @__PURE__ */ new Map());
34209
- const lastHold = useRef40(null);
34210
- const holdSeq = useRef40(0);
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 = useRef40(false);
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 useRef41, useState as useState95 } from "react";
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 = useRef41(null);
35640
+ const seenAtPreview = useRef42(null);
34909
35641
  const [said, setSaid] = useState95(null);
34910
- const listRef = useRef41(null);
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 useMemo56, useRef as useRef42, useState as useState96 } from "react";
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 = useRef42(null);
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 = useMemo56(() => {
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 useRef43, useState as useState97 } from "react";
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 = useRef43(null);
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 useMemo57, useRef as useRef44, useState as useState98 } from "react";
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 = useMemo57(() => Object.values(exposures).filter((e) => e.on), [exposures]);
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 = useRef44(null);
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 = useRef44(/* @__PURE__ */ new Set());
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 = useMemo57(() => {
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 useMemo59, useState as useState100 } from "react";
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 useMemo58, useState as useState99 } from "react";
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 = useMemo58(
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 = useMemo59(() => {
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 useMemo60, useState as useState101 } from "react";
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 = useMemo60(() => {
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 = useMemo60(
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 useMemo62, useRef as useRef46, useState as useState106 } from "react";
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 useMemo61, useRef as useRef45, useState as useState104 } from "react";
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 [refusal3, setRefusal] = useState104(null);
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 = useRef45("");
38173
- const stage = useRef45(null);
38174
- const questions = useMemo61(() => {
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 = useRef45(answers);
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 = useRef45(
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
- refusal3 ? /* @__PURE__ */ jsx124(
39094
+ refusal4 ? /* @__PURE__ */ jsx124(
38363
39095
  RefusalNotice,
38364
39096
  {
38365
- error: refusal3,
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 = useRef46(null);
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 = useMemo62(() => new Map((fields.data ?? []).map((f) => [f.key, f])), [fields.data]);
38884
- const stored = useMemo62(() => draft ? (forms ?? []).find((f) => f.id === draft.id) ?? null : null, [draft, forms]);
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 useRef47,
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 = useRef47(null);
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 useRef48, useState as useState109 } from "react";
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 = useRef48(null);
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 useMemo64 } from "react";
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 mapPgError2 } from "@ai-matrx/records/core";
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 useMemo63, useState as useState111 } from "react";
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 useMemo63(() => {
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 mapPgError2(
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 = useMemo64(() => {
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 = useMemo64(() => {
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 useMemo67, useState as useState114 } from "react";
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 useMemo66, useState as useState113 } from "react";
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 useMemo65, useState as useState112 } from "react";
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 useRef49 } from "react";
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 = useRef49(null);
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 = useMemo65(() => fields.data ?? [], [fields.data]);
41117
- const byKey = useMemo65(() => new Map(all.map((f) => [f.key, f])), [all]);
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 = useMemo66(() => onePerKey(fields.data ?? []), [fields.data]);
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 = useMemo67(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
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 useMemo68, useRef as useRef50, useState as useState115 } from "react";
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 mapPgError3 } from "@ai-matrx/records/core";
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 refusal2(message, hint) {
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 refusal2(`Pick the column to ${m.op === "avg" ? "average" : m.op}.`);
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 refusal2(
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 refusal2(`\u201C${group.relation}\u201D is not a relation of this table.`);
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 refusal2(
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 refusal2(
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 refusal2("\u201CAs of\u201D cannot reach across a relation yet.", "Ask without the related table's column, or without \u201Cas of\u201D.");
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 refusal2("\u201CAs of\u201D cannot cut dates into periods yet.", "Summarize by the date itself, or ask without \u201Cas of\u201D.");
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 refusal2("\u201CAs of\u201D can only be filtered with \u201Cis\u201D conditions, all of them true.", "Simplify the filter, or ask without \u201Cas of\u201D.");
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 refusal2(
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 refusal2("\u201CAs of\u201D is not a date and time.");
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: mapPgError3(response.error, "askQuestion.asOf") };
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 refusal2(`${m.key} held \u201C${bad.a_non_number}\u201D then, which is not a number, so its ${m.op} cannot be worked out.`);
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: mapPgError3(response.error, "questionsOf") };
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 refusal2("Name the question so the team can find it.");
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: mapPgError3(response.error, "questionSave") };
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: mapPgError3(response.error, "questionArchive") };
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 = useMemo68(() => fields.data ?? [], [fields.data]);
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 = useMemo68(() => hidden ? all.filter((f) => !hidden.has(f.key)) : [], [all, hidden]);
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 = useRef50(false);
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 = useMemo68(
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 useMemo69, useState as useState117 } from "react";
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 = useMemo69(
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 = useMemo69(() => onePerKey3(fields.data ?? []), [fields.data]);
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 useRef52, useState as useState120 } from "react";
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 useMemo70, useRef as useRef51, useState as useState119 } from "react";
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 = useRef51(null);
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 = useMemo70(() => {
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 = useRef52([]);
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 useMemo74, useRef as useRef53, useState as useState130 } from "react";
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 useMemo71, useState as useState125 } from "react";
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 = useMemo71(() => ({ kind: "table", id: tableId }), [tableId]);
46119
+ const source = useMemo72(() => ({ kind: "table", id: tableId }), [tableId]);
45388
46120
  const { def } = useDrillDefinition(open ? source : null);
45389
- const dimensions = useMemo71(() => drillDimensionsOf(def, NO_LABELS), [def]);
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 useMemo72, useState as useState126 } from "react";
45417
- import { useContentTransferCapabilities as useContentTransferCapabilities2 } from "@ai-matrx/design-system/content-transfer";
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 = useMemo72(
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 useMemo73, useState as useState128 } from "react";
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 = useMemo73(
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 isUuidShape3 } from "@ai-matrx/kit/uuid";
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 [refusal3, setRefusal] = useState130(null);
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
- refusal3 ? /* @__PURE__ */ jsx152(RefusalNotice, { error: refusal3 }) : null,
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 isUuidShape3(word) ? word.toLowerCase() : null;
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 = useRef53(null);
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 = useRef53(onShownViewChange);
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 = useRef53(viewAddress ?? null);
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 = useMemo74(
47124
+ const addressPort = useMemo75(
46393
47125
  () => ({ initial: arrival.current, report: reportGrid, resetEpoch: addressResetEpoch }),
46394
47126
  [reportGrid, addressResetEpoch]
46395
47127
  );
46396
- const hiddenApplied = useRef53(false);
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 = useRef53(onViewAddressChange);
47149
+ const addressReportRef = useRef54(onViewAddressChange);
46418
47150
  addressReportRef.current = onViewAddressChange;
46419
- const addressSent = useRef53(null);
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 = useRef53(actions);
47406
+ const actionsRef = useRef54(actions);
46675
47407
  actionsRef.current = actions;
46676
- const onActionsRef = useRef53(onActions);
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 && isUuidShape3(activeItemId) ? activeItemId : null,
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 useMemo75, useState as useState131 } from "react";
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 = useMemo75(
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 useMemo76 } from "react";
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 = useMemo76(() => fields.data ?? [], [fields.data]);
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 useMemo77, useState as useState133 } from "react";
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 useMemo77(() => templatePreview(spec, today ? { today } : {}), [spec, today]);
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 = useMemo77(() => ({ ...host, sayLevelNeeded: false }), [host]);
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;