@ai-matrx/records-ui 0.102.15 → 0.102.17

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
@@ -1134,12 +1134,12 @@ function PickOrAdd({
1134
1134
  children,
1135
1135
  chips,
1136
1136
  multi,
1137
- addFirst
1137
+ onEscape
1138
1138
  }) {
1139
1139
  const addRow = add && !foot ? add : null;
1140
1140
  const count = items.length + (addRow ? 1 : 0);
1141
- const addAt = addRow ? addFirst ? 0 : items.length : -1;
1142
- const itemAt = (index) => addRow && addFirst ? index - 1 : index;
1141
+ const addAt = addRow ? items.length : -1;
1142
+ const itemAt = (index) => index;
1143
1143
  const removable = (chips ?? []).filter((c) => c.onRemove);
1144
1144
  const keys = useListKeys({
1145
1145
  count,
@@ -1153,7 +1153,7 @@ function PickOrAdd({
1153
1153
  if (item && !item.disabled) onPick(item.id);
1154
1154
  },
1155
1155
  onNothing: onEnterWithNoMatch ?? (add && !add.disabled ? add.onAdd : void 0),
1156
- onClose: () => onOpenChange(false),
1156
+ onClose: () => onEscape ? onEscape() : onOpenChange(false),
1157
1157
  ...multi ? { onFinish: () => onOpenChange(false) } : {},
1158
1158
  ...removable.length > 0 ? { onBackspaceEmpty: () => removable[removable.length - 1]?.onRemove?.() } : {},
1159
1159
  searchEmpty: search === ""
@@ -1187,6 +1187,11 @@ function PickOrAdd({
1187
1187
  onKeyDown: (event) => {
1188
1188
  if (event.key !== "Tab") event.stopPropagation();
1189
1189
  },
1190
+ onEscapeKeyDown: (event) => {
1191
+ if (!onEscape) return;
1192
+ event.preventDefault();
1193
+ onEscape();
1194
+ },
1190
1195
  onCloseAutoFocus: (event) => {
1191
1196
  if (anchored) event.preventDefault();
1192
1197
  },
@@ -1208,7 +1213,6 @@ function PickOrAdd({
1208
1213
  notice,
1209
1214
  /* @__PURE__ */ jsxs5(ScrollArea, { className: "max-h-64", children: [
1210
1215
  /* @__PURE__ */ jsxs5("div", { role: "listbox", "aria-label": triggerLabel, "aria-multiselectable": multi ? true : void 0, children: [
1211
- addFirst ? addRowNode : null,
1212
1216
  items.map((item, index) => /* @__PURE__ */ jsx6(
1213
1217
  PickRow,
1214
1218
  {
@@ -1220,13 +1224,13 @@ function PickOrAdd({
1220
1224
  disabled: item.disabled,
1221
1225
  attrs: item.attrs,
1222
1226
  person: item.person,
1223
- highlighted: (addRow && addFirst ? index + 1 : index) === keys.highlight,
1227
+ highlighted: index === keys.highlight,
1224
1228
  onPick: () => onPick(item.id),
1225
- onPoint: () => keys.setHighlight(addRow && addFirst ? index + 1 : index)
1229
+ onPoint: () => keys.setHighlight(index)
1226
1230
  },
1227
1231
  item.id
1228
1232
  )),
1229
- addFirst ? null : addRowNode
1233
+ addRowNode
1230
1234
  ] }),
1231
1235
  items.length === 0 && empty ? empty : null
1232
1236
  ] }),
@@ -1271,7 +1275,7 @@ async function personRecordForMember(client, personTableId, people, member) {
1271
1275
  });
1272
1276
  return written;
1273
1277
  }
1274
- function PersonPicker({ field: field2, value, onChange, disabled, id, className, autoOpen, onClose, initialSearch }) {
1278
+ function PersonPicker({ field: field2, value, onChange, disabled, id, className, autoOpen, onClose, onCancel, initialSearch }) {
1275
1279
  const client = useOptionalRecordsClient();
1276
1280
  const host = useRecordsUi();
1277
1281
  const [members, setMembers] = useState4(null);
@@ -1385,6 +1389,7 @@ function PersonPicker({ field: field2, value, onChange, disabled, id, className,
1385
1389
  /* @__PURE__ */ jsx7(
1386
1390
  PickOrAdd,
1387
1391
  {
1392
+ ...anchored && onCancel ? { onEscape: onCancel } : {},
1388
1393
  anchored,
1389
1394
  multi: field2.multi,
1390
1395
  triggerId: id,
@@ -2531,7 +2536,7 @@ function tellApart(rows, nameOf2) {
2531
2536
  // src/RelationPicker.tsx
2532
2537
  import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2533
2538
  var NO_STORE_ON_THIS_SCREEN_REASON = "This question points at a record in somebody's own data, and a page answered without an account is never allowed to search that. Leave it blank \u2014 whoever receives your answer will fill it in.";
2534
- function RelationPicker({ field: field2, value, onChange, disabled, id, className, allowCreate = true, onPicked, autoOpen, onClose }) {
2539
+ function RelationPicker({ field: field2, value, onChange, disabled, id, className, allowCreate = true, onPicked, autoOpen, onClose, onCancel }) {
2535
2540
  const client = useOptionalRecordsClient2();
2536
2541
  const [rows, setRows] = useState6(null);
2537
2542
  const [words2, setWords] = useState6({});
@@ -2699,6 +2704,7 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
2699
2704
  PickOrAdd,
2700
2705
  {
2701
2706
  anchored,
2707
+ ...anchored && onCancel ? { onEscape: onCancel } : {},
2702
2708
  multi: field2.multi,
2703
2709
  chips: picked.map((recordId) => ({ id: recordId, label: titleOf(recordId), onRemove: () => toggle(recordId) })),
2704
2710
  triggerId: id,
@@ -4271,7 +4277,7 @@ function ChoiceAskButtons({
4271
4277
  onCancel,
4272
4278
  busy
4273
4279
  }) {
4274
- return /* @__PURE__ */ jsxs17("span", { "data-records-choice-ask": "", role: "group", "aria-label": choiceAskSentence(field2, words2), className: "flex flex-col gap-1", children: [
4280
+ return /* @__PURE__ */ jsxs17("span", { "data-records-choice-ask": "", "data-records-cell-note": "", role: "group", "aria-label": choiceAskSentence(field2, words2), className: "flex flex-col gap-1", children: [
4275
4281
  /* @__PURE__ */ jsx19("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field2, words2) }),
4276
4282
  /* @__PURE__ */ jsxs17("span", { className: "flex flex-wrap items-center gap-1", children: [
4277
4283
  /* @__PURE__ */ jsx19(Button8, { type: "button", size: "sm", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onAdd, children: "Add" }),
@@ -4308,7 +4314,11 @@ function typingOpens(field2) {
4308
4314
  var SHORT_REFUSAL = {
4309
4315
  email: "Enter a valid email",
4310
4316
  url: "Enter a valid link",
4311
- phone: "Enter a valid phone number"
4317
+ phone: "Enter a valid phone number",
4318
+ time: "Enter a time, like 2:30 PM",
4319
+ date: "Enter a date",
4320
+ number: "Enter a number",
4321
+ value: "Not a valid value"
4312
4322
  };
4313
4323
  function judgeTyped(field2, text, choices, nudge) {
4314
4324
  const trimmed = text.trim();
@@ -4317,7 +4327,7 @@ function judgeTyped(field2, text, choices, nudge) {
4317
4327
  if (trimmed === "") return { value: null };
4318
4328
  if (format && format.id === "time") {
4319
4329
  const read2 = readTypedTime2(trimmed);
4320
- return read2.ok ? { value: read2.value } : { refusal: `${fieldName(field2)} holds a time of day, and ${read2.why}` };
4330
+ return read2.ok ? { value: read2.value } : { refusal: SHORT_REFUSAL.time, why: `${fieldName(field2)} holds a time of day, and ${read2.why}` };
4321
4331
  }
4322
4332
  if (kind === "select" || kind === "multi_select") {
4323
4333
  if (!choices || nudge === null) return null;
@@ -4355,7 +4365,7 @@ function judgeTyped(field2, text, choices, nudge) {
4355
4365
  if (format && format.id === "rating") {
4356
4366
  const n = Number(trimmed);
4357
4367
  const max = format.options?.ratingMax ?? 5;
4358
- return Number.isInteger(n) && n >= 0 && n <= max ? { value: n === 0 ? null : n } : { refusal: `${fieldName(field2)} is a rating from 1 to ${max}, and \u201C${text}\u201D is not one.` };
4368
+ return Number.isInteger(n) && n >= 0 && n <= max ? { value: n === 0 ? null : n } : { refusal: `Enter 1 to ${max}`, why: `${fieldName(field2)} is a rating from 1 to ${max}.` };
4359
4369
  }
4360
4370
  if (kind === "phone" || format && format.id === "phone") {
4361
4371
  const digits = trimmed.replace(/\D/g, "");
@@ -4364,7 +4374,11 @@ function judgeTyped(field2, text, choices, nudge) {
4364
4374
  }
4365
4375
  const showsAsPercent = Boolean(format && (format.id === "percent" || format.id === "progress"));
4366
4376
  const read = coerceTypedAnswer(field2, text, { label: fieldName(field2), showsAsPercent });
4367
- if ("refusal" in read) return { refusal: kind === "email" || kind === "url" ? SHORT_REFUSAL[kind] : read.refusal };
4377
+ if ("refusal" in read) {
4378
+ if (kind === "email" || kind === "url") return { refusal: SHORT_REFUSAL[kind] };
4379
+ const short = kind === "datetime" ? SHORT_REFUSAL.date : kind === "number" || kind === "currency" || kind === "percent" || showsAsPercent ? SHORT_REFUSAL.number : read.refusal.length <= 32 ? read.refusal : SHORT_REFUSAL.value;
4380
+ return short === read.refusal ? { refusal: short } : { refusal: short, why: read.refusal };
4381
+ }
4368
4382
  if (typeof read.value === "number" && format && (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction") {
4369
4383
  return { value: Math.round(read.value / 100 * 1e9) / 1e9 };
4370
4384
  }
@@ -4449,7 +4463,7 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
4449
4463
  box,
4450
4464
  /* @__PURE__ */ jsx19(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field2) })
4451
4465
  ] }) : box,
4452
- judged === null ? /* @__PURE__ */ jsxs17("span", { className: "text-[10px] text-muted-foreground", children: [
4466
+ judged === null ? /* @__PURE__ */ jsxs17("span", { "data-records-cell-note": "", className: "text-[10px] text-muted-foreground", children: [
4453
4467
  "Reading ",
4454
4468
  fieldName(field2),
4455
4469
  "'s choices\u2026"
@@ -4469,10 +4483,19 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
4469
4483
  },
4470
4484
  onCancel: () => onCancel?.()
4471
4485
  }
4472
- ) : "refusal" in judged ? /* @__PURE__ */ jsxs17("span", { className: "flex flex-col gap-1", children: [
4473
- /* @__PURE__ */ jsx19("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: judged.refusal }),
4486
+ ) : "refusal" in judged ? /* @__PURE__ */ jsxs17("span", { "data-records-cell-note": "", className: "flex flex-col gap-1", children: [
4487
+ /* @__PURE__ */ jsx19(
4488
+ "span",
4489
+ {
4490
+ "data-records-typed-refusal": "",
4491
+ role: "status",
4492
+ title: "why" in judged ? judged.why : void 0,
4493
+ className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400",
4494
+ children: judged.refusal
4495
+ }
4496
+ ),
4474
4497
  judged.cancelOnly && onCancel ? /* @__PURE__ */ jsx19("span", { "data-records-choice-ask": "", children: /* @__PURE__ */ jsx19(Button8, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => onCancel(), children: "Cancel" }) }) : null
4475
- ] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ jsxs17("span", { "data-records-typed-reads-as": "", className: "text-[10px] text-muted-foreground", children: [
4498
+ ] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ jsxs17("span", { "data-records-typed-reads-as": "", "data-records-cell-note": "", className: "text-[10px] text-muted-foreground", children: [
4476
4499
  isChoiceAddition(judged.value) ? `Adds ${quoted(judged.value.add)} to the choices for ${fieldName(field2)}. ` : null,
4477
4500
  "Reads as",
4478
4501
  " ",
@@ -4566,9 +4589,9 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
4566
4589
  return /* @__PURE__ */ jsx19(CheckboxControl, { field: field2, value, onChange, disabled, id: inputId });
4567
4590
  case "select":
4568
4591
  case "multi_select":
4569
- return /* @__PURE__ */ jsx19(OptionControl, { field: field2, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
4592
+ return /* @__PURE__ */ jsx19(OptionControl, { field: field2, value, onChange, disabled, id: inputId, autoOpen, onClose, onCancel, addsChoices, initialSearch, asForm });
4570
4593
  case "member":
4571
- return /* @__PURE__ */ jsx19(PersonPicker, { field: field2, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
4594
+ return /* @__PURE__ */ jsx19(PersonPicker, { field: field2, value, onChange, disabled, id: inputId, autoOpen, onClose, onCancel, initialSearch });
4572
4595
  case "entity_reference":
4573
4596
  return /* @__PURE__ */ jsx19(EntityReferenceControl, { field: field2, value, onChange, disabled, id: inputId });
4574
4597
  case "attachment":
@@ -4577,7 +4600,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
4577
4600
  }
4578
4601
  return /* @__PURE__ */ jsx19(RelationPicker, { field: field2, value, onChange, disabled, id: inputId });
4579
4602
  case "relation":
4580
- return /* @__PURE__ */ jsx19(RelationPicker, { field: field2, value, onChange, disabled, id: inputId, onPicked: onCommit, autoOpen, onClose });
4603
+ return /* @__PURE__ */ jsx19(RelationPicker, { field: field2, value, onChange, disabled, id: inputId, onPicked: onCommit, autoOpen, onClose, onCancel });
4581
4604
  default:
4582
4605
  if (typeof value === "boolean" || field2.config?.["kind"] === "boolean") {
4583
4606
  return /* @__PURE__ */ jsx19(
@@ -4605,6 +4628,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
4605
4628
  function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
4606
4629
  const [text, setText] = useState16(() => openingText(field2, value));
4607
4630
  const [refusal4, setRefusal] = useState16(null);
4631
+ const [why, setWhy] = useState16(void 0);
4608
4632
  const sent = useRef11(value);
4609
4633
  useEffect11(() => {
4610
4634
  if (value === sent.current) return;
@@ -4622,6 +4646,7 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
4622
4646
  onChange(judged.value);
4623
4647
  } else if (judged && "refusal" in judged) {
4624
4648
  setRefusal(judged.refusal);
4649
+ setWhy("why" in judged ? judged.why : void 0);
4625
4650
  }
4626
4651
  };
4627
4652
  return /* @__PURE__ */ jsxs17("span", { className: "flex flex-col gap-0.5", children: [
@@ -4645,7 +4670,7 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
4645
4670
  ),
4646
4671
  helper && !disabled ? /* @__PURE__ */ jsx19(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field2) }) : null
4647
4672
  ] }),
4648
- refusal4 ? /* @__PURE__ */ jsx19("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal4 }) : null
4673
+ refusal4 ? /* @__PURE__ */ jsx19("span", { "data-records-typed-refusal": "", "data-records-cell-note": "", role: "status", title: why, className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal4 }) : null
4649
4674
  ] });
4650
4675
  }
4651
4676
  function CheckboxControl({ field: field2, value, onChange, disabled, id }) {
@@ -4715,8 +4740,9 @@ function JsonControl({ field: field2, value, onChange, disabled, id }) {
4715
4740
  }
4716
4741
  ),
4717
4742
  broken ? (
4718
- // The typed text is still in the box: the notice owns the two doors out.
4719
- /* @__PURE__ */ jsx19(
4743
+ // The typed text is still in the box: the notice owns the two doors out. In a grid cell it
4744
+ // floats over the table (`data-records-cell-note`), so the row never grows.
4745
+ /* @__PURE__ */ jsx19("span", { "data-records-cell-note": "", className: "block", children: /* @__PURE__ */ jsx19(
4720
4746
  RefusalNotice,
4721
4747
  {
4722
4748
  error: broken,
@@ -4726,7 +4752,7 @@ function JsonControl({ field: field2, value, onChange, disabled, id }) {
4726
4752
  setBroken(null);
4727
4753
  }
4728
4754
  }
4729
- )
4755
+ ) })
4730
4756
  ) : null
4731
4757
  ] });
4732
4758
  }
@@ -4739,7 +4765,7 @@ function inTheStoresOrder(options) {
4739
4765
  const made = (o) => String(o.created_at ?? "");
4740
4766
  return [...options].sort((a, b) => position(a) - position(b) || made(a).localeCompare(made(b)));
4741
4767
  }
4742
- function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, addsChoices, initialSearch, asForm }) {
4768
+ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, onCancel, addsChoices, initialSearch, asForm }) {
4743
4769
  const client = useOptionalRecordsClient7();
4744
4770
  const [options, setOptions] = useState16(null);
4745
4771
  const [refusal4, setRefusal] = useState16(null);
@@ -4807,6 +4833,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
4807
4833
  id,
4808
4834
  autoOpen,
4809
4835
  onClose,
4836
+ onCancel,
4810
4837
  initialSearch,
4811
4838
  addsChoices,
4812
4839
  allowOther: allowsOtherValues(field2),
@@ -4887,6 +4914,7 @@ function OpenChoicePicker({
4887
4914
  addsChoices,
4888
4915
  autoOpen,
4889
4916
  onClose,
4917
+ onCancel,
4890
4918
  initialSearch,
4891
4919
  allowOther = true,
4892
4920
  onChoicesChanged
@@ -4954,10 +4982,9 @@ function OpenChoicePicker({
4954
4982
  });
4955
4983
  };
4956
4984
  const offList = q !== "" && decided.decision !== "chosen" && decided.decision !== "empty";
4957
- const nothingMatches = q !== "" && visible.length === 0;
4958
4985
  const foot = null;
4959
4986
  const add = offList && (decided.decision === "ask" || decided.decision === "add") ? { label: `Create \u201C${q}\u201D`, onAdd: addTyped, disabled: adding } : offList && decided.decision === "keep_as_typed" ? { label: `Use \u201C${q}\u201D`, onAdd: () => choose(q) } : null;
4960
- const listed = nothingMatches && add ? options : visible;
4987
+ const listed = visible;
4961
4988
  const pickedOptions = current.map((v) => options.find((o) => isTheChosen(o, v)));
4962
4989
  const cellChips = pickedWords.map((word, i) => {
4963
4990
  const chip = chipOf(pickedOptions[i], word);
@@ -4985,6 +5012,7 @@ function OpenChoicePicker({
4985
5012
  PickOrAdd,
4986
5013
  {
4987
5014
  anchored,
5015
+ ...anchored && onCancel ? { onEscape: onCancel } : {},
4988
5016
  chips: headChips,
4989
5017
  multi: field2.multi,
4990
5018
  triggerLabel: `Pick for ${fieldName(field2)}`,
@@ -4996,7 +5024,6 @@ function OpenChoicePicker({
4996
5024
  setSearch(next);
4997
5025
  setAddRefused(null);
4998
5026
  },
4999
- addFirst: nothingMatches,
5000
5027
  items: listed.map((option) => ({
5001
5028
  id: option.id,
5002
5029
  label: titleOf(option),
@@ -6599,8 +6626,9 @@ function cardWords(record, field2, labels) {
6599
6626
 
6600
6627
  // src/gridEditing.tsx
6601
6628
  import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
6602
- var FLOATING_EDITOR_TRAY_CLASS = "pointer-events-none absolute left-0 z-[26] w-max max-w-[24rem] rounded-md border bg-popover px-1.5 py-0.5 shadow-md";
6603
- var FLOATING_EDITOR_NOTE_CLASS = "[&_[data-records-typed-reads-as]]:pointer-events-none [&_[data-records-typed-reads-as]]:absolute [&_[data-records-typed-reads-as]]:bottom-full [&_[data-records-typed-reads-as]]:left-0 [&_[data-records-typed-reads-as]]:z-[26] [&_[data-records-typed-reads-as]]:mb-1 [&_[data-records-typed-reads-as]]:w-max [&_[data-records-typed-reads-as]]:max-w-[24rem] [&_[data-records-typed-reads-as]]:rounded-md [&_[data-records-typed-reads-as]]:border [&_[data-records-typed-reads-as]]:bg-popover [&_[data-records-typed-reads-as]]:px-1.5 [&_[data-records-typed-reads-as]]:py-0.5 [&_[data-records-typed-reads-as]]:shadow-md";
6629
+ var FLOATING_CELL_NOTE_CLASS = "[&_[data-records-cell-note]]:absolute [&_[data-records-cell-note]]:bottom-full [&_[data-records-cell-note]]:left-0 [&_[data-records-cell-note]]:z-[26] [&_[data-records-cell-note]]:mb-1 [&_[data-records-cell-note]]:w-max [&_[data-records-cell-note]]:max-w-[24rem] [&_[data-records-cell-note]]:rounded-md [&_[data-records-cell-note]]:border [&_[data-records-cell-note]]:bg-popover [&_[data-records-cell-note]]:px-1.5 [&_[data-records-cell-note]]:py-0.5 [&_[data-records-cell-note]]:shadow-md";
6630
+ var FLOATING_CELL_TRAY_CLASS = "absolute left-0 top-full z-[26] mt-1 flex w-max max-w-[24rem] flex-col items-start gap-1";
6631
+ var FLOATING_CELL_TRAY_PIECE_CLASS = "rounded-md border bg-popover px-1.5 py-0.5 shadow-md";
6604
6632
  var NO_ROWS = [];
6605
6633
  function asksWhoChanged(event) {
6606
6634
  return event.altKey && event.shiftKey && !event.metaKey && !event.ctrlKey && (event.code === "KeyH" || event.key.toLowerCase() === "h");
@@ -7176,8 +7204,18 @@ function GridCell({
7176
7204
  const onLinkClickCapture = (event) => {
7177
7205
  const link = event.target instanceof Element ? event.target.closest("a[href]") : null;
7178
7206
  if (!(link instanceof HTMLElement) || !event.currentTarget.contains(link) || event.detail === 0) return;
7207
+ if (event.metaKey || event.ctrlKey || event.shiftKey) {
7208
+ cancelSinglePress();
7209
+ event.stopPropagation();
7210
+ return;
7211
+ }
7179
7212
  event.preventDefault();
7180
7213
  const cellTakesIt = editable && (clickOpens || opensAsAList(field2, hostTakesFiles(ui)));
7214
+ if (cellTakesIt && event.detail === 1 && (clickOpens || wasActive.current)) {
7215
+ cancelSinglePress();
7216
+ openThisCell(event);
7217
+ return;
7218
+ }
7181
7219
  if (event.detail === 1 && wasActive.current && !cellTakesIt) afterSinglePress(() => link.click());
7182
7220
  else cancelSinglePress();
7183
7221
  };
@@ -7186,32 +7224,51 @@ function GridCell({
7186
7224
  const refusal4 = editing ? editing.refusalOf(row.id, field2.key) : null;
7187
7225
  const editable = Boolean(editing) && canWrite && fieldIsEditable(field2);
7188
7226
  if (open && editing) {
7189
- return /* @__PURE__ */ jsx28(
7190
- OpenCell,
7191
- {
7192
- field: field2,
7193
- draft: editing.draft,
7194
- initialSearch: editing.searchSeed,
7195
- onType: editing.type,
7196
- onCommit: (move, via) => editing.commit(move, via),
7197
- onCancel: (via) => editing.cancel(via),
7198
- below: (
7199
- // KEPT EDITING: the refusal stays beside the value it is about, so the
7200
- // person reads what to change while changing it. Keep editing is the
7201
- // state they are in, so only Discard is offered. It is INSIDE the open
7202
- // cell, so pressing Discard is not "focus left the cell" — which would
7203
- // commit the refused value one more time on its way out.
7204
- refusal4 && !refusal4.conflict ? /* @__PURE__ */ jsx28(
7205
- RefusalNotice,
7206
- {
7207
- error: refusal4.error,
7208
- className: "py-1.5 text-left",
7209
- onDiscard: () => editing.discard(row.id, field2.key)
7210
- }
7211
- ) : null
7212
- )
7213
- }
7214
- );
7227
+ return /* @__PURE__ */ jsxs23("span", { "data-records-open-cell": "", className: "relative block w-full min-w-0", children: [
7228
+ /* @__PURE__ */ jsxs23("span", { "aria-hidden": "true", inert: true, "data-records-cell-ghost": "", className: "pointer-events-none invisible flex w-full min-w-0 select-none items-center gap-1", children: [
7229
+ /* @__PURE__ */ jsx28("span", { className: "block min-w-0 flex-1 truncate px-1 py-0.5", children: /* @__PURE__ */ jsx28(
7230
+ RecordValue,
7231
+ {
7232
+ inCell: true,
7233
+ field: field2,
7234
+ value: row.document?.[field2.key],
7235
+ document: row.document,
7236
+ recordId: row.id,
7237
+ withheld: withheldNoticeOf(row.hidden, field2.key),
7238
+ ...format ? { format } : {}
7239
+ }
7240
+ ) }),
7241
+ onAskWhoChanged ? /* @__PURE__ */ jsx28(WhoBadge, { field: field2, row, onAskWhoChanged: () => {
7242
+ }, onPressedTwice: () => {
7243
+ } }) : null
7244
+ ] }),
7245
+ /* @__PURE__ */ jsx28(
7246
+ OpenCell,
7247
+ {
7248
+ field: field2,
7249
+ draft: editing.draft,
7250
+ initialSearch: editing.searchSeed,
7251
+ onType: editing.type,
7252
+ onCommit: (move, via) => editing.commit(move, via),
7253
+ onCancel: (via) => editing.cancel(via),
7254
+ below: (
7255
+ // KEPT EDITING: the refusal stays beside the value it is about, so the
7256
+ // person reads what to change while changing it. Keep editing is the
7257
+ // state they are in, so only Discard is offered. It is INSIDE the open
7258
+ // cell, so pressing Discard is not "focus left the cell" — which would
7259
+ // commit the refused value one more time on its way out.
7260
+ refusal4 && !refusal4.conflict ? /* @__PURE__ */ jsx28(
7261
+ RefusalNotice,
7262
+ {
7263
+ error: refusal4.error,
7264
+ className: "py-1.5 text-left",
7265
+ onDiscard: () => editing.discard(row.id, field2.key)
7266
+ }
7267
+ ) : null
7268
+ )
7269
+ }
7270
+ )
7271
+ ] });
7215
7272
  }
7216
7273
  if (editorKindFor(field2) === "checkbox") {
7217
7274
  const answered = value === true || value === false;
@@ -7561,8 +7618,9 @@ function OpenCell({
7561
7618
  "data-matrx-cell-editor": "",
7562
7619
  tabIndex: -1,
7563
7620
  className: cn19(
7564
- "relative z-[25] flex w-full min-w-0 max-w-full flex-col gap-1 outline-none",
7565
- FLOATING_EDITOR_NOTE_CLASS,
7621
+ // OVER the cell's ghost (see `data-records-open-cell`), never in the table's measuring.
7622
+ "absolute inset-x-0 top-1/2 z-[25] flex w-full min-w-0 max-w-full -translate-y-1/2 flex-col gap-1 outline-none",
7623
+ FLOATING_CELL_NOTE_CLASS,
7566
7624
  // A field's own input is 36px (h-9); in a 35px row it grew the row 4px. In the cell it is
7567
7625
  // the row action strip's 32px, so opening a cell never changes the row (STABLE-TABLES).
7568
7626
  "[&_input:not([type=checkbox]):not([type=radio])]:h-8 [&_input:not([type=checkbox]):not([type=radio])]:py-0"
@@ -7621,11 +7679,13 @@ function OpenCell({
7621
7679
  addsChoices: true
7622
7680
  }
7623
7681
  ),
7624
- picker || asksAboutAChoice(draft) ? null : blurCommits ? /* @__PURE__ */ jsx28("span", { className: cn19("text-[10px] text-muted-foreground", FLOATING_EDITOR_TRAY_CLASS, "top-full mt-1"), "data-records-editor-hint": "", children: multiline ? "\u23CE saves \xB7 \u21E7\u23CE new line \xB7 Esc cancels \xB7 Tab next" : "\u23CE saves \xB7 Esc cancels \xB7 Tab next" }) : /* @__PURE__ */ jsxs23("span", { className: "flex items-center gap-1", children: [
7625
- /* @__PURE__ */ jsx28(Button10, { size: "sm", onClick: () => once(() => onCommit(null, "pick")), children: "Save" }),
7626
- /* @__PURE__ */ jsx28(Button10, { size: "sm", variant: "ghost", onClick: () => once(() => onCancel("pick")), children: "Cancel" })
7627
- ] }),
7628
- below
7682
+ /* @__PURE__ */ jsxs23("span", { "data-records-cell-tray": "", className: FLOATING_CELL_TRAY_CLASS, children: [
7683
+ picker || asksAboutAChoice(draft) ? null : blurCommits ? /* @__PURE__ */ jsx28("span", { className: cn19("pointer-events-none text-[10px] text-muted-foreground", FLOATING_CELL_TRAY_PIECE_CLASS), "data-records-editor-hint": "", children: multiline ? "\u23CE saves \xB7 \u21E7\u23CE new line \xB7 Esc cancels \xB7 Tab next" : "\u23CE saves \xB7 Esc cancels \xB7 Tab next" }) : /* @__PURE__ */ jsxs23("span", { className: cn19("flex items-center gap-1", FLOATING_CELL_TRAY_PIECE_CLASS), children: [
7684
+ /* @__PURE__ */ jsx28(Button10, { size: "sm", onClick: () => once(() => onCommit(null, "pick")), children: "Save" }),
7685
+ /* @__PURE__ */ jsx28(Button10, { size: "sm", variant: "ghost", onClick: () => once(() => onCancel("pick")), children: "Cancel" })
7686
+ ] }),
7687
+ below ? /* @__PURE__ */ jsx28("span", { className: "block bg-popover shadow-md", children: below }) : null
7688
+ ] })
7629
7689
  ]
7630
7690
  }
7631
7691
  );
@@ -10890,11 +10950,11 @@ function FieldEditor(props) {
10890
10950
  Checkbox6,
10891
10951
  {
10892
10952
  checked: required,
10893
- "aria-label": "Every record has to have one",
10953
+ "aria-label": "Required",
10894
10954
  onCheckedChange: (v) => setRequired(v === true)
10895
10955
  }
10896
10956
  ),
10897
- "Every record has to have one"
10957
+ /* @__PURE__ */ jsx40("span", { title: "Every record has to have one", children: "Required" })
10898
10958
  ] }),
10899
10959
  offersMany ? /* @__PURE__ */ jsxs35("label", { className: "flex items-center gap-1.5", children: [
10900
10960
  /* @__PURE__ */ jsx40(
@@ -14504,7 +14564,7 @@ function useMergedGridControls(args) {
14504
14564
  children: /* @__PURE__ */ jsxs47(DialogContent8, { className: "max-h-[85vh] overflow-y-auto sm:max-w-2xl", children: [
14505
14565
  /* @__PURE__ */ jsxs47(DialogHeader8, { children: [
14506
14566
  /* @__PURE__ */ jsx52(DialogTitle8, { children: dialog?.kind === "settings" ? `Column settings \xB7 ${fieldName(dialog.field)}` : dialog?.kind === "insert" && dialog.anchor ? `Add column ${dialog.side === "left" ? "left" : "right"} of ${fieldOf2(dialog.anchor) ? fieldName(fieldOf2(dialog.anchor)) : dialog.anchor}` : ADD_FIELD_OPEN_LABEL }),
14507
- /* @__PURE__ */ jsx52(DialogDescription6, { className: "sr-only", children: "The column\u2019s name, what it holds and how it looks." })
14567
+ /* @__PURE__ */ jsx52(DialogDescription6, { className: "sr-only", children: "Name, type and look" })
14508
14568
  ] }),
14509
14569
  dialog?.kind === "settings" ? /* @__PURE__ */ jsx52(
14510
14570
  FieldEditor,
@@ -19022,6 +19082,7 @@ function ImportWizard({ tableId, source, onDone, onWrote, className }) {
19022
19082
  // src/tableShape.ts
19023
19083
  import { codeSpanText as codeSpanText2, mapInlineCodeSpans } from "@ai-matrx/content-ir/source";
19024
19084
  import { humanizeIdentifier as humanizeIdentifier9 } from "@ai-matrx/kit/text-case";
19085
+ import { parseDelimited as readDelimited } from "@ai-matrx/kit/delimited";
19025
19086
  var FEWEST_LIST_ITEMS = 2;
19026
19087
  var FEWEST_KEY_VALUE_PAIRS = 2;
19027
19088
  var LONGEST_TEXT_READ = 2e6;
@@ -19199,38 +19260,7 @@ function shapeFromList(items, name, at) {
19199
19260
  };
19200
19261
  }
19201
19262
  function parseDelimited(text, delimiter) {
19202
- const rows = [];
19203
- let row = [];
19204
- let cell2 = "";
19205
- let quoted2 = false;
19206
- for (let i = 0; i < text.length; i += 1) {
19207
- const ch = text[i];
19208
- if (quoted2) {
19209
- if (ch === '"') {
19210
- if (text[i + 1] === '"') {
19211
- cell2 += '"';
19212
- i += 1;
19213
- } else quoted2 = false;
19214
- } else cell2 += ch;
19215
- continue;
19216
- }
19217
- if (ch === '"' && cell2.trim() === "") quoted2 = true;
19218
- else if (ch === delimiter) {
19219
- row.push(cell2);
19220
- cell2 = "";
19221
- } else if (ch === "\n" || ch === "\r") {
19222
- if (ch === "\r" && text[i + 1] === "\n") i += 1;
19223
- row.push(cell2);
19224
- rows.push(row);
19225
- row = [];
19226
- cell2 = "";
19227
- } else cell2 += ch;
19228
- }
19229
- if (cell2.length > 0 || row.length > 0) {
19230
- row.push(cell2);
19231
- rows.push(row);
19232
- }
19233
- return rows.filter((r) => r.some((c) => c.trim() !== ""));
19263
+ return readDelimited(text, { delimiter, skipEmptyLines: "greedy" }).data;
19234
19264
  }
19235
19265
  function delimitedShape(text, delimiter, fenced, at, name) {
19236
19266
  const matrix = parseDelimited(text.trim(), delimiter);
@@ -23018,8 +23048,11 @@ function GridBody({
23018
23048
  const rowMemoryKey = `${tableId}:${embedded ? "embedded" : "page"}:${openingKey}`;
23019
23049
  const rowsAnswered = Boolean(records.data) && !records.loading && !table.loading && !fields.loading;
23020
23050
  useEffect47(() => {
23021
- if (rowsAnswered) rememberRowCount(rowMemoryKey, rows.length);
23022
- }, [rowsAnswered, rowMemoryKey, rows.length]);
23051
+ if (rowsAnswered) {
23052
+ rememberRowCount(rowMemoryKey, rows.length);
23053
+ if (!embedded) rememberRowCount(`${tableId}:page:last`, rows.length);
23054
+ }
23055
+ }, [rowsAnswered, rowMemoryKey, rows.length, embedded, tableId]);
23023
23056
  if (table.error) return /* @__PURE__ */ jsx70(RefusalNotice, { error: table.error, className });
23024
23057
  if (fields.error) return /* @__PURE__ */ jsx70(RefusalNotice, { error: fields.error, className });
23025
23058
  const nothingToShowYet = table.loading || fields.loading || !rights.known || records.loading && rows.length === 0 || // The page read has neither answered nor refused: nothing has been said yet, so nothing is empty.
@@ -23204,7 +23237,7 @@ function GridBody({
23204
23237
  {
23205
23238
  ...fills ? { className: "min-h-0 flex-1" } : {},
23206
23239
  frameHeight: fills ? "fill" : "content",
23207
- loadingRows: fills ? "fill" : rememberedRowCount(rowMemoryKey, pageSize, 5),
23240
+ loadingRows: rememberedRowCount(rowMemoryKey, pageSize, fills ? "fill" : 5),
23208
23241
  ...!look.rowHeight ? { loadingRowHeight: RECORDS_GRID_ROW_PX } : {},
23209
23242
  data: rows,
23210
23243
  columns: tableColumns,
@@ -27182,7 +27215,7 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
27182
27215
  },
27183
27216
  variant: "destructive",
27184
27217
  title: `Move every row of \u201C${writable.find((t) => t.id === tableId)?.name ?? "this table"}\u201D to the archive?`,
27185
- description: "They stay restorable from the table's Archived items. Then the rows you are saving go in, through the import below.",
27218
+ description: "Restorable from Archived items",
27186
27219
  confirmLabel: replacing ? "Archiving\u2026" : "Archive them",
27187
27220
  cancelLabel: "Keep them",
27188
27221
  busy: replacing,
@@ -28696,18 +28729,25 @@ function RecordFieldsInPlace({
28696
28729
  const format = formatForField(field2);
28697
28730
  return /* @__PURE__ */ jsxs85("div", { className: "contents", children: [
28698
28731
  /* @__PURE__ */ jsx94("dt", { className: "flex items-baseline gap-1 truncate py-1 text-muted-foreground", children: renderLabel(field2) }),
28699
- /* @__PURE__ */ jsx94("dd", { className: "min-w-0 rounded hover:bg-muted/50", "data-records-in-place-field": field2.key, children: /* @__PURE__ */ jsx94(
28700
- GridCell,
28732
+ /* @__PURE__ */ jsx94(
28733
+ "dd",
28701
28734
  {
28702
- field: field2,
28703
- row,
28704
- editing: canWrite ? editing : null,
28705
- canWrite,
28706
- whyNot,
28707
- clickOpens: true,
28708
- ...format ? { format } : {}
28735
+ className: "min-w-0 rounded hover:bg-muted/50 [&_[data-matrx-cell-editor]_input:not([type=checkbox]):not([type=radio])]:!h-7",
28736
+ "data-records-in-place-field": field2.key,
28737
+ children: /* @__PURE__ */ jsx94(
28738
+ GridCell,
28739
+ {
28740
+ field: field2,
28741
+ row,
28742
+ editing: canWrite ? editing : null,
28743
+ canWrite,
28744
+ whyNot,
28745
+ clickOpens: true,
28746
+ ...format ? { format } : {}
28747
+ }
28748
+ )
28709
28749
  }
28710
- ) })
28750
+ )
28711
28751
  ] }, field2.id);
28712
28752
  }) }),
28713
28753
  /* @__PURE__ */ jsx94(UndoNotice, { undo })
@@ -28904,7 +28944,7 @@ function AddBody({ tableId }) {
28904
28944
  const made = await mutation.declare({ table_id: tableId, spec: { label: BODY_COLUMN_NAME, type: "rich_text" } });
28905
28945
  if (made) tableShapeChanged10(tableId);
28906
28946
  },
28907
- children: "Write on this page"
28947
+ children: "Add notes"
28908
28948
  }
28909
28949
  ),
28910
28950
  mutation.error ? /* @__PURE__ */ jsx96(RefusalNotice, { error: mutation.error }) : null
@@ -29049,7 +29089,7 @@ function computedInPlainWords(row, field2) {
29049
29089
  const shown4 = row.value === null || row.value === void 0 || row.value === "" ? "nothing" : field2 ? scalarText(field2, row.value) : String(row.value);
29050
29090
  const when = new Date(row.computed_at);
29051
29091
  const at = Number.isNaN(when.getTime()) ? "" : ` on ${when.toLocaleDateString()}`;
29052
- return `${name} was worked out as ${shown4}${at}.`;
29092
+ return `${name}: ${shown4}${at}`;
29053
29093
  }
29054
29094
 
29055
29095
  // src/systemTable.ts
@@ -29279,7 +29319,10 @@ async function keepLook(client, tableId, viewId, look) {
29279
29319
  return client.viewLookSet({ table_id: tableId, view_id: viewId, look: doc && Object.keys(doc).length > 0 ? doc : null });
29280
29320
  }
29281
29321
  var LOOK_WORDS = {
29322
+ /** The reason, for a tooltip or a screen reader — never a line on the page (interface-text). */
29282
29323
  yours: "You changed how this view looks. Only you see it.",
29324
+ /** The visible label for the same fact. */
29325
+ yoursLabel: "Only you see this",
29283
29326
  saveToView: "Save to view",
29284
29327
  saveAsNew: "Save as new view",
29285
29328
  reset: "Reset to view",
@@ -39014,7 +39057,7 @@ function WebhooksPanel({ tableId, className }) {
39014
39057
  if (!next && !busy) setStopping(null);
39015
39058
  },
39016
39059
  title: `Stop sending to ${stopping?.description ?? stopping?.target_url ?? "this address"}?`,
39017
- description: "Changes from now on are not sent there. The webhook is kept, switched off \u2014 nothing about it is deleted.",
39060
+ description: "Kept, switched off",
39018
39061
  confirmLabel: "Switch off",
39019
39062
  cancelLabel: "Keep sending",
39020
39063
  busy,
@@ -41497,6 +41540,39 @@ function useLinkGroupNamer(block, tableId) {
41497
41540
  }, [named, choices, labels]);
41498
41541
  }
41499
41542
 
41543
+ // src/measureWords.ts
41544
+ import { useEffect as useEffect97, useState as useState111 } from "react";
41545
+ import { useOptionalRecordsClient as useOptionalRecordsClient13 } from "@ai-matrx/records/react";
41546
+ import { humanizeIdentifier as humanizeIdentifier18 } from "@ai-matrx/kit/text-case";
41547
+ var OP_WORD = { sum: "Total", avg: "Average", min: "Lowest", max: "Highest" };
41548
+ function measureWords(key, fields) {
41549
+ if (key === "count") return "How many";
41550
+ const at = key.indexOf("_");
41551
+ if (at < 0) return humanizeIdentifier18(key);
41552
+ const op2 = key.slice(0, at);
41553
+ const column = key.slice(at + 1);
41554
+ const field2 = fields?.find((f) => f.key === column);
41555
+ const name = field2 ? fieldName(field2) : humanizeIdentifier18(column);
41556
+ const word = OP_WORD[op2];
41557
+ return word ? `${word} ${name.charAt(0).toLowerCase()}${name.slice(1)}` : `${humanizeIdentifier18(op2)} ${name}`;
41558
+ }
41559
+ function useMeasureWords(key, tableId) {
41560
+ const client = useOptionalRecordsClient13();
41561
+ const [fields, setFields] = useState111(null);
41562
+ const needs = key !== "count";
41563
+ useEffect97(() => {
41564
+ if (!client || !tableId || !needs) return;
41565
+ let cancelled = false;
41566
+ void client.fields({ table_id: tableId }).then((result) => {
41567
+ if (!cancelled && result.ok) setFields(result.data);
41568
+ });
41569
+ return () => {
41570
+ cancelled = true;
41571
+ };
41572
+ }, [client, tableId, needs]);
41573
+ return measureWords(key, fields);
41574
+ }
41575
+
41500
41576
  // src/ChartBlock.tsx
41501
41577
  import { Fragment as Fragment52, jsx as jsx134, jsxs as jsxs124 } from "react/jsx-runtime";
41502
41578
  var priorKey = (key) => `prior__${key}`;
@@ -41575,6 +41651,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41575
41651
  const series = compared ? [primary, priorKey(primary)] : [primary];
41576
41652
  const target = kind === "stuck" ? null : block.target ?? null;
41577
41653
  const named = useLinkGroupNamer(source ? NO_GROUPS : block, tableId);
41654
+ const measureName = useMeasureWords(primary, tableId);
41578
41655
  const points = useMemo66(() => {
41579
41656
  if (kind === "stuck") return [];
41580
41657
  const rows = block.rows ?? [];
@@ -41602,7 +41679,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41602
41679
  const config = useMemo66(() => {
41603
41680
  const out = {};
41604
41681
  out[primary] = {
41605
- label: windows ? windowName(windows.window, windows.period) : primary.replace("_", " of "),
41682
+ label: windows ? windowName(windows.window, windows.period) : measureName,
41606
41683
  color: SERIES_COLORS[0]
41607
41684
  };
41608
41685
  if (windows) {
@@ -41615,7 +41692,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41615
41692
  out[point.label] ??= { label: point.label, color: SERIES_COLORS[index % SERIES_COLORS.length] };
41616
41693
  });
41617
41694
  return out;
41618
- }, [primary, windows, points]);
41695
+ }, [primary, measureName, windows, points]);
41619
41696
  const goal = target && typeof target.value === "number" ? {
41620
41697
  value: typeof target.pace === "number" ? target.pace : block.bucket ? null : target.value,
41621
41698
  label: typeof target.pace === "number" && target.per !== "bucket" ? `${target.label} pace` : target.label
@@ -41660,7 +41737,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41660
41737
  /* @__PURE__ */ jsx134("span", { children: pretty(block.totals.current) }),
41661
41738
  /* @__PURE__ */ jsx134(Trend, { pct: block.totals.change_pct, aimingUp: !!target })
41662
41739
  ] }) : null,
41663
- /* @__PURE__ */ jsx134("span", { className: "ml-auto shrink-0 text-muted-foreground", children: kind === "stuck" ? `${block.days ?? 14} days` : primary.replace("_", " of ") })
41740
+ /* @__PURE__ */ jsx134("span", { className: "ml-auto shrink-0 text-muted-foreground", children: kind === "stuck" ? `${block.days ?? 14} days` : measureName })
41664
41741
  ] }),
41665
41742
  block.compare_refused ? /* @__PURE__ */ jsx134("p", { className: "px-1 text-xs text-muted-foreground", children: block.compare_refused }) : null,
41666
41743
  !block.refused && targetNote(target) ? /* @__PURE__ */ jsx134("p", { className: "px-1 text-xs text-muted-foreground", children: targetNote(target) }) : null,
@@ -41957,7 +42034,7 @@ function onlyWholeNumbers(rows) {
41957
42034
  }
41958
42035
 
41959
42036
  // src/DashboardCanvas.tsx
41960
- import { useCallback as useCallback58, useEffect as useEffect98, useMemo as useMemo69, useState as useState113 } from "react";
42037
+ import { useCallback as useCallback58, useEffect as useEffect99, useMemo as useMemo69, useState as useState114 } from "react";
41961
42038
  import { useFields as useFields29, useRecordsClient as useRecordsClient85, useTable as useTable31 } from "@ai-matrx/records/react";
41962
42039
  import {
41963
42040
  BasicInput as BasicInput30,
@@ -42125,7 +42202,7 @@ function GridCell2({
42125
42202
  }
42126
42203
 
42127
42204
  // src/AddChart.tsx
42128
- import { useMemo as useMemo68, useState as useState112 } from "react";
42205
+ import { useMemo as useMemo68, useState as useState113 } from "react";
42129
42206
  import { useFields as useFields28, useRecordsClient as useRecordsClient84 } from "@ai-matrx/records/react";
42130
42207
  import {
42131
42208
  Button as Button90,
@@ -42137,7 +42214,7 @@ import {
42137
42214
  } from "@ai-matrx/design-system";
42138
42215
 
42139
42216
  // src/TablePickers.tsx
42140
- import { useEffect as useEffect97, useMemo as useMemo67, useState as useState111 } from "react";
42217
+ import { useEffect as useEffect98, useMemo as useMemo67, useState as useState112 } from "react";
42141
42218
  import { RecordsProvider as RecordsProvider2, useFields as useFields27, useRecords as useRecords7, useTable as useTable30 } from "@ai-matrx/records/react";
42142
42219
  import { Button as Button89, CreatablePicker as CreatablePicker2 } from "@ai-matrx/design-system";
42143
42220
 
@@ -42255,8 +42332,8 @@ function readTablesAnywhere(dataSource) {
42255
42332
  return read;
42256
42333
  }
42257
42334
  function useTablesAnywhere(dataSource) {
42258
- const [state, setState] = useState111({ loading: true, error: null, rows: [] });
42259
- useEffect97(() => {
42335
+ const [state, setState] = useState112({ loading: true, error: null, rows: [] });
42336
+ useEffect98(() => {
42260
42337
  let live = true;
42261
42338
  void readTablesAnywhere(dataSource).then((result) => {
42262
42339
  if (live) setState(result);
@@ -42333,7 +42410,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
42333
42410
  const all = useMemo67(() => fields.data ?? [], [fields.data]);
42334
42411
  const byKey = useMemo67(() => new Map(all.map((f) => [f.key, f])), [all]);
42335
42412
  const keys = Object.keys(value);
42336
- const [adding, setAdding] = useState111(false);
42413
+ const [adding, setAdding] = useState112(false);
42337
42414
  const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
42338
42415
  const rename = (from, to) => {
42339
42416
  if (from === to) return;
@@ -42489,7 +42566,7 @@ function chartSpecFrom(args) {
42489
42566
  }
42490
42567
  function AddChart({ subject, onAdd, onClose }) {
42491
42568
  const client = useRecordsClient84();
42492
- const [tableId, setTableId] = useState112(subject);
42569
+ const [tableId, setTableId] = useState113(subject);
42493
42570
  const fields = useFields28(tableId);
42494
42571
  const all = useMemo68(() => onePerKey(fields.data ?? []), [fields.data]);
42495
42572
  const labels = useRecordLabels(all);
@@ -42497,11 +42574,11 @@ function AddChart({ subject, onAdd, onClose }) {
42497
42574
  const field2 = all.find((f) => f.key === key);
42498
42575
  return field2 ? scalarText(field2, value, labels) : String(value);
42499
42576
  };
42500
- const [measureKey5, setMeasureKey] = useState112("count");
42501
- const [splitKey, setSplitKey] = useState112("none");
42502
- const [kind, setKind] = useState112("auto");
42503
- const [filter, setFilter] = useState112({});
42504
- const [saving, setSaving] = useState112(false);
42577
+ const [measureKey5, setMeasureKey] = useState113("count");
42578
+ const [splitKey, setSplitKey] = useState113("none");
42579
+ const [kind, setKind] = useState113("auto");
42580
+ const [filter, setFilter] = useState113({});
42581
+ const [saving, setSaving] = useState113(false);
42505
42582
  const numbers = numberColumns(all);
42506
42583
  const choices = offerableFields(all, "choice");
42507
42584
  const dates = offerableFields(all, "date");
@@ -42648,20 +42725,20 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42648
42725
  const table = useTable31(tableId);
42649
42726
  const rights = useTableRights(table.data);
42650
42727
  const fields = useFields29(tableId);
42651
- const [boards, setBoards] = useState113(null);
42652
- const [pages, setPages] = useState113([]);
42653
- const [error, setError] = useState113(null);
42654
- const [activeId, setActiveId] = useState113(activeDashboardId ?? null);
42655
- const [madeOnMount, setMadeOnMount] = useState113("waiting");
42656
- const [askingToRemove, setAskingToRemove] = useState113(null);
42657
- const [run, setRun] = useState113(null);
42658
- const [running, setRunning] = useState113(false);
42659
- const [question, setQuestion] = useState113("");
42660
- const [asking, setAsking] = useState113(false);
42661
- const [scheduling, setScheduling] = useState113(false);
42662
- const [arranging, setArranging] = useState113(false);
42663
- const [adding, setAdding] = useState113(false);
42664
- const [grain, setGrain] = useState113(null);
42728
+ const [boards, setBoards] = useState114(null);
42729
+ const [pages, setPages] = useState114([]);
42730
+ const [error, setError] = useState114(null);
42731
+ const [activeId, setActiveId] = useState114(activeDashboardId ?? null);
42732
+ const [madeOnMount, setMadeOnMount] = useState114("waiting");
42733
+ const [askingToRemove, setAskingToRemove] = useState114(null);
42734
+ const [run, setRun] = useState114(null);
42735
+ const [running, setRunning] = useState114(false);
42736
+ const [question, setQuestion] = useState114("");
42737
+ const [asking, setAsking] = useState114(false);
42738
+ const [scheduling, setScheduling] = useState114(false);
42739
+ const [arranging, setArranging] = useState114(false);
42740
+ const [adding, setAdding] = useState114(false);
42741
+ const [grain, setGrain] = useState114(null);
42665
42742
  const runArgs = (dashboard_id) => ({
42666
42743
  dashboard_id,
42667
42744
  ...filter ? { filter } : {},
@@ -42679,11 +42756,11 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42679
42756
  setBoards(read);
42680
42757
  return read;
42681
42758
  }, [client, tableId]);
42682
- const [notKept, setNotKept] = useState113(null);
42683
- useEffect98(() => {
42759
+ const [notKept, setNotKept] = useState114(null);
42760
+ useEffect99(() => {
42684
42761
  void load();
42685
42762
  }, [load]);
42686
- useEffect98(() => {
42763
+ useEffect99(() => {
42687
42764
  if (!boards || boards.length === 0) return;
42688
42765
  if (createOnMount && madeOnMount !== "done") return;
42689
42766
  const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
@@ -42691,7 +42768,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42691
42768
  }, [boards, activeDashboardId, madeOnMount]);
42692
42769
  const board = useMemo69(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
42693
42770
  const filterKey = JSON.stringify(filter ?? {});
42694
- useEffect98(() => {
42771
+ useEffect99(() => {
42695
42772
  if (!activeId) {
42696
42773
  setRun(null);
42697
42774
  return;
@@ -42761,7 +42838,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42761
42838
  ]
42762
42839
  );
42763
42840
  }
42764
- useEffect98(() => {
42841
+ useEffect99(() => {
42765
42842
  if (!createOnMount || madeOnMount !== "waiting" || boards === null || !fields.data) return;
42766
42843
  setMadeOnMount("making");
42767
42844
  void create().then(() => setMadeOnMount("done"));
@@ -43206,10 +43283,10 @@ function TargetControl({
43206
43283
  onChange
43207
43284
  }) {
43208
43285
  const saved = !block.target ? "none" : "field" in block.target && block.target.field ? "field" : "value";
43209
- const [mode, setMode] = useState113(saved);
43286
+ const [mode, setMode] = useState114(saved);
43210
43287
  const savedValue = block.target && "value" in block.target && typeof block.target.value === "number" ? block.target.value : null;
43211
- const [draft, setDraft] = useState113(savedValue === null ? "" : String(savedValue));
43212
- useEffect98(() => {
43288
+ const [draft, setDraft] = useState114(savedValue === null ? "" : String(savedValue));
43289
+ useEffect99(() => {
43213
43290
  setMode(saved);
43214
43291
  setDraft(savedValue === null ? "" : String(savedValue));
43215
43292
  }, [saved, savedValue]);
@@ -43277,7 +43354,7 @@ function TargetControl({
43277
43354
 
43278
43355
  // src/QuestionPanel.tsx
43279
43356
  import { copyText as copyText8 } from "@ai-matrx/kit/clipboard";
43280
- import { useEffect as useEffect99, useMemo as useMemo70, useRef as useRef54, useState as useState114 } from "react";
43357
+ import { useEffect as useEffect100, useMemo as useMemo70, useRef as useRef54, useState as useState115 } from "react";
43281
43358
  import { Badge as Badge23, BasicInput as BasicInput31, Button as Button92, Checkbox as Checkbox16, Label as Label23, Skeleton as Skeleton34, cn as cn84 } from "@ai-matrx/design-system";
43282
43359
  import { useFields as useFields30, useRecordsClient as useRecordsClient86 } from "@ai-matrx/records/react";
43283
43360
 
@@ -43694,9 +43771,9 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43694
43771
  const fields = useFields30(tableId);
43695
43772
  const all = useMemo70(() => fields.data ?? [], [fields.data]);
43696
43773
  const me = client.config.actor?.user_id ?? null;
43697
- const [hidden, setHidden] = useState114(null);
43698
- const [related, setRelated] = useState114({});
43699
- useEffect99(() => {
43774
+ const [hidden, setHidden] = useState115(null);
43775
+ const [related, setRelated] = useState115({});
43776
+ useEffect100(() => {
43700
43777
  if (all.length === 0) {
43701
43778
  if (!fields.loading) setHidden(/* @__PURE__ */ new Set());
43702
43779
  return;
@@ -43720,17 +43797,17 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43720
43797
  };
43721
43798
  }, [client, tableId, all, fields.loading]);
43722
43799
  const offered = useMemo70(() => hidden ? all.filter((f) => !hidden.has(f.key)) : [], [all, hidden]);
43723
- const [saved, setSaved] = useState114(null);
43724
- const [savedEpoch, setSavedEpoch] = useState114(0);
43725
- const [current, setCurrent] = useState114(null);
43726
- const [spec, setSpec] = useState114(newQuestion);
43727
- const [name, setName] = useState114("");
43728
- const [shared, setShared] = useState114(true);
43729
- const [saveError, setSaveError] = useState114(null);
43730
- const [saving, setSaving] = useState114(false);
43731
- const [linkMissed, setLinkMissed] = useState114(false);
43800
+ const [saved, setSaved] = useState115(null);
43801
+ const [savedEpoch, setSavedEpoch] = useState115(0);
43802
+ const [current, setCurrent] = useState115(null);
43803
+ const [spec, setSpec] = useState115(newQuestion);
43804
+ const [name, setName] = useState115("");
43805
+ const [shared, setShared] = useState115(true);
43806
+ const [saveError, setSaveError] = useState115(null);
43807
+ const [saving, setSaving] = useState115(false);
43808
+ const [linkMissed, setLinkMissed] = useState115(false);
43732
43809
  const openedFromLink = useRef54(false);
43733
- useEffect99(() => {
43810
+ useEffect100(() => {
43734
43811
  let live = true;
43735
43812
  void questionsOf(client, tableId).then((answer2) => {
43736
43813
  if (!live) return;
@@ -43753,16 +43830,16 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43753
43830
  setShared(q ? q.shared : true);
43754
43831
  setSaveError(null);
43755
43832
  };
43756
- useEffect99(() => {
43833
+ useEffect100(() => {
43757
43834
  if (!draft) return;
43758
43835
  open(null);
43759
43836
  setSpec(draft);
43760
43837
  }, [draft]);
43761
43838
  const mine = !current || me !== null && current.createdBy === me;
43762
- const [answer, setAnswer] = useState114(null);
43763
- const [asking, setAsking] = useState114(false);
43839
+ const [answer, setAnswer] = useState115(null);
43840
+ const [asking, setAsking] = useState115(false);
43764
43841
  const specKey = JSON.stringify(spec);
43765
- useEffect99(() => {
43842
+ useEffect100(() => {
43766
43843
  if (all.length === 0) return;
43767
43844
  let live = true;
43768
43845
  setAsking(true);
@@ -44204,7 +44281,7 @@ function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATE
44204
44281
  }
44205
44282
 
44206
44283
  // src/TableAsk.tsx
44207
- import { useState as useState115 } from "react";
44284
+ import { useState as useState116 } from "react";
44208
44285
  import { BasicInput as BasicInput32, Button as Button93, Popover as Popover12, PopoverContent as PopoverContent12, PopoverTrigger as PopoverTrigger12, Skeleton as Skeleton35 } from "@ai-matrx/design-system";
44209
44286
  import { optionLabel as optionLabel4 } from "@ai-matrx/records";
44210
44287
  import { useFields as useFields31, useRecordsClient as useRecordsClient87 } from "@ai-matrx/records/react";
@@ -44427,9 +44504,9 @@ function TableAsk({ tableId, onOpenInQuestions }) {
44427
44504
  const client = useRecordsClient87();
44428
44505
  const fields = useFields31(tableId);
44429
44506
  const all = fields.data ?? [];
44430
- const [open, setOpen] = useState115(false);
44431
- const [words2, setWords] = useState115("");
44432
- const [said, setSaid] = useState115({ kind: "idle" });
44507
+ const [open, setOpen] = useState116(false);
44508
+ const [words2, setWords] = useState116("");
44509
+ const [said, setSaid] = useState116({ kind: "idle" });
44433
44510
  const ask = async () => {
44434
44511
  if (words2.trim() === "" || all.length === 0) return;
44435
44512
  const choices = {};
@@ -44502,7 +44579,7 @@ function TableAsk({ tableId, onOpenInQuestions }) {
44502
44579
  }
44503
44580
 
44504
44581
  // src/PageScreen.tsx
44505
- import { useCallback as useCallback59, useEffect as useEffect100, useMemo as useMemo71, useState as useState116 } from "react";
44582
+ import { useCallback as useCallback59, useEffect as useEffect101, useMemo as useMemo71, useState as useState117 } from "react";
44506
44583
  import {
44507
44584
  useFields as useFields32,
44508
44585
  useRecordPage as useRecordPage3,
@@ -44527,18 +44604,18 @@ function PageScreen({
44527
44604
  const client = useRecordsClient88();
44528
44605
  const host = useRecordsUi();
44529
44606
  const organizationId = client.config.organizationId;
44530
- const [page, setPage] = useState116(null);
44531
- const [missing, setMissing] = useState116(false);
44532
- const [error, setError] = useState116(null);
44533
- const [level, setLevel] = useState116(null);
44534
- const [editing, setEditing] = useState116(startEditing);
44535
- const [run, setRun] = useState116(null);
44536
- const [saveError, setSaveError] = useState116(null);
44537
- const [askingToArchive, setAskingToArchive] = useState116(false);
44538
- const [selected, setSelected] = useState116({});
44539
- const [filterValues, setFilterValues] = useState116({});
44540
- const [mine, setMine] = useState116({});
44541
- const [making, setMaking] = useState116("waiting");
44607
+ const [page, setPage] = useState117(null);
44608
+ const [missing, setMissing] = useState117(false);
44609
+ const [error, setError] = useState117(null);
44610
+ const [level, setLevel] = useState117(null);
44611
+ const [editing, setEditing] = useState117(startEditing);
44612
+ const [run, setRun] = useState117(null);
44613
+ const [saveError, setSaveError] = useState117(null);
44614
+ const [askingToArchive, setAskingToArchive] = useState117(false);
44615
+ const [selected, setSelected] = useState117({});
44616
+ const [filterValues, setFilterValues] = useState117({});
44617
+ const [mine, setMine] = useState117({});
44618
+ const [making, setMaking] = useState117("waiting");
44542
44619
  const id = page?.id ?? pageId ?? null;
44543
44620
  const load = useCallback59(
44544
44621
  async (want) => {
@@ -44559,7 +44636,7 @@ function PageScreen({
44559
44636
  },
44560
44637
  [client]
44561
44638
  );
44562
- useEffect100(() => {
44639
+ useEffect101(() => {
44563
44640
  if (!newOnTable || pageId || making !== "waiting") return;
44564
44641
  setMaking("making");
44565
44642
  void client.dashboardDeclare({
@@ -44579,11 +44656,11 @@ function PageScreen({
44579
44656
  onCreated?.(made.data);
44580
44657
  });
44581
44658
  }, [client, newOnTable, pageId, making, load, onCreated]);
44582
- useEffect100(() => {
44659
+ useEffect101(() => {
44583
44660
  if (!pageId) return;
44584
44661
  void load(pageId);
44585
44662
  }, [pageId, load]);
44586
- useEffect100(() => {
44663
+ useEffect101(() => {
44587
44664
  if (!id) return;
44588
44665
  let live = true;
44589
44666
  void client.myLevels({ ids: [id], subject: "record" }).then((answered) => {
@@ -44595,7 +44672,7 @@ function PageScreen({
44595
44672
  }, [client, id]);
44596
44673
  const canEdit = level !== null && EDIT_LEVELS.has(level);
44597
44674
  const chartKey = page ? JSON.stringify(page.blocks.map((b) => b.id)) + page.version : "";
44598
- useEffect100(() => {
44675
+ useEffect101(() => {
44599
44676
  if (!page || page.blocks.length === 0) {
44600
44677
  setRun(null);
44601
44678
  return;
@@ -44840,8 +44917,8 @@ function AppletBlockView({ block }) {
44840
44917
  }
44841
44918
  function AppletPick({ value, onChange }) {
44842
44919
  const host = useRecordsUi();
44843
- const [options, setOptions] = useState116(null);
44844
- useEffect100(() => {
44920
+ const [options, setOptions] = useState117(null);
44921
+ useEffect101(() => {
44845
44922
  let live = true;
44846
44923
  host.applets?.list().then((apps) => live && setOptions(apps.map((a) => ({ value: a.id, label: a.name })))).catch(() => live && setOptions([]));
44847
44924
  return () => {
@@ -44877,8 +44954,8 @@ function ListBlockView({
44877
44954
  const table = useTable32(block.table_id);
44878
44955
  const fields = useFields32(block.table_id);
44879
44956
  const all = useMemo71(() => onePerKey3(fields.data ?? []), [fields.data]);
44880
- const [view, setView] = useState116(block.view_id ? "reading" : null);
44881
- useEffect100(() => {
44957
+ const [view, setView] = useState117(block.view_id ? "reading" : null);
44958
+ useEffect101(() => {
44882
44959
  if (!block.view_id) {
44883
44960
  setView(null);
44884
44961
  return;
@@ -44895,8 +44972,8 @@ function ListBlockView({
44895
44972
  };
44896
44973
  }, [client, block.table_id, block.view_id]);
44897
44974
  const meField = block.me_field ? all.find((f) => f.key === block.me_field) : void 0;
44898
- const [me, setMe] = useState116(null);
44899
- useEffect100(() => {
44975
+ const [me, setMe] = useState117(null);
44976
+ useEffect101(() => {
44900
44977
  if (!mine || !meField?.relation_target || !viewerUserId) {
44901
44978
  setMe(null);
44902
44979
  return;
@@ -44926,12 +45003,12 @@ function ListBlockView({
44926
45003
  ...sort.length > 0 ? { sort } : {}
44927
45004
  });
44928
45005
  const reload = page.reload;
44929
- useEffect100(() => onRecordChanged(() => reload()), [reload]);
45006
+ useEffect101(() => onRecordChanged(() => reload()), [reload]);
44930
45007
  const rows = nobodyIsMe ? [] : page.data?.rows ?? [];
44931
45008
  const columns = block.columns && block.columns.length > 0 ? block.columns.map((k) => all.find((f) => f.key === k)).filter((f) => !!f) : [...all].sort((a, b) => (a.sort ?? 100) - (b.sort ?? 100)).slice(0, DEFAULT_COLUMNS);
44932
45009
  const firstId = rows[0]?.id ?? null;
44933
45010
  const stillThere = selected !== null && rows.some((r) => r.id === selected);
44934
- useEffect100(() => {
45011
+ useEffect101(() => {
44935
45012
  if (page.loading || waiting) return;
44936
45013
  if (!stillThere) onSelect(firstId);
44937
45014
  }, [firstId, stillThere, page.loading, waiting]);
@@ -44994,11 +45071,11 @@ function ActionButton2({ block, recordId }) {
44994
45071
  const client = useRecordsClient88();
44995
45072
  const actionsRead = useRowActions2(block.action_id ? block.table_id : null);
44996
45073
  const action3 = !block.action_id ? null : actionsRead.data ? actionsRead.data.actions.find((a) => a.id === block.action_id) ?? null : actionsRead.loading ? "reading" : null;
44997
- const [asking, setAsking] = useState116(false);
44998
- const [running, setRunning] = useState116(false);
44999
- const [done, setDone] = useState116(null);
45000
- const [error, setError] = useState116(null);
45001
- useEffect100(() => {
45074
+ const [asking, setAsking] = useState117(false);
45075
+ const [running, setRunning] = useState117(false);
45076
+ const [done, setDone] = useState117(null);
45077
+ const [error, setError] = useState117(null);
45078
+ useEffect101(() => {
45002
45079
  setDone(null);
45003
45080
  setError(null);
45004
45081
  setAsking(false);
@@ -45037,9 +45114,9 @@ function ActionButton2({ block, recordId }) {
45037
45114
  }
45038
45115
  function FormBlockView({ block }) {
45039
45116
  const client = useRecordsClient88();
45040
- const [form, setForm] = useState116("reading");
45041
- const [sent, setSent] = useState116(0);
45042
- useEffect100(() => {
45117
+ const [form, setForm] = useState117("reading");
45118
+ const [sent, setSent] = useState117(0);
45119
+ useEffect101(() => {
45043
45120
  if (!block.form_id) {
45044
45121
  setForm(null);
45045
45122
  return;
@@ -45164,10 +45241,10 @@ function FieldPick({
45164
45241
  }
45165
45242
  function ListSettings({ block, onChange }) {
45166
45243
  const client = useRecordsClient88();
45167
- const [views, setViews] = useState116([]);
45244
+ const [views, setViews] = useState117([]);
45168
45245
  const fields = useFields32(block.table_id);
45169
45246
  const all = onePerKey3(fields.data ?? []);
45170
- useEffect100(() => {
45247
+ useEffect101(() => {
45171
45248
  let live = true;
45172
45249
  void client.views({ table_id: block.table_id }).then((answered) => {
45173
45250
  if (live) setViews(answered.ok ? answered.data : []);
@@ -45243,8 +45320,8 @@ function ActionPicker({ tableId, value, onChange }) {
45243
45320
  }
45244
45321
  function FormPicker({ tableId, value, onChange }) {
45245
45322
  const client = useRecordsClient88();
45246
- const [forms, setForms] = useState116([]);
45247
- useEffect100(() => {
45323
+ const [forms, setForms] = useState117([]);
45324
+ useEffect101(() => {
45248
45325
  let live = true;
45249
45326
  void client.forms({ table_id: tableId }).then((answered) => {
45250
45327
  if (live) setForms(answered.ok ? answered.data : []);
@@ -45290,7 +45367,7 @@ function onePerKey3(all) {
45290
45367
 
45291
45368
  // src/FormsPanel.tsx
45292
45369
  import { copyText as copyText9 } from "@ai-matrx/kit/clipboard";
45293
- import { useCallback as useCallback60, useEffect as useEffect101, useState as useState117 } from "react";
45370
+ import { useCallback as useCallback60, useEffect as useEffect102, useState as useState118 } from "react";
45294
45371
  import { useRecordsClient as useRecordsClient89, useTable as useTable33 } from "@ai-matrx/records/react";
45295
45372
  import { publicFormPath as publicFormPath2 } from "@ai-matrx/records";
45296
45373
  import { Badge as Badge24, Button as Button95, Skeleton as Skeleton37, cn as cn86 } from "@ai-matrx/design-system";
@@ -45307,15 +45384,15 @@ function FormsPanel({ tableId, activeFormId, className }) {
45307
45384
  const host = useRecordsUi();
45308
45385
  const table = useTable33(tableId);
45309
45386
  const rights = useTableRights(table.data);
45310
- const [forms, setForms] = useState117(null);
45311
- const [error, setError] = useState117(null);
45312
- const [busy, setBusy] = useState117(null);
45313
- const [copied, setCopied] = useState117(null);
45314
- const [building, setBuilding] = useState117(false);
45315
- const [archivedSaid, setArchivedSaid] = useState117(null);
45387
+ const [forms, setForms] = useState118(null);
45388
+ const [error, setError] = useState118(null);
45389
+ const [busy, setBusy] = useState118(null);
45390
+ const [copied, setCopied] = useState118(null);
45391
+ const [building, setBuilding] = useState118(false);
45392
+ const [archivedSaid, setArchivedSaid] = useState118(null);
45316
45393
  const linked = activeFormId && forms !== null ? forms.find((f) => f.form_id === activeFormId) ?? null : null;
45317
45394
  const linkedMissing = Boolean(activeFormId) && forms !== null && linked === null;
45318
- useEffect101(() => {
45395
+ useEffect102(() => {
45319
45396
  if (linked && rights.structure) setBuilding(true);
45320
45397
  }, [linked, rights.structure]);
45321
45398
  const load = useCallback60(async () => {
@@ -45328,7 +45405,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
45328
45405
  setError(null);
45329
45406
  setForms(answered.data);
45330
45407
  }, [client, tableId]);
45331
- useEffect101(() => {
45408
+ useEffect102(() => {
45332
45409
  void load();
45333
45410
  }, [load]);
45334
45411
  const toggle = useCallback60(
@@ -45345,7 +45422,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
45345
45422
  },
45346
45423
  [client, load]
45347
45424
  );
45348
- const [shown4, setShown] = useState117(null);
45425
+ const [shown4, setShown] = useState118(null);
45349
45426
  const copy = useCallback60(async (url, formId) => {
45350
45427
  if (await copyText9(url)) {
45351
45428
  setCopied(formId);
@@ -45473,12 +45550,12 @@ function FormsPanel({ tableId, activeFormId, className }) {
45473
45550
  }
45474
45551
 
45475
45552
  // src/CaptureSheet.tsx
45476
- import { useCallback as useCallback62, useEffect as useEffect103, useRef as useRef56, useState as useState119 } from "react";
45553
+ import { useCallback as useCallback62, useEffect as useEffect104, useRef as useRef56, useState as useState120 } from "react";
45477
45554
  import { useFields as useFields33, useRecordsClient as useRecordsClient91, useTable as useTable34 } from "@ai-matrx/records/react";
45478
45555
  import { Button as Button97, Input as Input8, Skeleton as Skeleton39, Textarea as Textarea7, cn as cn88 } from "@ai-matrx/design-system";
45479
45556
 
45480
45557
  // src/CaptureRun.tsx
45481
- import { useCallback as useCallback61, useEffect as useEffect102, useMemo as useMemo72, useRef as useRef55, useState as useState118 } from "react";
45558
+ import { useCallback as useCallback61, useEffect as useEffect103, useMemo as useMemo72, useRef as useRef55, useState as useState119 } from "react";
45482
45559
  import {
45483
45560
  coerceTypedAnswer as coerceTypedAnswer3,
45484
45561
  coercionLabel,
@@ -45525,19 +45602,19 @@ function whereWeAre(timeoutMs = 4e3) {
45525
45602
  function CaptureRun({ sheetId, face: given, className }) {
45526
45603
  const client = useRecordsClient90();
45527
45604
  const host = useRecordsUi();
45528
- const [face, setFace] = useState118(given);
45529
- const [loadFailed, setLoadFailed] = useState118(null);
45530
- const [at, setAt] = useState118(0);
45531
- const [answers, setAnswers] = useState118({});
45532
- const [files, setFiles] = useState118({});
45533
- const [missing, setMissing] = useState118(null);
45534
- const [done, setDone] = useState118(null);
45535
- const [counts, setCounts] = useState118({ waiting: 0, sending: 0, refused: 0, landed: 0 });
45536
- const [items, setItems] = useState118([]);
45537
- const [lastSynced, setLastSynced] = useState118(null);
45538
- const [sending, setSending] = useState118(false);
45605
+ const [face, setFace] = useState119(given);
45606
+ const [loadFailed, setLoadFailed] = useState119(null);
45607
+ const [at, setAt] = useState119(0);
45608
+ const [answers, setAnswers] = useState119({});
45609
+ const [files, setFiles] = useState119({});
45610
+ const [missing, setMissing] = useState119(null);
45611
+ const [done, setDone] = useState119(null);
45612
+ const [counts, setCounts] = useState119({ waiting: 0, sending: 0, refused: 0, landed: 0 });
45613
+ const [items, setItems] = useState119([]);
45614
+ const [lastSynced, setLastSynced] = useState119(null);
45615
+ const [sending, setSending] = useState119(false);
45539
45616
  const queueRef = useRef55(null);
45540
- useEffect102(() => {
45617
+ useEffect103(() => {
45541
45618
  const q2 = openCaptureQueue({
45542
45619
  onChange: (c, all) => {
45543
45620
  setCounts(c);
@@ -45575,7 +45652,7 @@ function CaptureRun({ sheetId, face: given, className }) {
45575
45652
  void q2.sync().then(() => void q2.lastSyncedAt().then(setLastSynced));
45576
45653
  return () => q2.dispose();
45577
45654
  }, [client, host]);
45578
- useEffect102(() => {
45655
+ useEffect103(() => {
45579
45656
  if (given !== void 0) return;
45580
45657
  let cancelled = false;
45581
45658
  void client.captureOpen({ sheet_id: sheetId }).then((res) => {
@@ -45907,15 +45984,15 @@ function AdHocCaptureSheet({
45907
45984
  const host = useRecordsUi();
45908
45985
  const table = useTable34(tableId);
45909
45986
  const fields = useFields33(tableId);
45910
- const [mode, setMode] = useState119("reading");
45911
- const [reading, setReading] = useState119("");
45912
- const [note, setNote] = useState119("");
45913
- const [fileId, setFileId] = useState119(null);
45914
- const [pending, setPending] = useState119(null);
45915
- const [saved, setSaved] = useState119([]);
45916
- const [error, setError] = useState119(null);
45917
- const [uploadError, setUploadError] = useState119(null);
45918
- const [flushing, setFlushing] = useState119(false);
45987
+ const [mode, setMode] = useState120("reading");
45988
+ const [reading, setReading] = useState120("");
45989
+ const [note, setNote] = useState120("");
45990
+ const [fileId, setFileId] = useState120(null);
45991
+ const [pending, setPending] = useState120(null);
45992
+ const [saved, setSaved] = useState120([]);
45993
+ const [error, setError] = useState120(null);
45994
+ const [uploadError, setUploadError] = useState120(null);
45995
+ const [flushing, setFlushing] = useState120(false);
45919
45996
  const queue = useRef56([]);
45920
45997
  const keep = useCallback62(
45921
45998
  async (next) => {
@@ -45925,7 +46002,7 @@ function AdHocCaptureSheet({
45925
46002
  },
45926
46003
  [host]
45927
46004
  );
45928
- useEffect103(() => {
46005
+ useEffect104(() => {
45929
46006
  let cancelled = false;
45930
46007
  void (async () => {
45931
46008
  const held = host.captureQueue ? await host.captureQueue.load() : [];
@@ -46104,17 +46181,17 @@ function AdHocCaptureSheet({
46104
46181
  }
46105
46182
 
46106
46183
  // src/PortalShell.tsx
46107
- import { useCallback as useCallback63, useEffect as useEffect104, useState as useState120 } from "react";
46184
+ import { useCallback as useCallback63, useEffect as useEffect105, useState as useState121 } from "react";
46108
46185
  import { useRecordsClient as useRecordsClient92 } from "@ai-matrx/records/react";
46109
46186
  import { Button as Button98, Skeleton as Skeleton40, cn as cn89 } from "@ai-matrx/design-system";
46110
46187
  import { jsx as jsx146, jsxs as jsxs135 } from "react/jsx-runtime";
46111
46188
  function PortalShell({ tableId, form, resourceType = "record", className }) {
46112
46189
  const client = useRecordsClient92();
46113
- const [card, setCard] = useState120(null);
46114
- const [reach, setReach] = useState120(null);
46115
- const [error, setError] = useState120(null);
46116
- const [open, setOpen] = useState120(null);
46117
- const [sending, setSending] = useState120(false);
46190
+ const [card, setCard] = useState121(null);
46191
+ const [reach, setReach] = useState121(null);
46192
+ const [error, setError] = useState121(null);
46193
+ const [open, setOpen] = useState121(null);
46194
+ const [sending, setSending] = useState121(false);
46118
46195
  const load = useCallback63(async () => {
46119
46196
  const who = await client.externalPrincipalCard();
46120
46197
  if (!who.ok) {
@@ -46130,7 +46207,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
46130
46207
  }
46131
46208
  setReach(reached.data.map((row) => row.resource_id));
46132
46209
  }, [client, resourceType]);
46133
- useEffect104(() => {
46210
+ useEffect105(() => {
46134
46211
  void load();
46135
46212
  }, [load]);
46136
46213
  if (error) {
@@ -46189,8 +46266,8 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
46189
46266
  }
46190
46267
  function PortalRow({ tableId, recordId }) {
46191
46268
  const client = useRecordsClient92();
46192
- const [title, setTitle] = useState120(null);
46193
- useEffect104(() => {
46269
+ const [title, setTitle] = useState121(null);
46270
+ useEffect105(() => {
46194
46271
  let cancelled = false;
46195
46272
  void client.recordRead({ record_id: recordId }).then((answered) => {
46196
46273
  if (cancelled) return;
@@ -46210,7 +46287,7 @@ function PortalRow({ tableId, recordId }) {
46210
46287
  }
46211
46288
 
46212
46289
  // src/PublicViewPage.tsx
46213
- import { useCallback as useCallback64, useEffect as useEffect105, useState as useState121 } from "react";
46290
+ import { useCallback as useCallback64, useEffect as useEffect106, useState as useState122 } from "react";
46214
46291
  import { useRecordsClient as useRecordsClient93 } from "@ai-matrx/records/react";
46215
46292
  import { Skeleton as Skeleton41, cn as cn90 } from "@ai-matrx/design-system";
46216
46293
 
@@ -46228,12 +46305,12 @@ function publicReadOf(binding) {
46228
46305
  import { jsx as jsx147, jsxs as jsxs136 } from "react/jsx-runtime";
46229
46306
  function PublicViewPage({ slug, className }) {
46230
46307
  const client = useRecordsClient93();
46231
- const [binding, setBinding] = useState121(null);
46232
- const [rows, setRows] = useState121(null);
46233
- const [fields, setFields] = useState121(null);
46234
- const [error, setError] = useState121(null);
46235
- const [plan, setPlan] = useState121(null);
46236
- const [gap, setGap] = useState121(null);
46308
+ const [binding, setBinding] = useState122(null);
46309
+ const [rows, setRows] = useState122(null);
46310
+ const [fields, setFields] = useState122(null);
46311
+ const [error, setError] = useState122(null);
46312
+ const [plan, setPlan] = useState122(null);
46313
+ const [gap, setGap] = useState122(null);
46237
46314
  const load = useCallback64(async () => {
46238
46315
  const notice = await client.worldPublishGapNotice();
46239
46316
  if (notice.ok) setGap(notice.data);
@@ -46284,7 +46361,7 @@ function PublicViewPage({ slug, className }) {
46284
46361
  }
46285
46362
  setRows([{ id: chosen.recordId, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
46286
46363
  }, [client, slug]);
46287
- useEffect105(() => {
46364
+ useEffect106(() => {
46288
46365
  void load();
46289
46366
  }, [load]);
46290
46367
  if (error) return /* @__PURE__ */ jsx147(RefusalNotice, { error, className });
@@ -46322,7 +46399,7 @@ function PublicRow({ row, fields }) {
46322
46399
 
46323
46400
  // src/EmbedFrame.tsx
46324
46401
  import { copyText as copyText10 } from "@ai-matrx/kit/clipboard";
46325
- import { useCallback as useCallback65, useEffect as useEffect106, useState as useState122 } from "react";
46402
+ import { useCallback as useCallback65, useEffect as useEffect107, useState as useState123 } from "react";
46326
46403
  import { useRecordsClient as useRecordsClient94 } from "@ai-matrx/records/react";
46327
46404
  import { Button as Button99, Input as Input9, Skeleton as Skeleton42, Textarea as Textarea8, cn as cn91 } from "@ai-matrx/design-system";
46328
46405
  import { useTable as useTable35 } from "@ai-matrx/records/react";
@@ -46339,11 +46416,11 @@ function EmbedFrame({
46339
46416
  const host = useRecordsUi();
46340
46417
  const table = useTable35(tableId);
46341
46418
  const rights = useTableRights(table.data);
46342
- const [origins, setOrigins] = useState122("");
46343
- const [secret, setSecret] = useState122(null);
46344
- const [tokenId, setTokenId] = useState122(null);
46345
- const [error, setError] = useState122(null);
46346
- const [busy, setBusy] = useState122(false);
46419
+ const [origins, setOrigins] = useState123("");
46420
+ const [secret, setSecret] = useState123(null);
46421
+ const [tokenId, setTokenId] = useState123(null);
46422
+ const [error, setError] = useState123(null);
46423
+ const [busy, setBusy] = useState123(false);
46347
46424
  const mode = formId ? "write" : "read";
46348
46425
  const parsed = origins.split(/[\s,]+/).map((o) => o.trim()).filter((o) => o.length > 0);
46349
46426
  const issue = useCallback65(async () => {
@@ -46430,12 +46507,12 @@ function EmbedFrame({
46430
46507
  }
46431
46508
  function useEmbedHandshake(args) {
46432
46509
  const client = useRecordsClient94();
46433
- const [binding, setBinding] = useState122(null);
46434
- const [error, setError] = useState122(null);
46435
- const [loading, setLoading] = useState122(true);
46510
+ const [binding, setBinding] = useState123(null);
46511
+ const [error, setError] = useState123(null);
46512
+ const [loading, setLoading] = useState123(true);
46436
46513
  const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
46437
46514
  const { secret, requiredMode } = args;
46438
- useEffect106(() => {
46515
+ useEffect107(() => {
46439
46516
  let cancelled = false;
46440
46517
  setLoading(true);
46441
46518
  setError(null);
@@ -46458,7 +46535,7 @@ function useEmbedHandshake(args) {
46458
46535
 
46459
46536
  // src/TablePage.tsx
46460
46537
  import { copyText as copyText12 } from "@ai-matrx/kit/clipboard";
46461
- import { useCallback as useCallback67, useEffect as useEffect109, useMemo as useMemo76, useRef as useRef57, useState as useState129 } from "react";
46538
+ import { useCallback as useCallback67, useEffect as useEffect110, useMemo as useMemo76, useRef as useRef57, useState as useState130 } from "react";
46462
46539
  import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
46463
46540
  import { useFields as useFields36, useRecordsClient as useRecordsClient96, useTable as useTable36 } from "@ai-matrx/records/react";
46464
46541
  import {
@@ -46478,7 +46555,7 @@ import {
46478
46555
  cn as cn94,
46479
46556
  useIsMobile as useIsMobile2
46480
46557
  } from "@ai-matrx/design-system";
46481
- import { humanizeIdentifier as humanizeIdentifier18 } from "@ai-matrx/kit/text-case";
46558
+ import { humanizeIdentifier as humanizeIdentifier19 } from "@ai-matrx/kit/text-case";
46482
46559
 
46483
46560
  // src/viewShare.ts
46484
46561
  import { exportCsv as exportCsv2 } from "@ai-matrx/records/core";
@@ -46522,13 +46599,13 @@ async function downloadViewCsv(args) {
46522
46599
  }
46523
46600
 
46524
46601
  // src/RecordPanel.tsx
46525
- import { Fragment as Fragment61, useState as useState123 } from "react";
46602
+ import { Fragment as Fragment61, useState as useState124 } from "react";
46526
46603
  import { Button as Button100, Separator as Separator13 } from "@ai-matrx/design-system";
46527
46604
  import { useFields as useFields34, useRecord as useRecord4 } from "@ai-matrx/records/react";
46528
46605
  import { Fragment as Fragment62, jsx as jsx149, jsxs as jsxs138 } from "react/jsx-runtime";
46529
46606
  function RecordPanel({ tableId, recordId, onClose, onAskAboutField, onPage = false }) {
46530
46607
  const host = useRecordsUi();
46531
- const [asking, setAsking] = useState123(null);
46608
+ const [asking, setAsking] = useState124(null);
46532
46609
  return /* @__PURE__ */ jsxs138("div", { className: "space-y-3", "data-record-panel": recordId, children: [
46533
46610
  /* @__PURE__ */ jsx149(Peek, { tableId, recordId, onPage, ...onClose ? { onClose } : {} }),
46534
46611
  onPage ? /* @__PURE__ */ jsxs138(Fragment62, { children: [
@@ -46606,7 +46683,7 @@ function LinkedLists({ tableId, recordId }) {
46606
46683
  }
46607
46684
  function RecordAsk({ tableId, recordId }) {
46608
46685
  const host = useRecordsUi();
46609
- const [open, setOpen] = useState123(false);
46686
+ const [open, setOpen] = useState124(false);
46610
46687
  if (!host.chat) return null;
46611
46688
  return /* @__PURE__ */ jsxs138("section", { className: "flex min-w-0 flex-col gap-1.5", "data-record-ask": open ? "open" : "", children: [
46612
46689
  /* @__PURE__ */ jsx149(Separator13, {}),
@@ -46615,7 +46692,7 @@ function RecordAsk({ tableId, recordId }) {
46615
46692
  }
46616
46693
 
46617
46694
  // src/breakDown.tsx
46618
- import { useMemo as useMemo73, useState as useState124 } from "react";
46695
+ import { useMemo as useMemo73, useState as useState125 } from "react";
46619
46696
  import {
46620
46697
  Button as Button101,
46621
46698
  Dialog as Dialog14,
@@ -46655,7 +46732,7 @@ function BreakDownDialog({
46655
46732
  const source = useMemo73(() => ({ kind: "table", id: tableId }), [tableId]);
46656
46733
  const { def } = useDrillDefinition(open ? source : null);
46657
46734
  const dimensions = useMemo73(() => drillDimensionsOf(def, NO_LABELS), [def]);
46658
- const [picked, setPicked] = useState124(null);
46735
+ const [picked, setPicked] = useState125(null);
46659
46736
  const key = picked ?? held?.field ?? dimensions[0]?.key ?? "";
46660
46737
  return /* @__PURE__ */ jsx150(Dialog14, { open, onOpenChange, children: /* @__PURE__ */ jsxs139(DialogContent14, { "data-break-down": "", className: "max-w-sm", children: [
46661
46738
  /* @__PURE__ */ jsx150(DialogHeader14, { children: /* @__PURE__ */ jsx150(DialogTitle14, { children: "Break down by" }) }),
@@ -46682,7 +46759,7 @@ function BreakDownDialog({
46682
46759
 
46683
46760
  // src/TableReference.tsx
46684
46761
  import { copyText as copyText11 } from "@ai-matrx/kit/clipboard";
46685
- import { useCallback as useCallback66, useMemo as useMemo74, useState as useState125 } from "react";
46762
+ import { useCallback as useCallback66, useMemo as useMemo74, useState as useState126 } from "react";
46686
46763
  import { useContentTransferCapabilities as useContentTransferCapabilities2 } from "@ai-matrx/alchemy/react/workspace";
46687
46764
  import { Button as Button102, Dialog as Dialog15, DialogContent as DialogContent15, DialogHeader as DialogHeader15, DialogTitle as DialogTitle15 } from "@ai-matrx/design-system";
46688
46765
  import { jsx as jsx151, jsxs as jsxs140 } from "react/jsx-runtime";
@@ -46710,7 +46787,7 @@ function TableReferenceDialog({
46710
46787
  }) {
46711
46788
  const port = useContentTransferCapabilities2().reference;
46712
46789
  const notify = useRecordsUi().notify;
46713
- const [copied, setCopied] = useState125(null);
46790
+ const [copied, setCopied] = useState126(null);
46714
46791
  const choices = useMemo74(
46715
46792
  () => tableReferenceChoices(table.id, tableName(table)).filter((c) => port?.supports(c.reference)),
46716
46793
  [table, port]
@@ -46738,7 +46815,7 @@ function TableReferenceDialog({
46738
46815
  }
46739
46816
 
46740
46817
  // src/TableDuplicate.tsx
46741
- import { useState as useState126 } from "react";
46818
+ import { useState as useState127 } from "react";
46742
46819
  import { tableShapeChanged as tableShapeChanged12, useRecordsClient as useRecordsClient95 } from "@ai-matrx/records/react";
46743
46820
  import { Button as Button103, Dialog as Dialog16, DialogContent as DialogContent16, DialogFooter as DialogFooter11, DialogHeader as DialogHeader16, DialogTitle as DialogTitle16, ErrorBox as ErrorBox8, Input as Input10, Switch as Switch5 } from "@ai-matrx/design-system";
46744
46821
  import { Fragment as Fragment63, jsx as jsx152, jsxs as jsxs141 } from "react/jsx-runtime";
@@ -46753,9 +46830,9 @@ function duplicateProgressWords(p) {
46753
46830
  function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated }) {
46754
46831
  const client = useRecordsClient95();
46755
46832
  const host = useRecordsUi();
46756
- const [typed2, setTyped] = useState126(() => copyNameFor(name));
46757
- const [withRecords, setWithRecords] = useState126(true);
46758
- const [phase, setPhase] = useState126({ kind: "asking" });
46833
+ const [typed2, setTyped] = useState127(() => copyNameFor(name));
46834
+ const [withRecords, setWithRecords] = useState127(true);
46835
+ const [phase, setPhase] = useState127({ kind: "asking" });
46759
46836
  const problem = tableNameProblem(typed2);
46760
46837
  const copying = phase.kind === "copying";
46761
46838
  const close = (next) => {
@@ -46840,7 +46917,7 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
46840
46917
  }
46841
46918
 
46842
46919
  // src/ViewFilter.tsx
46843
- import { useEffect as useEffect107, useMemo as useMemo75, useState as useState127 } from "react";
46920
+ import { useEffect as useEffect108, useMemo as useMemo75, useState as useState128 } from "react";
46844
46921
  import { Button as Button104, Popover as Popover13, PopoverContent as PopoverContent13, PopoverTrigger as PopoverTrigger13 } from "@ai-matrx/design-system";
46845
46922
  import { useFields as useFields35 } from "@ai-matrx/records/react";
46846
46923
  import { jsx as jsx153, jsxs as jsxs142 } from "react/jsx-runtime";
@@ -46854,11 +46931,11 @@ function conditionCount(expr) {
46854
46931
  }
46855
46932
  function ViewFilter({ tableId, view, onApply, className }) {
46856
46933
  const fields = useFields35(tableId);
46857
- const [open, setOpen] = useState127(false);
46934
+ const [open, setOpen] = useState128(false);
46858
46935
  const saved = view?.where ?? null;
46859
- const [draft, setDraft] = useState127(saved);
46936
+ const [draft, setDraft] = useState128(saved);
46860
46937
  const savedKey = JSON.stringify(saved);
46861
- useEffect107(() => {
46938
+ useEffect108(() => {
46862
46939
  setDraft(saved);
46863
46940
  }, [view?.id, savedKey]);
46864
46941
  const conditionFields = useMemo75(
@@ -46906,7 +46983,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
46906
46983
  ConditionGroup,
46907
46984
  {
46908
46985
  lead: "Show records where",
46909
- emptyLabel: "every record",
46986
+ emptyLabel: "Pick a field",
46910
46987
  expr: draft,
46911
46988
  fields: conditionFields,
46912
46989
  onChange: setDraft
@@ -46942,8 +47019,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
46942
47019
  /* @__PURE__ */ jsx153(Button104, { size: "sm", variant: "ghost", onClick: () => {
46943
47020
  setDraft(saved);
46944
47021
  setOpen(false);
46945
- }, children: "Cancel" }),
46946
- changed ? /* @__PURE__ */ jsx153("span", { className: "text-muted-foreground", children: "Not applied yet." }) : null
47022
+ }, children: "Cancel" })
46947
47023
  ] })
46948
47024
  ]
46949
47025
  }
@@ -47034,7 +47110,7 @@ function phoneTableActions(actions) {
47034
47110
  }
47035
47111
 
47036
47112
  // src/toolbarFit.ts
47037
- import { useEffect as useEffect108, useState as useState128 } from "react";
47113
+ import { useEffect as useEffect109, useState as useState129 } from "react";
47038
47114
  var FOLDED_GUESS = { look: 104, chooser: 96, tools: 120 };
47039
47115
  var SLOT_MIN = 36;
47040
47116
  function toolbarFold(input) {
@@ -47091,8 +47167,8 @@ function rowNeeds(row) {
47091
47167
  return { needs: needs + gap * Math.max(0, pieces.length - 1), gap };
47092
47168
  }
47093
47169
  function useToolbarFit(row) {
47094
- const [fold, setFold] = useState128(0);
47095
- useEffect108(() => {
47170
+ const [fold, setFold] = useState129(0);
47171
+ useEffect109(() => {
47096
47172
  if (!row) return;
47097
47173
  const widths = {
47098
47174
  look: { full: null, folded: null },
@@ -47176,8 +47252,8 @@ function clippedEnds(scrollLeft, clientWidth, scrollWidth) {
47176
47252
  return start && end ? "both" : start ? "start" : end ? "end" : "none";
47177
47253
  }
47178
47254
  function useSlotScroll(slot) {
47179
- const [ends, setEnds] = useState128("none");
47180
- useEffect108(() => {
47255
+ const [ends, setEnds] = useState129("none");
47256
+ useEffect109(() => {
47181
47257
  if (!slot) return;
47182
47258
  let pending = 0;
47183
47259
  const read = () => {
@@ -47260,7 +47336,7 @@ function RailFrame({
47260
47336
  function filterInWords(filter, fields) {
47261
47337
  const nameOf2 = (key) => {
47262
47338
  const field2 = fields.find((f) => f.key === key);
47263
- return field2 ? fieldName(field2) : humanizeIdentifier18(key);
47339
+ return field2 ? fieldName(field2) : humanizeIdentifier19(key);
47264
47340
  };
47265
47341
  const parts = Object.keys(filter).map((key) => {
47266
47342
  const value = filter[key];
@@ -47295,10 +47371,10 @@ function TableNotHere({
47295
47371
  className
47296
47372
  }) {
47297
47373
  const client = useRecordsClient96();
47298
- const [archived, setArchived] = useState129({ phase: "asking" });
47299
- const [restoring, setRestoring] = useState129(false);
47300
- const [refusal4, setRefusal] = useState129(null);
47301
- useEffect109(() => {
47374
+ const [archived, setArchived] = useState130({ phase: "asking" });
47375
+ const [restoring, setRestoring] = useState130(false);
47376
+ const [refusal4, setRefusal] = useState130(null);
47377
+ useEffect110(() => {
47302
47378
  let alive = true;
47303
47379
  void client.tableArchived({ table_id: tableId }).then((answered) => {
47304
47380
  if (!alive) return;
@@ -47505,9 +47581,9 @@ function TablePage({
47505
47581
  const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
47506
47582
  const organizationId = useRecordsClient96().config.organizationId;
47507
47583
  const publicReadOnly = usePublicReadOnly(client, organizationId, tableId, table.data, rights);
47508
- const [view, setView] = useState129(null);
47509
- const [looks, setLooks] = useState129(void 0);
47510
- useEffect109(() => {
47584
+ const [view, setView] = useState130(null);
47585
+ const [looks, setLooks] = useState130(void 0);
47586
+ useEffect110(() => {
47511
47587
  let live = true;
47512
47588
  setLooks(void 0);
47513
47589
  void readLooks(client, tableId).then((answered) => {
@@ -47520,7 +47596,7 @@ function TablePage({
47520
47596
  }, [client, tableId]);
47521
47597
  const look = view && looks ? looks[view.id] : void 0;
47522
47598
  const shown4 = view ? applyLook(view, look) : null;
47523
- const [viewsEpoch, setViewsEpoch] = useState129(0);
47599
+ const [viewsEpoch, setViewsEpoch] = useState130(0);
47524
47600
  const opening = openingRail(activeRecordId, activeRail);
47525
47601
  const recordsUi = useRecordsUi();
47526
47602
  const hostLayouts = recordsUi.layouts ?? [];
@@ -47530,39 +47606,39 @@ function TablePage({
47530
47606
  const questionsFromLink = questionsFromParam(activeView);
47531
47607
  const openedByPackage = openingView(hostFromLink || savedFromLink || questionsFromLink ? null : activeView, activeDashboardId);
47532
47608
  const opened = hostFromLink ? { ...openedByPackage, main: "records" } : questionsFromLink ? { ...openedByPackage, main: "questions" } : openedByPackage;
47533
- const [hostLayout, setHostLayout] = useState129(hostFromLink);
47534
- const [views, setViews] = useState129(void 0);
47535
- const [pickedViewId, setPickedViewId] = useState129(savedFromLink);
47609
+ const [hostLayout, setHostLayout] = useState130(hostFromLink);
47610
+ const [views, setViews] = useState130(void 0);
47611
+ const [pickedViewId, setPickedViewId] = useState130(savedFromLink);
47536
47612
  const viewSeen = useRef57(null);
47537
- const [viewLinkMissed, setViewLinkMissed] = useState129(false);
47538
- const [layoutChosen, setLayoutChosen] = useState129(false);
47613
+ const [viewLinkMissed, setViewLinkMissed] = useState130(false);
47614
+ const [layoutChosen, setLayoutChosen] = useState130(false);
47539
47615
  const railAsked = typeof activeRail === "string" ? activeRail.trim() : "";
47540
47616
  const railUnknown = railAsked !== "" && railFromParam(railAsked) === null ? railAsked : null;
47541
47617
  const shareFromLink = railFromParam(activeRail) === "share";
47542
47618
  const canShare = useCanShare();
47543
47619
  const itemFor = (which) => railFromParam(activeRail) === which ? activeItemId ?? null : null;
47544
- const [asking, setAsking] = useState129(null);
47545
- const [layoutFromLink, setLayoutFromLink] = useState129(opened.layout);
47546
- const [surface, setSurface] = useState129({
47620
+ const [asking, setAsking] = useState130(null);
47621
+ const [layoutFromLink, setLayoutFromLink] = useState130(opened.layout);
47622
+ const [surface, setSurface] = useState130({
47547
47623
  main: opened.main,
47548
47624
  rail: opening.rail
47549
47625
  });
47550
47626
  const { main, rail } = surface;
47551
- const [questionDraft, setQuestionDraft] = useState129(null);
47627
+ const [questionDraft, setQuestionDraft] = useState130(null);
47552
47628
  const setRail = (next) => setSurface((now) => ({ ...now, rail: next }));
47553
- const [importEpoch, setImportEpoch] = useState129(0);
47554
- const [openRecord, setOpenRecord] = useState129(opening.record);
47629
+ const [importEpoch, setImportEpoch] = useState130(0);
47630
+ const [openRecord, setOpenRecord] = useState130(opening.record);
47555
47631
  const phone = useIsMobile2();
47556
- const [shareAsked, setShareAsked] = useState129(0);
47632
+ const [shareAsked, setShareAsked] = useState130(0);
47557
47633
  const { open: renameOpen, setOpen: setRenameOpen, ask: askRename, menuContentProps: renameMenuProps } = useRenameFromMenu();
47558
- const [archiveAsked, setArchiveAsked] = useState129(0);
47559
- const [moveAsked, setMoveAsked] = useState129(0);
47560
- const [duplicateOpen, setDuplicateOpen] = useState129(false);
47561
- const [referenceOpen, setReferenceOpen] = useState129(false);
47562
- const [breakDownOpen, setBreakDownOpen] = useState129(false);
47634
+ const [archiveAsked, setArchiveAsked] = useState130(0);
47635
+ const [moveAsked, setMoveAsked] = useState130(0);
47636
+ const [duplicateOpen, setDuplicateOpen] = useState130(false);
47637
+ const [referenceOpen, setReferenceOpen] = useState130(false);
47638
+ const [breakDownOpen, setBreakDownOpen] = useState130(false);
47563
47639
  const canGetReference = useCanGetReference();
47564
- const [toolbarSlot, setToolbarSlot] = useState129(null);
47565
- const [toolbarRow, setToolbarRow] = useState129(null);
47640
+ const [toolbarSlot, setToolbarSlot] = useState130(null);
47641
+ const [toolbarRow, setToolbarRow] = useState130(null);
47566
47642
  const toolbarFold2 = useToolbarFit(toolbarRow);
47567
47643
  const slotClipped = useSlotScroll(toolbarSlot);
47568
47644
  const face = tableOpening(view, hostLayouts.map((h) => h.id));
@@ -47573,7 +47649,7 @@ function TablePage({
47573
47649
  const chooserCompact = !embedded && !designated && !phone && toolbarFold2 >= 2;
47574
47650
  const controlsInSheet = phone && !designated;
47575
47651
  const shareInMenu = phone || toolbarFold2 >= 4;
47576
- useEffect109(() => {
47652
+ useEffect110(() => {
47577
47653
  if (face.kind !== "designated") return;
47578
47654
  if (hostFromLink || opened.layout || layoutChosen) return;
47579
47655
  setHostLayout(face.hostLayout);
@@ -47606,7 +47682,7 @@ function TablePage({
47606
47682
  const shownSignature = JSON.stringify(shownReport);
47607
47683
  const reportRef = useRef57(onShownViewChange);
47608
47684
  reportRef.current = onShownViewChange;
47609
- useEffect109(() => {
47685
+ useEffect110(() => {
47610
47686
  reportRef.current?.(JSON.parse(shownSignature));
47611
47687
  }, [shownSignature]);
47612
47688
  const pickLayout = (next) => {
@@ -47623,18 +47699,18 @@ function TablePage({
47623
47699
  setSurface((now) => ({ ...now, main: "records" }));
47624
47700
  onViewChanged?.(id);
47625
47701
  };
47626
- useEffect109(() => {
47702
+ useEffect110(() => {
47627
47703
  if (!activeRecordId) return;
47628
47704
  setOpenRecord(activeRecordId);
47629
47705
  setSurface((now) => ({ ...now, rail: "record" }));
47630
47706
  }, [activeRecordId]);
47631
- useEffect109(() => {
47707
+ useEffect110(() => {
47632
47708
  if (activeRecordId) return;
47633
47709
  const named = railFromParam(activeRail);
47634
47710
  if (named === null || named === "share") return;
47635
47711
  setSurface((now) => ({ ...now, rail: named }));
47636
47712
  }, [activeRail, activeRecordId]);
47637
- useEffect109(() => {
47713
+ useEffect110(() => {
47638
47714
  const host = hostLayoutFor(activeView);
47639
47715
  if (host) {
47640
47716
  setHostLayout(host);
@@ -47648,7 +47724,7 @@ function TablePage({
47648
47724
  setLayoutFromLink(isLayout ? named : null);
47649
47725
  setSurface((now) => ({ ...now, main: isLayout ? "records" : named }));
47650
47726
  }, [activeView]);
47651
- const [viewSaveRefused, setViewSaveRefused] = useState129(null);
47727
+ const [viewSaveRefused, setViewSaveRefused] = useState130(null);
47652
47728
  const patchView = useCallback67(
47653
47729
  async (asked3) => {
47654
47730
  const current = view;
@@ -47666,8 +47742,8 @@ function TablePage({
47666
47742
  [client, tableId, view, looks]
47667
47743
  );
47668
47744
  const arrival = useRef57(viewAddress ?? null);
47669
- const [gridQuery, setGridQuery] = useState129(null);
47670
- const [addressResetEpoch, setAddressResetEpoch] = useState129(0);
47745
+ const [gridQuery, setGridQuery] = useState130(null);
47746
+ const [addressResetEpoch, setAddressResetEpoch] = useState130(0);
47671
47747
  const reportGrid = useCallback67((q) => {
47672
47748
  const next = { sort: q.sort, filters: q.filters, search: q.search, page: q.page };
47673
47749
  setGridQuery((held) => sameViewAddress(held, next) ? held : next);
@@ -47677,7 +47753,7 @@ function TablePage({
47677
47753
  [reportGrid, addressResetEpoch]
47678
47754
  );
47679
47755
  const hiddenApplied = useRef57(false);
47680
- useEffect109(() => {
47756
+ useEffect110(() => {
47681
47757
  const hidden = arrival.current?.hidden;
47682
47758
  if (hiddenApplied.current || !view || !looks || !hidden || hidden.length === 0) return;
47683
47759
  hiddenApplied.current = true;
@@ -47700,7 +47776,7 @@ function TablePage({
47700
47776
  const addressReportRef = useRef57(onViewAddressChange);
47701
47777
  addressReportRef.current = onViewAddressChange;
47702
47778
  const addressSent = useRef57(null);
47703
- useEffect109(() => {
47779
+ useEffect110(() => {
47704
47780
  if (!addressReady) return;
47705
47781
  if (addressSent.current === null && addressSignature === JSON.stringify(viewAddressToParams(arrival.current))) {
47706
47782
  addressSent.current = addressSignature;
@@ -47712,9 +47788,9 @@ function TablePage({
47712
47788
  }, [addressReady, addressSignature]);
47713
47789
  const queryShowing = !isViewAddressEmpty({ ...gridQuery ?? {}, hidden: [] });
47714
47790
  const lookShowing = Boolean(view && looks && (lookDiffers(view, looks[view.id]) || queryShowing));
47715
- const [lookRefused, setLookRefused] = useState129(null);
47716
- const [namingLook, setNamingLook] = useState129(false);
47717
- const [lookName, setLookName] = useState129("");
47791
+ const [lookRefused, setLookRefused] = useState130(null);
47792
+ const [namingLook, setNamingLook] = useState130(false);
47793
+ const [lookName, setLookName] = useState130("");
47718
47794
  const resetLook = async () => {
47719
47795
  const current = view;
47720
47796
  setAddressResetEpoch((n) => n + 1);
@@ -47773,7 +47849,7 @@ function TablePage({
47773
47849
  setPickedViewId(written.data);
47774
47850
  setViewsEpoch((n) => n + 1);
47775
47851
  };
47776
- const [designateRefused, setDesignateRefused] = useState129(null);
47852
+ const [designateRefused, setDesignateRefused] = useState130(null);
47777
47853
  const opensAs = view?.isDefault ? openingLayoutOf(view) : null;
47778
47854
  const canDesignate = Boolean(
47779
47855
  rights.write && view && layoutShowing && layoutShowing !== opensAs && (storeKeepsLayout(layoutShowing) || hostLayouts.some((h) => h.id === layoutShowing))
@@ -47956,10 +48032,10 @@ function TablePage({
47956
48032
  actionsRef.current = actions;
47957
48033
  const onActionsRef = useRef57(onActions);
47958
48034
  onActionsRef.current = onActions;
47959
- useEffect109(() => {
48035
+ useEffect110(() => {
47960
48036
  onActionsRef.current?.(actionsRef.current);
47961
48037
  });
47962
- useEffect109(() => {
48038
+ useEffect110(() => {
47963
48039
  const onKey = (event) => {
47964
48040
  const asked3 = objectActionForKey(actionsRef.current, event);
47965
48041
  if (!asked3) return;
@@ -48188,7 +48264,7 @@ function TablePage({
48188
48264
  ] })
48189
48265
  ] }) }),
48190
48266
  /* @__PURE__ */ jsxs144(DropdownMenuContent9, { align: "start", className: "w-60", "data-view-look-menu-content": "", children: [
48191
- /* @__PURE__ */ jsx155(DropdownMenuLabel3, { className: "text-xs font-normal text-muted-foreground", children: LOOK_WORDS.yours }),
48267
+ /* @__PURE__ */ jsx155(DropdownMenuLabel3, { className: "text-xs font-normal text-muted-foreground", title: LOOK_WORDS.yours, children: LOOK_WORDS.yoursLabel }),
48192
48268
  lookSavable ? /* @__PURE__ */ jsx155(DropdownMenuItem7, { onSelect: () => void saveLookToView(), "data-view-look-save": "", children: LOOK_WORDS.saveToView }) : null,
48193
48269
  rights.write ? /* @__PURE__ */ jsx155(DropdownMenuItem7, { onSelect: () => setNamingLook(true), "data-view-look-save-new": "", children: LOOK_WORDS.saveAsNew }) : null,
48194
48270
  /* @__PURE__ */ jsx155(DropdownMenuItem7, { onSelect: () => void resetLook(), "data-view-look-reset": "", children: LOOK_WORDS.reset })
@@ -48354,7 +48430,17 @@ function TablePage({
48354
48430
  children: cameFromLine(cameFrom, activeGroupField ?? null, askedInWords)
48355
48431
  }
48356
48432
  ) : null,
48357
- faceUnknown ? /* @__PURE__ */ jsx155(RecordsSkeleton, { layout: skeletonLayoutFor(shownLayout), embedded }) : /* @__PURE__ */ jsx155(
48433
+ faceUnknown ? (
48434
+ /* REVIEW-FIX 10: a full page paints the rows this table showed last time (else fills). */
48435
+ /* @__PURE__ */ jsx155(
48436
+ RecordsSkeleton,
48437
+ {
48438
+ layout: skeletonLayoutFor(shownLayout),
48439
+ embedded,
48440
+ ...embedded ? {} : { rows: rememberedRowCount(`${tableId}:page:last`, 100, "fill") }
48441
+ }
48442
+ )
48443
+ ) : /* @__PURE__ */ jsx155(
48358
48444
  ViewSwitcher,
48359
48445
  {
48360
48446
  chooser: false,
@@ -48500,8 +48586,8 @@ var PUBLIC_READ_ONLY = "Public \xB7 read only";
48500
48586
  function usePublicReadOnly(client, organizationId, tableId, table, rights) {
48501
48587
  const readOnly = rights.known && rights.read && !rights.write;
48502
48588
  const marked = table?.published_to_web;
48503
- const [isPublic, setIsPublic] = useState129(false);
48504
- useEffect109(() => {
48589
+ const [isPublic, setIsPublic] = useState130(false);
48590
+ useEffect110(() => {
48505
48591
  if (!readOnly || !table) {
48506
48592
  setIsPublic(false);
48507
48593
  return;
@@ -48526,7 +48612,7 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
48526
48612
  // src/entityViews.tsx
48527
48613
  import { TapTargetSearchGroup as TapTargetSearchGroup2, TooltipProvider } from "@ai-matrx/design-system";
48528
48614
  import { MatrxTableCardShowMore as MatrxTableCardShowMore3 } from "@ai-matrx/design-system/data-table";
48529
- import { useEffect as useEffect110, useMemo as useMemo77, useState as useState130 } from "react";
48615
+ import { useEffect as useEffect111, useMemo as useMemo77, useState as useState131 } from "react";
48530
48616
  import { Button as Button106, ErrorBox as ErrorBox9, Input as Input12, cn as cn95 } from "@ai-matrx/design-system";
48531
48617
  import { useRecordsClient as useRecordsClient97 } from "@ai-matrx/records/react";
48532
48618
  import { Fragment as Fragment65, jsx as jsx156, jsxs as jsxs145 } from "react/jsx-runtime";
@@ -48543,8 +48629,8 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
48543
48629
  () => cardFields ? entity.columns.filter((c) => cardFields.includes(c.key)) : entity.columns.filter((c) => c !== title && c !== column && c.type !== "choice").slice(0, 2),
48544
48630
  [cardFields, entity.columns, title, column]
48545
48631
  );
48546
- const [refused, setRefused] = useState130(null);
48547
- const [over, setOver] = useState130(null);
48632
+ const [refused, setRefused] = useState131(null);
48633
+ const [over, setOver] = useState131(null);
48548
48634
  if (entity.error) return /* @__PURE__ */ jsx156("p", { className: "px-1 py-3 text-xs text-muted-foreground", children: `This board could not be read: ${entity.error}` });
48549
48635
  if (!entity.loading && !column) {
48550
48636
  return /* @__PURE__ */ jsx156("p", { className: "px-1 py-3 text-xs text-muted-foreground", children: `${entity.label ?? "This table"} has no choice column to make a board of.` });
@@ -48612,8 +48698,8 @@ function EntityChartBlock({ source, kind, by, measure, title, where, organizatio
48612
48698
  const client = useRecordsClient97();
48613
48699
  const m = measure ?? { op: "count" };
48614
48700
  const ask = JSON.stringify([source.token, by ?? null, m, where ?? null, organization ?? null]);
48615
- const [block, setBlock] = useState130(null);
48616
- useEffect110(() => {
48701
+ const [block, setBlock] = useState131(null);
48702
+ useEffect111(() => {
48617
48703
  let cancelled = false;
48618
48704
  const question = {
48619
48705
  ...by ? { by: [by] } : {},
@@ -48676,20 +48762,20 @@ function EntityTablePageBody({
48676
48762
  actions,
48677
48763
  className
48678
48764
  }) {
48679
- const [typed2, setTyped] = useState130("");
48765
+ const [typed2, setTyped] = useState131("");
48680
48766
  const term = searchOverride ?? typed2;
48681
48767
  const entity = useEntityTable(source.token, { pageSize, search: term });
48682
- const [layout, setLayout] = useState130(opened);
48683
- useEffect110(() => setLayout(opened), [opened]);
48768
+ const [layout, setLayout] = useState131(opened);
48769
+ useEffect111(() => setLayout(opened), [opened]);
48684
48770
  const choose = (next) => {
48685
48771
  setLayout(next);
48686
48772
  onLayoutChange?.(next);
48687
48773
  };
48688
48774
  const boardable = entityChoiceColumns(entity.columns).length > 0;
48689
48775
  const nameColumn = entityNameColumn(entity.columns);
48690
- const [naming, setNaming] = useState130(null);
48691
- const [adding, setAdding] = useState130(false);
48692
- const [addRefused, setAddRefused] = useState130(null);
48776
+ const [naming, setNaming] = useState131(null);
48777
+ const [adding, setAdding] = useState131(false);
48778
+ const [addRefused, setAddRefused] = useState131(null);
48693
48779
  const add = async () => {
48694
48780
  const name = (naming ?? "").trim();
48695
48781
  if (!name || !nameColumn || adding) return;
@@ -48701,7 +48787,7 @@ function EntityTablePageBody({
48701
48787
  setNaming(null);
48702
48788
  onOpenRecord?.(made.id);
48703
48789
  };
48704
- const [question, setQuestion] = useState130(() => questionFromGrouping(void 0));
48790
+ const [question, setQuestion] = useState131(() => questionFromGrouping(void 0));
48705
48791
  const { config: drill } = useDrill({
48706
48792
  source,
48707
48793
  question,
@@ -48804,7 +48890,7 @@ function TablePage2(props) {
48804
48890
  }
48805
48891
 
48806
48892
  // src/DataBindingPicker.tsx
48807
- import { useEffect as useEffect111, useMemo as useMemo78 } from "react";
48893
+ import { useEffect as useEffect112, useMemo as useMemo78 } from "react";
48808
48894
  import { isEntityReferenceConfig } from "@ai-matrx/records";
48809
48895
  import { useFields as useFields37, useTable as useTable37 } from "@ai-matrx/records/react";
48810
48896
  import { BasicInput as BasicInput34, Button as Button107, CreatablePicker as CreatablePicker3, cn as cn96 } from "@ai-matrx/design-system";
@@ -48900,7 +48986,7 @@ function BindingDetails({
48900
48986
  const fields = useFields37(tableId);
48901
48987
  const fieldList = useMemo78(() => fields.data ?? [], [fields.data]);
48902
48988
  const shape = binding.semantic_type;
48903
- useEffect111(() => {
48989
+ useEffect112(() => {
48904
48990
  if (disabled || shape === "value" || binding.transform || fields.loading || fieldList.length === 0) return;
48905
48991
  onChange({
48906
48992
  ...binding,
@@ -49122,7 +49208,7 @@ function RecordNameWords({ tableId, recordId }) {
49122
49208
  }
49123
49209
 
49124
49210
  // src/HeldChangeDecision.tsx
49125
- import { useEffect as useEffect112, useState as useState131 } from "react";
49211
+ import { useEffect as useEffect113, useState as useState132 } from "react";
49126
49212
  import { RecordsProvider as RecordsProvider3, useRecordsClient as useRecordsClient98 } from "@ai-matrx/records/react";
49127
49213
  import { Button as Button108 } from "@ai-matrx/design-system";
49128
49214
  import { jsx as jsx160, jsxs as jsxs148 } from "react/jsx-runtime";
@@ -49131,10 +49217,10 @@ function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, on
49131
49217
  }
49132
49218
  function Decision({ approvalId, onDecided }) {
49133
49219
  const client = useRecordsClient98();
49134
- const [may, setMay] = useState131(null);
49135
- const [busy, setBusy] = useState131(null);
49136
- const [error, setError] = useState131(null);
49137
- useEffect112(() => {
49220
+ const [may, setMay] = useState132(null);
49221
+ const [busy, setBusy] = useState132(null);
49222
+ const [error, setError] = useState132(null);
49223
+ useEffect113(() => {
49138
49224
  let live = true;
49139
49225
  void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
49140
49226
  if (!live) return;
@@ -49167,7 +49253,7 @@ function Decision({ approvalId, onDecided }) {
49167
49253
  }
49168
49254
 
49169
49255
  // src/TemplatePreview.tsx
49170
- import { useEffect as useEffect113, useMemo as useMemo79, useState as useState132 } from "react";
49256
+ import { useEffect as useEffect114, useMemo as useMemo79, useState as useState133 } from "react";
49171
49257
  import { templatePreview } from "@ai-matrx/records/memory";
49172
49258
  import { useRecordsClient as useRecordsClient99 } from "@ai-matrx/records/react";
49173
49259
  import { jsx as jsx161, jsxs as jsxs149 } from "react/jsx-runtime";
@@ -49178,7 +49264,7 @@ function TemplatePreview({ spec, today, initialTable, host, aside, booking, clas
49178
49264
  const preview = useTemplatePreview(spec, today);
49179
49265
  const bound2 = useMemo79(() => ({ ...host, sayLevelNeeded: false }), [host]);
49180
49266
  const first = preview.tables.find((t) => t.token === initialTable) ?? preview.tables[0];
49181
- const [active, setActive] = useState132(first?.id ?? null);
49267
+ const [active, setActive] = useState133(first?.id ?? null);
49182
49268
  const table = preview.tables.find((t) => t.id === active) ?? first;
49183
49269
  if (!table) return null;
49184
49270
  return /* @__PURE__ */ jsxs149("div", { className: ["flex min-w-0 flex-col gap-3", className].filter(Boolean).join(" "), "data-template-preview": preview.tables.length, children: [
@@ -49216,9 +49302,9 @@ function TemplatePreview({ spec, today, initialTable, host, aside, booking, clas
49216
49302
  }
49217
49303
  function PreviewForms({ preview, booking }) {
49218
49304
  const client = useRecordsClient99();
49219
- const [forms, setForms] = useState132(null);
49220
- const [pages, setPages] = useState132([]);
49221
- useEffect113(() => {
49305
+ const [forms, setForms] = useState133(null);
49306
+ const [pages, setPages] = useState133([]);
49307
+ useEffect114(() => {
49222
49308
  let gone = false;
49223
49309
  void client.forms().then((answered) => {
49224
49310
  if (!gone) setForms(answered.ok ? answered.data.map(formFromSummary) : []);