@ai-matrx/records-ui 0.102.14 → 0.102.16

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,46 @@ 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__ */ jsx28("span", { "aria-hidden": "true", "data-records-cell-ghost": "", className: "pointer-events-none invisible block select-none truncate px-1 py-0.5", children: /* @__PURE__ */ jsx28(
7229
+ RecordValue,
7230
+ {
7231
+ inCell: true,
7232
+ field: field2,
7233
+ value: row.document?.[field2.key],
7234
+ document: row.document,
7235
+ recordId: row.id,
7236
+ withheld: withheldNoticeOf(row.hidden, field2.key),
7237
+ ...format ? { format } : {}
7238
+ }
7239
+ ) }),
7240
+ /* @__PURE__ */ jsx28(
7241
+ OpenCell,
7242
+ {
7243
+ field: field2,
7244
+ draft: editing.draft,
7245
+ initialSearch: editing.searchSeed,
7246
+ onType: editing.type,
7247
+ onCommit: (move, via) => editing.commit(move, via),
7248
+ onCancel: (via) => editing.cancel(via),
7249
+ below: (
7250
+ // KEPT EDITING: the refusal stays beside the value it is about, so the
7251
+ // person reads what to change while changing it. Keep editing is the
7252
+ // state they are in, so only Discard is offered. It is INSIDE the open
7253
+ // cell, so pressing Discard is not "focus left the cell" — which would
7254
+ // commit the refused value one more time on its way out.
7255
+ refusal4 && !refusal4.conflict ? /* @__PURE__ */ jsx28(
7256
+ RefusalNotice,
7257
+ {
7258
+ error: refusal4.error,
7259
+ className: "py-1.5 text-left",
7260
+ onDiscard: () => editing.discard(row.id, field2.key)
7261
+ }
7262
+ ) : null
7263
+ )
7264
+ }
7265
+ )
7266
+ ] });
7215
7267
  }
7216
7268
  if (editorKindFor(field2) === "checkbox") {
7217
7269
  const answered = value === true || value === false;
@@ -7561,8 +7613,9 @@ function OpenCell({
7561
7613
  "data-matrx-cell-editor": "",
7562
7614
  tabIndex: -1,
7563
7615
  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,
7616
+ // OVER the cell's ghost (see `data-records-open-cell`), never in the table's measuring.
7617
+ "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",
7618
+ FLOATING_CELL_NOTE_CLASS,
7566
7619
  // A field's own input is 36px (h-9); in a 35px row it grew the row 4px. In the cell it is
7567
7620
  // the row action strip's 32px, so opening a cell never changes the row (STABLE-TABLES).
7568
7621
  "[&_input:not([type=checkbox]):not([type=radio])]:h-8 [&_input:not([type=checkbox]):not([type=radio])]:py-0"
@@ -7621,11 +7674,13 @@ function OpenCell({
7621
7674
  addsChoices: true
7622
7675
  }
7623
7676
  ),
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
7677
+ /* @__PURE__ */ jsxs23("span", { "data-records-cell-tray": "", className: FLOATING_CELL_TRAY_CLASS, children: [
7678
+ 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: [
7679
+ /* @__PURE__ */ jsx28(Button10, { size: "sm", onClick: () => once(() => onCommit(null, "pick")), children: "Save" }),
7680
+ /* @__PURE__ */ jsx28(Button10, { size: "sm", variant: "ghost", onClick: () => once(() => onCancel("pick")), children: "Cancel" })
7681
+ ] }),
7682
+ below ? /* @__PURE__ */ jsx28("span", { className: "block bg-popover shadow-md", children: below }) : null
7683
+ ] })
7629
7684
  ]
7630
7685
  }
7631
7686
  );
@@ -7748,15 +7803,28 @@ function BodySkeleton({ layout, embedded, rows }) {
7748
7803
  /* @__PURE__ */ jsx29("div", { className: "flex h-9 items-center gap-6 border-b border-border px-3", children: Array.from({ length: 6 }, (_, i) => /* @__PURE__ */ jsx29(Skeleton2, { shape: "line", width: "sm", className: "w-16" }, i)) }),
7749
7804
  Array.from({ length: Math.min(lineCount, 8) }, (_, i) => /* @__PURE__ */ jsx29("div", { className: "flex h-10 items-center border-b border-border/60 px-3", children: /* @__PURE__ */ jsx29(Skeleton2, { className: "h-6 rounded-md", style: { marginLeft: `${i * 13 % 45}%`, width: `${20 + i * 7 % 25}%` } }) }, i))
7750
7805
  ] });
7751
- case "form":
7752
7806
  case "record":
7807
+ return /* @__PURE__ */ jsxs24("div", { className: "flex min-h-0 flex-1 flex-col gap-2 overflow-hidden", "data-records-skeleton-part": "body", children: [
7808
+ /* @__PURE__ */ jsx29(Skeleton2, { shape: "title", width: "1/2", className: "h-8", "data-records-skeleton-part": "title" }),
7809
+ /* @__PURE__ */ jsxs24("div", { className: "flex h-[38px] items-center gap-2", "data-records-skeleton-part": "actions", children: [
7810
+ /* @__PURE__ */ jsx29(Skeleton2, { shape: "control", width: "sm", className: "h-8" }),
7811
+ /* @__PURE__ */ jsx29(Skeleton2, { shape: "control", width: "sm", className: "h-8" })
7812
+ ] }),
7813
+ /* @__PURE__ */ jsx29("div", { className: "h-px w-full shrink-0 bg-border" }),
7814
+ /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-[minmax(6rem,12rem)_1fr] gap-x-3 gap-y-0.5", "data-records-skeleton-part": "fields", children: Array.from({ length: 6 }, (_, i) => /* @__PURE__ */ jsxs24("div", { className: "contents", children: [
7815
+ /* @__PURE__ */ jsx29(Skeleton2, { shape: "line", width: "2/3", className: "my-[7px]" }),
7816
+ /* @__PURE__ */ jsx29(Skeleton2, { shape: "row", className: "h-7" })
7817
+ ] }, i)) }),
7818
+ /* @__PURE__ */ jsx29(Skeleton2, { shape: "block", height: "lg" })
7819
+ ] });
7820
+ case "form":
7753
7821
  return /* @__PURE__ */ jsxs24("div", { className: "flex min-h-0 flex-1 flex-col gap-4 overflow-hidden", "data-records-skeleton-part": "body", children: [
7754
7822
  /* @__PURE__ */ jsx29(Skeleton2, { shape: "title", width: "1/2" }),
7755
7823
  /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-[minmax(6rem,12rem)_1fr] gap-x-3 gap-y-1.5", children: Array.from({ length: 6 }, (_, i) => /* @__PURE__ */ jsxs24("div", { className: "contents", children: [
7756
7824
  /* @__PURE__ */ jsx29(Skeleton2, { shape: "line", width: "2/3", className: "my-1.5" }),
7757
7825
  /* @__PURE__ */ jsx29(Skeleton2, { shape: "row", className: "h-7" })
7758
7826
  ] }, i)) }),
7759
- layout === "record" ? /* @__PURE__ */ jsx29(Skeleton2, { shape: "block", height: "lg" }) : /* @__PURE__ */ jsx29(Skeleton2, { shape: "control", width: "sm" })
7827
+ /* @__PURE__ */ jsx29(Skeleton2, { shape: "control", width: "sm" })
7760
7828
  ] });
7761
7829
  case "chart":
7762
7830
  return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-2", "data-records-skeleton-part": "body", children: [
@@ -10877,11 +10945,11 @@ function FieldEditor(props) {
10877
10945
  Checkbox6,
10878
10946
  {
10879
10947
  checked: required,
10880
- "aria-label": "Every record has to have one",
10948
+ "aria-label": "Required",
10881
10949
  onCheckedChange: (v) => setRequired(v === true)
10882
10950
  }
10883
10951
  ),
10884
- "Every record has to have one"
10952
+ /* @__PURE__ */ jsx40("span", { title: "Every record has to have one", children: "Required" })
10885
10953
  ] }),
10886
10954
  offersMany ? /* @__PURE__ */ jsxs35("label", { className: "flex items-center gap-1.5", children: [
10887
10955
  /* @__PURE__ */ jsx40(
@@ -14491,7 +14559,7 @@ function useMergedGridControls(args) {
14491
14559
  children: /* @__PURE__ */ jsxs47(DialogContent8, { className: "max-h-[85vh] overflow-y-auto sm:max-w-2xl", children: [
14492
14560
  /* @__PURE__ */ jsxs47(DialogHeader8, { children: [
14493
14561
  /* @__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 }),
14494
- /* @__PURE__ */ jsx52(DialogDescription6, { className: "sr-only", children: "The column\u2019s name, what it holds and how it looks." })
14562
+ /* @__PURE__ */ jsx52(DialogDescription6, { className: "sr-only", children: "Name, type and look" })
14495
14563
  ] }),
14496
14564
  dialog?.kind === "settings" ? /* @__PURE__ */ jsx52(
14497
14565
  FieldEditor,
@@ -19009,6 +19077,7 @@ function ImportWizard({ tableId, source, onDone, onWrote, className }) {
19009
19077
  // src/tableShape.ts
19010
19078
  import { codeSpanText as codeSpanText2, mapInlineCodeSpans } from "@ai-matrx/content-ir/source";
19011
19079
  import { humanizeIdentifier as humanizeIdentifier9 } from "@ai-matrx/kit/text-case";
19080
+ import { parseDelimited as readDelimited } from "@ai-matrx/kit/delimited";
19012
19081
  var FEWEST_LIST_ITEMS = 2;
19013
19082
  var FEWEST_KEY_VALUE_PAIRS = 2;
19014
19083
  var LONGEST_TEXT_READ = 2e6;
@@ -19186,38 +19255,7 @@ function shapeFromList(items, name, at) {
19186
19255
  };
19187
19256
  }
19188
19257
  function parseDelimited(text, delimiter) {
19189
- const rows = [];
19190
- let row = [];
19191
- let cell2 = "";
19192
- let quoted2 = false;
19193
- for (let i = 0; i < text.length; i += 1) {
19194
- const ch = text[i];
19195
- if (quoted2) {
19196
- if (ch === '"') {
19197
- if (text[i + 1] === '"') {
19198
- cell2 += '"';
19199
- i += 1;
19200
- } else quoted2 = false;
19201
- } else cell2 += ch;
19202
- continue;
19203
- }
19204
- if (ch === '"' && cell2.trim() === "") quoted2 = true;
19205
- else if (ch === delimiter) {
19206
- row.push(cell2);
19207
- cell2 = "";
19208
- } else if (ch === "\n" || ch === "\r") {
19209
- if (ch === "\r" && text[i + 1] === "\n") i += 1;
19210
- row.push(cell2);
19211
- rows.push(row);
19212
- row = [];
19213
- cell2 = "";
19214
- } else cell2 += ch;
19215
- }
19216
- if (cell2.length > 0 || row.length > 0) {
19217
- row.push(cell2);
19218
- rows.push(row);
19219
- }
19220
- return rows.filter((r) => r.some((c) => c.trim() !== ""));
19258
+ return readDelimited(text, { delimiter, skipEmptyLines: "greedy" }).data;
19221
19259
  }
19222
19260
  function delimitedShape(text, delimiter, fenced, at, name) {
19223
19261
  const matrix = parseDelimited(text.trim(), delimiter);
@@ -23191,7 +23229,7 @@ function GridBody({
23191
23229
  {
23192
23230
  ...fills ? { className: "min-h-0 flex-1" } : {},
23193
23231
  frameHeight: fills ? "fill" : "content",
23194
- loadingRows: fills ? "fill" : rememberedRowCount(rowMemoryKey, pageSize, 5),
23232
+ loadingRows: rememberedRowCount(rowMemoryKey, pageSize, fills ? "fill" : 5),
23195
23233
  ...!look.rowHeight ? { loadingRowHeight: RECORDS_GRID_ROW_PX } : {},
23196
23234
  data: rows,
23197
23235
  columns: tableColumns,
@@ -27169,7 +27207,7 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
27169
27207
  },
27170
27208
  variant: "destructive",
27171
27209
  title: `Move every row of \u201C${writable.find((t) => t.id === tableId)?.name ?? "this table"}\u201D to the archive?`,
27172
- description: "They stay restorable from the table's Archived items. Then the rows you are saving go in, through the import below.",
27210
+ description: "Restorable from Archived items",
27173
27211
  confirmLabel: replacing ? "Archiving\u2026" : "Archive them",
27174
27212
  cancelLabel: "Keep them",
27175
27213
  busy: replacing,
@@ -28683,18 +28721,25 @@ function RecordFieldsInPlace({
28683
28721
  const format = formatForField(field2);
28684
28722
  return /* @__PURE__ */ jsxs85("div", { className: "contents", children: [
28685
28723
  /* @__PURE__ */ jsx94("dt", { className: "flex items-baseline gap-1 truncate py-1 text-muted-foreground", children: renderLabel(field2) }),
28686
- /* @__PURE__ */ jsx94("dd", { className: "min-w-0 rounded hover:bg-muted/50", "data-records-in-place-field": field2.key, children: /* @__PURE__ */ jsx94(
28687
- GridCell,
28724
+ /* @__PURE__ */ jsx94(
28725
+ "dd",
28688
28726
  {
28689
- field: field2,
28690
- row,
28691
- editing: canWrite ? editing : null,
28692
- canWrite,
28693
- whyNot,
28694
- clickOpens: true,
28695
- ...format ? { format } : {}
28727
+ className: "min-w-0 rounded hover:bg-muted/50 [&_[data-matrx-cell-editor]_input:not([type=checkbox]):not([type=radio])]:!h-7",
28728
+ "data-records-in-place-field": field2.key,
28729
+ children: /* @__PURE__ */ jsx94(
28730
+ GridCell,
28731
+ {
28732
+ field: field2,
28733
+ row,
28734
+ editing: canWrite ? editing : null,
28735
+ canWrite,
28736
+ whyNot,
28737
+ clickOpens: true,
28738
+ ...format ? { format } : {}
28739
+ }
28740
+ )
28696
28741
  }
28697
- ) })
28742
+ )
28698
28743
  ] }, field2.id);
28699
28744
  }) }),
28700
28745
  /* @__PURE__ */ jsx94(UndoNotice, { undo })
@@ -28891,7 +28936,7 @@ function AddBody({ tableId }) {
28891
28936
  const made = await mutation.declare({ table_id: tableId, spec: { label: BODY_COLUMN_NAME, type: "rich_text" } });
28892
28937
  if (made) tableShapeChanged10(tableId);
28893
28938
  },
28894
- children: "Write on this page"
28939
+ children: "Add notes"
28895
28940
  }
28896
28941
  ),
28897
28942
  mutation.error ? /* @__PURE__ */ jsx96(RefusalNotice, { error: mutation.error }) : null
@@ -29036,7 +29081,7 @@ function computedInPlainWords(row, field2) {
29036
29081
  const shown4 = row.value === null || row.value === void 0 || row.value === "" ? "nothing" : field2 ? scalarText(field2, row.value) : String(row.value);
29037
29082
  const when = new Date(row.computed_at);
29038
29083
  const at = Number.isNaN(when.getTime()) ? "" : ` on ${when.toLocaleDateString()}`;
29039
- return `${name} was worked out as ${shown4}${at}.`;
29084
+ return `${name}: ${shown4}${at}`;
29040
29085
  }
29041
29086
 
29042
29087
  // src/systemTable.ts
@@ -29266,7 +29311,10 @@ async function keepLook(client, tableId, viewId, look) {
29266
29311
  return client.viewLookSet({ table_id: tableId, view_id: viewId, look: doc && Object.keys(doc).length > 0 ? doc : null });
29267
29312
  }
29268
29313
  var LOOK_WORDS = {
29314
+ /** The reason, for a tooltip or a screen reader — never a line on the page (interface-text). */
29269
29315
  yours: "You changed how this view looks. Only you see it.",
29316
+ /** The visible label for the same fact. */
29317
+ yoursLabel: "Only you see this",
29270
29318
  saveToView: "Save to view",
29271
29319
  saveAsNew: "Save as new view",
29272
29320
  reset: "Reset to view",
@@ -39001,7 +39049,7 @@ function WebhooksPanel({ tableId, className }) {
39001
39049
  if (!next && !busy) setStopping(null);
39002
39050
  },
39003
39051
  title: `Stop sending to ${stopping?.description ?? stopping?.target_url ?? "this address"}?`,
39004
- description: "Changes from now on are not sent there. The webhook is kept, switched off \u2014 nothing about it is deleted.",
39052
+ description: "Kept, switched off",
39005
39053
  confirmLabel: "Switch off",
39006
39054
  cancelLabel: "Keep sending",
39007
39055
  busy,
@@ -41484,6 +41532,39 @@ function useLinkGroupNamer(block, tableId) {
41484
41532
  }, [named, choices, labels]);
41485
41533
  }
41486
41534
 
41535
+ // src/measureWords.ts
41536
+ import { useEffect as useEffect97, useState as useState111 } from "react";
41537
+ import { useOptionalRecordsClient as useOptionalRecordsClient13 } from "@ai-matrx/records/react";
41538
+ import { humanizeIdentifier as humanizeIdentifier18 } from "@ai-matrx/kit/text-case";
41539
+ var OP_WORD = { sum: "Total", avg: "Average", min: "Lowest", max: "Highest" };
41540
+ function measureWords(key, fields) {
41541
+ if (key === "count") return "How many";
41542
+ const at = key.indexOf("_");
41543
+ if (at < 0) return humanizeIdentifier18(key);
41544
+ const op2 = key.slice(0, at);
41545
+ const column = key.slice(at + 1);
41546
+ const field2 = fields?.find((f) => f.key === column);
41547
+ const name = field2 ? fieldName(field2) : humanizeIdentifier18(column);
41548
+ const word = OP_WORD[op2];
41549
+ return word ? `${word} ${name.charAt(0).toLowerCase()}${name.slice(1)}` : `${humanizeIdentifier18(op2)} ${name}`;
41550
+ }
41551
+ function useMeasureWords(key, tableId) {
41552
+ const client = useOptionalRecordsClient13();
41553
+ const [fields, setFields] = useState111(null);
41554
+ const needs = key !== "count";
41555
+ useEffect97(() => {
41556
+ if (!client || !tableId || !needs) return;
41557
+ let cancelled = false;
41558
+ void client.fields({ table_id: tableId }).then((result) => {
41559
+ if (!cancelled && result.ok) setFields(result.data);
41560
+ });
41561
+ return () => {
41562
+ cancelled = true;
41563
+ };
41564
+ }, [client, tableId, needs]);
41565
+ return measureWords(key, fields);
41566
+ }
41567
+
41487
41568
  // src/ChartBlock.tsx
41488
41569
  import { Fragment as Fragment52, jsx as jsx134, jsxs as jsxs124 } from "react/jsx-runtime";
41489
41570
  var priorKey = (key) => `prior__${key}`;
@@ -41562,6 +41643,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41562
41643
  const series = compared ? [primary, priorKey(primary)] : [primary];
41563
41644
  const target = kind === "stuck" ? null : block.target ?? null;
41564
41645
  const named = useLinkGroupNamer(source ? NO_GROUPS : block, tableId);
41646
+ const measureName = useMeasureWords(primary, tableId);
41565
41647
  const points = useMemo66(() => {
41566
41648
  if (kind === "stuck") return [];
41567
41649
  const rows = block.rows ?? [];
@@ -41589,7 +41671,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41589
41671
  const config = useMemo66(() => {
41590
41672
  const out = {};
41591
41673
  out[primary] = {
41592
- label: windows ? windowName(windows.window, windows.period) : primary.replace("_", " of "),
41674
+ label: windows ? windowName(windows.window, windows.period) : measureName,
41593
41675
  color: SERIES_COLORS[0]
41594
41676
  };
41595
41677
  if (windows) {
@@ -41602,7 +41684,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41602
41684
  out[point.label] ??= { label: point.label, color: SERIES_COLORS[index % SERIES_COLORS.length] };
41603
41685
  });
41604
41686
  return out;
41605
- }, [primary, windows, points]);
41687
+ }, [primary, measureName, windows, points]);
41606
41688
  const goal = target && typeof target.value === "number" ? {
41607
41689
  value: typeof target.pace === "number" ? target.pace : block.bucket ? null : target.value,
41608
41690
  label: typeof target.pace === "number" && target.per !== "bucket" ? `${target.label} pace` : target.label
@@ -41647,7 +41729,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41647
41729
  /* @__PURE__ */ jsx134("span", { children: pretty(block.totals.current) }),
41648
41730
  /* @__PURE__ */ jsx134(Trend, { pct: block.totals.change_pct, aimingUp: !!target })
41649
41731
  ] }) : null,
41650
- /* @__PURE__ */ jsx134("span", { className: "ml-auto shrink-0 text-muted-foreground", children: kind === "stuck" ? `${block.days ?? 14} days` : primary.replace("_", " of ") })
41732
+ /* @__PURE__ */ jsx134("span", { className: "ml-auto shrink-0 text-muted-foreground", children: kind === "stuck" ? `${block.days ?? 14} days` : measureName })
41651
41733
  ] }),
41652
41734
  block.compare_refused ? /* @__PURE__ */ jsx134("p", { className: "px-1 text-xs text-muted-foreground", children: block.compare_refused }) : null,
41653
41735
  !block.refused && targetNote(target) ? /* @__PURE__ */ jsx134("p", { className: "px-1 text-xs text-muted-foreground", children: targetNote(target) }) : null,
@@ -41944,7 +42026,7 @@ function onlyWholeNumbers(rows) {
41944
42026
  }
41945
42027
 
41946
42028
  // src/DashboardCanvas.tsx
41947
- import { useCallback as useCallback58, useEffect as useEffect98, useMemo as useMemo69, useState as useState113 } from "react";
42029
+ import { useCallback as useCallback58, useEffect as useEffect99, useMemo as useMemo69, useState as useState114 } from "react";
41948
42030
  import { useFields as useFields29, useRecordsClient as useRecordsClient85, useTable as useTable31 } from "@ai-matrx/records/react";
41949
42031
  import {
41950
42032
  BasicInput as BasicInput30,
@@ -42112,7 +42194,7 @@ function GridCell2({
42112
42194
  }
42113
42195
 
42114
42196
  // src/AddChart.tsx
42115
- import { useMemo as useMemo68, useState as useState112 } from "react";
42197
+ import { useMemo as useMemo68, useState as useState113 } from "react";
42116
42198
  import { useFields as useFields28, useRecordsClient as useRecordsClient84 } from "@ai-matrx/records/react";
42117
42199
  import {
42118
42200
  Button as Button90,
@@ -42124,7 +42206,7 @@ import {
42124
42206
  } from "@ai-matrx/design-system";
42125
42207
 
42126
42208
  // src/TablePickers.tsx
42127
- import { useEffect as useEffect97, useMemo as useMemo67, useState as useState111 } from "react";
42209
+ import { useEffect as useEffect98, useMemo as useMemo67, useState as useState112 } from "react";
42128
42210
  import { RecordsProvider as RecordsProvider2, useFields as useFields27, useRecords as useRecords7, useTable as useTable30 } from "@ai-matrx/records/react";
42129
42211
  import { Button as Button89, CreatablePicker as CreatablePicker2 } from "@ai-matrx/design-system";
42130
42212
 
@@ -42242,8 +42324,8 @@ function readTablesAnywhere(dataSource) {
42242
42324
  return read;
42243
42325
  }
42244
42326
  function useTablesAnywhere(dataSource) {
42245
- const [state, setState] = useState111({ loading: true, error: null, rows: [] });
42246
- useEffect97(() => {
42327
+ const [state, setState] = useState112({ loading: true, error: null, rows: [] });
42328
+ useEffect98(() => {
42247
42329
  let live = true;
42248
42330
  void readTablesAnywhere(dataSource).then((result) => {
42249
42331
  if (live) setState(result);
@@ -42320,7 +42402,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
42320
42402
  const all = useMemo67(() => fields.data ?? [], [fields.data]);
42321
42403
  const byKey = useMemo67(() => new Map(all.map((f) => [f.key, f])), [all]);
42322
42404
  const keys = Object.keys(value);
42323
- const [adding, setAdding] = useState111(false);
42405
+ const [adding, setAdding] = useState112(false);
42324
42406
  const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
42325
42407
  const rename = (from, to) => {
42326
42408
  if (from === to) return;
@@ -42476,7 +42558,7 @@ function chartSpecFrom(args) {
42476
42558
  }
42477
42559
  function AddChart({ subject, onAdd, onClose }) {
42478
42560
  const client = useRecordsClient84();
42479
- const [tableId, setTableId] = useState112(subject);
42561
+ const [tableId, setTableId] = useState113(subject);
42480
42562
  const fields = useFields28(tableId);
42481
42563
  const all = useMemo68(() => onePerKey(fields.data ?? []), [fields.data]);
42482
42564
  const labels = useRecordLabels(all);
@@ -42484,11 +42566,11 @@ function AddChart({ subject, onAdd, onClose }) {
42484
42566
  const field2 = all.find((f) => f.key === key);
42485
42567
  return field2 ? scalarText(field2, value, labels) : String(value);
42486
42568
  };
42487
- const [measureKey5, setMeasureKey] = useState112("count");
42488
- const [splitKey, setSplitKey] = useState112("none");
42489
- const [kind, setKind] = useState112("auto");
42490
- const [filter, setFilter] = useState112({});
42491
- const [saving, setSaving] = useState112(false);
42569
+ const [measureKey5, setMeasureKey] = useState113("count");
42570
+ const [splitKey, setSplitKey] = useState113("none");
42571
+ const [kind, setKind] = useState113("auto");
42572
+ const [filter, setFilter] = useState113({});
42573
+ const [saving, setSaving] = useState113(false);
42492
42574
  const numbers = numberColumns(all);
42493
42575
  const choices = offerableFields(all, "choice");
42494
42576
  const dates = offerableFields(all, "date");
@@ -42635,20 +42717,20 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42635
42717
  const table = useTable31(tableId);
42636
42718
  const rights = useTableRights(table.data);
42637
42719
  const fields = useFields29(tableId);
42638
- const [boards, setBoards] = useState113(null);
42639
- const [pages, setPages] = useState113([]);
42640
- const [error, setError] = useState113(null);
42641
- const [activeId, setActiveId] = useState113(activeDashboardId ?? null);
42642
- const [madeOnMount, setMadeOnMount] = useState113("waiting");
42643
- const [askingToRemove, setAskingToRemove] = useState113(null);
42644
- const [run, setRun] = useState113(null);
42645
- const [running, setRunning] = useState113(false);
42646
- const [question, setQuestion] = useState113("");
42647
- const [asking, setAsking] = useState113(false);
42648
- const [scheduling, setScheduling] = useState113(false);
42649
- const [arranging, setArranging] = useState113(false);
42650
- const [adding, setAdding] = useState113(false);
42651
- const [grain, setGrain] = useState113(null);
42720
+ const [boards, setBoards] = useState114(null);
42721
+ const [pages, setPages] = useState114([]);
42722
+ const [error, setError] = useState114(null);
42723
+ const [activeId, setActiveId] = useState114(activeDashboardId ?? null);
42724
+ const [madeOnMount, setMadeOnMount] = useState114("waiting");
42725
+ const [askingToRemove, setAskingToRemove] = useState114(null);
42726
+ const [run, setRun] = useState114(null);
42727
+ const [running, setRunning] = useState114(false);
42728
+ const [question, setQuestion] = useState114("");
42729
+ const [asking, setAsking] = useState114(false);
42730
+ const [scheduling, setScheduling] = useState114(false);
42731
+ const [arranging, setArranging] = useState114(false);
42732
+ const [adding, setAdding] = useState114(false);
42733
+ const [grain, setGrain] = useState114(null);
42652
42734
  const runArgs = (dashboard_id) => ({
42653
42735
  dashboard_id,
42654
42736
  ...filter ? { filter } : {},
@@ -42666,11 +42748,11 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42666
42748
  setBoards(read);
42667
42749
  return read;
42668
42750
  }, [client, tableId]);
42669
- const [notKept, setNotKept] = useState113(null);
42670
- useEffect98(() => {
42751
+ const [notKept, setNotKept] = useState114(null);
42752
+ useEffect99(() => {
42671
42753
  void load();
42672
42754
  }, [load]);
42673
- useEffect98(() => {
42755
+ useEffect99(() => {
42674
42756
  if (!boards || boards.length === 0) return;
42675
42757
  if (createOnMount && madeOnMount !== "done") return;
42676
42758
  const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
@@ -42678,7 +42760,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42678
42760
  }, [boards, activeDashboardId, madeOnMount]);
42679
42761
  const board = useMemo69(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
42680
42762
  const filterKey = JSON.stringify(filter ?? {});
42681
- useEffect98(() => {
42763
+ useEffect99(() => {
42682
42764
  if (!activeId) {
42683
42765
  setRun(null);
42684
42766
  return;
@@ -42748,7 +42830,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42748
42830
  ]
42749
42831
  );
42750
42832
  }
42751
- useEffect98(() => {
42833
+ useEffect99(() => {
42752
42834
  if (!createOnMount || madeOnMount !== "waiting" || boards === null || !fields.data) return;
42753
42835
  setMadeOnMount("making");
42754
42836
  void create().then(() => setMadeOnMount("done"));
@@ -43193,10 +43275,10 @@ function TargetControl({
43193
43275
  onChange
43194
43276
  }) {
43195
43277
  const saved = !block.target ? "none" : "field" in block.target && block.target.field ? "field" : "value";
43196
- const [mode, setMode] = useState113(saved);
43278
+ const [mode, setMode] = useState114(saved);
43197
43279
  const savedValue = block.target && "value" in block.target && typeof block.target.value === "number" ? block.target.value : null;
43198
- const [draft, setDraft] = useState113(savedValue === null ? "" : String(savedValue));
43199
- useEffect98(() => {
43280
+ const [draft, setDraft] = useState114(savedValue === null ? "" : String(savedValue));
43281
+ useEffect99(() => {
43200
43282
  setMode(saved);
43201
43283
  setDraft(savedValue === null ? "" : String(savedValue));
43202
43284
  }, [saved, savedValue]);
@@ -43264,7 +43346,7 @@ function TargetControl({
43264
43346
 
43265
43347
  // src/QuestionPanel.tsx
43266
43348
  import { copyText as copyText8 } from "@ai-matrx/kit/clipboard";
43267
- import { useEffect as useEffect99, useMemo as useMemo70, useRef as useRef54, useState as useState114 } from "react";
43349
+ import { useEffect as useEffect100, useMemo as useMemo70, useRef as useRef54, useState as useState115 } from "react";
43268
43350
  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";
43269
43351
  import { useFields as useFields30, useRecordsClient as useRecordsClient86 } from "@ai-matrx/records/react";
43270
43352
 
@@ -43681,9 +43763,9 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43681
43763
  const fields = useFields30(tableId);
43682
43764
  const all = useMemo70(() => fields.data ?? [], [fields.data]);
43683
43765
  const me = client.config.actor?.user_id ?? null;
43684
- const [hidden, setHidden] = useState114(null);
43685
- const [related, setRelated] = useState114({});
43686
- useEffect99(() => {
43766
+ const [hidden, setHidden] = useState115(null);
43767
+ const [related, setRelated] = useState115({});
43768
+ useEffect100(() => {
43687
43769
  if (all.length === 0) {
43688
43770
  if (!fields.loading) setHidden(/* @__PURE__ */ new Set());
43689
43771
  return;
@@ -43707,17 +43789,17 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43707
43789
  };
43708
43790
  }, [client, tableId, all, fields.loading]);
43709
43791
  const offered = useMemo70(() => hidden ? all.filter((f) => !hidden.has(f.key)) : [], [all, hidden]);
43710
- const [saved, setSaved] = useState114(null);
43711
- const [savedEpoch, setSavedEpoch] = useState114(0);
43712
- const [current, setCurrent] = useState114(null);
43713
- const [spec, setSpec] = useState114(newQuestion);
43714
- const [name, setName] = useState114("");
43715
- const [shared, setShared] = useState114(true);
43716
- const [saveError, setSaveError] = useState114(null);
43717
- const [saving, setSaving] = useState114(false);
43718
- const [linkMissed, setLinkMissed] = useState114(false);
43792
+ const [saved, setSaved] = useState115(null);
43793
+ const [savedEpoch, setSavedEpoch] = useState115(0);
43794
+ const [current, setCurrent] = useState115(null);
43795
+ const [spec, setSpec] = useState115(newQuestion);
43796
+ const [name, setName] = useState115("");
43797
+ const [shared, setShared] = useState115(true);
43798
+ const [saveError, setSaveError] = useState115(null);
43799
+ const [saving, setSaving] = useState115(false);
43800
+ const [linkMissed, setLinkMissed] = useState115(false);
43719
43801
  const openedFromLink = useRef54(false);
43720
- useEffect99(() => {
43802
+ useEffect100(() => {
43721
43803
  let live = true;
43722
43804
  void questionsOf(client, tableId).then((answer2) => {
43723
43805
  if (!live) return;
@@ -43740,16 +43822,16 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43740
43822
  setShared(q ? q.shared : true);
43741
43823
  setSaveError(null);
43742
43824
  };
43743
- useEffect99(() => {
43825
+ useEffect100(() => {
43744
43826
  if (!draft) return;
43745
43827
  open(null);
43746
43828
  setSpec(draft);
43747
43829
  }, [draft]);
43748
43830
  const mine = !current || me !== null && current.createdBy === me;
43749
- const [answer, setAnswer] = useState114(null);
43750
- const [asking, setAsking] = useState114(false);
43831
+ const [answer, setAnswer] = useState115(null);
43832
+ const [asking, setAsking] = useState115(false);
43751
43833
  const specKey = JSON.stringify(spec);
43752
- useEffect99(() => {
43834
+ useEffect100(() => {
43753
43835
  if (all.length === 0) return;
43754
43836
  let live = true;
43755
43837
  setAsking(true);
@@ -44191,7 +44273,7 @@ function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATE
44191
44273
  }
44192
44274
 
44193
44275
  // src/TableAsk.tsx
44194
- import { useState as useState115 } from "react";
44276
+ import { useState as useState116 } from "react";
44195
44277
  import { BasicInput as BasicInput32, Button as Button93, Popover as Popover12, PopoverContent as PopoverContent12, PopoverTrigger as PopoverTrigger12, Skeleton as Skeleton35 } from "@ai-matrx/design-system";
44196
44278
  import { optionLabel as optionLabel4 } from "@ai-matrx/records";
44197
44279
  import { useFields as useFields31, useRecordsClient as useRecordsClient87 } from "@ai-matrx/records/react";
@@ -44414,9 +44496,9 @@ function TableAsk({ tableId, onOpenInQuestions }) {
44414
44496
  const client = useRecordsClient87();
44415
44497
  const fields = useFields31(tableId);
44416
44498
  const all = fields.data ?? [];
44417
- const [open, setOpen] = useState115(false);
44418
- const [words2, setWords] = useState115("");
44419
- const [said, setSaid] = useState115({ kind: "idle" });
44499
+ const [open, setOpen] = useState116(false);
44500
+ const [words2, setWords] = useState116("");
44501
+ const [said, setSaid] = useState116({ kind: "idle" });
44420
44502
  const ask = async () => {
44421
44503
  if (words2.trim() === "" || all.length === 0) return;
44422
44504
  const choices = {};
@@ -44489,7 +44571,7 @@ function TableAsk({ tableId, onOpenInQuestions }) {
44489
44571
  }
44490
44572
 
44491
44573
  // src/PageScreen.tsx
44492
- import { useCallback as useCallback59, useEffect as useEffect100, useMemo as useMemo71, useState as useState116 } from "react";
44574
+ import { useCallback as useCallback59, useEffect as useEffect101, useMemo as useMemo71, useState as useState117 } from "react";
44493
44575
  import {
44494
44576
  useFields as useFields32,
44495
44577
  useRecordPage as useRecordPage3,
@@ -44514,18 +44596,18 @@ function PageScreen({
44514
44596
  const client = useRecordsClient88();
44515
44597
  const host = useRecordsUi();
44516
44598
  const organizationId = client.config.organizationId;
44517
- const [page, setPage] = useState116(null);
44518
- const [missing, setMissing] = useState116(false);
44519
- const [error, setError] = useState116(null);
44520
- const [level, setLevel] = useState116(null);
44521
- const [editing, setEditing] = useState116(startEditing);
44522
- const [run, setRun] = useState116(null);
44523
- const [saveError, setSaveError] = useState116(null);
44524
- const [askingToArchive, setAskingToArchive] = useState116(false);
44525
- const [selected, setSelected] = useState116({});
44526
- const [filterValues, setFilterValues] = useState116({});
44527
- const [mine, setMine] = useState116({});
44528
- const [making, setMaking] = useState116("waiting");
44599
+ const [page, setPage] = useState117(null);
44600
+ const [missing, setMissing] = useState117(false);
44601
+ const [error, setError] = useState117(null);
44602
+ const [level, setLevel] = useState117(null);
44603
+ const [editing, setEditing] = useState117(startEditing);
44604
+ const [run, setRun] = useState117(null);
44605
+ const [saveError, setSaveError] = useState117(null);
44606
+ const [askingToArchive, setAskingToArchive] = useState117(false);
44607
+ const [selected, setSelected] = useState117({});
44608
+ const [filterValues, setFilterValues] = useState117({});
44609
+ const [mine, setMine] = useState117({});
44610
+ const [making, setMaking] = useState117("waiting");
44529
44611
  const id = page?.id ?? pageId ?? null;
44530
44612
  const load = useCallback59(
44531
44613
  async (want) => {
@@ -44546,7 +44628,7 @@ function PageScreen({
44546
44628
  },
44547
44629
  [client]
44548
44630
  );
44549
- useEffect100(() => {
44631
+ useEffect101(() => {
44550
44632
  if (!newOnTable || pageId || making !== "waiting") return;
44551
44633
  setMaking("making");
44552
44634
  void client.dashboardDeclare({
@@ -44566,11 +44648,11 @@ function PageScreen({
44566
44648
  onCreated?.(made.data);
44567
44649
  });
44568
44650
  }, [client, newOnTable, pageId, making, load, onCreated]);
44569
- useEffect100(() => {
44651
+ useEffect101(() => {
44570
44652
  if (!pageId) return;
44571
44653
  void load(pageId);
44572
44654
  }, [pageId, load]);
44573
- useEffect100(() => {
44655
+ useEffect101(() => {
44574
44656
  if (!id) return;
44575
44657
  let live = true;
44576
44658
  void client.myLevels({ ids: [id], subject: "record" }).then((answered) => {
@@ -44582,7 +44664,7 @@ function PageScreen({
44582
44664
  }, [client, id]);
44583
44665
  const canEdit = level !== null && EDIT_LEVELS.has(level);
44584
44666
  const chartKey = page ? JSON.stringify(page.blocks.map((b) => b.id)) + page.version : "";
44585
- useEffect100(() => {
44667
+ useEffect101(() => {
44586
44668
  if (!page || page.blocks.length === 0) {
44587
44669
  setRun(null);
44588
44670
  return;
@@ -44827,8 +44909,8 @@ function AppletBlockView({ block }) {
44827
44909
  }
44828
44910
  function AppletPick({ value, onChange }) {
44829
44911
  const host = useRecordsUi();
44830
- const [options, setOptions] = useState116(null);
44831
- useEffect100(() => {
44912
+ const [options, setOptions] = useState117(null);
44913
+ useEffect101(() => {
44832
44914
  let live = true;
44833
44915
  host.applets?.list().then((apps) => live && setOptions(apps.map((a) => ({ value: a.id, label: a.name })))).catch(() => live && setOptions([]));
44834
44916
  return () => {
@@ -44864,8 +44946,8 @@ function ListBlockView({
44864
44946
  const table = useTable32(block.table_id);
44865
44947
  const fields = useFields32(block.table_id);
44866
44948
  const all = useMemo71(() => onePerKey3(fields.data ?? []), [fields.data]);
44867
- const [view, setView] = useState116(block.view_id ? "reading" : null);
44868
- useEffect100(() => {
44949
+ const [view, setView] = useState117(block.view_id ? "reading" : null);
44950
+ useEffect101(() => {
44869
44951
  if (!block.view_id) {
44870
44952
  setView(null);
44871
44953
  return;
@@ -44882,8 +44964,8 @@ function ListBlockView({
44882
44964
  };
44883
44965
  }, [client, block.table_id, block.view_id]);
44884
44966
  const meField = block.me_field ? all.find((f) => f.key === block.me_field) : void 0;
44885
- const [me, setMe] = useState116(null);
44886
- useEffect100(() => {
44967
+ const [me, setMe] = useState117(null);
44968
+ useEffect101(() => {
44887
44969
  if (!mine || !meField?.relation_target || !viewerUserId) {
44888
44970
  setMe(null);
44889
44971
  return;
@@ -44913,12 +44995,12 @@ function ListBlockView({
44913
44995
  ...sort.length > 0 ? { sort } : {}
44914
44996
  });
44915
44997
  const reload = page.reload;
44916
- useEffect100(() => onRecordChanged(() => reload()), [reload]);
44998
+ useEffect101(() => onRecordChanged(() => reload()), [reload]);
44917
44999
  const rows = nobodyIsMe ? [] : page.data?.rows ?? [];
44918
45000
  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);
44919
45001
  const firstId = rows[0]?.id ?? null;
44920
45002
  const stillThere = selected !== null && rows.some((r) => r.id === selected);
44921
- useEffect100(() => {
45003
+ useEffect101(() => {
44922
45004
  if (page.loading || waiting) return;
44923
45005
  if (!stillThere) onSelect(firstId);
44924
45006
  }, [firstId, stillThere, page.loading, waiting]);
@@ -44981,11 +45063,11 @@ function ActionButton2({ block, recordId }) {
44981
45063
  const client = useRecordsClient88();
44982
45064
  const actionsRead = useRowActions2(block.action_id ? block.table_id : null);
44983
45065
  const action3 = !block.action_id ? null : actionsRead.data ? actionsRead.data.actions.find((a) => a.id === block.action_id) ?? null : actionsRead.loading ? "reading" : null;
44984
- const [asking, setAsking] = useState116(false);
44985
- const [running, setRunning] = useState116(false);
44986
- const [done, setDone] = useState116(null);
44987
- const [error, setError] = useState116(null);
44988
- useEffect100(() => {
45066
+ const [asking, setAsking] = useState117(false);
45067
+ const [running, setRunning] = useState117(false);
45068
+ const [done, setDone] = useState117(null);
45069
+ const [error, setError] = useState117(null);
45070
+ useEffect101(() => {
44989
45071
  setDone(null);
44990
45072
  setError(null);
44991
45073
  setAsking(false);
@@ -45024,9 +45106,9 @@ function ActionButton2({ block, recordId }) {
45024
45106
  }
45025
45107
  function FormBlockView({ block }) {
45026
45108
  const client = useRecordsClient88();
45027
- const [form, setForm] = useState116("reading");
45028
- const [sent, setSent] = useState116(0);
45029
- useEffect100(() => {
45109
+ const [form, setForm] = useState117("reading");
45110
+ const [sent, setSent] = useState117(0);
45111
+ useEffect101(() => {
45030
45112
  if (!block.form_id) {
45031
45113
  setForm(null);
45032
45114
  return;
@@ -45151,10 +45233,10 @@ function FieldPick({
45151
45233
  }
45152
45234
  function ListSettings({ block, onChange }) {
45153
45235
  const client = useRecordsClient88();
45154
- const [views, setViews] = useState116([]);
45236
+ const [views, setViews] = useState117([]);
45155
45237
  const fields = useFields32(block.table_id);
45156
45238
  const all = onePerKey3(fields.data ?? []);
45157
- useEffect100(() => {
45239
+ useEffect101(() => {
45158
45240
  let live = true;
45159
45241
  void client.views({ table_id: block.table_id }).then((answered) => {
45160
45242
  if (live) setViews(answered.ok ? answered.data : []);
@@ -45230,8 +45312,8 @@ function ActionPicker({ tableId, value, onChange }) {
45230
45312
  }
45231
45313
  function FormPicker({ tableId, value, onChange }) {
45232
45314
  const client = useRecordsClient88();
45233
- const [forms, setForms] = useState116([]);
45234
- useEffect100(() => {
45315
+ const [forms, setForms] = useState117([]);
45316
+ useEffect101(() => {
45235
45317
  let live = true;
45236
45318
  void client.forms({ table_id: tableId }).then((answered) => {
45237
45319
  if (live) setForms(answered.ok ? answered.data : []);
@@ -45277,7 +45359,7 @@ function onePerKey3(all) {
45277
45359
 
45278
45360
  // src/FormsPanel.tsx
45279
45361
  import { copyText as copyText9 } from "@ai-matrx/kit/clipboard";
45280
- import { useCallback as useCallback60, useEffect as useEffect101, useState as useState117 } from "react";
45362
+ import { useCallback as useCallback60, useEffect as useEffect102, useState as useState118 } from "react";
45281
45363
  import { useRecordsClient as useRecordsClient89, useTable as useTable33 } from "@ai-matrx/records/react";
45282
45364
  import { publicFormPath as publicFormPath2 } from "@ai-matrx/records";
45283
45365
  import { Badge as Badge24, Button as Button95, Skeleton as Skeleton37, cn as cn86 } from "@ai-matrx/design-system";
@@ -45294,15 +45376,15 @@ function FormsPanel({ tableId, activeFormId, className }) {
45294
45376
  const host = useRecordsUi();
45295
45377
  const table = useTable33(tableId);
45296
45378
  const rights = useTableRights(table.data);
45297
- const [forms, setForms] = useState117(null);
45298
- const [error, setError] = useState117(null);
45299
- const [busy, setBusy] = useState117(null);
45300
- const [copied, setCopied] = useState117(null);
45301
- const [building, setBuilding] = useState117(false);
45302
- const [archivedSaid, setArchivedSaid] = useState117(null);
45379
+ const [forms, setForms] = useState118(null);
45380
+ const [error, setError] = useState118(null);
45381
+ const [busy, setBusy] = useState118(null);
45382
+ const [copied, setCopied] = useState118(null);
45383
+ const [building, setBuilding] = useState118(false);
45384
+ const [archivedSaid, setArchivedSaid] = useState118(null);
45303
45385
  const linked = activeFormId && forms !== null ? forms.find((f) => f.form_id === activeFormId) ?? null : null;
45304
45386
  const linkedMissing = Boolean(activeFormId) && forms !== null && linked === null;
45305
- useEffect101(() => {
45387
+ useEffect102(() => {
45306
45388
  if (linked && rights.structure) setBuilding(true);
45307
45389
  }, [linked, rights.structure]);
45308
45390
  const load = useCallback60(async () => {
@@ -45315,7 +45397,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
45315
45397
  setError(null);
45316
45398
  setForms(answered.data);
45317
45399
  }, [client, tableId]);
45318
- useEffect101(() => {
45400
+ useEffect102(() => {
45319
45401
  void load();
45320
45402
  }, [load]);
45321
45403
  const toggle = useCallback60(
@@ -45332,7 +45414,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
45332
45414
  },
45333
45415
  [client, load]
45334
45416
  );
45335
- const [shown4, setShown] = useState117(null);
45417
+ const [shown4, setShown] = useState118(null);
45336
45418
  const copy = useCallback60(async (url, formId) => {
45337
45419
  if (await copyText9(url)) {
45338
45420
  setCopied(formId);
@@ -45460,12 +45542,12 @@ function FormsPanel({ tableId, activeFormId, className }) {
45460
45542
  }
45461
45543
 
45462
45544
  // src/CaptureSheet.tsx
45463
- import { useCallback as useCallback62, useEffect as useEffect103, useRef as useRef56, useState as useState119 } from "react";
45545
+ import { useCallback as useCallback62, useEffect as useEffect104, useRef as useRef56, useState as useState120 } from "react";
45464
45546
  import { useFields as useFields33, useRecordsClient as useRecordsClient91, useTable as useTable34 } from "@ai-matrx/records/react";
45465
45547
  import { Button as Button97, Input as Input8, Skeleton as Skeleton39, Textarea as Textarea7, cn as cn88 } from "@ai-matrx/design-system";
45466
45548
 
45467
45549
  // src/CaptureRun.tsx
45468
- import { useCallback as useCallback61, useEffect as useEffect102, useMemo as useMemo72, useRef as useRef55, useState as useState118 } from "react";
45550
+ import { useCallback as useCallback61, useEffect as useEffect103, useMemo as useMemo72, useRef as useRef55, useState as useState119 } from "react";
45469
45551
  import {
45470
45552
  coerceTypedAnswer as coerceTypedAnswer3,
45471
45553
  coercionLabel,
@@ -45512,19 +45594,19 @@ function whereWeAre(timeoutMs = 4e3) {
45512
45594
  function CaptureRun({ sheetId, face: given, className }) {
45513
45595
  const client = useRecordsClient90();
45514
45596
  const host = useRecordsUi();
45515
- const [face, setFace] = useState118(given);
45516
- const [loadFailed, setLoadFailed] = useState118(null);
45517
- const [at, setAt] = useState118(0);
45518
- const [answers, setAnswers] = useState118({});
45519
- const [files, setFiles] = useState118({});
45520
- const [missing, setMissing] = useState118(null);
45521
- const [done, setDone] = useState118(null);
45522
- const [counts, setCounts] = useState118({ waiting: 0, sending: 0, refused: 0, landed: 0 });
45523
- const [items, setItems] = useState118([]);
45524
- const [lastSynced, setLastSynced] = useState118(null);
45525
- const [sending, setSending] = useState118(false);
45597
+ const [face, setFace] = useState119(given);
45598
+ const [loadFailed, setLoadFailed] = useState119(null);
45599
+ const [at, setAt] = useState119(0);
45600
+ const [answers, setAnswers] = useState119({});
45601
+ const [files, setFiles] = useState119({});
45602
+ const [missing, setMissing] = useState119(null);
45603
+ const [done, setDone] = useState119(null);
45604
+ const [counts, setCounts] = useState119({ waiting: 0, sending: 0, refused: 0, landed: 0 });
45605
+ const [items, setItems] = useState119([]);
45606
+ const [lastSynced, setLastSynced] = useState119(null);
45607
+ const [sending, setSending] = useState119(false);
45526
45608
  const queueRef = useRef55(null);
45527
- useEffect102(() => {
45609
+ useEffect103(() => {
45528
45610
  const q2 = openCaptureQueue({
45529
45611
  onChange: (c, all) => {
45530
45612
  setCounts(c);
@@ -45562,7 +45644,7 @@ function CaptureRun({ sheetId, face: given, className }) {
45562
45644
  void q2.sync().then(() => void q2.lastSyncedAt().then(setLastSynced));
45563
45645
  return () => q2.dispose();
45564
45646
  }, [client, host]);
45565
- useEffect102(() => {
45647
+ useEffect103(() => {
45566
45648
  if (given !== void 0) return;
45567
45649
  let cancelled = false;
45568
45650
  void client.captureOpen({ sheet_id: sheetId }).then((res) => {
@@ -45894,15 +45976,15 @@ function AdHocCaptureSheet({
45894
45976
  const host = useRecordsUi();
45895
45977
  const table = useTable34(tableId);
45896
45978
  const fields = useFields33(tableId);
45897
- const [mode, setMode] = useState119("reading");
45898
- const [reading, setReading] = useState119("");
45899
- const [note, setNote] = useState119("");
45900
- const [fileId, setFileId] = useState119(null);
45901
- const [pending, setPending] = useState119(null);
45902
- const [saved, setSaved] = useState119([]);
45903
- const [error, setError] = useState119(null);
45904
- const [uploadError, setUploadError] = useState119(null);
45905
- const [flushing, setFlushing] = useState119(false);
45979
+ const [mode, setMode] = useState120("reading");
45980
+ const [reading, setReading] = useState120("");
45981
+ const [note, setNote] = useState120("");
45982
+ const [fileId, setFileId] = useState120(null);
45983
+ const [pending, setPending] = useState120(null);
45984
+ const [saved, setSaved] = useState120([]);
45985
+ const [error, setError] = useState120(null);
45986
+ const [uploadError, setUploadError] = useState120(null);
45987
+ const [flushing, setFlushing] = useState120(false);
45906
45988
  const queue = useRef56([]);
45907
45989
  const keep = useCallback62(
45908
45990
  async (next) => {
@@ -45912,7 +45994,7 @@ function AdHocCaptureSheet({
45912
45994
  },
45913
45995
  [host]
45914
45996
  );
45915
- useEffect103(() => {
45997
+ useEffect104(() => {
45916
45998
  let cancelled = false;
45917
45999
  void (async () => {
45918
46000
  const held = host.captureQueue ? await host.captureQueue.load() : [];
@@ -46091,17 +46173,17 @@ function AdHocCaptureSheet({
46091
46173
  }
46092
46174
 
46093
46175
  // src/PortalShell.tsx
46094
- import { useCallback as useCallback63, useEffect as useEffect104, useState as useState120 } from "react";
46176
+ import { useCallback as useCallback63, useEffect as useEffect105, useState as useState121 } from "react";
46095
46177
  import { useRecordsClient as useRecordsClient92 } from "@ai-matrx/records/react";
46096
46178
  import { Button as Button98, Skeleton as Skeleton40, cn as cn89 } from "@ai-matrx/design-system";
46097
46179
  import { jsx as jsx146, jsxs as jsxs135 } from "react/jsx-runtime";
46098
46180
  function PortalShell({ tableId, form, resourceType = "record", className }) {
46099
46181
  const client = useRecordsClient92();
46100
- const [card, setCard] = useState120(null);
46101
- const [reach, setReach] = useState120(null);
46102
- const [error, setError] = useState120(null);
46103
- const [open, setOpen] = useState120(null);
46104
- const [sending, setSending] = useState120(false);
46182
+ const [card, setCard] = useState121(null);
46183
+ const [reach, setReach] = useState121(null);
46184
+ const [error, setError] = useState121(null);
46185
+ const [open, setOpen] = useState121(null);
46186
+ const [sending, setSending] = useState121(false);
46105
46187
  const load = useCallback63(async () => {
46106
46188
  const who = await client.externalPrincipalCard();
46107
46189
  if (!who.ok) {
@@ -46117,7 +46199,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
46117
46199
  }
46118
46200
  setReach(reached.data.map((row) => row.resource_id));
46119
46201
  }, [client, resourceType]);
46120
- useEffect104(() => {
46202
+ useEffect105(() => {
46121
46203
  void load();
46122
46204
  }, [load]);
46123
46205
  if (error) {
@@ -46176,8 +46258,8 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
46176
46258
  }
46177
46259
  function PortalRow({ tableId, recordId }) {
46178
46260
  const client = useRecordsClient92();
46179
- const [title, setTitle] = useState120(null);
46180
- useEffect104(() => {
46261
+ const [title, setTitle] = useState121(null);
46262
+ useEffect105(() => {
46181
46263
  let cancelled = false;
46182
46264
  void client.recordRead({ record_id: recordId }).then((answered) => {
46183
46265
  if (cancelled) return;
@@ -46197,7 +46279,7 @@ function PortalRow({ tableId, recordId }) {
46197
46279
  }
46198
46280
 
46199
46281
  // src/PublicViewPage.tsx
46200
- import { useCallback as useCallback64, useEffect as useEffect105, useState as useState121 } from "react";
46282
+ import { useCallback as useCallback64, useEffect as useEffect106, useState as useState122 } from "react";
46201
46283
  import { useRecordsClient as useRecordsClient93 } from "@ai-matrx/records/react";
46202
46284
  import { Skeleton as Skeleton41, cn as cn90 } from "@ai-matrx/design-system";
46203
46285
 
@@ -46215,12 +46297,12 @@ function publicReadOf(binding) {
46215
46297
  import { jsx as jsx147, jsxs as jsxs136 } from "react/jsx-runtime";
46216
46298
  function PublicViewPage({ slug, className }) {
46217
46299
  const client = useRecordsClient93();
46218
- const [binding, setBinding] = useState121(null);
46219
- const [rows, setRows] = useState121(null);
46220
- const [fields, setFields] = useState121(null);
46221
- const [error, setError] = useState121(null);
46222
- const [plan, setPlan] = useState121(null);
46223
- const [gap, setGap] = useState121(null);
46300
+ const [binding, setBinding] = useState122(null);
46301
+ const [rows, setRows] = useState122(null);
46302
+ const [fields, setFields] = useState122(null);
46303
+ const [error, setError] = useState122(null);
46304
+ const [plan, setPlan] = useState122(null);
46305
+ const [gap, setGap] = useState122(null);
46224
46306
  const load = useCallback64(async () => {
46225
46307
  const notice = await client.worldPublishGapNotice();
46226
46308
  if (notice.ok) setGap(notice.data);
@@ -46271,7 +46353,7 @@ function PublicViewPage({ slug, className }) {
46271
46353
  }
46272
46354
  setRows([{ id: chosen.recordId, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
46273
46355
  }, [client, slug]);
46274
- useEffect105(() => {
46356
+ useEffect106(() => {
46275
46357
  void load();
46276
46358
  }, [load]);
46277
46359
  if (error) return /* @__PURE__ */ jsx147(RefusalNotice, { error, className });
@@ -46309,7 +46391,7 @@ function PublicRow({ row, fields }) {
46309
46391
 
46310
46392
  // src/EmbedFrame.tsx
46311
46393
  import { copyText as copyText10 } from "@ai-matrx/kit/clipboard";
46312
- import { useCallback as useCallback65, useEffect as useEffect106, useState as useState122 } from "react";
46394
+ import { useCallback as useCallback65, useEffect as useEffect107, useState as useState123 } from "react";
46313
46395
  import { useRecordsClient as useRecordsClient94 } from "@ai-matrx/records/react";
46314
46396
  import { Button as Button99, Input as Input9, Skeleton as Skeleton42, Textarea as Textarea8, cn as cn91 } from "@ai-matrx/design-system";
46315
46397
  import { useTable as useTable35 } from "@ai-matrx/records/react";
@@ -46326,11 +46408,11 @@ function EmbedFrame({
46326
46408
  const host = useRecordsUi();
46327
46409
  const table = useTable35(tableId);
46328
46410
  const rights = useTableRights(table.data);
46329
- const [origins, setOrigins] = useState122("");
46330
- const [secret, setSecret] = useState122(null);
46331
- const [tokenId, setTokenId] = useState122(null);
46332
- const [error, setError] = useState122(null);
46333
- const [busy, setBusy] = useState122(false);
46411
+ const [origins, setOrigins] = useState123("");
46412
+ const [secret, setSecret] = useState123(null);
46413
+ const [tokenId, setTokenId] = useState123(null);
46414
+ const [error, setError] = useState123(null);
46415
+ const [busy, setBusy] = useState123(false);
46334
46416
  const mode = formId ? "write" : "read";
46335
46417
  const parsed = origins.split(/[\s,]+/).map((o) => o.trim()).filter((o) => o.length > 0);
46336
46418
  const issue = useCallback65(async () => {
@@ -46417,12 +46499,12 @@ function EmbedFrame({
46417
46499
  }
46418
46500
  function useEmbedHandshake(args) {
46419
46501
  const client = useRecordsClient94();
46420
- const [binding, setBinding] = useState122(null);
46421
- const [error, setError] = useState122(null);
46422
- const [loading, setLoading] = useState122(true);
46502
+ const [binding, setBinding] = useState123(null);
46503
+ const [error, setError] = useState123(null);
46504
+ const [loading, setLoading] = useState123(true);
46423
46505
  const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
46424
46506
  const { secret, requiredMode } = args;
46425
- useEffect106(() => {
46507
+ useEffect107(() => {
46426
46508
  let cancelled = false;
46427
46509
  setLoading(true);
46428
46510
  setError(null);
@@ -46445,7 +46527,7 @@ function useEmbedHandshake(args) {
46445
46527
 
46446
46528
  // src/TablePage.tsx
46447
46529
  import { copyText as copyText12 } from "@ai-matrx/kit/clipboard";
46448
- import { useCallback as useCallback67, useEffect as useEffect109, useMemo as useMemo76, useRef as useRef57, useState as useState129 } from "react";
46530
+ import { useCallback as useCallback67, useEffect as useEffect110, useMemo as useMemo76, useRef as useRef57, useState as useState130 } from "react";
46449
46531
  import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
46450
46532
  import { useFields as useFields36, useRecordsClient as useRecordsClient96, useTable as useTable36 } from "@ai-matrx/records/react";
46451
46533
  import {
@@ -46465,7 +46547,7 @@ import {
46465
46547
  cn as cn94,
46466
46548
  useIsMobile as useIsMobile2
46467
46549
  } from "@ai-matrx/design-system";
46468
- import { humanizeIdentifier as humanizeIdentifier18 } from "@ai-matrx/kit/text-case";
46550
+ import { humanizeIdentifier as humanizeIdentifier19 } from "@ai-matrx/kit/text-case";
46469
46551
 
46470
46552
  // src/viewShare.ts
46471
46553
  import { exportCsv as exportCsv2 } from "@ai-matrx/records/core";
@@ -46509,13 +46591,13 @@ async function downloadViewCsv(args) {
46509
46591
  }
46510
46592
 
46511
46593
  // src/RecordPanel.tsx
46512
- import { Fragment as Fragment61, useState as useState123 } from "react";
46594
+ import { Fragment as Fragment61, useState as useState124 } from "react";
46513
46595
  import { Button as Button100, Separator as Separator13 } from "@ai-matrx/design-system";
46514
46596
  import { useFields as useFields34, useRecord as useRecord4 } from "@ai-matrx/records/react";
46515
46597
  import { Fragment as Fragment62, jsx as jsx149, jsxs as jsxs138 } from "react/jsx-runtime";
46516
46598
  function RecordPanel({ tableId, recordId, onClose, onAskAboutField, onPage = false }) {
46517
46599
  const host = useRecordsUi();
46518
- const [asking, setAsking] = useState123(null);
46600
+ const [asking, setAsking] = useState124(null);
46519
46601
  return /* @__PURE__ */ jsxs138("div", { className: "space-y-3", "data-record-panel": recordId, children: [
46520
46602
  /* @__PURE__ */ jsx149(Peek, { tableId, recordId, onPage, ...onClose ? { onClose } : {} }),
46521
46603
  onPage ? /* @__PURE__ */ jsxs138(Fragment62, { children: [
@@ -46593,7 +46675,7 @@ function LinkedLists({ tableId, recordId }) {
46593
46675
  }
46594
46676
  function RecordAsk({ tableId, recordId }) {
46595
46677
  const host = useRecordsUi();
46596
- const [open, setOpen] = useState123(false);
46678
+ const [open, setOpen] = useState124(false);
46597
46679
  if (!host.chat) return null;
46598
46680
  return /* @__PURE__ */ jsxs138("section", { className: "flex min-w-0 flex-col gap-1.5", "data-record-ask": open ? "open" : "", children: [
46599
46681
  /* @__PURE__ */ jsx149(Separator13, {}),
@@ -46602,7 +46684,7 @@ function RecordAsk({ tableId, recordId }) {
46602
46684
  }
46603
46685
 
46604
46686
  // src/breakDown.tsx
46605
- import { useMemo as useMemo73, useState as useState124 } from "react";
46687
+ import { useMemo as useMemo73, useState as useState125 } from "react";
46606
46688
  import {
46607
46689
  Button as Button101,
46608
46690
  Dialog as Dialog14,
@@ -46642,7 +46724,7 @@ function BreakDownDialog({
46642
46724
  const source = useMemo73(() => ({ kind: "table", id: tableId }), [tableId]);
46643
46725
  const { def } = useDrillDefinition(open ? source : null);
46644
46726
  const dimensions = useMemo73(() => drillDimensionsOf(def, NO_LABELS), [def]);
46645
- const [picked, setPicked] = useState124(null);
46727
+ const [picked, setPicked] = useState125(null);
46646
46728
  const key = picked ?? held?.field ?? dimensions[0]?.key ?? "";
46647
46729
  return /* @__PURE__ */ jsx150(Dialog14, { open, onOpenChange, children: /* @__PURE__ */ jsxs139(DialogContent14, { "data-break-down": "", className: "max-w-sm", children: [
46648
46730
  /* @__PURE__ */ jsx150(DialogHeader14, { children: /* @__PURE__ */ jsx150(DialogTitle14, { children: "Break down by" }) }),
@@ -46669,7 +46751,7 @@ function BreakDownDialog({
46669
46751
 
46670
46752
  // src/TableReference.tsx
46671
46753
  import { copyText as copyText11 } from "@ai-matrx/kit/clipboard";
46672
- import { useCallback as useCallback66, useMemo as useMemo74, useState as useState125 } from "react";
46754
+ import { useCallback as useCallback66, useMemo as useMemo74, useState as useState126 } from "react";
46673
46755
  import { useContentTransferCapabilities as useContentTransferCapabilities2 } from "@ai-matrx/alchemy/react/workspace";
46674
46756
  import { Button as Button102, Dialog as Dialog15, DialogContent as DialogContent15, DialogHeader as DialogHeader15, DialogTitle as DialogTitle15 } from "@ai-matrx/design-system";
46675
46757
  import { jsx as jsx151, jsxs as jsxs140 } from "react/jsx-runtime";
@@ -46697,7 +46779,7 @@ function TableReferenceDialog({
46697
46779
  }) {
46698
46780
  const port = useContentTransferCapabilities2().reference;
46699
46781
  const notify = useRecordsUi().notify;
46700
- const [copied, setCopied] = useState125(null);
46782
+ const [copied, setCopied] = useState126(null);
46701
46783
  const choices = useMemo74(
46702
46784
  () => tableReferenceChoices(table.id, tableName(table)).filter((c) => port?.supports(c.reference)),
46703
46785
  [table, port]
@@ -46725,7 +46807,7 @@ function TableReferenceDialog({
46725
46807
  }
46726
46808
 
46727
46809
  // src/TableDuplicate.tsx
46728
- import { useState as useState126 } from "react";
46810
+ import { useState as useState127 } from "react";
46729
46811
  import { tableShapeChanged as tableShapeChanged12, useRecordsClient as useRecordsClient95 } from "@ai-matrx/records/react";
46730
46812
  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";
46731
46813
  import { Fragment as Fragment63, jsx as jsx152, jsxs as jsxs141 } from "react/jsx-runtime";
@@ -46740,9 +46822,9 @@ function duplicateProgressWords(p) {
46740
46822
  function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated }) {
46741
46823
  const client = useRecordsClient95();
46742
46824
  const host = useRecordsUi();
46743
- const [typed2, setTyped] = useState126(() => copyNameFor(name));
46744
- const [withRecords, setWithRecords] = useState126(true);
46745
- const [phase, setPhase] = useState126({ kind: "asking" });
46825
+ const [typed2, setTyped] = useState127(() => copyNameFor(name));
46826
+ const [withRecords, setWithRecords] = useState127(true);
46827
+ const [phase, setPhase] = useState127({ kind: "asking" });
46746
46828
  const problem = tableNameProblem(typed2);
46747
46829
  const copying = phase.kind === "copying";
46748
46830
  const close = (next) => {
@@ -46827,7 +46909,7 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
46827
46909
  }
46828
46910
 
46829
46911
  // src/ViewFilter.tsx
46830
- import { useEffect as useEffect107, useMemo as useMemo75, useState as useState127 } from "react";
46912
+ import { useEffect as useEffect108, useMemo as useMemo75, useState as useState128 } from "react";
46831
46913
  import { Button as Button104, Popover as Popover13, PopoverContent as PopoverContent13, PopoverTrigger as PopoverTrigger13 } from "@ai-matrx/design-system";
46832
46914
  import { useFields as useFields35 } from "@ai-matrx/records/react";
46833
46915
  import { jsx as jsx153, jsxs as jsxs142 } from "react/jsx-runtime";
@@ -46841,11 +46923,11 @@ function conditionCount(expr) {
46841
46923
  }
46842
46924
  function ViewFilter({ tableId, view, onApply, className }) {
46843
46925
  const fields = useFields35(tableId);
46844
- const [open, setOpen] = useState127(false);
46926
+ const [open, setOpen] = useState128(false);
46845
46927
  const saved = view?.where ?? null;
46846
- const [draft, setDraft] = useState127(saved);
46928
+ const [draft, setDraft] = useState128(saved);
46847
46929
  const savedKey = JSON.stringify(saved);
46848
- useEffect107(() => {
46930
+ useEffect108(() => {
46849
46931
  setDraft(saved);
46850
46932
  }, [view?.id, savedKey]);
46851
46933
  const conditionFields = useMemo75(
@@ -46893,7 +46975,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
46893
46975
  ConditionGroup,
46894
46976
  {
46895
46977
  lead: "Show records where",
46896
- emptyLabel: "every record",
46978
+ emptyLabel: "Pick a field",
46897
46979
  expr: draft,
46898
46980
  fields: conditionFields,
46899
46981
  onChange: setDraft
@@ -46929,8 +47011,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
46929
47011
  /* @__PURE__ */ jsx153(Button104, { size: "sm", variant: "ghost", onClick: () => {
46930
47012
  setDraft(saved);
46931
47013
  setOpen(false);
46932
- }, children: "Cancel" }),
46933
- changed ? /* @__PURE__ */ jsx153("span", { className: "text-muted-foreground", children: "Not applied yet." }) : null
47014
+ }, children: "Cancel" })
46934
47015
  ] })
46935
47016
  ]
46936
47017
  }
@@ -47021,7 +47102,7 @@ function phoneTableActions(actions) {
47021
47102
  }
47022
47103
 
47023
47104
  // src/toolbarFit.ts
47024
- import { useEffect as useEffect108, useState as useState128 } from "react";
47105
+ import { useEffect as useEffect109, useState as useState129 } from "react";
47025
47106
  var FOLDED_GUESS = { look: 104, chooser: 96, tools: 120 };
47026
47107
  var SLOT_MIN = 36;
47027
47108
  function toolbarFold(input) {
@@ -47078,8 +47159,8 @@ function rowNeeds(row) {
47078
47159
  return { needs: needs + gap * Math.max(0, pieces.length - 1), gap };
47079
47160
  }
47080
47161
  function useToolbarFit(row) {
47081
- const [fold, setFold] = useState128(0);
47082
- useEffect108(() => {
47162
+ const [fold, setFold] = useState129(0);
47163
+ useEffect109(() => {
47083
47164
  if (!row) return;
47084
47165
  const widths = {
47085
47166
  look: { full: null, folded: null },
@@ -47163,8 +47244,8 @@ function clippedEnds(scrollLeft, clientWidth, scrollWidth) {
47163
47244
  return start && end ? "both" : start ? "start" : end ? "end" : "none";
47164
47245
  }
47165
47246
  function useSlotScroll(slot) {
47166
- const [ends, setEnds] = useState128("none");
47167
- useEffect108(() => {
47247
+ const [ends, setEnds] = useState129("none");
47248
+ useEffect109(() => {
47168
47249
  if (!slot) return;
47169
47250
  let pending = 0;
47170
47251
  const read = () => {
@@ -47247,7 +47328,7 @@ function RailFrame({
47247
47328
  function filterInWords(filter, fields) {
47248
47329
  const nameOf2 = (key) => {
47249
47330
  const field2 = fields.find((f) => f.key === key);
47250
- return field2 ? fieldName(field2) : humanizeIdentifier18(key);
47331
+ return field2 ? fieldName(field2) : humanizeIdentifier19(key);
47251
47332
  };
47252
47333
  const parts = Object.keys(filter).map((key) => {
47253
47334
  const value = filter[key];
@@ -47282,10 +47363,10 @@ function TableNotHere({
47282
47363
  className
47283
47364
  }) {
47284
47365
  const client = useRecordsClient96();
47285
- const [archived, setArchived] = useState129({ phase: "asking" });
47286
- const [restoring, setRestoring] = useState129(false);
47287
- const [refusal4, setRefusal] = useState129(null);
47288
- useEffect109(() => {
47366
+ const [archived, setArchived] = useState130({ phase: "asking" });
47367
+ const [restoring, setRestoring] = useState130(false);
47368
+ const [refusal4, setRefusal] = useState130(null);
47369
+ useEffect110(() => {
47289
47370
  let alive = true;
47290
47371
  void client.tableArchived({ table_id: tableId }).then((answered) => {
47291
47372
  if (!alive) return;
@@ -47492,9 +47573,9 @@ function TablePage({
47492
47573
  const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
47493
47574
  const organizationId = useRecordsClient96().config.organizationId;
47494
47575
  const publicReadOnly = usePublicReadOnly(client, organizationId, tableId, table.data, rights);
47495
- const [view, setView] = useState129(null);
47496
- const [looks, setLooks] = useState129(void 0);
47497
- useEffect109(() => {
47576
+ const [view, setView] = useState130(null);
47577
+ const [looks, setLooks] = useState130(void 0);
47578
+ useEffect110(() => {
47498
47579
  let live = true;
47499
47580
  setLooks(void 0);
47500
47581
  void readLooks(client, tableId).then((answered) => {
@@ -47507,7 +47588,7 @@ function TablePage({
47507
47588
  }, [client, tableId]);
47508
47589
  const look = view && looks ? looks[view.id] : void 0;
47509
47590
  const shown4 = view ? applyLook(view, look) : null;
47510
- const [viewsEpoch, setViewsEpoch] = useState129(0);
47591
+ const [viewsEpoch, setViewsEpoch] = useState130(0);
47511
47592
  const opening = openingRail(activeRecordId, activeRail);
47512
47593
  const recordsUi = useRecordsUi();
47513
47594
  const hostLayouts = recordsUi.layouts ?? [];
@@ -47517,39 +47598,39 @@ function TablePage({
47517
47598
  const questionsFromLink = questionsFromParam(activeView);
47518
47599
  const openedByPackage = openingView(hostFromLink || savedFromLink || questionsFromLink ? null : activeView, activeDashboardId);
47519
47600
  const opened = hostFromLink ? { ...openedByPackage, main: "records" } : questionsFromLink ? { ...openedByPackage, main: "questions" } : openedByPackage;
47520
- const [hostLayout, setHostLayout] = useState129(hostFromLink);
47521
- const [views, setViews] = useState129(void 0);
47522
- const [pickedViewId, setPickedViewId] = useState129(savedFromLink);
47601
+ const [hostLayout, setHostLayout] = useState130(hostFromLink);
47602
+ const [views, setViews] = useState130(void 0);
47603
+ const [pickedViewId, setPickedViewId] = useState130(savedFromLink);
47523
47604
  const viewSeen = useRef57(null);
47524
- const [viewLinkMissed, setViewLinkMissed] = useState129(false);
47525
- const [layoutChosen, setLayoutChosen] = useState129(false);
47605
+ const [viewLinkMissed, setViewLinkMissed] = useState130(false);
47606
+ const [layoutChosen, setLayoutChosen] = useState130(false);
47526
47607
  const railAsked = typeof activeRail === "string" ? activeRail.trim() : "";
47527
47608
  const railUnknown = railAsked !== "" && railFromParam(railAsked) === null ? railAsked : null;
47528
47609
  const shareFromLink = railFromParam(activeRail) === "share";
47529
47610
  const canShare = useCanShare();
47530
47611
  const itemFor = (which) => railFromParam(activeRail) === which ? activeItemId ?? null : null;
47531
- const [asking, setAsking] = useState129(null);
47532
- const [layoutFromLink, setLayoutFromLink] = useState129(opened.layout);
47533
- const [surface, setSurface] = useState129({
47612
+ const [asking, setAsking] = useState130(null);
47613
+ const [layoutFromLink, setLayoutFromLink] = useState130(opened.layout);
47614
+ const [surface, setSurface] = useState130({
47534
47615
  main: opened.main,
47535
47616
  rail: opening.rail
47536
47617
  });
47537
47618
  const { main, rail } = surface;
47538
- const [questionDraft, setQuestionDraft] = useState129(null);
47619
+ const [questionDraft, setQuestionDraft] = useState130(null);
47539
47620
  const setRail = (next) => setSurface((now) => ({ ...now, rail: next }));
47540
- const [importEpoch, setImportEpoch] = useState129(0);
47541
- const [openRecord, setOpenRecord] = useState129(opening.record);
47621
+ const [importEpoch, setImportEpoch] = useState130(0);
47622
+ const [openRecord, setOpenRecord] = useState130(opening.record);
47542
47623
  const phone = useIsMobile2();
47543
- const [shareAsked, setShareAsked] = useState129(0);
47624
+ const [shareAsked, setShareAsked] = useState130(0);
47544
47625
  const { open: renameOpen, setOpen: setRenameOpen, ask: askRename, menuContentProps: renameMenuProps } = useRenameFromMenu();
47545
- const [archiveAsked, setArchiveAsked] = useState129(0);
47546
- const [moveAsked, setMoveAsked] = useState129(0);
47547
- const [duplicateOpen, setDuplicateOpen] = useState129(false);
47548
- const [referenceOpen, setReferenceOpen] = useState129(false);
47549
- const [breakDownOpen, setBreakDownOpen] = useState129(false);
47626
+ const [archiveAsked, setArchiveAsked] = useState130(0);
47627
+ const [moveAsked, setMoveAsked] = useState130(0);
47628
+ const [duplicateOpen, setDuplicateOpen] = useState130(false);
47629
+ const [referenceOpen, setReferenceOpen] = useState130(false);
47630
+ const [breakDownOpen, setBreakDownOpen] = useState130(false);
47550
47631
  const canGetReference = useCanGetReference();
47551
- const [toolbarSlot, setToolbarSlot] = useState129(null);
47552
- const [toolbarRow, setToolbarRow] = useState129(null);
47632
+ const [toolbarSlot, setToolbarSlot] = useState130(null);
47633
+ const [toolbarRow, setToolbarRow] = useState130(null);
47553
47634
  const toolbarFold2 = useToolbarFit(toolbarRow);
47554
47635
  const slotClipped = useSlotScroll(toolbarSlot);
47555
47636
  const face = tableOpening(view, hostLayouts.map((h) => h.id));
@@ -47560,7 +47641,7 @@ function TablePage({
47560
47641
  const chooserCompact = !embedded && !designated && !phone && toolbarFold2 >= 2;
47561
47642
  const controlsInSheet = phone && !designated;
47562
47643
  const shareInMenu = phone || toolbarFold2 >= 4;
47563
- useEffect109(() => {
47644
+ useEffect110(() => {
47564
47645
  if (face.kind !== "designated") return;
47565
47646
  if (hostFromLink || opened.layout || layoutChosen) return;
47566
47647
  setHostLayout(face.hostLayout);
@@ -47593,7 +47674,7 @@ function TablePage({
47593
47674
  const shownSignature = JSON.stringify(shownReport);
47594
47675
  const reportRef = useRef57(onShownViewChange);
47595
47676
  reportRef.current = onShownViewChange;
47596
- useEffect109(() => {
47677
+ useEffect110(() => {
47597
47678
  reportRef.current?.(JSON.parse(shownSignature));
47598
47679
  }, [shownSignature]);
47599
47680
  const pickLayout = (next) => {
@@ -47610,18 +47691,18 @@ function TablePage({
47610
47691
  setSurface((now) => ({ ...now, main: "records" }));
47611
47692
  onViewChanged?.(id);
47612
47693
  };
47613
- useEffect109(() => {
47694
+ useEffect110(() => {
47614
47695
  if (!activeRecordId) return;
47615
47696
  setOpenRecord(activeRecordId);
47616
47697
  setSurface((now) => ({ ...now, rail: "record" }));
47617
47698
  }, [activeRecordId]);
47618
- useEffect109(() => {
47699
+ useEffect110(() => {
47619
47700
  if (activeRecordId) return;
47620
47701
  const named = railFromParam(activeRail);
47621
47702
  if (named === null || named === "share") return;
47622
47703
  setSurface((now) => ({ ...now, rail: named }));
47623
47704
  }, [activeRail, activeRecordId]);
47624
- useEffect109(() => {
47705
+ useEffect110(() => {
47625
47706
  const host = hostLayoutFor(activeView);
47626
47707
  if (host) {
47627
47708
  setHostLayout(host);
@@ -47635,7 +47716,7 @@ function TablePage({
47635
47716
  setLayoutFromLink(isLayout ? named : null);
47636
47717
  setSurface((now) => ({ ...now, main: isLayout ? "records" : named }));
47637
47718
  }, [activeView]);
47638
- const [viewSaveRefused, setViewSaveRefused] = useState129(null);
47719
+ const [viewSaveRefused, setViewSaveRefused] = useState130(null);
47639
47720
  const patchView = useCallback67(
47640
47721
  async (asked3) => {
47641
47722
  const current = view;
@@ -47653,8 +47734,8 @@ function TablePage({
47653
47734
  [client, tableId, view, looks]
47654
47735
  );
47655
47736
  const arrival = useRef57(viewAddress ?? null);
47656
- const [gridQuery, setGridQuery] = useState129(null);
47657
- const [addressResetEpoch, setAddressResetEpoch] = useState129(0);
47737
+ const [gridQuery, setGridQuery] = useState130(null);
47738
+ const [addressResetEpoch, setAddressResetEpoch] = useState130(0);
47658
47739
  const reportGrid = useCallback67((q) => {
47659
47740
  const next = { sort: q.sort, filters: q.filters, search: q.search, page: q.page };
47660
47741
  setGridQuery((held) => sameViewAddress(held, next) ? held : next);
@@ -47664,7 +47745,7 @@ function TablePage({
47664
47745
  [reportGrid, addressResetEpoch]
47665
47746
  );
47666
47747
  const hiddenApplied = useRef57(false);
47667
- useEffect109(() => {
47748
+ useEffect110(() => {
47668
47749
  const hidden = arrival.current?.hidden;
47669
47750
  if (hiddenApplied.current || !view || !looks || !hidden || hidden.length === 0) return;
47670
47751
  hiddenApplied.current = true;
@@ -47687,7 +47768,7 @@ function TablePage({
47687
47768
  const addressReportRef = useRef57(onViewAddressChange);
47688
47769
  addressReportRef.current = onViewAddressChange;
47689
47770
  const addressSent = useRef57(null);
47690
- useEffect109(() => {
47771
+ useEffect110(() => {
47691
47772
  if (!addressReady) return;
47692
47773
  if (addressSent.current === null && addressSignature === JSON.stringify(viewAddressToParams(arrival.current))) {
47693
47774
  addressSent.current = addressSignature;
@@ -47699,9 +47780,9 @@ function TablePage({
47699
47780
  }, [addressReady, addressSignature]);
47700
47781
  const queryShowing = !isViewAddressEmpty({ ...gridQuery ?? {}, hidden: [] });
47701
47782
  const lookShowing = Boolean(view && looks && (lookDiffers(view, looks[view.id]) || queryShowing));
47702
- const [lookRefused, setLookRefused] = useState129(null);
47703
- const [namingLook, setNamingLook] = useState129(false);
47704
- const [lookName, setLookName] = useState129("");
47783
+ const [lookRefused, setLookRefused] = useState130(null);
47784
+ const [namingLook, setNamingLook] = useState130(false);
47785
+ const [lookName, setLookName] = useState130("");
47705
47786
  const resetLook = async () => {
47706
47787
  const current = view;
47707
47788
  setAddressResetEpoch((n) => n + 1);
@@ -47760,7 +47841,7 @@ function TablePage({
47760
47841
  setPickedViewId(written.data);
47761
47842
  setViewsEpoch((n) => n + 1);
47762
47843
  };
47763
- const [designateRefused, setDesignateRefused] = useState129(null);
47844
+ const [designateRefused, setDesignateRefused] = useState130(null);
47764
47845
  const opensAs = view?.isDefault ? openingLayoutOf(view) : null;
47765
47846
  const canDesignate = Boolean(
47766
47847
  rights.write && view && layoutShowing && layoutShowing !== opensAs && (storeKeepsLayout(layoutShowing) || hostLayouts.some((h) => h.id === layoutShowing))
@@ -47943,10 +48024,10 @@ function TablePage({
47943
48024
  actionsRef.current = actions;
47944
48025
  const onActionsRef = useRef57(onActions);
47945
48026
  onActionsRef.current = onActions;
47946
- useEffect109(() => {
48027
+ useEffect110(() => {
47947
48028
  onActionsRef.current?.(actionsRef.current);
47948
48029
  });
47949
- useEffect109(() => {
48030
+ useEffect110(() => {
47950
48031
  const onKey = (event) => {
47951
48032
  const asked3 = objectActionForKey(actionsRef.current, event);
47952
48033
  if (!asked3) return;
@@ -48175,7 +48256,7 @@ function TablePage({
48175
48256
  ] })
48176
48257
  ] }) }),
48177
48258
  /* @__PURE__ */ jsxs144(DropdownMenuContent9, { align: "start", className: "w-60", "data-view-look-menu-content": "", children: [
48178
- /* @__PURE__ */ jsx155(DropdownMenuLabel3, { className: "text-xs font-normal text-muted-foreground", children: LOOK_WORDS.yours }),
48259
+ /* @__PURE__ */ jsx155(DropdownMenuLabel3, { className: "text-xs font-normal text-muted-foreground", title: LOOK_WORDS.yours, children: LOOK_WORDS.yoursLabel }),
48179
48260
  lookSavable ? /* @__PURE__ */ jsx155(DropdownMenuItem7, { onSelect: () => void saveLookToView(), "data-view-look-save": "", children: LOOK_WORDS.saveToView }) : null,
48180
48261
  rights.write ? /* @__PURE__ */ jsx155(DropdownMenuItem7, { onSelect: () => setNamingLook(true), "data-view-look-save-new": "", children: LOOK_WORDS.saveAsNew }) : null,
48181
48262
  /* @__PURE__ */ jsx155(DropdownMenuItem7, { onSelect: () => void resetLook(), "data-view-look-reset": "", children: LOOK_WORDS.reset })
@@ -48487,8 +48568,8 @@ var PUBLIC_READ_ONLY = "Public \xB7 read only";
48487
48568
  function usePublicReadOnly(client, organizationId, tableId, table, rights) {
48488
48569
  const readOnly = rights.known && rights.read && !rights.write;
48489
48570
  const marked = table?.published_to_web;
48490
- const [isPublic, setIsPublic] = useState129(false);
48491
- useEffect109(() => {
48571
+ const [isPublic, setIsPublic] = useState130(false);
48572
+ useEffect110(() => {
48492
48573
  if (!readOnly || !table) {
48493
48574
  setIsPublic(false);
48494
48575
  return;
@@ -48513,7 +48594,7 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
48513
48594
  // src/entityViews.tsx
48514
48595
  import { TapTargetSearchGroup as TapTargetSearchGroup2, TooltipProvider } from "@ai-matrx/design-system";
48515
48596
  import { MatrxTableCardShowMore as MatrxTableCardShowMore3 } from "@ai-matrx/design-system/data-table";
48516
- import { useEffect as useEffect110, useMemo as useMemo77, useState as useState130 } from "react";
48597
+ import { useEffect as useEffect111, useMemo as useMemo77, useState as useState131 } from "react";
48517
48598
  import { Button as Button106, ErrorBox as ErrorBox9, Input as Input12, cn as cn95 } from "@ai-matrx/design-system";
48518
48599
  import { useRecordsClient as useRecordsClient97 } from "@ai-matrx/records/react";
48519
48600
  import { Fragment as Fragment65, jsx as jsx156, jsxs as jsxs145 } from "react/jsx-runtime";
@@ -48530,8 +48611,8 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
48530
48611
  () => cardFields ? entity.columns.filter((c) => cardFields.includes(c.key)) : entity.columns.filter((c) => c !== title && c !== column && c.type !== "choice").slice(0, 2),
48531
48612
  [cardFields, entity.columns, title, column]
48532
48613
  );
48533
- const [refused, setRefused] = useState130(null);
48534
- const [over, setOver] = useState130(null);
48614
+ const [refused, setRefused] = useState131(null);
48615
+ const [over, setOver] = useState131(null);
48535
48616
  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}` });
48536
48617
  if (!entity.loading && !column) {
48537
48618
  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.` });
@@ -48599,8 +48680,8 @@ function EntityChartBlock({ source, kind, by, measure, title, where, organizatio
48599
48680
  const client = useRecordsClient97();
48600
48681
  const m = measure ?? { op: "count" };
48601
48682
  const ask = JSON.stringify([source.token, by ?? null, m, where ?? null, organization ?? null]);
48602
- const [block, setBlock] = useState130(null);
48603
- useEffect110(() => {
48683
+ const [block, setBlock] = useState131(null);
48684
+ useEffect111(() => {
48604
48685
  let cancelled = false;
48605
48686
  const question = {
48606
48687
  ...by ? { by: [by] } : {},
@@ -48663,20 +48744,20 @@ function EntityTablePageBody({
48663
48744
  actions,
48664
48745
  className
48665
48746
  }) {
48666
- const [typed2, setTyped] = useState130("");
48747
+ const [typed2, setTyped] = useState131("");
48667
48748
  const term = searchOverride ?? typed2;
48668
48749
  const entity = useEntityTable(source.token, { pageSize, search: term });
48669
- const [layout, setLayout] = useState130(opened);
48670
- useEffect110(() => setLayout(opened), [opened]);
48750
+ const [layout, setLayout] = useState131(opened);
48751
+ useEffect111(() => setLayout(opened), [opened]);
48671
48752
  const choose = (next) => {
48672
48753
  setLayout(next);
48673
48754
  onLayoutChange?.(next);
48674
48755
  };
48675
48756
  const boardable = entityChoiceColumns(entity.columns).length > 0;
48676
48757
  const nameColumn = entityNameColumn(entity.columns);
48677
- const [naming, setNaming] = useState130(null);
48678
- const [adding, setAdding] = useState130(false);
48679
- const [addRefused, setAddRefused] = useState130(null);
48758
+ const [naming, setNaming] = useState131(null);
48759
+ const [adding, setAdding] = useState131(false);
48760
+ const [addRefused, setAddRefused] = useState131(null);
48680
48761
  const add = async () => {
48681
48762
  const name = (naming ?? "").trim();
48682
48763
  if (!name || !nameColumn || adding) return;
@@ -48688,7 +48769,7 @@ function EntityTablePageBody({
48688
48769
  setNaming(null);
48689
48770
  onOpenRecord?.(made.id);
48690
48771
  };
48691
- const [question, setQuestion] = useState130(() => questionFromGrouping(void 0));
48772
+ const [question, setQuestion] = useState131(() => questionFromGrouping(void 0));
48692
48773
  const { config: drill } = useDrill({
48693
48774
  source,
48694
48775
  question,
@@ -48791,7 +48872,7 @@ function TablePage2(props) {
48791
48872
  }
48792
48873
 
48793
48874
  // src/DataBindingPicker.tsx
48794
- import { useEffect as useEffect111, useMemo as useMemo78 } from "react";
48875
+ import { useEffect as useEffect112, useMemo as useMemo78 } from "react";
48795
48876
  import { isEntityReferenceConfig } from "@ai-matrx/records";
48796
48877
  import { useFields as useFields37, useTable as useTable37 } from "@ai-matrx/records/react";
48797
48878
  import { BasicInput as BasicInput34, Button as Button107, CreatablePicker as CreatablePicker3, cn as cn96 } from "@ai-matrx/design-system";
@@ -48887,7 +48968,7 @@ function BindingDetails({
48887
48968
  const fields = useFields37(tableId);
48888
48969
  const fieldList = useMemo78(() => fields.data ?? [], [fields.data]);
48889
48970
  const shape = binding.semantic_type;
48890
- useEffect111(() => {
48971
+ useEffect112(() => {
48891
48972
  if (disabled || shape === "value" || binding.transform || fields.loading || fieldList.length === 0) return;
48892
48973
  onChange({
48893
48974
  ...binding,
@@ -49109,7 +49190,7 @@ function RecordNameWords({ tableId, recordId }) {
49109
49190
  }
49110
49191
 
49111
49192
  // src/HeldChangeDecision.tsx
49112
- import { useEffect as useEffect112, useState as useState131 } from "react";
49193
+ import { useEffect as useEffect113, useState as useState132 } from "react";
49113
49194
  import { RecordsProvider as RecordsProvider3, useRecordsClient as useRecordsClient98 } from "@ai-matrx/records/react";
49114
49195
  import { Button as Button108 } from "@ai-matrx/design-system";
49115
49196
  import { jsx as jsx160, jsxs as jsxs148 } from "react/jsx-runtime";
@@ -49118,10 +49199,10 @@ function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, on
49118
49199
  }
49119
49200
  function Decision({ approvalId, onDecided }) {
49120
49201
  const client = useRecordsClient98();
49121
- const [may, setMay] = useState131(null);
49122
- const [busy, setBusy] = useState131(null);
49123
- const [error, setError] = useState131(null);
49124
- useEffect112(() => {
49202
+ const [may, setMay] = useState132(null);
49203
+ const [busy, setBusy] = useState132(null);
49204
+ const [error, setError] = useState132(null);
49205
+ useEffect113(() => {
49125
49206
  let live = true;
49126
49207
  void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
49127
49208
  if (!live) return;
@@ -49154,7 +49235,7 @@ function Decision({ approvalId, onDecided }) {
49154
49235
  }
49155
49236
 
49156
49237
  // src/TemplatePreview.tsx
49157
- import { useEffect as useEffect113, useMemo as useMemo79, useState as useState132 } from "react";
49238
+ import { useEffect as useEffect114, useMemo as useMemo79, useState as useState133 } from "react";
49158
49239
  import { templatePreview } from "@ai-matrx/records/memory";
49159
49240
  import { useRecordsClient as useRecordsClient99 } from "@ai-matrx/records/react";
49160
49241
  import { jsx as jsx161, jsxs as jsxs149 } from "react/jsx-runtime";
@@ -49165,7 +49246,7 @@ function TemplatePreview({ spec, today, initialTable, host, aside, booking, clas
49165
49246
  const preview = useTemplatePreview(spec, today);
49166
49247
  const bound2 = useMemo79(() => ({ ...host, sayLevelNeeded: false }), [host]);
49167
49248
  const first = preview.tables.find((t) => t.token === initialTable) ?? preview.tables[0];
49168
- const [active, setActive] = useState132(first?.id ?? null);
49249
+ const [active, setActive] = useState133(first?.id ?? null);
49169
49250
  const table = preview.tables.find((t) => t.id === active) ?? first;
49170
49251
  if (!table) return null;
49171
49252
  return /* @__PURE__ */ jsxs149("div", { className: ["flex min-w-0 flex-col gap-3", className].filter(Boolean).join(" "), "data-template-preview": preview.tables.length, children: [
@@ -49203,9 +49284,9 @@ function TemplatePreview({ spec, today, initialTable, host, aside, booking, clas
49203
49284
  }
49204
49285
  function PreviewForms({ preview, booking }) {
49205
49286
  const client = useRecordsClient99();
49206
- const [forms, setForms] = useState132(null);
49207
- const [pages, setPages] = useState132([]);
49208
- useEffect113(() => {
49287
+ const [forms, setForms] = useState133(null);
49288
+ const [pages, setPages] = useState133([]);
49289
+ useEffect114(() => {
49209
49290
  let gone = false;
49210
49291
  void client.forms().then((answered) => {
49211
49292
  if (!gone) setForms(answered.ok ? answered.data.map(formFromSummary) : []);