@ai-matrx/records-ui 0.102.15 → 0.102.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1715,12 +1715,12 @@ function PickOrAdd({
1715
1715
  children,
1716
1716
  chips,
1717
1717
  multi,
1718
- addFirst
1718
+ onEscape
1719
1719
  }) {
1720
1720
  const addRow = add && !foot ? add : null;
1721
1721
  const count = items.length + (addRow ? 1 : 0);
1722
- const addAt = addRow ? addFirst ? 0 : items.length : -1;
1723
- const itemAt = (index) => addRow && addFirst ? index - 1 : index;
1722
+ const addAt = addRow ? items.length : -1;
1723
+ const itemAt = (index) => index;
1724
1724
  const removable = (chips ?? []).filter((c) => c.onRemove);
1725
1725
  const keys = useListKeys({
1726
1726
  count,
@@ -1734,7 +1734,7 @@ function PickOrAdd({
1734
1734
  if (item && !item.disabled) onPick(item.id);
1735
1735
  },
1736
1736
  onNothing: onEnterWithNoMatch ?? (add && !add.disabled ? add.onAdd : void 0),
1737
- onClose: () => onOpenChange(false),
1737
+ onClose: () => onEscape ? onEscape() : onOpenChange(false),
1738
1738
  ...multi ? { onFinish: () => onOpenChange(false) } : {},
1739
1739
  ...removable.length > 0 ? { onBackspaceEmpty: () => removable[removable.length - 1]?.onRemove?.() } : {},
1740
1740
  searchEmpty: search === ""
@@ -1768,6 +1768,11 @@ function PickOrAdd({
1768
1768
  onKeyDown: (event) => {
1769
1769
  if (event.key !== "Tab") event.stopPropagation();
1770
1770
  },
1771
+ onEscapeKeyDown: (event) => {
1772
+ if (!onEscape) return;
1773
+ event.preventDefault();
1774
+ onEscape();
1775
+ },
1771
1776
  onCloseAutoFocus: (event) => {
1772
1777
  if (anchored) event.preventDefault();
1773
1778
  },
@@ -1789,7 +1794,6 @@ function PickOrAdd({
1789
1794
  notice,
1790
1795
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system5.ScrollArea, { className: "max-h-64", children: [
1791
1796
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { role: "listbox", "aria-label": triggerLabel, "aria-multiselectable": multi ? true : void 0, children: [
1792
- addFirst ? addRowNode : null,
1793
1797
  items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1794
1798
  PickRow,
1795
1799
  {
@@ -1801,13 +1805,13 @@ function PickOrAdd({
1801
1805
  disabled: item.disabled,
1802
1806
  attrs: item.attrs,
1803
1807
  person: item.person,
1804
- highlighted: (addRow && addFirst ? index + 1 : index) === keys.highlight,
1808
+ highlighted: index === keys.highlight,
1805
1809
  onPick: () => onPick(item.id),
1806
- onPoint: () => keys.setHighlight(addRow && addFirst ? index + 1 : index)
1810
+ onPoint: () => keys.setHighlight(index)
1807
1811
  },
1808
1812
  item.id
1809
1813
  )),
1810
- addFirst ? null : addRowNode
1814
+ addRowNode
1811
1815
  ] }),
1812
1816
  items.length === 0 && empty ? empty : null
1813
1817
  ] }),
@@ -1852,7 +1856,7 @@ async function personRecordForMember(client, personTableId, people, member) {
1852
1856
  });
1853
1857
  return written;
1854
1858
  }
1855
- function PersonPicker({ field: field2, value, onChange, disabled, id, className, autoOpen, onClose, initialSearch }) {
1859
+ function PersonPicker({ field: field2, value, onChange, disabled, id, className, autoOpen, onClose, onCancel, initialSearch }) {
1856
1860
  const client = (0, import_react9.useOptionalRecordsClient)();
1857
1861
  const host = useRecordsUi();
1858
1862
  const [members, setMembers] = (0, import_react8.useState)(null);
@@ -1966,6 +1970,7 @@ function PersonPicker({ field: field2, value, onChange, disabled, id, className,
1966
1970
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1967
1971
  PickOrAdd,
1968
1972
  {
1973
+ ...anchored && onCancel ? { onEscape: onCancel } : {},
1969
1974
  anchored,
1970
1975
  multi: field2.multi,
1971
1976
  triggerId: id,
@@ -3073,7 +3078,7 @@ var import_jsx_runtime9 = (
3073
3078
  require("react/jsx-runtime")
3074
3079
  );
3075
3080
  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.";
3076
- function RelationPicker({ field: field2, value, onChange, disabled, id, className, allowCreate = true, onPicked, autoOpen, onClose }) {
3081
+ function RelationPicker({ field: field2, value, onChange, disabled, id, className, allowCreate = true, onPicked, autoOpen, onClose, onCancel }) {
3077
3082
  const client = (0, import_react12.useOptionalRecordsClient)();
3078
3083
  const [rows, setRows] = (0, import_react11.useState)(null);
3079
3084
  const [words2, setWords] = (0, import_react11.useState)({});
@@ -3237,6 +3242,7 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
3237
3242
  PickOrAdd,
3238
3243
  {
3239
3244
  anchored,
3245
+ ...anchored && onCancel ? { onEscape: onCancel } : {},
3240
3246
  multi: field2.multi,
3241
3247
  chips: picked.map((recordId) => ({ id: recordId, label: titleOf(recordId), onRemove: () => toggle(recordId) })),
3242
3248
  triggerId: id,
@@ -4809,7 +4815,7 @@ function ChoiceAskButtons({
4809
4815
  onCancel,
4810
4816
  busy
4811
4817
  }) {
4812
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { "data-records-choice-ask": "", role: "group", "aria-label": choiceAskSentence(field2, words2), className: "flex flex-col gap-1", children: [
4818
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { "data-records-choice-ask": "", "data-records-cell-note": "", role: "group", "aria-label": choiceAskSentence(field2, words2), className: "flex flex-col gap-1", children: [
4813
4819
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field2, words2) }),
4814
4820
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "flex flex-wrap items-center gap-1", children: [
4815
4821
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_design_system17.Button, { type: "button", size: "sm", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onAdd, children: "Add" }),
@@ -4846,7 +4852,11 @@ function typingOpens(field2) {
4846
4852
  var SHORT_REFUSAL = {
4847
4853
  email: "Enter a valid email",
4848
4854
  url: "Enter a valid link",
4849
- phone: "Enter a valid phone number"
4855
+ phone: "Enter a valid phone number",
4856
+ time: "Enter a time, like 2:30 PM",
4857
+ date: "Enter a date",
4858
+ number: "Enter a number",
4859
+ value: "Not a valid value"
4850
4860
  };
4851
4861
  function judgeTyped(field2, text, choices, nudge) {
4852
4862
  const trimmed = text.trim();
@@ -4855,7 +4865,7 @@ function judgeTyped(field2, text, choices, nudge) {
4855
4865
  if (trimmed === "") return { value: null };
4856
4866
  if (format && format.id === "time") {
4857
4867
  const read2 = (0, import_records12.readTypedTime)(trimmed);
4858
- return read2.ok ? { value: read2.value } : { refusal: `${fieldName(field2)} holds a time of day, and ${read2.why}` };
4868
+ return read2.ok ? { value: read2.value } : { refusal: SHORT_REFUSAL.time, why: `${fieldName(field2)} holds a time of day, and ${read2.why}` };
4859
4869
  }
4860
4870
  if (kind === "select" || kind === "multi_select") {
4861
4871
  if (!choices || nudge === null) return null;
@@ -4893,7 +4903,7 @@ function judgeTyped(field2, text, choices, nudge) {
4893
4903
  if (format && format.id === "rating") {
4894
4904
  const n = Number(trimmed);
4895
4905
  const max = format.options?.ratingMax ?? 5;
4896
- 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.` };
4906
+ 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}.` };
4897
4907
  }
4898
4908
  if (kind === "phone" || format && format.id === "phone") {
4899
4909
  const digits = trimmed.replace(/\D/g, "");
@@ -4902,7 +4912,11 @@ function judgeTyped(field2, text, choices, nudge) {
4902
4912
  }
4903
4913
  const showsAsPercent = Boolean(format && (format.id === "percent" || format.id === "progress"));
4904
4914
  const read = (0, import_records12.coerceTypedAnswer)(field2, text, { label: fieldName(field2), showsAsPercent });
4905
- if ("refusal" in read) return { refusal: kind === "email" || kind === "url" ? SHORT_REFUSAL[kind] : read.refusal };
4915
+ if ("refusal" in read) {
4916
+ if (kind === "email" || kind === "url") return { refusal: SHORT_REFUSAL[kind] };
4917
+ 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;
4918
+ return short === read.refusal ? { refusal: short } : { refusal: short, why: read.refusal };
4919
+ }
4906
4920
  if (typeof read.value === "number" && format && (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction") {
4907
4921
  return { value: Math.round(read.value / 100 * 1e9) / 1e9 };
4908
4922
  }
@@ -4987,7 +5001,7 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
4987
5001
  box,
4988
5002
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field2) })
4989
5003
  ] }) : box,
4990
- judged === null ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-[10px] text-muted-foreground", children: [
5004
+ judged === null ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { "data-records-cell-note": "", className: "text-[10px] text-muted-foreground", children: [
4991
5005
  "Reading ",
4992
5006
  fieldName(field2),
4993
5007
  "'s choices\u2026"
@@ -5007,10 +5021,19 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
5007
5021
  },
5008
5022
  onCancel: () => onCancel?.()
5009
5023
  }
5010
- ) : "refusal" in judged ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "flex flex-col gap-1", children: [
5011
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: judged.refusal }),
5024
+ ) : "refusal" in judged ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { "data-records-cell-note": "", className: "flex flex-col gap-1", children: [
5025
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5026
+ "span",
5027
+ {
5028
+ "data-records-typed-refusal": "",
5029
+ role: "status",
5030
+ title: "why" in judged ? judged.why : void 0,
5031
+ className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400",
5032
+ children: judged.refusal
5033
+ }
5034
+ ),
5012
5035
  judged.cancelOnly && onCancel ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "data-records-choice-ask": "", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_design_system17.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => onCancel(), children: "Cancel" }) }) : null
5013
- ] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { "data-records-typed-reads-as": "", className: "text-[10px] text-muted-foreground", children: [
5036
+ ] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { "data-records-typed-reads-as": "", "data-records-cell-note": "", className: "text-[10px] text-muted-foreground", children: [
5014
5037
  isChoiceAddition(judged.value) ? `Adds ${quoted(judged.value.add)} to the choices for ${fieldName(field2)}. ` : null,
5015
5038
  "Reads as",
5016
5039
  " ",
@@ -5104,9 +5127,9 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
5104
5127
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CheckboxControl, { field: field2, value, onChange, disabled, id: inputId });
5105
5128
  case "select":
5106
5129
  case "multi_select":
5107
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(OptionControl, { field: field2, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
5130
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(OptionControl, { field: field2, value, onChange, disabled, id: inputId, autoOpen, onClose, onCancel, addsChoices, initialSearch, asForm });
5108
5131
  case "member":
5109
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PersonPicker, { field: field2, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
5132
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PersonPicker, { field: field2, value, onChange, disabled, id: inputId, autoOpen, onClose, onCancel, initialSearch });
5110
5133
  case "entity_reference":
5111
5134
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(EntityReferenceControl, { field: field2, value, onChange, disabled, id: inputId });
5112
5135
  case "attachment":
@@ -5115,7 +5138,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
5115
5138
  }
5116
5139
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RelationPicker, { field: field2, value, onChange, disabled, id: inputId });
5117
5140
  case "relation":
5118
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RelationPicker, { field: field2, value, onChange, disabled, id: inputId, onPicked: onCommit, autoOpen, onClose });
5141
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RelationPicker, { field: field2, value, onChange, disabled, id: inputId, onPicked: onCommit, autoOpen, onClose, onCancel });
5119
5142
  default:
5120
5143
  if (typeof value === "boolean" || field2.config?.["kind"] === "boolean") {
5121
5144
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
@@ -5143,6 +5166,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
5143
5166
  function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
5144
5167
  const [text, setText] = (0, import_react28.useState)(() => openingText(field2, value));
5145
5168
  const [refusal4, setRefusal] = (0, import_react28.useState)(null);
5169
+ const [why, setWhy] = (0, import_react28.useState)(void 0);
5146
5170
  const sent = (0, import_react28.useRef)(value);
5147
5171
  (0, import_react28.useEffect)(() => {
5148
5172
  if (value === sent.current) return;
@@ -5160,6 +5184,7 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
5160
5184
  onChange(judged.value);
5161
5185
  } else if (judged && "refusal" in judged) {
5162
5186
  setRefusal(judged.refusal);
5187
+ setWhy("why" in judged ? judged.why : void 0);
5163
5188
  }
5164
5189
  };
5165
5190
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "flex flex-col gap-0.5", children: [
@@ -5183,7 +5208,7 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
5183
5208
  ),
5184
5209
  helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field2) }) : null
5185
5210
  ] }),
5186
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal4 }) : null
5211
+ refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("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
5187
5212
  ] });
5188
5213
  }
5189
5214
  function CheckboxControl({ field: field2, value, onChange, disabled, id }) {
@@ -5253,8 +5278,9 @@ function JsonControl({ field: field2, value, onChange, disabled, id }) {
5253
5278
  }
5254
5279
  ),
5255
5280
  broken ? (
5256
- // The typed text is still in the box: the notice owns the two doors out.
5257
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5281
+ // The typed text is still in the box: the notice owns the two doors out. In a grid cell it
5282
+ // floats over the table (`data-records-cell-note`), so the row never grows.
5283
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "data-records-cell-note": "", className: "block", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5258
5284
  RefusalNotice,
5259
5285
  {
5260
5286
  error: broken,
@@ -5264,7 +5290,7 @@ function JsonControl({ field: field2, value, onChange, disabled, id }) {
5264
5290
  setBroken(null);
5265
5291
  }
5266
5292
  }
5267
- )
5293
+ ) })
5268
5294
  ) : null
5269
5295
  ] });
5270
5296
  }
@@ -5277,7 +5303,7 @@ function inTheStoresOrder(options) {
5277
5303
  const made = (o) => String(o.created_at ?? "");
5278
5304
  return [...options].sort((a, b) => position(a) - position(b) || made(a).localeCompare(made(b)));
5279
5305
  }
5280
- function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, addsChoices, initialSearch, asForm }) {
5306
+ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, onCancel, addsChoices, initialSearch, asForm }) {
5281
5307
  const client = (0, import_react29.useOptionalRecordsClient)();
5282
5308
  const [options, setOptions] = (0, import_react28.useState)(null);
5283
5309
  const [refusal4, setRefusal] = (0, import_react28.useState)(null);
@@ -5345,6 +5371,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
5345
5371
  id,
5346
5372
  autoOpen,
5347
5373
  onClose,
5374
+ onCancel,
5348
5375
  initialSearch,
5349
5376
  addsChoices,
5350
5377
  allowOther: (0, import_records12.allowsOtherValues)(field2),
@@ -5425,6 +5452,7 @@ function OpenChoicePicker({
5425
5452
  addsChoices,
5426
5453
  autoOpen,
5427
5454
  onClose,
5455
+ onCancel,
5428
5456
  initialSearch,
5429
5457
  allowOther = true,
5430
5458
  onChoicesChanged
@@ -5492,10 +5520,9 @@ function OpenChoicePicker({
5492
5520
  });
5493
5521
  };
5494
5522
  const offList = q !== "" && decided.decision !== "chosen" && decided.decision !== "empty";
5495
- const nothingMatches = q !== "" && visible.length === 0;
5496
5523
  const foot = null;
5497
5524
  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;
5498
- const listed = nothingMatches && add ? options : visible;
5525
+ const listed = visible;
5499
5526
  const pickedOptions = current.map((v) => options.find((o) => (0, import_records12.isTheChosen)(o, v)));
5500
5527
  const cellChips = pickedWords.map((word, i) => {
5501
5528
  const chip = chipOf(pickedOptions[i], word);
@@ -5523,6 +5550,7 @@ function OpenChoicePicker({
5523
5550
  PickOrAdd,
5524
5551
  {
5525
5552
  anchored,
5553
+ ...anchored && onCancel ? { onEscape: onCancel } : {},
5526
5554
  chips: headChips,
5527
5555
  multi: field2.multi,
5528
5556
  triggerLabel: `Pick for ${fieldName(field2)}`,
@@ -5534,7 +5562,6 @@ function OpenChoicePicker({
5534
5562
  setSearch(next);
5535
5563
  setAddRefused(null);
5536
5564
  },
5537
- addFirst: nothingMatches,
5538
5565
  items: listed.map((option) => ({
5539
5566
  id: option.id,
5540
5567
  label: titleOf(option),
@@ -7137,8 +7164,9 @@ function cardWords(record, field2, labels) {
7137
7164
 
7138
7165
  // src/gridEditing.tsx
7139
7166
  var import_jsx_runtime28 = require("react/jsx-runtime");
7140
- 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";
7141
- 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";
7167
+ 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";
7168
+ 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";
7169
+ var FLOATING_CELL_TRAY_PIECE_CLASS = "rounded-md border bg-popover px-1.5 py-0.5 shadow-md";
7142
7170
  var NO_ROWS = [];
7143
7171
  function asksWhoChanged(event) {
7144
7172
  return event.altKey && event.shiftKey && !event.metaKey && !event.ctrlKey && (event.code === "KeyH" || event.key.toLowerCase() === "h");
@@ -7714,8 +7742,18 @@ function GridCell({
7714
7742
  const onLinkClickCapture = (event) => {
7715
7743
  const link = event.target instanceof Element ? event.target.closest("a[href]") : null;
7716
7744
  if (!(link instanceof HTMLElement) || !event.currentTarget.contains(link) || event.detail === 0) return;
7745
+ if (event.metaKey || event.ctrlKey || event.shiftKey) {
7746
+ cancelSinglePress();
7747
+ event.stopPropagation();
7748
+ return;
7749
+ }
7717
7750
  event.preventDefault();
7718
7751
  const cellTakesIt = editable && (clickOpens || opensAsAList(field2, hostTakesFiles(ui)));
7752
+ if (cellTakesIt && event.detail === 1 && (clickOpens || wasActive.current)) {
7753
+ cancelSinglePress();
7754
+ openThisCell(event);
7755
+ return;
7756
+ }
7719
7757
  if (event.detail === 1 && wasActive.current && !cellTakesIt) afterSinglePress(() => link.click());
7720
7758
  else cancelSinglePress();
7721
7759
  };
@@ -7724,32 +7762,51 @@ function GridCell({
7724
7762
  const refusal4 = editing ? editing.refusalOf(row.id, field2.key) : null;
7725
7763
  const editable = Boolean(editing) && canWrite && fieldIsEditable(field2);
7726
7764
  if (open && editing) {
7727
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7728
- OpenCell,
7729
- {
7730
- field: field2,
7731
- draft: editing.draft,
7732
- initialSearch: editing.searchSeed,
7733
- onType: editing.type,
7734
- onCommit: (move, via) => editing.commit(move, via),
7735
- onCancel: (via) => editing.cancel(via),
7736
- below: (
7737
- // KEPT EDITING: the refusal stays beside the value it is about, so the
7738
- // person reads what to change while changing it. Keep editing is the
7739
- // state they are in, so only Discard is offered. It is INSIDE the open
7740
- // cell, so pressing Discard is not "focus left the cell" — which would
7741
- // commit the refused value one more time on its way out.
7742
- refusal4 && !refusal4.conflict ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7743
- RefusalNotice,
7744
- {
7745
- error: refusal4.error,
7746
- className: "py-1.5 text-left",
7747
- onDiscard: () => editing.discard(row.id, field2.key)
7748
- }
7749
- ) : null
7750
- )
7751
- }
7752
- );
7765
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { "data-records-open-cell": "", className: "relative block w-full min-w-0", children: [
7766
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { "aria-hidden": "true", inert: true, "data-records-cell-ghost": "", className: "pointer-events-none invisible flex w-full min-w-0 select-none items-center gap-1", children: [
7767
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "block min-w-0 flex-1 truncate px-1 py-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7768
+ RecordValue,
7769
+ {
7770
+ inCell: true,
7771
+ field: field2,
7772
+ value: row.document?.[field2.key],
7773
+ document: row.document,
7774
+ recordId: row.id,
7775
+ withheld: withheldNoticeOf(row.hidden, field2.key),
7776
+ ...format ? { format } : {}
7777
+ }
7778
+ ) }),
7779
+ onAskWhoChanged ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(WhoBadge, { field: field2, row, onAskWhoChanged: () => {
7780
+ }, onPressedTwice: () => {
7781
+ } }) : null
7782
+ ] }),
7783
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7784
+ OpenCell,
7785
+ {
7786
+ field: field2,
7787
+ draft: editing.draft,
7788
+ initialSearch: editing.searchSeed,
7789
+ onType: editing.type,
7790
+ onCommit: (move, via) => editing.commit(move, via),
7791
+ onCancel: (via) => editing.cancel(via),
7792
+ below: (
7793
+ // KEPT EDITING: the refusal stays beside the value it is about, so the
7794
+ // person reads what to change while changing it. Keep editing is the
7795
+ // state they are in, so only Discard is offered. It is INSIDE the open
7796
+ // cell, so pressing Discard is not "focus left the cell" — which would
7797
+ // commit the refused value one more time on its way out.
7798
+ refusal4 && !refusal4.conflict ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7799
+ RefusalNotice,
7800
+ {
7801
+ error: refusal4.error,
7802
+ className: "py-1.5 text-left",
7803
+ onDiscard: () => editing.discard(row.id, field2.key)
7804
+ }
7805
+ ) : null
7806
+ )
7807
+ }
7808
+ )
7809
+ ] });
7753
7810
  }
7754
7811
  if (editorKindFor(field2) === "checkbox") {
7755
7812
  const answered = value === true || value === false;
@@ -8099,8 +8156,9 @@ function OpenCell({
8099
8156
  "data-matrx-cell-editor": "",
8100
8157
  tabIndex: -1,
8101
8158
  className: (0, import_design_system23.cn)(
8102
- "relative z-[25] flex w-full min-w-0 max-w-full flex-col gap-1 outline-none",
8103
- FLOATING_EDITOR_NOTE_CLASS,
8159
+ // OVER the cell's ghost (see `data-records-open-cell`), never in the table's measuring.
8160
+ "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",
8161
+ FLOATING_CELL_NOTE_CLASS,
8104
8162
  // A field's own input is 36px (h-9); in a 35px row it grew the row 4px. In the cell it is
8105
8163
  // the row action strip's 32px, so opening a cell never changes the row (STABLE-TABLES).
8106
8164
  "[&_input:not([type=checkbox]):not([type=radio])]:h-8 [&_input:not([type=checkbox]):not([type=radio])]:py-0"
@@ -8159,11 +8217,13 @@ function OpenCell({
8159
8217
  addsChoices: true
8160
8218
  }
8161
8219
  ),
8162
- picker || asksAboutAChoice(draft) ? null : blurCommits ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: (0, import_design_system23.cn)("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__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "flex items-center gap-1", children: [
8163
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_design_system23.Button, { size: "sm", onClick: () => once(() => onCommit(null, "pick")), children: "Save" }),
8164
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_design_system23.Button, { size: "sm", variant: "ghost", onClick: () => once(() => onCancel("pick")), children: "Cancel" })
8165
- ] }),
8166
- below
8220
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { "data-records-cell-tray": "", className: FLOATING_CELL_TRAY_CLASS, children: [
8221
+ picker || asksAboutAChoice(draft) ? null : blurCommits ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: (0, import_design_system23.cn)("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__ */ (0, import_jsx_runtime28.jsxs)("span", { className: (0, import_design_system23.cn)("flex items-center gap-1", FLOATING_CELL_TRAY_PIECE_CLASS), children: [
8222
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_design_system23.Button, { size: "sm", onClick: () => once(() => onCommit(null, "pick")), children: "Save" }),
8223
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_design_system23.Button, { size: "sm", variant: "ghost", onClick: () => once(() => onCancel("pick")), children: "Cancel" })
8224
+ ] }),
8225
+ below ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "block bg-popover shadow-md", children: below }) : null
8226
+ ] })
8167
8227
  ]
8168
8228
  }
8169
8229
  );
@@ -11364,11 +11424,11 @@ function FieldEditor(props) {
11364
11424
  import_design_system34.Checkbox,
11365
11425
  {
11366
11426
  checked: required,
11367
- "aria-label": "Every record has to have one",
11427
+ "aria-label": "Required",
11368
11428
  onCheckedChange: (v) => setRequired(v === true)
11369
11429
  }
11370
11430
  ),
11371
- "Every record has to have one"
11431
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { title: "Every record has to have one", children: "Required" })
11372
11432
  ] }),
11373
11433
  offersMany ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("label", { className: "flex items-center gap-1.5", children: [
11374
11434
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
@@ -14894,7 +14954,7 @@ function useMergedGridControls(args) {
14894
14954
  children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_design_system46.DialogContent, { className: "max-h-[85vh] overflow-y-auto sm:max-w-2xl", children: [
14895
14955
  /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_design_system46.DialogHeader, { children: [
14896
14956
  /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_design_system46.DialogTitle, { 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 }),
14897
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_design_system46.DialogDescription, { className: "sr-only", children: "The column\u2019s name, what it holds and how it looks." })
14957
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_design_system46.DialogDescription, { className: "sr-only", children: "Name, type and look" })
14898
14958
  ] }),
14899
14959
  dialog?.kind === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
14900
14960
  FieldEditor,
@@ -19356,6 +19416,7 @@ function ImportWizard({ tableId, source, onDone, onWrote, className }) {
19356
19416
  // src/tableShape.ts
19357
19417
  var import_source2 = require("@ai-matrx/content-ir/source");
19358
19418
  var import_text_case9 = require("@ai-matrx/kit/text-case");
19419
+ var import_delimited2 = require("@ai-matrx/kit/delimited");
19359
19420
  var FEWEST_LIST_ITEMS = 2;
19360
19421
  var FEWEST_KEY_VALUE_PAIRS = 2;
19361
19422
  var LONGEST_TEXT_READ = 2e6;
@@ -19533,38 +19594,7 @@ function shapeFromList(items, name, at) {
19533
19594
  };
19534
19595
  }
19535
19596
  function parseDelimited(text, delimiter) {
19536
- const rows = [];
19537
- let row = [];
19538
- let cell2 = "";
19539
- let quoted2 = false;
19540
- for (let i = 0; i < text.length; i += 1) {
19541
- const ch = text[i];
19542
- if (quoted2) {
19543
- if (ch === '"') {
19544
- if (text[i + 1] === '"') {
19545
- cell2 += '"';
19546
- i += 1;
19547
- } else quoted2 = false;
19548
- } else cell2 += ch;
19549
- continue;
19550
- }
19551
- if (ch === '"' && cell2.trim() === "") quoted2 = true;
19552
- else if (ch === delimiter) {
19553
- row.push(cell2);
19554
- cell2 = "";
19555
- } else if (ch === "\n" || ch === "\r") {
19556
- if (ch === "\r" && text[i + 1] === "\n") i += 1;
19557
- row.push(cell2);
19558
- rows.push(row);
19559
- row = [];
19560
- cell2 = "";
19561
- } else cell2 += ch;
19562
- }
19563
- if (cell2.length > 0 || row.length > 0) {
19564
- row.push(cell2);
19565
- rows.push(row);
19566
- }
19567
- return rows.filter((r) => r.some((c) => c.trim() !== ""));
19597
+ return (0, import_delimited2.parseDelimited)(text, { delimiter, skipEmptyLines: "greedy" }).data;
19568
19598
  }
19569
19599
  function delimitedShape(text, delimiter, fenced, at, name) {
19570
19600
  const matrix = parseDelimited(text.trim(), delimiter);
@@ -23331,8 +23361,11 @@ function GridBody({
23331
23361
  const rowMemoryKey = `${tableId}:${embedded ? "embedded" : "page"}:${openingKey}`;
23332
23362
  const rowsAnswered = Boolean(records.data) && !records.loading && !table.loading && !fields.loading;
23333
23363
  (0, import_react112.useEffect)(() => {
23334
- if (rowsAnswered) rememberRowCount(rowMemoryKey, rows.length);
23335
- }, [rowsAnswered, rowMemoryKey, rows.length]);
23364
+ if (rowsAnswered) {
23365
+ rememberRowCount(rowMemoryKey, rows.length);
23366
+ if (!embedded) rememberRowCount(`${tableId}:page:last`, rows.length);
23367
+ }
23368
+ }, [rowsAnswered, rowMemoryKey, rows.length, embedded, tableId]);
23336
23369
  if (table.error) return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(RefusalNotice, { error: table.error, className });
23337
23370
  if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(RefusalNotice, { error: fields.error, className });
23338
23371
  const nothingToShowYet = table.loading || fields.loading || !rights.known || records.loading && rows.length === 0 || // The page read has neither answered nor refused: nothing has been said yet, so nothing is empty.
@@ -23517,7 +23550,7 @@ function GridBody({
23517
23550
  {
23518
23551
  ...fills ? { className: "min-h-0 flex-1" } : {},
23519
23552
  frameHeight: fills ? "fill" : "content",
23520
- loadingRows: fills ? "fill" : rememberedRowCount(rowMemoryKey, pageSize, 5),
23553
+ loadingRows: rememberedRowCount(rowMemoryKey, pageSize, fills ? "fill" : 5),
23521
23554
  ...!look.rowHeight ? { loadingRowHeight: RECORDS_GRID_ROW_PX } : {},
23522
23555
  data: rows,
23523
23556
  columns: tableColumns,
@@ -27456,7 +27489,7 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
27456
27489
  },
27457
27490
  variant: "destructive",
27458
27491
  title: `Move every row of \u201C${writable.find((t) => t.id === tableId)?.name ?? "this table"}\u201D to the archive?`,
27459
- description: "They stay restorable from the table's Archived items. Then the rows you are saving go in, through the import below.",
27492
+ description: "Restorable from Archived items",
27460
27493
  confirmLabel: replacing ? "Archiving\u2026" : "Archive them",
27461
27494
  cancelLabel: "Keep them",
27462
27495
  busy: replacing,
@@ -28943,18 +28976,25 @@ function RecordFieldsInPlace({
28943
28976
  const format = formatForField(field2);
28944
28977
  return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "contents", children: [
28945
28978
  /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("dt", { className: "flex items-baseline gap-1 truncate py-1 text-muted-foreground", children: renderLabel(field2) }),
28946
- /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("dd", { className: "min-w-0 rounded hover:bg-muted/50", "data-records-in-place-field": field2.key, children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
28947
- GridCell,
28979
+ /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
28980
+ "dd",
28948
28981
  {
28949
- field: field2,
28950
- row,
28951
- editing: canWrite ? editing : null,
28952
- canWrite,
28953
- whyNot,
28954
- clickOpens: true,
28955
- ...format ? { format } : {}
28982
+ className: "min-w-0 rounded hover:bg-muted/50 [&_[data-matrx-cell-editor]_input:not([type=checkbox]):not([type=radio])]:!h-7",
28983
+ "data-records-in-place-field": field2.key,
28984
+ children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
28985
+ GridCell,
28986
+ {
28987
+ field: field2,
28988
+ row,
28989
+ editing: canWrite ? editing : null,
28990
+ canWrite,
28991
+ whyNot,
28992
+ clickOpens: true,
28993
+ ...format ? { format } : {}
28994
+ }
28995
+ )
28956
28996
  }
28957
- ) })
28997
+ )
28958
28998
  ] }, field2.id);
28959
28999
  }) }),
28960
29000
  /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(UndoNotice, { undo })
@@ -29151,7 +29191,7 @@ function AddBody({ tableId }) {
29151
29191
  const made = await mutation.declare({ table_id: tableId, spec: { label: BODY_COLUMN_NAME, type: "rich_text" } });
29152
29192
  if (made) (0, import_react160.tableShapeChanged)(tableId);
29153
29193
  },
29154
- children: "Write on this page"
29194
+ children: "Add notes"
29155
29195
  }
29156
29196
  ),
29157
29197
  mutation.error ? /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(RefusalNotice, { error: mutation.error }) : null
@@ -29296,7 +29336,7 @@ function computedInPlainWords(row, field2) {
29296
29336
  const shown4 = row.value === null || row.value === void 0 || row.value === "" ? "nothing" : field2 ? scalarText(field2, row.value) : String(row.value);
29297
29337
  const when = new Date(row.computed_at);
29298
29338
  const at = Number.isNaN(when.getTime()) ? "" : ` on ${when.toLocaleDateString()}`;
29299
- return `${name} was worked out as ${shown4}${at}.`;
29339
+ return `${name}: ${shown4}${at}`;
29300
29340
  }
29301
29341
 
29302
29342
  // src/systemTable.ts
@@ -29526,7 +29566,10 @@ async function keepLook(client, tableId, viewId, look) {
29526
29566
  return client.viewLookSet({ table_id: tableId, view_id: viewId, look: doc && Object.keys(doc).length > 0 ? doc : null });
29527
29567
  }
29528
29568
  var LOOK_WORDS = {
29569
+ /** The reason, for a tooltip or a screen reader — never a line on the page (interface-text). */
29529
29570
  yours: "You changed how this view looks. Only you see it.",
29571
+ /** The visible label for the same fact. */
29572
+ yoursLabel: "Only you see this",
29530
29573
  saveToView: "Save to view",
29531
29574
  saveAsNew: "Save as new view",
29532
29575
  reset: "Reset to view",
@@ -39196,7 +39239,7 @@ function WebhooksPanel({ tableId, className }) {
39196
39239
  if (!next && !busy) setStopping(null);
39197
39240
  },
39198
39241
  title: `Stop sending to ${stopping?.description ?? stopping?.target_url ?? "this address"}?`,
39199
- description: "Changes from now on are not sent there. The webhook is kept, switched off \u2014 nothing about it is deleted.",
39242
+ description: "Kept, switched off",
39200
39243
  confirmLabel: "Switch off",
39201
39244
  cancelLabel: "Keep sending",
39202
39245
  busy,
@@ -41590,7 +41633,7 @@ function SignBlock({ tableId, recordId, render, className }) {
41590
41633
  }
41591
41634
 
41592
41635
  // src/ChartBlock.tsx
41593
- var import_react232 = require("react");
41636
+ var import_react234 = require("react");
41594
41637
  var import_recharts = require("recharts");
41595
41638
  var import_records57 = require("@ai-matrx/records");
41596
41639
  var import_core21 = require("@ai-matrx/records/core");
@@ -41650,6 +41693,39 @@ function useLinkGroupNamer(block, tableId) {
41650
41693
  }, [named, choices, labels]);
41651
41694
  }
41652
41695
 
41696
+ // src/measureWords.ts
41697
+ var import_react232 = require("react");
41698
+ var import_react233 = require("@ai-matrx/records/react");
41699
+ var import_text_case18 = require("@ai-matrx/kit/text-case");
41700
+ var OP_WORD = { sum: "Total", avg: "Average", min: "Lowest", max: "Highest" };
41701
+ function measureWords(key, fields) {
41702
+ if (key === "count") return "How many";
41703
+ const at = key.indexOf("_");
41704
+ if (at < 0) return (0, import_text_case18.humanizeIdentifier)(key);
41705
+ const op2 = key.slice(0, at);
41706
+ const column = key.slice(at + 1);
41707
+ const field2 = fields?.find((f) => f.key === column);
41708
+ const name = field2 ? fieldName(field2) : (0, import_text_case18.humanizeIdentifier)(column);
41709
+ const word = OP_WORD[op2];
41710
+ return word ? `${word} ${name.charAt(0).toLowerCase()}${name.slice(1)}` : `${(0, import_text_case18.humanizeIdentifier)(op2)} ${name}`;
41711
+ }
41712
+ function useMeasureWords(key, tableId) {
41713
+ const client = (0, import_react233.useOptionalRecordsClient)();
41714
+ const [fields, setFields] = (0, import_react232.useState)(null);
41715
+ const needs = key !== "count";
41716
+ (0, import_react232.useEffect)(() => {
41717
+ if (!client || !tableId || !needs) return;
41718
+ let cancelled = false;
41719
+ void client.fields({ table_id: tableId }).then((result) => {
41720
+ if (!cancelled && result.ok) setFields(result.data);
41721
+ });
41722
+ return () => {
41723
+ cancelled = true;
41724
+ };
41725
+ }, [client, tableId, needs]);
41726
+ return measureWords(key, fields);
41727
+ }
41728
+
41653
41729
  // src/ChartBlock.tsx
41654
41730
  var import_jsx_runtime134 = require("react/jsx-runtime");
41655
41731
  var priorKey = (key) => `prior__${key}`;
@@ -41728,7 +41804,8 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41728
41804
  const series = compared ? [primary, priorKey(primary)] : [primary];
41729
41805
  const target = kind === "stuck" ? null : block.target ?? null;
41730
41806
  const named = useLinkGroupNamer(source ? NO_GROUPS : block, tableId);
41731
- const points = (0, import_react232.useMemo)(() => {
41807
+ const measureName = useMeasureWords(primary, tableId);
41808
+ const points = (0, import_react234.useMemo)(() => {
41732
41809
  if (kind === "stuck") return [];
41733
41810
  const rows = block.rows ?? [];
41734
41811
  return rows.map((row, index) => {
@@ -41752,10 +41829,10 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41752
41829
  };
41753
41830
  });
41754
41831
  }, [block.rows, kind, primary, compared, grain, windows, named]);
41755
- const config = (0, import_react232.useMemo)(() => {
41832
+ const config = (0, import_react234.useMemo)(() => {
41756
41833
  const out = {};
41757
41834
  out[primary] = {
41758
- label: windows ? windowName(windows.window, windows.period) : primary.replace("_", " of "),
41835
+ label: windows ? windowName(windows.window, windows.period) : measureName,
41759
41836
  color: SERIES_COLORS[0]
41760
41837
  };
41761
41838
  if (windows) {
@@ -41768,7 +41845,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41768
41845
  out[point.label] ??= { label: point.label, color: SERIES_COLORS[index % SERIES_COLORS.length] };
41769
41846
  });
41770
41847
  return out;
41771
- }, [primary, windows, points]);
41848
+ }, [primary, measureName, windows, points]);
41772
41849
  const goal = target && typeof target.value === "number" ? {
41773
41850
  value: typeof target.pace === "number" ? target.pace : block.bucket ? null : target.value,
41774
41851
  label: typeof target.pace === "number" && target.per !== "bucket" ? `${target.label} pace` : target.label
@@ -41813,7 +41890,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41813
41890
  /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { children: pretty(block.totals.current) }),
41814
41891
  /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(Trend, { pct: block.totals.change_pct, aimingUp: !!target })
41815
41892
  ] }) : null,
41816
- /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { className: "ml-auto shrink-0 text-muted-foreground", children: kind === "stuck" ? `${block.days ?? 14} days` : primary.replace("_", " of ") })
41893
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { className: "ml-auto shrink-0 text-muted-foreground", children: kind === "stuck" ? `${block.days ?? 14} days` : measureName })
41817
41894
  ] }),
41818
41895
  block.compare_refused ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: block.compare_refused }) : null,
41819
41896
  !block.refused && targetNote(target) ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: targetNote(target) }) : null,
@@ -42110,8 +42187,8 @@ function onlyWholeNumbers(rows) {
42110
42187
  }
42111
42188
 
42112
42189
  // src/DashboardCanvas.tsx
42113
- var import_react239 = require("react");
42114
- var import_react240 = require("@ai-matrx/records/react");
42190
+ var import_react241 = require("react");
42191
+ var import_react242 = require("@ai-matrx/records/react");
42115
42192
  var import_design_system124 = require("@ai-matrx/design-system");
42116
42193
 
42117
42194
  // src/DashboardGrid.tsx
@@ -42253,18 +42330,18 @@ function GridCell2({
42253
42330
  }
42254
42331
 
42255
42332
  // src/AddChart.tsx
42256
- var import_react237 = require("react");
42257
- var import_react238 = require("@ai-matrx/records/react");
42333
+ var import_react239 = require("react");
42334
+ var import_react240 = require("@ai-matrx/records/react");
42258
42335
  var import_design_system123 = require("@ai-matrx/design-system");
42259
42336
 
42260
42337
  // src/TablePickers.tsx
42261
- var import_react235 = require("react");
42262
- var import_react236 = require("@ai-matrx/records/react");
42338
+ var import_react237 = require("react");
42339
+ var import_react238 = require("@ai-matrx/records/react");
42263
42340
  var import_design_system122 = require("@ai-matrx/design-system");
42264
42341
 
42265
42342
  // src/RecordsMount.tsx
42266
- var import_react233 = require("react");
42267
- var import_react234 = require("@ai-matrx/records/react");
42343
+ var import_react235 = require("react");
42344
+ var import_react236 = require("@ai-matrx/records/react");
42268
42345
  var import_jsx_runtime136 = require("react/jsx-runtime");
42269
42346
  var STORE_DECIDES_REASON = "This host offers exactly what the record store says this person may do: the level comes back with the table on the read door, so a control they cannot use is never drawn in the first place.";
42270
42347
  function storeDecidesRights(_table) {
@@ -42278,10 +42355,10 @@ function RecordsMount({
42278
42355
  }) {
42279
42356
  const bound2 = useShallowStableHost(host);
42280
42357
  void letTheStoreDecideRights;
42281
- return /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(import_react234.RecordsProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(RecordsUiProvider, { value: bound2, children: /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(RecordLabelProvider, { children }) }) });
42358
+ return /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(import_react236.RecordsProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(RecordsUiProvider, { value: bound2, children: /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(RecordLabelProvider, { children }) }) });
42282
42359
  }
42283
42360
  function useShallowStableHost(host) {
42284
- const held = (0, import_react233.useRef)(null);
42361
+ const held = (0, import_react235.useRef)(null);
42285
42362
  const next = host ?? {};
42286
42363
  const previous = held.current;
42287
42364
  if (previous !== null && sameParts(previous, next)) return previous;
@@ -42376,8 +42453,8 @@ function readTablesAnywhere(dataSource) {
42376
42453
  return read;
42377
42454
  }
42378
42455
  function useTablesAnywhere(dataSource) {
42379
- const [state, setState] = (0, import_react235.useState)({ loading: true, error: null, rows: [] });
42380
- (0, import_react235.useEffect)(() => {
42456
+ const [state, setState] = (0, import_react237.useState)({ loading: true, error: null, rows: [] });
42457
+ (0, import_react237.useEffect)(() => {
42381
42458
  let live = true;
42382
42459
  void readTablesAnywhere(dataSource).then((result) => {
42383
42460
  if (live) setState(result);
@@ -42447,14 +42524,14 @@ function TableScope({ dataSource, userId, tableId, children, fallback = null, un
42447
42524
  const organizationId = list.rows.find((t) => t.table_id === tableId)?.organization_id ?? null;
42448
42525
  if (tableId && !organizationId && !list.loading) return /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_jsx_runtime137.Fragment, { children: unavailable ?? fallback });
42449
42526
  if (!tableId || !organizationId) return /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_jsx_runtime137.Fragment, { children: fallback });
42450
- return /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_react236.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children });
42527
+ return /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_react238.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children });
42451
42528
  }
42452
42529
  function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
42453
- const fields = (0, import_react236.useFields)(tableId);
42454
- const all = (0, import_react235.useMemo)(() => fields.data ?? [], [fields.data]);
42455
- const byKey = (0, import_react235.useMemo)(() => new Map(all.map((f) => [f.key, f])), [all]);
42530
+ const fields = (0, import_react238.useFields)(tableId);
42531
+ const all = (0, import_react237.useMemo)(() => fields.data ?? [], [fields.data]);
42532
+ const byKey = (0, import_react237.useMemo)(() => new Map(all.map((f) => [f.key, f])), [all]);
42456
42533
  const keys = Object.keys(value);
42457
- const [adding, setAdding] = (0, import_react235.useState)(false);
42534
+ const [adding, setAdding] = (0, import_react237.useState)(false);
42458
42535
  const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
42459
42536
  const rename = (from, to) => {
42460
42537
  if (from === to) return;
@@ -42542,8 +42619,8 @@ function ColumnValueRow({
42542
42619
  ] });
42543
42620
  }
42544
42621
  function RecordPicker({ tableId, value, onChange, disabled }) {
42545
- const table = (0, import_react236.useTable)(tableId);
42546
- const records = (0, import_react236.useRecords)(tableId, { pageSize: 200 });
42622
+ const table = (0, import_react238.useTable)(tableId);
42623
+ const records = (0, import_react238.useRecords)(tableId, { pageSize: 200 });
42547
42624
  const rows = records.data?.rows ?? [];
42548
42625
  const options = rows.map((row) => ({
42549
42626
  value: row.id,
@@ -42609,20 +42686,20 @@ function chartSpecFrom(args) {
42609
42686
  };
42610
42687
  }
42611
42688
  function AddChart({ subject, onAdd, onClose }) {
42612
- const client = (0, import_react238.useRecordsClient)();
42613
- const [tableId, setTableId] = (0, import_react237.useState)(subject);
42614
- const fields = (0, import_react238.useFields)(tableId);
42615
- const all = (0, import_react237.useMemo)(() => onePerKey(fields.data ?? []), [fields.data]);
42689
+ const client = (0, import_react240.useRecordsClient)();
42690
+ const [tableId, setTableId] = (0, import_react239.useState)(subject);
42691
+ const fields = (0, import_react240.useFields)(tableId);
42692
+ const all = (0, import_react239.useMemo)(() => onePerKey(fields.data ?? []), [fields.data]);
42616
42693
  const labels = useRecordLabels(all);
42617
42694
  const wordsFor2 = (key, value) => {
42618
42695
  const field2 = all.find((f) => f.key === key);
42619
42696
  return field2 ? scalarText(field2, value, labels) : String(value);
42620
42697
  };
42621
- const [measureKey5, setMeasureKey] = (0, import_react237.useState)("count");
42622
- const [splitKey, setSplitKey] = (0, import_react237.useState)("none");
42623
- const [kind, setKind] = (0, import_react237.useState)("auto");
42624
- const [filter, setFilter] = (0, import_react237.useState)({});
42625
- const [saving, setSaving] = (0, import_react237.useState)(false);
42698
+ const [measureKey5, setMeasureKey] = (0, import_react239.useState)("count");
42699
+ const [splitKey, setSplitKey] = (0, import_react239.useState)("none");
42700
+ const [kind, setKind] = (0, import_react239.useState)("auto");
42701
+ const [filter, setFilter] = (0, import_react239.useState)({});
42702
+ const [saving, setSaving] = (0, import_react239.useState)(false);
42626
42703
  const numbers = numberColumns(all);
42627
42704
  const choices = offerableFields(all, "choice");
42628
42705
  const dates = offerableFields(all, "date");
@@ -42764,31 +42841,31 @@ function combineFilter(base, extra, fieldIdOf) {
42764
42841
  // src/DashboardCanvas.tsx
42765
42842
  var import_jsx_runtime139 = require("react/jsx-runtime");
42766
42843
  function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, onCreated, className }) {
42767
- const client = (0, import_react240.useRecordsClient)();
42844
+ const client = (0, import_react242.useRecordsClient)();
42768
42845
  const host = useRecordsUi();
42769
- const table = (0, import_react240.useTable)(tableId);
42846
+ const table = (0, import_react242.useTable)(tableId);
42770
42847
  const rights = useTableRights(table.data);
42771
- const fields = (0, import_react240.useFields)(tableId);
42772
- const [boards, setBoards] = (0, import_react239.useState)(null);
42773
- const [pages, setPages] = (0, import_react239.useState)([]);
42774
- const [error, setError] = (0, import_react239.useState)(null);
42775
- const [activeId, setActiveId] = (0, import_react239.useState)(activeDashboardId ?? null);
42776
- const [madeOnMount, setMadeOnMount] = (0, import_react239.useState)("waiting");
42777
- const [askingToRemove, setAskingToRemove] = (0, import_react239.useState)(null);
42778
- const [run, setRun] = (0, import_react239.useState)(null);
42779
- const [running, setRunning] = (0, import_react239.useState)(false);
42780
- const [question, setQuestion] = (0, import_react239.useState)("");
42781
- const [asking, setAsking] = (0, import_react239.useState)(false);
42782
- const [scheduling, setScheduling] = (0, import_react239.useState)(false);
42783
- const [arranging, setArranging] = (0, import_react239.useState)(false);
42784
- const [adding, setAdding] = (0, import_react239.useState)(false);
42785
- const [grain, setGrain] = (0, import_react239.useState)(null);
42848
+ const fields = (0, import_react242.useFields)(tableId);
42849
+ const [boards, setBoards] = (0, import_react241.useState)(null);
42850
+ const [pages, setPages] = (0, import_react241.useState)([]);
42851
+ const [error, setError] = (0, import_react241.useState)(null);
42852
+ const [activeId, setActiveId] = (0, import_react241.useState)(activeDashboardId ?? null);
42853
+ const [madeOnMount, setMadeOnMount] = (0, import_react241.useState)("waiting");
42854
+ const [askingToRemove, setAskingToRemove] = (0, import_react241.useState)(null);
42855
+ const [run, setRun] = (0, import_react241.useState)(null);
42856
+ const [running, setRunning] = (0, import_react241.useState)(false);
42857
+ const [question, setQuestion] = (0, import_react241.useState)("");
42858
+ const [asking, setAsking] = (0, import_react241.useState)(false);
42859
+ const [scheduling, setScheduling] = (0, import_react241.useState)(false);
42860
+ const [arranging, setArranging] = (0, import_react241.useState)(false);
42861
+ const [adding, setAdding] = (0, import_react241.useState)(false);
42862
+ const [grain, setGrain] = (0, import_react241.useState)(null);
42786
42863
  const runArgs = (dashboard_id) => ({
42787
42864
  dashboard_id,
42788
42865
  ...filter ? { filter } : {},
42789
42866
  ...grain ? { grain } : {}
42790
42867
  });
42791
- const load = (0, import_react239.useCallback)(async () => {
42868
+ const load = (0, import_react241.useCallback)(async () => {
42792
42869
  const answered = await client.dashboards({ table_id: tableId });
42793
42870
  if (!answered.ok) {
42794
42871
  setError(answered.error);
@@ -42800,19 +42877,19 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42800
42877
  setBoards(read);
42801
42878
  return read;
42802
42879
  }, [client, tableId]);
42803
- const [notKept, setNotKept] = (0, import_react239.useState)(null);
42804
- (0, import_react239.useEffect)(() => {
42880
+ const [notKept, setNotKept] = (0, import_react241.useState)(null);
42881
+ (0, import_react241.useEffect)(() => {
42805
42882
  void load();
42806
42883
  }, [load]);
42807
- (0, import_react239.useEffect)(() => {
42884
+ (0, import_react241.useEffect)(() => {
42808
42885
  if (!boards || boards.length === 0) return;
42809
42886
  if (createOnMount && madeOnMount !== "done") return;
42810
42887
  const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
42811
42888
  if (chosen.id !== activeId) setActiveId(chosen.id);
42812
42889
  }, [boards, activeDashboardId, madeOnMount]);
42813
- const board = (0, import_react239.useMemo)(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
42890
+ const board = (0, import_react241.useMemo)(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
42814
42891
  const filterKey = JSON.stringify(filter ?? {});
42815
- (0, import_react239.useEffect)(() => {
42892
+ (0, import_react241.useEffect)(() => {
42816
42893
  if (!activeId) {
42817
42894
  setRun(null);
42818
42895
  return;
@@ -42830,7 +42907,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42830
42907
  cancelled = true;
42831
42908
  };
42832
42909
  }, [client, activeId, filterKey, grain]);
42833
- const declare2 = (0, import_react239.useCallback)(
42910
+ const declare2 = (0, import_react241.useCallback)(
42834
42911
  async (next, blocks) => {
42835
42912
  const written = await client.dashboardDeclare(
42836
42913
  // Every block leaves with its own id — kept, or minted here (v6 lane 11).
@@ -42882,12 +42959,12 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42882
42959
  ]
42883
42960
  );
42884
42961
  }
42885
- (0, import_react239.useEffect)(() => {
42962
+ (0, import_react241.useEffect)(() => {
42886
42963
  if (!createOnMount || madeOnMount !== "waiting" || boards === null || !fields.data) return;
42887
42964
  setMadeOnMount("making");
42888
42965
  void create().then(() => setMadeOnMount("done"));
42889
42966
  }, [createOnMount, madeOnMount, boards, fields.data]);
42890
- const refresh = (0, import_react239.useCallback)(async () => {
42967
+ const refresh = (0, import_react241.useCallback)(async () => {
42891
42968
  if (!activeId) return;
42892
42969
  setRunning(true);
42893
42970
  const again = await client.dashboardRun(runArgs(activeId));
@@ -43099,7 +43176,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
43099
43176
  ] });
43100
43177
  }
43101
43178
  function ChartOfTable({ block, subject, table }) {
43102
- const named = (0, import_react240.useTable)(table);
43179
+ const named = (0, import_react242.useTable)(table);
43103
43180
  return /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(ChartBlock, { block, subject, tableName: named.data?.name ?? "\u2014" });
43104
43181
  }
43105
43182
  function BlockSettingsMenu({
@@ -43129,7 +43206,7 @@ function BlockSettings({
43129
43206
  title,
43130
43207
  onChange
43131
43208
  }) {
43132
- const own3 = (0, import_react240.useFields)(spec.subject);
43209
+ const own3 = (0, import_react242.useFields)(spec.subject);
43133
43210
  const fields = own3.data ?? [];
43134
43211
  return /* @__PURE__ */ (0, import_jsx_runtime139.jsxs)("div", { className: "flex flex-col items-stretch gap-1.5 text-xs", children: [
43135
43212
  /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(
@@ -43327,10 +43404,10 @@ function TargetControl({
43327
43404
  onChange
43328
43405
  }) {
43329
43406
  const saved = !block.target ? "none" : "field" in block.target && block.target.field ? "field" : "value";
43330
- const [mode, setMode] = (0, import_react239.useState)(saved);
43407
+ const [mode, setMode] = (0, import_react241.useState)(saved);
43331
43408
  const savedValue = block.target && "value" in block.target && typeof block.target.value === "number" ? block.target.value : null;
43332
- const [draft, setDraft] = (0, import_react239.useState)(savedValue === null ? "" : String(savedValue));
43333
- (0, import_react239.useEffect)(() => {
43409
+ const [draft, setDraft] = (0, import_react241.useState)(savedValue === null ? "" : String(savedValue));
43410
+ (0, import_react241.useEffect)(() => {
43334
43411
  setMode(saved);
43335
43412
  setDraft(savedValue === null ? "" : String(savedValue));
43336
43413
  }, [saved, savedValue]);
@@ -43398,9 +43475,9 @@ function TargetControl({
43398
43475
 
43399
43476
  // src/QuestionPanel.tsx
43400
43477
  var import_clipboard9 = require("@ai-matrx/kit/clipboard");
43401
- var import_react241 = require("react");
43478
+ var import_react243 = require("react");
43402
43479
  var import_design_system125 = require("@ai-matrx/design-system");
43403
- var import_react242 = require("@ai-matrx/records/react");
43480
+ var import_react244 = require("@ai-matrx/records/react");
43404
43481
 
43405
43482
  // src/question.ts
43406
43483
  var import_records59 = require("@ai-matrx/records");
@@ -43811,13 +43888,13 @@ function fromLocalInput(value) {
43811
43888
  return Number.isNaN(d.getTime()) ? null : d.toISOString();
43812
43889
  }
43813
43890
  function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43814
- const client = (0, import_react242.useRecordsClient)();
43815
- const fields = (0, import_react242.useFields)(tableId);
43816
- const all = (0, import_react241.useMemo)(() => fields.data ?? [], [fields.data]);
43891
+ const client = (0, import_react244.useRecordsClient)();
43892
+ const fields = (0, import_react244.useFields)(tableId);
43893
+ const all = (0, import_react243.useMemo)(() => fields.data ?? [], [fields.data]);
43817
43894
  const me = client.config.actor?.user_id ?? null;
43818
- const [hidden, setHidden] = (0, import_react241.useState)(null);
43819
- const [related, setRelated] = (0, import_react241.useState)({});
43820
- (0, import_react241.useEffect)(() => {
43895
+ const [hidden, setHidden] = (0, import_react243.useState)(null);
43896
+ const [related, setRelated] = (0, import_react243.useState)({});
43897
+ (0, import_react243.useEffect)(() => {
43821
43898
  if (all.length === 0) {
43822
43899
  if (!fields.loading) setHidden(/* @__PURE__ */ new Set());
43823
43900
  return;
@@ -43840,18 +43917,18 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43840
43917
  live = false;
43841
43918
  };
43842
43919
  }, [client, tableId, all, fields.loading]);
43843
- const offered = (0, import_react241.useMemo)(() => hidden ? all.filter((f) => !hidden.has(f.key)) : [], [all, hidden]);
43844
- const [saved, setSaved] = (0, import_react241.useState)(null);
43845
- const [savedEpoch, setSavedEpoch] = (0, import_react241.useState)(0);
43846
- const [current, setCurrent] = (0, import_react241.useState)(null);
43847
- const [spec, setSpec] = (0, import_react241.useState)(newQuestion);
43848
- const [name, setName] = (0, import_react241.useState)("");
43849
- const [shared, setShared] = (0, import_react241.useState)(true);
43850
- const [saveError, setSaveError] = (0, import_react241.useState)(null);
43851
- const [saving, setSaving] = (0, import_react241.useState)(false);
43852
- const [linkMissed, setLinkMissed] = (0, import_react241.useState)(false);
43853
- const openedFromLink = (0, import_react241.useRef)(false);
43854
- (0, import_react241.useEffect)(() => {
43920
+ const offered = (0, import_react243.useMemo)(() => hidden ? all.filter((f) => !hidden.has(f.key)) : [], [all, hidden]);
43921
+ const [saved, setSaved] = (0, import_react243.useState)(null);
43922
+ const [savedEpoch, setSavedEpoch] = (0, import_react243.useState)(0);
43923
+ const [current, setCurrent] = (0, import_react243.useState)(null);
43924
+ const [spec, setSpec] = (0, import_react243.useState)(newQuestion);
43925
+ const [name, setName] = (0, import_react243.useState)("");
43926
+ const [shared, setShared] = (0, import_react243.useState)(true);
43927
+ const [saveError, setSaveError] = (0, import_react243.useState)(null);
43928
+ const [saving, setSaving] = (0, import_react243.useState)(false);
43929
+ const [linkMissed, setLinkMissed] = (0, import_react243.useState)(false);
43930
+ const openedFromLink = (0, import_react243.useRef)(false);
43931
+ (0, import_react243.useEffect)(() => {
43855
43932
  let live = true;
43856
43933
  void questionsOf(client, tableId).then((answer2) => {
43857
43934
  if (!live) return;
@@ -43874,16 +43951,16 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43874
43951
  setShared(q ? q.shared : true);
43875
43952
  setSaveError(null);
43876
43953
  };
43877
- (0, import_react241.useEffect)(() => {
43954
+ (0, import_react243.useEffect)(() => {
43878
43955
  if (!draft) return;
43879
43956
  open(null);
43880
43957
  setSpec(draft);
43881
43958
  }, [draft]);
43882
43959
  const mine = !current || me !== null && current.createdBy === me;
43883
- const [answer, setAnswer] = (0, import_react241.useState)(null);
43884
- const [asking, setAsking] = (0, import_react241.useState)(false);
43960
+ const [answer, setAnswer] = (0, import_react243.useState)(null);
43961
+ const [asking, setAsking] = (0, import_react243.useState)(false);
43885
43962
  const specKey = JSON.stringify(spec);
43886
- (0, import_react241.useEffect)(() => {
43963
+ (0, import_react243.useEffect)(() => {
43887
43964
  if (all.length === 0) return;
43888
43965
  let live = true;
43889
43966
  setAsking(true);
@@ -44229,7 +44306,7 @@ function formatValue(key, value, fields) {
44229
44306
  return new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(value);
44230
44307
  }
44231
44308
  function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATED }) {
44232
- const block = (0, import_react241.useMemo)(
44309
+ const block = (0, import_react243.useMemo)(
44233
44310
  () => ({
44234
44311
  kind: "table",
44235
44312
  group_by: answer.groupKey && spec.group?.kind === "field" ? [answer.groupKey] : [],
@@ -44325,10 +44402,10 @@ function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATE
44325
44402
  }
44326
44403
 
44327
44404
  // src/TableAsk.tsx
44328
- var import_react243 = require("react");
44405
+ var import_react245 = require("react");
44329
44406
  var import_design_system126 = require("@ai-matrx/design-system");
44330
44407
  var import_records60 = require("@ai-matrx/records");
44331
- var import_react244 = require("@ai-matrx/records/react");
44408
+ var import_react246 = require("@ai-matrx/records/react");
44332
44409
 
44333
44410
  // src/askWords.ts
44334
44411
  var ASK_EXAMPLE = "count where Status is Open by Unit";
@@ -44545,12 +44622,12 @@ function askExampleFor(fields) {
44545
44622
  return by ? `count by ${fieldName(by)}` : "count";
44546
44623
  }
44547
44624
  function TableAsk({ tableId, onOpenInQuestions }) {
44548
- const client = (0, import_react244.useRecordsClient)();
44549
- const fields = (0, import_react244.useFields)(tableId);
44625
+ const client = (0, import_react246.useRecordsClient)();
44626
+ const fields = (0, import_react246.useFields)(tableId);
44550
44627
  const all = fields.data ?? [];
44551
- const [open, setOpen] = (0, import_react243.useState)(false);
44552
- const [words2, setWords] = (0, import_react243.useState)("");
44553
- const [said, setSaid] = (0, import_react243.useState)({ kind: "idle" });
44628
+ const [open, setOpen] = (0, import_react245.useState)(false);
44629
+ const [words2, setWords] = (0, import_react245.useState)("");
44630
+ const [said, setSaid] = (0, import_react245.useState)({ kind: "idle" });
44554
44631
  const ask = async () => {
44555
44632
  if (words2.trim() === "" || all.length === 0) return;
44556
44633
  const choices = {};
@@ -44623,8 +44700,8 @@ function TableAsk({ tableId, onOpenInQuestions }) {
44623
44700
  }
44624
44701
 
44625
44702
  // src/PageScreen.tsx
44626
- var import_react245 = require("react");
44627
- var import_react246 = require("@ai-matrx/records/react");
44703
+ var import_react247 = require("react");
44704
+ var import_react248 = require("@ai-matrx/records/react");
44628
44705
  var import_core24 = require("@ai-matrx/records/core");
44629
44706
  var import_design_system127 = require("@ai-matrx/design-system");
44630
44707
  var import_jsx_runtime142 = require("react/jsx-runtime");
@@ -44639,23 +44716,23 @@ function PageScreen({
44639
44716
  header,
44640
44717
  className
44641
44718
  }) {
44642
- const client = (0, import_react246.useRecordsClient)();
44719
+ const client = (0, import_react248.useRecordsClient)();
44643
44720
  const host = useRecordsUi();
44644
44721
  const organizationId = client.config.organizationId;
44645
- const [page, setPage] = (0, import_react245.useState)(null);
44646
- const [missing, setMissing] = (0, import_react245.useState)(false);
44647
- const [error, setError] = (0, import_react245.useState)(null);
44648
- const [level, setLevel] = (0, import_react245.useState)(null);
44649
- const [editing, setEditing] = (0, import_react245.useState)(startEditing);
44650
- const [run, setRun] = (0, import_react245.useState)(null);
44651
- const [saveError, setSaveError] = (0, import_react245.useState)(null);
44652
- const [askingToArchive, setAskingToArchive] = (0, import_react245.useState)(false);
44653
- const [selected, setSelected] = (0, import_react245.useState)({});
44654
- const [filterValues, setFilterValues] = (0, import_react245.useState)({});
44655
- const [mine, setMine] = (0, import_react245.useState)({});
44656
- const [making, setMaking] = (0, import_react245.useState)("waiting");
44722
+ const [page, setPage] = (0, import_react247.useState)(null);
44723
+ const [missing, setMissing] = (0, import_react247.useState)(false);
44724
+ const [error, setError] = (0, import_react247.useState)(null);
44725
+ const [level, setLevel] = (0, import_react247.useState)(null);
44726
+ const [editing, setEditing] = (0, import_react247.useState)(startEditing);
44727
+ const [run, setRun] = (0, import_react247.useState)(null);
44728
+ const [saveError, setSaveError] = (0, import_react247.useState)(null);
44729
+ const [askingToArchive, setAskingToArchive] = (0, import_react247.useState)(false);
44730
+ const [selected, setSelected] = (0, import_react247.useState)({});
44731
+ const [filterValues, setFilterValues] = (0, import_react247.useState)({});
44732
+ const [mine, setMine] = (0, import_react247.useState)({});
44733
+ const [making, setMaking] = (0, import_react247.useState)("waiting");
44657
44734
  const id = page?.id ?? pageId ?? null;
44658
- const load = (0, import_react245.useCallback)(
44735
+ const load = (0, import_react247.useCallback)(
44659
44736
  async (want) => {
44660
44737
  const answered = await client.dashboards({ table_id: null });
44661
44738
  if (!answered.ok) {
@@ -44674,7 +44751,7 @@ function PageScreen({
44674
44751
  },
44675
44752
  [client]
44676
44753
  );
44677
- (0, import_react245.useEffect)(() => {
44754
+ (0, import_react247.useEffect)(() => {
44678
44755
  if (!newOnTable || pageId || making !== "waiting") return;
44679
44756
  setMaking("making");
44680
44757
  void client.dashboardDeclare({
@@ -44694,11 +44771,11 @@ function PageScreen({
44694
44771
  onCreated?.(made.data);
44695
44772
  });
44696
44773
  }, [client, newOnTable, pageId, making, load, onCreated]);
44697
- (0, import_react245.useEffect)(() => {
44774
+ (0, import_react247.useEffect)(() => {
44698
44775
  if (!pageId) return;
44699
44776
  void load(pageId);
44700
44777
  }, [pageId, load]);
44701
- (0, import_react245.useEffect)(() => {
44778
+ (0, import_react247.useEffect)(() => {
44702
44779
  if (!id) return;
44703
44780
  let live = true;
44704
44781
  void client.myLevels({ ids: [id], subject: "record" }).then((answered) => {
@@ -44710,7 +44787,7 @@ function PageScreen({
44710
44787
  }, [client, id]);
44711
44788
  const canEdit = level !== null && EDIT_LEVELS.has(level);
44712
44789
  const chartKey = page ? JSON.stringify(page.blocks.map((b) => b.id)) + page.version : "";
44713
- (0, import_react245.useEffect)(() => {
44790
+ (0, import_react247.useEffect)(() => {
44714
44791
  if (!page || page.blocks.length === 0) {
44715
44792
  setRun(null);
44716
44793
  return;
@@ -44725,11 +44802,11 @@ function PageScreen({
44725
44802
  live = false;
44726
44803
  };
44727
44804
  }, [client, chartKey]);
44728
- const blocks = (0, import_react245.useMemo)(
44805
+ const blocks = (0, import_react247.useMemo)(
44729
44806
  () => page ? pageBlocksOf(page.presentation, page.blocks.map((b) => b.id ?? "").filter(Boolean)) : [],
44730
44807
  [page]
44731
44808
  );
44732
- const save = (0, import_react245.useCallback)(
44809
+ const save = (0, import_react247.useCallback)(
44733
44810
  async (next) => {
44734
44811
  if (!page) return;
44735
44812
  const charts = withBlockIds(next.charts ?? page.blocks);
@@ -44753,7 +44830,7 @@ function PageScreen({
44753
44830
  },
44754
44831
  [client, page, blocks, load]
44755
44832
  );
44756
- const archive = (0, import_react245.useCallback)(async () => {
44833
+ const archive = (0, import_react247.useCallback)(async () => {
44757
44834
  if (!page) return;
44758
44835
  setAskingToArchive(false);
44759
44836
  const gone = await client.dashboardDelete({ dashboard_id: page.id });
@@ -44955,8 +45032,8 @@ function AppletBlockView({ block }) {
44955
45032
  }
44956
45033
  function AppletPick({ value, onChange }) {
44957
45034
  const host = useRecordsUi();
44958
- const [options, setOptions] = (0, import_react245.useState)(null);
44959
- (0, import_react245.useEffect)(() => {
45035
+ const [options, setOptions] = (0, import_react247.useState)(null);
45036
+ (0, import_react247.useEffect)(() => {
44960
45037
  let live = true;
44961
45038
  host.applets?.list().then((apps) => live && setOptions(apps.map((a) => ({ value: a.id, label: a.name })))).catch(() => live && setOptions([]));
44962
45039
  return () => {
@@ -44988,12 +45065,12 @@ function ListBlockView({
44988
45065
  mine,
44989
45066
  onMine
44990
45067
  }) {
44991
- const client = (0, import_react246.useRecordsClient)();
44992
- const table = (0, import_react246.useTable)(block.table_id);
44993
- const fields = (0, import_react246.useFields)(block.table_id);
44994
- const all = (0, import_react245.useMemo)(() => onePerKey3(fields.data ?? []), [fields.data]);
44995
- const [view, setView] = (0, import_react245.useState)(block.view_id ? "reading" : null);
44996
- (0, import_react245.useEffect)(() => {
45068
+ const client = (0, import_react248.useRecordsClient)();
45069
+ const table = (0, import_react248.useTable)(block.table_id);
45070
+ const fields = (0, import_react248.useFields)(block.table_id);
45071
+ const all = (0, import_react247.useMemo)(() => onePerKey3(fields.data ?? []), [fields.data]);
45072
+ const [view, setView] = (0, import_react247.useState)(block.view_id ? "reading" : null);
45073
+ (0, import_react247.useEffect)(() => {
44997
45074
  if (!block.view_id) {
44998
45075
  setView(null);
44999
45076
  return;
@@ -45010,8 +45087,8 @@ function ListBlockView({
45010
45087
  };
45011
45088
  }, [client, block.table_id, block.view_id]);
45012
45089
  const meField = block.me_field ? all.find((f) => f.key === block.me_field) : void 0;
45013
- const [me, setMe] = (0, import_react245.useState)(null);
45014
- (0, import_react245.useEffect)(() => {
45090
+ const [me, setMe] = (0, import_react247.useState)(null);
45091
+ (0, import_react247.useEffect)(() => {
45015
45092
  if (!mine || !meField?.relation_target || !viewerUserId) {
45016
45093
  setMe(null);
45017
45094
  return;
@@ -45035,18 +45112,18 @@ function ListBlockView({
45035
45112
  const sort = view && view !== "reading" ? (view.sorts ?? []).map((s) => ({ field: s.field, direction: s.direction })) : [];
45036
45113
  const nobodyIsMe = mine && !!meField && me !== null && me !== "reading" && me.id === null;
45037
45114
  const waiting = view === "reading" || mine && !!meField && (me === "reading" || me === null) && !!viewerUserId;
45038
- const page = (0, import_react246.useRecordPage)(waiting || nobodyIsMe ? null : block.table_id, {
45115
+ const page = (0, import_react248.useRecordPage)(waiting || nobodyIsMe ? null : block.table_id, {
45039
45116
  pageSize: block.limit ?? 50,
45040
45117
  ...filter ? { filter } : {},
45041
45118
  ...sort.length > 0 ? { sort } : {}
45042
45119
  });
45043
45120
  const reload = page.reload;
45044
- (0, import_react245.useEffect)(() => (0, import_core24.onRecordChanged)(() => reload()), [reload]);
45121
+ (0, import_react247.useEffect)(() => (0, import_core24.onRecordChanged)(() => reload()), [reload]);
45045
45122
  const rows = nobodyIsMe ? [] : page.data?.rows ?? [];
45046
45123
  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);
45047
45124
  const firstId = rows[0]?.id ?? null;
45048
45125
  const stillThere = selected !== null && rows.some((r) => r.id === selected);
45049
- (0, import_react245.useEffect)(() => {
45126
+ (0, import_react247.useEffect)(() => {
45050
45127
  if (page.loading || waiting) return;
45051
45128
  if (!stillThere) onSelect(firstId);
45052
45129
  }, [firstId, stillThere, page.loading, waiting]);
@@ -45106,14 +45183,14 @@ function ListBlockView({
45106
45183
  ] });
45107
45184
  }
45108
45185
  function ActionButton2({ block, recordId }) {
45109
- const client = (0, import_react246.useRecordsClient)();
45110
- const actionsRead = (0, import_react246.useRowActions)(block.action_id ? block.table_id : null);
45186
+ const client = (0, import_react248.useRecordsClient)();
45187
+ const actionsRead = (0, import_react248.useRowActions)(block.action_id ? block.table_id : null);
45111
45188
  const action3 = !block.action_id ? null : actionsRead.data ? actionsRead.data.actions.find((a) => a.id === block.action_id) ?? null : actionsRead.loading ? "reading" : null;
45112
- const [asking, setAsking] = (0, import_react245.useState)(false);
45113
- const [running, setRunning] = (0, import_react245.useState)(false);
45114
- const [done, setDone] = (0, import_react245.useState)(null);
45115
- const [error, setError] = (0, import_react245.useState)(null);
45116
- (0, import_react245.useEffect)(() => {
45189
+ const [asking, setAsking] = (0, import_react247.useState)(false);
45190
+ const [running, setRunning] = (0, import_react247.useState)(false);
45191
+ const [done, setDone] = (0, import_react247.useState)(null);
45192
+ const [error, setError] = (0, import_react247.useState)(null);
45193
+ (0, import_react247.useEffect)(() => {
45117
45194
  setDone(null);
45118
45195
  setError(null);
45119
45196
  setAsking(false);
@@ -45151,10 +45228,10 @@ function ActionButton2({ block, recordId }) {
45151
45228
  ] });
45152
45229
  }
45153
45230
  function FormBlockView({ block }) {
45154
- const client = (0, import_react246.useRecordsClient)();
45155
- const [form, setForm] = (0, import_react245.useState)("reading");
45156
- const [sent, setSent] = (0, import_react245.useState)(0);
45157
- (0, import_react245.useEffect)(() => {
45231
+ const client = (0, import_react248.useRecordsClient)();
45232
+ const [form, setForm] = (0, import_react247.useState)("reading");
45233
+ const [sent, setSent] = (0, import_react247.useState)(0);
45234
+ (0, import_react247.useEffect)(() => {
45158
45235
  if (!block.form_id) {
45159
45236
  setForm(null);
45160
45237
  return;
@@ -45172,7 +45249,7 @@ function FormBlockView({ block }) {
45172
45249
  return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(FormRunner, { form: formFromSummary(form), onSubmitted: () => setSent((n) => n + 1) }, sent);
45173
45250
  }
45174
45251
  function FilterBlockView({ block, value, onChange }) {
45175
- const fields = (0, import_react246.useFields)(block.table_id);
45252
+ const fields = (0, import_react248.useFields)(block.table_id);
45176
45253
  const field2 = (fields.data ?? []).find((f) => f.key === block.field);
45177
45254
  if (!block.field) return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(BlockNote, { children: "Choose the column this filter narrows by." });
45178
45255
  if (!field2) return fields.loading ? /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(import_design_system127.Skeleton, { className: "h-9 w-40" }) : /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(BlockNote, { children: "That column is no longer on the table." });
@@ -45267,7 +45344,7 @@ function FieldPick({
45267
45344
  onChange,
45268
45345
  allowNone
45269
45346
  }) {
45270
- const fields = (0, import_react246.useFields)(tableId);
45347
+ const fields = (0, import_react248.useFields)(tableId);
45271
45348
  const all = onePerKey3(fields.data ?? []);
45272
45349
  const picked = want === "member" ? all.filter((f) => editorKindFor(f) === "member") : want === "choice" ? [...offerableFields(all, "choice"), ...all.filter((f) => editorKindFor(f) === "checkbox" || editorKindFor(f) === "member")] : all;
45273
45350
  const seen = /* @__PURE__ */ new Set();
@@ -45278,11 +45355,11 @@ function FieldPick({
45278
45355
  return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(PickOne, { label, placeholder: label, value, options, onChange, className: "h-7 w-40" });
45279
45356
  }
45280
45357
  function ListSettings({ block, onChange }) {
45281
- const client = (0, import_react246.useRecordsClient)();
45282
- const [views, setViews] = (0, import_react245.useState)([]);
45283
- const fields = (0, import_react246.useFields)(block.table_id);
45358
+ const client = (0, import_react248.useRecordsClient)();
45359
+ const [views, setViews] = (0, import_react247.useState)([]);
45360
+ const fields = (0, import_react248.useFields)(block.table_id);
45284
45361
  const all = onePerKey3(fields.data ?? []);
45285
- (0, import_react245.useEffect)(() => {
45362
+ (0, import_react247.useEffect)(() => {
45286
45363
  let live = true;
45287
45364
  void client.views({ table_id: block.table_id }).then((answered) => {
45288
45365
  if (live) setViews(answered.ok ? answered.data : []);
@@ -45352,14 +45429,14 @@ function ListSettings({ block, onChange }) {
45352
45429
  ] });
45353
45430
  }
45354
45431
  function ActionPicker({ tableId, value, onChange }) {
45355
- const actions = (0, import_react246.useRowActions)(tableId).data?.actions ?? [];
45432
+ const actions = (0, import_react248.useRowActions)(tableId).data?.actions ?? [];
45356
45433
  const options = actions.filter((a) => a.id && a.kind !== "agent").map((a) => ({ value: a.id, label: a.name }));
45357
45434
  return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(PickOne, { label: "Action", placeholder: "Choose an action", value, options, onChange: (v) => onChange(v), className: "h-7 w-40" });
45358
45435
  }
45359
45436
  function FormPicker({ tableId, value, onChange }) {
45360
- const client = (0, import_react246.useRecordsClient)();
45361
- const [forms, setForms] = (0, import_react245.useState)([]);
45362
- (0, import_react245.useEffect)(() => {
45437
+ const client = (0, import_react248.useRecordsClient)();
45438
+ const [forms, setForms] = (0, import_react247.useState)([]);
45439
+ (0, import_react247.useEffect)(() => {
45363
45440
  let live = true;
45364
45441
  void client.forms({ table_id: tableId }).then((answered) => {
45365
45442
  if (live) setForms(answered.ok ? answered.data : []);
@@ -45405,8 +45482,8 @@ function onePerKey3(all) {
45405
45482
 
45406
45483
  // src/FormsPanel.tsx
45407
45484
  var import_clipboard10 = require("@ai-matrx/kit/clipboard");
45408
- var import_react247 = require("react");
45409
- var import_react248 = require("@ai-matrx/records/react");
45485
+ var import_react249 = require("react");
45486
+ var import_react250 = require("@ai-matrx/records/react");
45410
45487
  var import_records61 = require("@ai-matrx/records");
45411
45488
  var import_design_system128 = require("@ai-matrx/design-system");
45412
45489
  var import_jsx_runtime143 = require("react/jsx-runtime");
@@ -45418,22 +45495,22 @@ function formSuggestion(tableName2) {
45418
45495
  return `Make me a form that collects new ${subject} entries and tells me when somebody answers.`;
45419
45496
  }
45420
45497
  function FormsPanel({ tableId, activeFormId, className }) {
45421
- const client = (0, import_react248.useRecordsClient)();
45498
+ const client = (0, import_react250.useRecordsClient)();
45422
45499
  const host = useRecordsUi();
45423
- const table = (0, import_react248.useTable)(tableId);
45500
+ const table = (0, import_react250.useTable)(tableId);
45424
45501
  const rights = useTableRights(table.data);
45425
- const [forms, setForms] = (0, import_react247.useState)(null);
45426
- const [error, setError] = (0, import_react247.useState)(null);
45427
- const [busy, setBusy] = (0, import_react247.useState)(null);
45428
- const [copied, setCopied] = (0, import_react247.useState)(null);
45429
- const [building, setBuilding] = (0, import_react247.useState)(false);
45430
- const [archivedSaid, setArchivedSaid] = (0, import_react247.useState)(null);
45502
+ const [forms, setForms] = (0, import_react249.useState)(null);
45503
+ const [error, setError] = (0, import_react249.useState)(null);
45504
+ const [busy, setBusy] = (0, import_react249.useState)(null);
45505
+ const [copied, setCopied] = (0, import_react249.useState)(null);
45506
+ const [building, setBuilding] = (0, import_react249.useState)(false);
45507
+ const [archivedSaid, setArchivedSaid] = (0, import_react249.useState)(null);
45431
45508
  const linked = activeFormId && forms !== null ? forms.find((f) => f.form_id === activeFormId) ?? null : null;
45432
45509
  const linkedMissing = Boolean(activeFormId) && forms !== null && linked === null;
45433
- (0, import_react247.useEffect)(() => {
45510
+ (0, import_react249.useEffect)(() => {
45434
45511
  if (linked && rights.structure) setBuilding(true);
45435
45512
  }, [linked, rights.structure]);
45436
- const load = (0, import_react247.useCallback)(async () => {
45513
+ const load = (0, import_react249.useCallback)(async () => {
45437
45514
  const answered = await client.forms({ table_id: tableId });
45438
45515
  if (!answered.ok) {
45439
45516
  setError(answered.error);
@@ -45443,10 +45520,10 @@ function FormsPanel({ tableId, activeFormId, className }) {
45443
45520
  setError(null);
45444
45521
  setForms(answered.data);
45445
45522
  }, [client, tableId]);
45446
- (0, import_react247.useEffect)(() => {
45523
+ (0, import_react249.useEffect)(() => {
45447
45524
  void load();
45448
45525
  }, [load]);
45449
- const toggle = (0, import_react247.useCallback)(
45526
+ const toggle = (0, import_react249.useCallback)(
45450
45527
  async (form) => {
45451
45528
  setBusy(form.form_id);
45452
45529
  const wanted = form.published_at === null || form.closed_at !== null;
@@ -45460,8 +45537,8 @@ function FormsPanel({ tableId, activeFormId, className }) {
45460
45537
  },
45461
45538
  [client, load]
45462
45539
  );
45463
- const [shown4, setShown] = (0, import_react247.useState)(null);
45464
- const copy = (0, import_react247.useCallback)(async (url, formId) => {
45540
+ const [shown4, setShown] = (0, import_react249.useState)(null);
45541
+ const copy = (0, import_react249.useCallback)(async (url, formId) => {
45465
45542
  if (await (0, import_clipboard10.copyText)(url)) {
45466
45543
  setCopied(formId);
45467
45544
  setShown(null);
@@ -45588,14 +45665,14 @@ function FormsPanel({ tableId, activeFormId, className }) {
45588
45665
  }
45589
45666
 
45590
45667
  // src/CaptureSheet.tsx
45591
- var import_react251 = require("react");
45592
- var import_react252 = require("@ai-matrx/records/react");
45668
+ var import_react253 = require("react");
45669
+ var import_react254 = require("@ai-matrx/records/react");
45593
45670
  var import_design_system130 = require("@ai-matrx/design-system");
45594
45671
 
45595
45672
  // src/CaptureRun.tsx
45596
- var import_react249 = require("react");
45673
+ var import_react251 = require("react");
45597
45674
  var import_records62 = require("@ai-matrx/records");
45598
- var import_react250 = require("@ai-matrx/records/react");
45675
+ var import_react252 = require("@ai-matrx/records/react");
45599
45676
  var import_design_system129 = require("@ai-matrx/design-system");
45600
45677
  var import_jsx_runtime144 = require("react/jsx-runtime");
45601
45678
  function controlFor(field2) {
@@ -45634,21 +45711,21 @@ function whereWeAre(timeoutMs = 4e3) {
45634
45711
  });
45635
45712
  }
45636
45713
  function CaptureRun({ sheetId, face: given, className }) {
45637
- const client = (0, import_react250.useRecordsClient)();
45714
+ const client = (0, import_react252.useRecordsClient)();
45638
45715
  const host = useRecordsUi();
45639
- const [face, setFace] = (0, import_react249.useState)(given);
45640
- const [loadFailed, setLoadFailed] = (0, import_react249.useState)(null);
45641
- const [at, setAt] = (0, import_react249.useState)(0);
45642
- const [answers, setAnswers] = (0, import_react249.useState)({});
45643
- const [files, setFiles] = (0, import_react249.useState)({});
45644
- const [missing, setMissing] = (0, import_react249.useState)(null);
45645
- const [done, setDone] = (0, import_react249.useState)(null);
45646
- const [counts, setCounts] = (0, import_react249.useState)({ waiting: 0, sending: 0, refused: 0, landed: 0 });
45647
- const [items, setItems] = (0, import_react249.useState)([]);
45648
- const [lastSynced, setLastSynced] = (0, import_react249.useState)(null);
45649
- const [sending, setSending] = (0, import_react249.useState)(false);
45650
- const queueRef = (0, import_react249.useRef)(null);
45651
- (0, import_react249.useEffect)(() => {
45716
+ const [face, setFace] = (0, import_react251.useState)(given);
45717
+ const [loadFailed, setLoadFailed] = (0, import_react251.useState)(null);
45718
+ const [at, setAt] = (0, import_react251.useState)(0);
45719
+ const [answers, setAnswers] = (0, import_react251.useState)({});
45720
+ const [files, setFiles] = (0, import_react251.useState)({});
45721
+ const [missing, setMissing] = (0, import_react251.useState)(null);
45722
+ const [done, setDone] = (0, import_react251.useState)(null);
45723
+ const [counts, setCounts] = (0, import_react251.useState)({ waiting: 0, sending: 0, refused: 0, landed: 0 });
45724
+ const [items, setItems] = (0, import_react251.useState)([]);
45725
+ const [lastSynced, setLastSynced] = (0, import_react251.useState)(null);
45726
+ const [sending, setSending] = (0, import_react251.useState)(false);
45727
+ const queueRef = (0, import_react251.useRef)(null);
45728
+ (0, import_react251.useEffect)(() => {
45652
45729
  const q2 = (0, import_records62.openCaptureQueue)({
45653
45730
  onChange: (c, all) => {
45654
45731
  setCounts(c);
@@ -45686,7 +45763,7 @@ function CaptureRun({ sheetId, face: given, className }) {
45686
45763
  void q2.sync().then(() => void q2.lastSyncedAt().then(setLastSynced));
45687
45764
  return () => q2.dispose();
45688
45765
  }, [client, host]);
45689
- (0, import_react249.useEffect)(() => {
45766
+ (0, import_react251.useEffect)(() => {
45690
45767
  if (given !== void 0) return;
45691
45768
  let cancelled = false;
45692
45769
  void client.captureOpen({ sheet_id: sheetId }).then((res) => {
@@ -45698,7 +45775,7 @@ function CaptureRun({ sheetId, face: given, className }) {
45698
45775
  cancelled = true;
45699
45776
  };
45700
45777
  }, [client, given, sheetId]);
45701
- const questions = (0, import_react249.useMemo)(() => {
45778
+ const questions = (0, import_react251.useMemo)(() => {
45702
45779
  const asked3 = face?.presentation?.questions ?? [];
45703
45780
  if (asked3.length > 0) return asked3;
45704
45781
  return (face?.fields ?? []).map((f) => ({
@@ -45708,11 +45785,11 @@ function CaptureRun({ sheetId, face: given, className }) {
45708
45785
  required: f.required
45709
45786
  }));
45710
45787
  }, [face]);
45711
- const fieldOf2 = (0, import_react249.useCallback)(
45788
+ const fieldOf2 = (0, import_react251.useCallback)(
45712
45789
  (key) => (face?.fields ?? []).find((f) => f.key === key),
45713
45790
  [face]
45714
45791
  );
45715
- const sync = (0, import_react249.useCallback)(async () => {
45792
+ const sync = (0, import_react251.useCallback)(async () => {
45716
45793
  const q2 = queueRef.current;
45717
45794
  if (!q2) return;
45718
45795
  setSending(true);
@@ -45725,7 +45802,7 @@ function CaptureRun({ sheetId, face: given, className }) {
45725
45802
  setSending(false);
45726
45803
  }
45727
45804
  }, []);
45728
- const answered = (0, import_react249.useCallback)(
45805
+ const answered = (0, import_react251.useCallback)(
45729
45806
  (key) => {
45730
45807
  if (files[key]) return true;
45731
45808
  const v = answers[key];
@@ -46014,21 +46091,21 @@ function AdHocCaptureSheet({
46014
46091
  attachmentField,
46015
46092
  className
46016
46093
  }) {
46017
- const client = (0, import_react252.useRecordsClient)();
46094
+ const client = (0, import_react254.useRecordsClient)();
46018
46095
  const host = useRecordsUi();
46019
- const table = (0, import_react252.useTable)(tableId);
46020
- const fields = (0, import_react252.useFields)(tableId);
46021
- const [mode, setMode] = (0, import_react251.useState)("reading");
46022
- const [reading, setReading] = (0, import_react251.useState)("");
46023
- const [note, setNote] = (0, import_react251.useState)("");
46024
- const [fileId, setFileId] = (0, import_react251.useState)(null);
46025
- const [pending, setPending] = (0, import_react251.useState)(null);
46026
- const [saved, setSaved] = (0, import_react251.useState)([]);
46027
- const [error, setError] = (0, import_react251.useState)(null);
46028
- const [uploadError, setUploadError] = (0, import_react251.useState)(null);
46029
- const [flushing, setFlushing] = (0, import_react251.useState)(false);
46030
- const queue = (0, import_react251.useRef)([]);
46031
- const keep = (0, import_react251.useCallback)(
46096
+ const table = (0, import_react254.useTable)(tableId);
46097
+ const fields = (0, import_react254.useFields)(tableId);
46098
+ const [mode, setMode] = (0, import_react253.useState)("reading");
46099
+ const [reading, setReading] = (0, import_react253.useState)("");
46100
+ const [note, setNote] = (0, import_react253.useState)("");
46101
+ const [fileId, setFileId] = (0, import_react253.useState)(null);
46102
+ const [pending, setPending] = (0, import_react253.useState)(null);
46103
+ const [saved, setSaved] = (0, import_react253.useState)([]);
46104
+ const [error, setError] = (0, import_react253.useState)(null);
46105
+ const [uploadError, setUploadError] = (0, import_react253.useState)(null);
46106
+ const [flushing, setFlushing] = (0, import_react253.useState)(false);
46107
+ const queue = (0, import_react253.useRef)([]);
46108
+ const keep = (0, import_react253.useCallback)(
46032
46109
  async (next) => {
46033
46110
  queue.current = next;
46034
46111
  setPending(next);
@@ -46036,7 +46113,7 @@ function AdHocCaptureSheet({
46036
46113
  },
46037
46114
  [host]
46038
46115
  );
46039
- (0, import_react251.useEffect)(() => {
46116
+ (0, import_react253.useEffect)(() => {
46040
46117
  let cancelled = false;
46041
46118
  void (async () => {
46042
46119
  const held = host.captureQueue ? await host.captureQueue.load() : [];
@@ -46048,7 +46125,7 @@ function AdHocCaptureSheet({
46048
46125
  cancelled = true;
46049
46126
  };
46050
46127
  }, [host]);
46051
- const resolved = (0, import_react251.useCallback)(() => {
46128
+ const resolved = (0, import_react253.useCallback)(() => {
46052
46129
  const all = fields.data ?? [];
46053
46130
  return {
46054
46131
  reading: readingField ?? all.find((f) => f.type === "range")?.key ?? null,
@@ -46056,7 +46133,7 @@ function AdHocCaptureSheet({
46056
46133
  attachment: attachmentField ?? all.find((f) => f.format === "file" || f.format === "image")?.key ?? null
46057
46134
  };
46058
46135
  }, [attachmentField, fields.data, noteField, readingField, table.data]);
46059
- const flush = (0, import_react251.useCallback)(async () => {
46136
+ const flush = (0, import_react253.useCallback)(async () => {
46060
46137
  if (flushing || queue.current.length === 0) return;
46061
46138
  setFlushing(true);
46062
46139
  const left = [];
@@ -46215,18 +46292,18 @@ function AdHocCaptureSheet({
46215
46292
  }
46216
46293
 
46217
46294
  // src/PortalShell.tsx
46218
- var import_react253 = require("react");
46219
- var import_react254 = require("@ai-matrx/records/react");
46295
+ var import_react255 = require("react");
46296
+ var import_react256 = require("@ai-matrx/records/react");
46220
46297
  var import_design_system131 = require("@ai-matrx/design-system");
46221
46298
  var import_jsx_runtime146 = require("react/jsx-runtime");
46222
46299
  function PortalShell({ tableId, form, resourceType = "record", className }) {
46223
- const client = (0, import_react254.useRecordsClient)();
46224
- const [card, setCard] = (0, import_react253.useState)(null);
46225
- const [reach, setReach] = (0, import_react253.useState)(null);
46226
- const [error, setError] = (0, import_react253.useState)(null);
46227
- const [open, setOpen] = (0, import_react253.useState)(null);
46228
- const [sending, setSending] = (0, import_react253.useState)(false);
46229
- const load = (0, import_react253.useCallback)(async () => {
46300
+ const client = (0, import_react256.useRecordsClient)();
46301
+ const [card, setCard] = (0, import_react255.useState)(null);
46302
+ const [reach, setReach] = (0, import_react255.useState)(null);
46303
+ const [error, setError] = (0, import_react255.useState)(null);
46304
+ const [open, setOpen] = (0, import_react255.useState)(null);
46305
+ const [sending, setSending] = (0, import_react255.useState)(false);
46306
+ const load = (0, import_react255.useCallback)(async () => {
46230
46307
  const who = await client.externalPrincipalCard();
46231
46308
  if (!who.ok) {
46232
46309
  setError(who.error);
@@ -46241,7 +46318,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
46241
46318
  }
46242
46319
  setReach(reached.data.map((row) => row.resource_id));
46243
46320
  }, [client, resourceType]);
46244
- (0, import_react253.useEffect)(() => {
46321
+ (0, import_react255.useEffect)(() => {
46245
46322
  void load();
46246
46323
  }, [load]);
46247
46324
  if (error) {
@@ -46299,9 +46376,9 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
46299
46376
  ] });
46300
46377
  }
46301
46378
  function PortalRow({ tableId, recordId }) {
46302
- const client = (0, import_react254.useRecordsClient)();
46303
- const [title, setTitle] = (0, import_react253.useState)(null);
46304
- (0, import_react253.useEffect)(() => {
46379
+ const client = (0, import_react256.useRecordsClient)();
46380
+ const [title, setTitle] = (0, import_react255.useState)(null);
46381
+ (0, import_react255.useEffect)(() => {
46305
46382
  let cancelled = false;
46306
46383
  void client.recordRead({ record_id: recordId }).then((answered) => {
46307
46384
  if (cancelled) return;
@@ -46321,8 +46398,8 @@ function PortalRow({ tableId, recordId }) {
46321
46398
  }
46322
46399
 
46323
46400
  // src/PublicViewPage.tsx
46324
- var import_react255 = require("react");
46325
- var import_react256 = require("@ai-matrx/records/react");
46401
+ var import_react257 = require("react");
46402
+ var import_react258 = require("@ai-matrx/records/react");
46326
46403
  var import_design_system132 = require("@ai-matrx/design-system");
46327
46404
 
46328
46405
  // src/publicBinding.ts
@@ -46338,14 +46415,14 @@ function publicReadOf(binding) {
46338
46415
  // src/PublicViewPage.tsx
46339
46416
  var import_jsx_runtime147 = require("react/jsx-runtime");
46340
46417
  function PublicViewPage({ slug, className }) {
46341
- const client = (0, import_react256.useRecordsClient)();
46342
- const [binding, setBinding] = (0, import_react255.useState)(null);
46343
- const [rows, setRows] = (0, import_react255.useState)(null);
46344
- const [fields, setFields] = (0, import_react255.useState)(null);
46345
- const [error, setError] = (0, import_react255.useState)(null);
46346
- const [plan, setPlan] = (0, import_react255.useState)(null);
46347
- const [gap, setGap] = (0, import_react255.useState)(null);
46348
- const load = (0, import_react255.useCallback)(async () => {
46418
+ const client = (0, import_react258.useRecordsClient)();
46419
+ const [binding, setBinding] = (0, import_react257.useState)(null);
46420
+ const [rows, setRows] = (0, import_react257.useState)(null);
46421
+ const [fields, setFields] = (0, import_react257.useState)(null);
46422
+ const [error, setError] = (0, import_react257.useState)(null);
46423
+ const [plan, setPlan] = (0, import_react257.useState)(null);
46424
+ const [gap, setGap] = (0, import_react257.useState)(null);
46425
+ const load = (0, import_react257.useCallback)(async () => {
46349
46426
  const notice = await client.worldPublishGapNotice();
46350
46427
  if (notice.ok) setGap(notice.data);
46351
46428
  const resolved = await client.resolvePublishBindingKind({ slug });
@@ -46395,7 +46472,7 @@ function PublicViewPage({ slug, className }) {
46395
46472
  }
46396
46473
  setRows([{ id: chosen.recordId, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
46397
46474
  }, [client, slug]);
46398
- (0, import_react255.useEffect)(() => {
46475
+ (0, import_react257.useEffect)(() => {
46399
46476
  void load();
46400
46477
  }, [load]);
46401
46478
  if (error) return /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(RefusalNotice, { error, className });
@@ -46433,10 +46510,10 @@ function PublicRow({ row, fields }) {
46433
46510
 
46434
46511
  // src/EmbedFrame.tsx
46435
46512
  var import_clipboard11 = require("@ai-matrx/kit/clipboard");
46436
- var import_react257 = require("react");
46437
- var import_react258 = require("@ai-matrx/records/react");
46513
+ var import_react259 = require("react");
46514
+ var import_react260 = require("@ai-matrx/records/react");
46438
46515
  var import_design_system133 = require("@ai-matrx/design-system");
46439
- var import_react259 = require("@ai-matrx/records/react");
46516
+ var import_react261 = require("@ai-matrx/records/react");
46440
46517
  var import_jsx_runtime148 = require("react/jsx-runtime");
46441
46518
  function EmbedFrame({
46442
46519
  tableId,
@@ -46446,18 +46523,18 @@ function EmbedFrame({
46446
46523
  embedUrl,
46447
46524
  className
46448
46525
  }) {
46449
- const client = (0, import_react258.useRecordsClient)();
46526
+ const client = (0, import_react260.useRecordsClient)();
46450
46527
  const host = useRecordsUi();
46451
- const table = (0, import_react259.useTable)(tableId);
46528
+ const table = (0, import_react261.useTable)(tableId);
46452
46529
  const rights = useTableRights(table.data);
46453
- const [origins, setOrigins] = (0, import_react257.useState)("");
46454
- const [secret, setSecret] = (0, import_react257.useState)(null);
46455
- const [tokenId, setTokenId] = (0, import_react257.useState)(null);
46456
- const [error, setError] = (0, import_react257.useState)(null);
46457
- const [busy, setBusy] = (0, import_react257.useState)(false);
46530
+ const [origins, setOrigins] = (0, import_react259.useState)("");
46531
+ const [secret, setSecret] = (0, import_react259.useState)(null);
46532
+ const [tokenId, setTokenId] = (0, import_react259.useState)(null);
46533
+ const [error, setError] = (0, import_react259.useState)(null);
46534
+ const [busy, setBusy] = (0, import_react259.useState)(false);
46458
46535
  const mode = formId ? "write" : "read";
46459
46536
  const parsed = origins.split(/[\s,]+/).map((o) => o.trim()).filter((o) => o.length > 0);
46460
- const issue = (0, import_react257.useCallback)(async () => {
46537
+ const issue = (0, import_react259.useCallback)(async () => {
46461
46538
  setBusy(true);
46462
46539
  setError(null);
46463
46540
  const minted = await client.anonTokenIssue({
@@ -46476,7 +46553,7 @@ function EmbedFrame({
46476
46553
  setTokenId(minted.data.token_id);
46477
46554
  host.notify?.success("Embed token issued. Copy it now \u2014 it is never shown again.");
46478
46555
  }, [client, formId, host, mode, parsed, recordId, savedViewId]);
46479
- const revoke = (0, import_react257.useCallback)(async () => {
46556
+ const revoke = (0, import_react259.useCallback)(async () => {
46480
46557
  if (!tokenId) return;
46481
46558
  setBusy(true);
46482
46559
  const done = await client.anonTokenRevoke({ token_id: tokenId });
@@ -46540,13 +46617,13 @@ function EmbedFrame({
46540
46617
  ] });
46541
46618
  }
46542
46619
  function useEmbedHandshake(args) {
46543
- const client = (0, import_react258.useRecordsClient)();
46544
- const [binding, setBinding] = (0, import_react257.useState)(null);
46545
- const [error, setError] = (0, import_react257.useState)(null);
46546
- const [loading, setLoading] = (0, import_react257.useState)(true);
46620
+ const client = (0, import_react260.useRecordsClient)();
46621
+ const [binding, setBinding] = (0, import_react259.useState)(null);
46622
+ const [error, setError] = (0, import_react259.useState)(null);
46623
+ const [loading, setLoading] = (0, import_react259.useState)(true);
46547
46624
  const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
46548
46625
  const { secret, requiredMode } = args;
46549
- (0, import_react257.useEffect)(() => {
46626
+ (0, import_react259.useEffect)(() => {
46550
46627
  let cancelled = false;
46551
46628
  setLoading(true);
46552
46629
  setError(null);
@@ -46569,11 +46646,11 @@ function useEmbedHandshake(args) {
46569
46646
 
46570
46647
  // src/TablePage.tsx
46571
46648
  var import_clipboard13 = require("@ai-matrx/kit/clipboard");
46572
- var import_react269 = require("react");
46649
+ var import_react271 = require("react");
46573
46650
  var import_records63 = require("@ai-matrx/records");
46574
- var import_react270 = require("@ai-matrx/records/react");
46651
+ var import_react272 = require("@ai-matrx/records/react");
46575
46652
  var import_design_system140 = require("@ai-matrx/design-system");
46576
- var import_text_case18 = require("@ai-matrx/kit/text-case");
46653
+ var import_text_case19 = require("@ai-matrx/kit/text-case");
46577
46654
 
46578
46655
  // src/viewShare.ts
46579
46656
  var import_core25 = require("@ai-matrx/records/core");
@@ -46617,13 +46694,13 @@ async function downloadViewCsv(args) {
46617
46694
  }
46618
46695
 
46619
46696
  // src/RecordPanel.tsx
46620
- var import_react260 = require("react");
46697
+ var import_react262 = require("react");
46621
46698
  var import_design_system134 = require("@ai-matrx/design-system");
46622
- var import_react261 = require("@ai-matrx/records/react");
46699
+ var import_react263 = require("@ai-matrx/records/react");
46623
46700
  var import_jsx_runtime149 = require("react/jsx-runtime");
46624
46701
  function RecordPanel({ tableId, recordId, onClose, onAskAboutField, onPage = false }) {
46625
46702
  const host = useRecordsUi();
46626
- const [asking, setAsking] = (0, import_react260.useState)(null);
46703
+ const [asking, setAsking] = (0, import_react262.useState)(null);
46627
46704
  return /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { className: "space-y-3", "data-record-panel": recordId, children: [
46628
46705
  /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(Peek, { tableId, recordId, onPage, ...onClose ? { onClose } : {} }),
46629
46706
  onPage ? /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)(import_jsx_runtime149.Fragment, { children: [
@@ -46642,7 +46719,7 @@ function RecordPanel({ tableId, recordId, onClose, onAskAboutField, onPage = fal
46642
46719
  }
46643
46720
  ),
46644
46721
  !onAskAboutField && asking ? /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(FieldHistoryPanel, { tableId, fieldKey: asking, recordId, onClose: () => setAsking(null) }) : null,
46645
- host.recordSections ? /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)(import_react260.Fragment, { children: [
46722
+ host.recordSections ? /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)(import_react262.Fragment, { children: [
46646
46723
  /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(import_design_system134.Separator, {}),
46647
46724
  host.recordSections({ tableId, recordId })
46648
46725
  ] }) : null,
@@ -46653,8 +46730,8 @@ function RecordPanel({ tableId, recordId, onClose, onAskAboutField, onPage = fal
46653
46730
  ] });
46654
46731
  }
46655
46732
  function LinkedLists({ tableId, recordId }) {
46656
- const fields = (0, import_react261.useFields)(tableId);
46657
- const record = (0, import_react261.useRecord)(recordId, true, { tableId });
46733
+ const fields = (0, import_react263.useFields)(tableId);
46734
+ const record = (0, import_react263.useRecord)(recordId, true, { tableId });
46658
46735
  const links = (fields.data ?? []).filter((field2) => editorKindFor(field2) === "relation");
46659
46736
  const labels = useRecordLabels(links);
46660
46737
  const document2 = record.data?.document;
@@ -46701,7 +46778,7 @@ function LinkedLists({ tableId, recordId }) {
46701
46778
  }
46702
46779
  function RecordAsk({ tableId, recordId }) {
46703
46780
  const host = useRecordsUi();
46704
- const [open, setOpen] = (0, import_react260.useState)(false);
46781
+ const [open, setOpen] = (0, import_react262.useState)(false);
46705
46782
  if (!host.chat) return null;
46706
46783
  return /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("section", { className: "flex min-w-0 flex-col gap-1.5", "data-record-ask": open ? "open" : "", children: [
46707
46784
  /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(import_design_system134.Separator, {}),
@@ -46710,7 +46787,7 @@ function RecordAsk({ tableId, recordId }) {
46710
46787
  }
46711
46788
 
46712
46789
  // src/breakDown.tsx
46713
- var import_react262 = require("react");
46790
+ var import_react264 = require("react");
46714
46791
  var import_design_system135 = require("@ai-matrx/design-system");
46715
46792
  var import_jsx_runtime150 = require("react/jsx-runtime");
46716
46793
  var BREAK_DOWN_ACTION_ID = "break-down";
@@ -46736,10 +46813,10 @@ function BreakDownDialog({
46736
46813
  onOpenChange,
46737
46814
  onApply
46738
46815
  }) {
46739
- const source = (0, import_react262.useMemo)(() => ({ kind: "table", id: tableId }), [tableId]);
46816
+ const source = (0, import_react264.useMemo)(() => ({ kind: "table", id: tableId }), [tableId]);
46740
46817
  const { def } = useDrillDefinition(open ? source : null);
46741
- const dimensions = (0, import_react262.useMemo)(() => drillDimensionsOf(def, NO_LABELS), [def]);
46742
- const [picked, setPicked] = (0, import_react262.useState)(null);
46818
+ const dimensions = (0, import_react264.useMemo)(() => drillDimensionsOf(def, NO_LABELS), [def]);
46819
+ const [picked, setPicked] = (0, import_react264.useState)(null);
46743
46820
  const key = picked ?? held?.field ?? dimensions[0]?.key ?? "";
46744
46821
  return /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(import_design_system135.Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime150.jsxs)(import_design_system135.DialogContent, { "data-break-down": "", className: "max-w-sm", children: [
46745
46822
  /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(import_design_system135.DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(import_design_system135.DialogTitle, { children: "Break down by" }) }),
@@ -46766,7 +46843,7 @@ function BreakDownDialog({
46766
46843
 
46767
46844
  // src/TableReference.tsx
46768
46845
  var import_clipboard12 = require("@ai-matrx/kit/clipboard");
46769
- var import_react263 = require("react");
46846
+ var import_react265 = require("react");
46770
46847
  var import_workspace2 = require("@ai-matrx/alchemy/react/workspace");
46771
46848
  var import_design_system136 = require("@ai-matrx/design-system");
46772
46849
  var import_jsx_runtime151 = require("react/jsx-runtime");
@@ -46794,12 +46871,12 @@ function TableReferenceDialog({
46794
46871
  }) {
46795
46872
  const port = (0, import_workspace2.useContentTransferCapabilities)().reference;
46796
46873
  const notify = useRecordsUi().notify;
46797
- const [copied, setCopied] = (0, import_react263.useState)(null);
46798
- const choices = (0, import_react263.useMemo)(
46874
+ const [copied, setCopied] = (0, import_react265.useState)(null);
46875
+ const choices = (0, import_react265.useMemo)(
46799
46876
  () => tableReferenceChoices(table.id, tableName(table)).filter((c) => port?.supports(c.reference)),
46800
46877
  [table, port]
46801
46878
  );
46802
- const copy = (0, import_react263.useCallback)(
46879
+ const copy = (0, import_react265.useCallback)(
46803
46880
  async (choice) => {
46804
46881
  if (!port) return;
46805
46882
  try {
@@ -46822,8 +46899,8 @@ function TableReferenceDialog({
46822
46899
  }
46823
46900
 
46824
46901
  // src/TableDuplicate.tsx
46825
- var import_react264 = require("react");
46826
- var import_react265 = require("@ai-matrx/records/react");
46902
+ var import_react266 = require("react");
46903
+ var import_react267 = require("@ai-matrx/records/react");
46827
46904
  var import_design_system137 = require("@ai-matrx/design-system");
46828
46905
  var import_jsx_runtime152 = require("react/jsx-runtime");
46829
46906
  function copyNameFor(name) {
@@ -46835,11 +46912,11 @@ function duplicateProgressWords(p) {
46835
46912
  return "Copying columns\u2026";
46836
46913
  }
46837
46914
  function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated }) {
46838
- const client = (0, import_react265.useRecordsClient)();
46915
+ const client = (0, import_react267.useRecordsClient)();
46839
46916
  const host = useRecordsUi();
46840
- const [typed2, setTyped] = (0, import_react264.useState)(() => copyNameFor(name));
46841
- const [withRecords, setWithRecords] = (0, import_react264.useState)(true);
46842
- const [phase, setPhase] = (0, import_react264.useState)({ kind: "asking" });
46917
+ const [typed2, setTyped] = (0, import_react266.useState)(() => copyNameFor(name));
46918
+ const [withRecords, setWithRecords] = (0, import_react266.useState)(true);
46919
+ const [phase, setPhase] = (0, import_react266.useState)({ kind: "asking" });
46843
46920
  const problem = tableNameProblem(typed2);
46844
46921
  const copying = phase.kind === "copying";
46845
46922
  const close = (next) => {
@@ -46863,7 +46940,7 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
46863
46940
  setPhase({ kind: "refused", sentence: refusalSentence(made.error) });
46864
46941
  return;
46865
46942
  }
46866
- (0, import_react265.tableShapeChanged)(made.data.table.id);
46943
+ (0, import_react267.tableShapeChanged)(made.data.table.id);
46867
46944
  setPhase({ kind: "done", copy: made.data });
46868
46945
  host.notify?.success(`Made ${made.data.table.name}`);
46869
46946
  };
@@ -46924,9 +47001,9 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
46924
47001
  }
46925
47002
 
46926
47003
  // src/ViewFilter.tsx
46927
- var import_react266 = require("react");
47004
+ var import_react268 = require("react");
46928
47005
  var import_design_system138 = require("@ai-matrx/design-system");
46929
- var import_react267 = require("@ai-matrx/records/react");
47006
+ var import_react269 = require("@ai-matrx/records/react");
46930
47007
  var import_jsx_runtime153 = require("react/jsx-runtime");
46931
47008
  function conditionCount(expr) {
46932
47009
  if (!expr || typeof expr !== "object" || Array.isArray(expr)) return 0;
@@ -46937,15 +47014,15 @@ function conditionCount(expr) {
46937
47014
  return 1;
46938
47015
  }
46939
47016
  function ViewFilter({ tableId, view, onApply, className }) {
46940
- const fields = (0, import_react267.useFields)(tableId);
46941
- const [open, setOpen] = (0, import_react266.useState)(false);
47017
+ const fields = (0, import_react269.useFields)(tableId);
47018
+ const [open, setOpen] = (0, import_react268.useState)(false);
46942
47019
  const saved = view?.where ?? null;
46943
- const [draft, setDraft] = (0, import_react266.useState)(saved);
47020
+ const [draft, setDraft] = (0, import_react268.useState)(saved);
46944
47021
  const savedKey = JSON.stringify(saved);
46945
- (0, import_react266.useEffect)(() => {
47022
+ (0, import_react268.useEffect)(() => {
46946
47023
  setDraft(saved);
46947
47024
  }, [view?.id, savedKey]);
46948
- const conditionFields = (0, import_react266.useMemo)(
47025
+ const conditionFields = (0, import_react268.useMemo)(
46949
47026
  () => (fields.data ?? []).map((f) => ({ id: f.id, key: f.key, label: f.label || f.key, field: f })),
46950
47027
  [fields.data]
46951
47028
  );
@@ -46990,7 +47067,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
46990
47067
  ConditionGroup,
46991
47068
  {
46992
47069
  lead: "Show records where",
46993
- emptyLabel: "every record",
47070
+ emptyLabel: "Pick a field",
46994
47071
  expr: draft,
46995
47072
  fields: conditionFields,
46996
47073
  onChange: setDraft
@@ -47026,8 +47103,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
47026
47103
  /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(import_design_system138.Button, { size: "sm", variant: "ghost", onClick: () => {
47027
47104
  setDraft(saved);
47028
47105
  setOpen(false);
47029
- }, children: "Cancel" }),
47030
- changed ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)("span", { className: "text-muted-foreground", children: "Not applied yet." }) : null
47106
+ }, children: "Cancel" })
47031
47107
  ] })
47032
47108
  ]
47033
47109
  }
@@ -47118,7 +47194,7 @@ function phoneTableActions(actions) {
47118
47194
  }
47119
47195
 
47120
47196
  // src/toolbarFit.ts
47121
- var import_react268 = require("react");
47197
+ var import_react270 = require("react");
47122
47198
  var FOLDED_GUESS = { look: 104, chooser: 96, tools: 120 };
47123
47199
  var SLOT_MIN = 36;
47124
47200
  function toolbarFold(input) {
@@ -47175,8 +47251,8 @@ function rowNeeds(row) {
47175
47251
  return { needs: needs + gap * Math.max(0, pieces.length - 1), gap };
47176
47252
  }
47177
47253
  function useToolbarFit(row) {
47178
- const [fold, setFold] = (0, import_react268.useState)(0);
47179
- (0, import_react268.useEffect)(() => {
47254
+ const [fold, setFold] = (0, import_react270.useState)(0);
47255
+ (0, import_react270.useEffect)(() => {
47180
47256
  if (!row) return;
47181
47257
  const widths = {
47182
47258
  look: { full: null, folded: null },
@@ -47260,8 +47336,8 @@ function clippedEnds(scrollLeft, clientWidth, scrollWidth) {
47260
47336
  return start && end ? "both" : start ? "start" : end ? "end" : "none";
47261
47337
  }
47262
47338
  function useSlotScroll(slot) {
47263
- const [ends, setEnds] = (0, import_react268.useState)("none");
47264
- (0, import_react268.useEffect)(() => {
47339
+ const [ends, setEnds] = (0, import_react270.useState)("none");
47340
+ (0, import_react270.useEffect)(() => {
47265
47341
  if (!slot) return;
47266
47342
  let pending = 0;
47267
47343
  const read = () => {
@@ -47344,7 +47420,7 @@ function RailFrame({
47344
47420
  function filterInWords(filter, fields) {
47345
47421
  const nameOf2 = (key) => {
47346
47422
  const field2 = fields.find((f) => f.key === key);
47347
- return field2 ? fieldName(field2) : (0, import_text_case18.humanizeIdentifier)(key);
47423
+ return field2 ? fieldName(field2) : (0, import_text_case19.humanizeIdentifier)(key);
47348
47424
  };
47349
47425
  const parts = Object.keys(filter).map((key) => {
47350
47426
  const value = filter[key];
@@ -47378,11 +47454,11 @@ function TableNotHere({
47378
47454
  leaveLabel,
47379
47455
  className
47380
47456
  }) {
47381
- const client = (0, import_react270.useRecordsClient)();
47382
- const [archived, setArchived] = (0, import_react269.useState)({ phase: "asking" });
47383
- const [restoring, setRestoring] = (0, import_react269.useState)(false);
47384
- const [refusal4, setRefusal] = (0, import_react269.useState)(null);
47385
- (0, import_react269.useEffect)(() => {
47457
+ const client = (0, import_react272.useRecordsClient)();
47458
+ const [archived, setArchived] = (0, import_react271.useState)({ phase: "asking" });
47459
+ const [restoring, setRestoring] = (0, import_react271.useState)(false);
47460
+ const [refusal4, setRefusal] = (0, import_react271.useState)(null);
47461
+ (0, import_react271.useEffect)(() => {
47386
47462
  let alive = true;
47387
47463
  void client.tableArchived({ table_id: tableId }).then((answered) => {
47388
47464
  if (!alive) return;
@@ -47580,18 +47656,18 @@ function TablePage({
47580
47656
  onViewAddressChange,
47581
47657
  className
47582
47658
  }) {
47583
- const client = (0, import_react270.useRecordsClient)();
47584
- const table = (0, import_react270.useTable)(tableId);
47659
+ const client = (0, import_react272.useRecordsClient)();
47660
+ const table = (0, import_react272.useTable)(tableId);
47585
47661
  const rights = useTableRights(table.data);
47586
- const pageFields = (0, import_react270.useFields)(filter ? tableId : null);
47587
- const allFields = (0, import_react270.useFields)(tableId);
47662
+ const pageFields = (0, import_react272.useFields)(filter ? tableId : null);
47663
+ const allFields = (0, import_react272.useFields)(tableId);
47588
47664
  const viewLabels = useRecordLabels(allFields.data ?? void 0);
47589
47665
  const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
47590
- const organizationId = (0, import_react270.useRecordsClient)().config.organizationId;
47666
+ const organizationId = (0, import_react272.useRecordsClient)().config.organizationId;
47591
47667
  const publicReadOnly = usePublicReadOnly(client, organizationId, tableId, table.data, rights);
47592
- const [view, setView] = (0, import_react269.useState)(null);
47593
- const [looks, setLooks] = (0, import_react269.useState)(void 0);
47594
- (0, import_react269.useEffect)(() => {
47668
+ const [view, setView] = (0, import_react271.useState)(null);
47669
+ const [looks, setLooks] = (0, import_react271.useState)(void 0);
47670
+ (0, import_react271.useEffect)(() => {
47595
47671
  let live = true;
47596
47672
  setLooks(void 0);
47597
47673
  void readLooks(client, tableId).then((answered) => {
@@ -47604,7 +47680,7 @@ function TablePage({
47604
47680
  }, [client, tableId]);
47605
47681
  const look = view && looks ? looks[view.id] : void 0;
47606
47682
  const shown4 = view ? applyLook(view, look) : null;
47607
- const [viewsEpoch, setViewsEpoch] = (0, import_react269.useState)(0);
47683
+ const [viewsEpoch, setViewsEpoch] = (0, import_react271.useState)(0);
47608
47684
  const opening = openingRail(activeRecordId, activeRail);
47609
47685
  const recordsUi = useRecordsUi();
47610
47686
  const hostLayouts = recordsUi.layouts ?? [];
@@ -47614,39 +47690,39 @@ function TablePage({
47614
47690
  const questionsFromLink = questionsFromParam(activeView);
47615
47691
  const openedByPackage = openingView(hostFromLink || savedFromLink || questionsFromLink ? null : activeView, activeDashboardId);
47616
47692
  const opened = hostFromLink ? { ...openedByPackage, main: "records" } : questionsFromLink ? { ...openedByPackage, main: "questions" } : openedByPackage;
47617
- const [hostLayout, setHostLayout] = (0, import_react269.useState)(hostFromLink);
47618
- const [views, setViews] = (0, import_react269.useState)(void 0);
47619
- const [pickedViewId, setPickedViewId] = (0, import_react269.useState)(savedFromLink);
47620
- const viewSeen = (0, import_react269.useRef)(null);
47621
- const [viewLinkMissed, setViewLinkMissed] = (0, import_react269.useState)(false);
47622
- const [layoutChosen, setLayoutChosen] = (0, import_react269.useState)(false);
47693
+ const [hostLayout, setHostLayout] = (0, import_react271.useState)(hostFromLink);
47694
+ const [views, setViews] = (0, import_react271.useState)(void 0);
47695
+ const [pickedViewId, setPickedViewId] = (0, import_react271.useState)(savedFromLink);
47696
+ const viewSeen = (0, import_react271.useRef)(null);
47697
+ const [viewLinkMissed, setViewLinkMissed] = (0, import_react271.useState)(false);
47698
+ const [layoutChosen, setLayoutChosen] = (0, import_react271.useState)(false);
47623
47699
  const railAsked = typeof activeRail === "string" ? activeRail.trim() : "";
47624
47700
  const railUnknown = railAsked !== "" && railFromParam(railAsked) === null ? railAsked : null;
47625
47701
  const shareFromLink = railFromParam(activeRail) === "share";
47626
47702
  const canShare = useCanShare();
47627
47703
  const itemFor = (which) => railFromParam(activeRail) === which ? activeItemId ?? null : null;
47628
- const [asking, setAsking] = (0, import_react269.useState)(null);
47629
- const [layoutFromLink, setLayoutFromLink] = (0, import_react269.useState)(opened.layout);
47630
- const [surface, setSurface] = (0, import_react269.useState)({
47704
+ const [asking, setAsking] = (0, import_react271.useState)(null);
47705
+ const [layoutFromLink, setLayoutFromLink] = (0, import_react271.useState)(opened.layout);
47706
+ const [surface, setSurface] = (0, import_react271.useState)({
47631
47707
  main: opened.main,
47632
47708
  rail: opening.rail
47633
47709
  });
47634
47710
  const { main, rail } = surface;
47635
- const [questionDraft, setQuestionDraft] = (0, import_react269.useState)(null);
47711
+ const [questionDraft, setQuestionDraft] = (0, import_react271.useState)(null);
47636
47712
  const setRail = (next) => setSurface((now) => ({ ...now, rail: next }));
47637
- const [importEpoch, setImportEpoch] = (0, import_react269.useState)(0);
47638
- const [openRecord, setOpenRecord] = (0, import_react269.useState)(opening.record);
47713
+ const [importEpoch, setImportEpoch] = (0, import_react271.useState)(0);
47714
+ const [openRecord, setOpenRecord] = (0, import_react271.useState)(opening.record);
47639
47715
  const phone = (0, import_design_system140.useIsMobile)();
47640
- const [shareAsked, setShareAsked] = (0, import_react269.useState)(0);
47716
+ const [shareAsked, setShareAsked] = (0, import_react271.useState)(0);
47641
47717
  const { open: renameOpen, setOpen: setRenameOpen, ask: askRename, menuContentProps: renameMenuProps } = useRenameFromMenu();
47642
- const [archiveAsked, setArchiveAsked] = (0, import_react269.useState)(0);
47643
- const [moveAsked, setMoveAsked] = (0, import_react269.useState)(0);
47644
- const [duplicateOpen, setDuplicateOpen] = (0, import_react269.useState)(false);
47645
- const [referenceOpen, setReferenceOpen] = (0, import_react269.useState)(false);
47646
- const [breakDownOpen, setBreakDownOpen] = (0, import_react269.useState)(false);
47718
+ const [archiveAsked, setArchiveAsked] = (0, import_react271.useState)(0);
47719
+ const [moveAsked, setMoveAsked] = (0, import_react271.useState)(0);
47720
+ const [duplicateOpen, setDuplicateOpen] = (0, import_react271.useState)(false);
47721
+ const [referenceOpen, setReferenceOpen] = (0, import_react271.useState)(false);
47722
+ const [breakDownOpen, setBreakDownOpen] = (0, import_react271.useState)(false);
47647
47723
  const canGetReference = useCanGetReference();
47648
- const [toolbarSlot, setToolbarSlot] = (0, import_react269.useState)(null);
47649
- const [toolbarRow, setToolbarRow] = (0, import_react269.useState)(null);
47724
+ const [toolbarSlot, setToolbarSlot] = (0, import_react271.useState)(null);
47725
+ const [toolbarRow, setToolbarRow] = (0, import_react271.useState)(null);
47650
47726
  const toolbarFold2 = useToolbarFit(toolbarRow);
47651
47727
  const slotClipped = useSlotScroll(toolbarSlot);
47652
47728
  const face = tableOpening(view, hostLayouts.map((h) => h.id));
@@ -47657,7 +47733,7 @@ function TablePage({
47657
47733
  const chooserCompact = !embedded && !designated && !phone && toolbarFold2 >= 2;
47658
47734
  const controlsInSheet = phone && !designated;
47659
47735
  const shareInMenu = phone || toolbarFold2 >= 4;
47660
- (0, import_react269.useEffect)(() => {
47736
+ (0, import_react271.useEffect)(() => {
47661
47737
  if (face.kind !== "designated") return;
47662
47738
  if (hostFromLink || opened.layout || layoutChosen) return;
47663
47739
  setHostLayout(face.hostLayout);
@@ -47688,9 +47764,9 @@ function TablePage({
47688
47764
  lookDiffers: view ? lookDiffers(view, look) : false
47689
47765
  };
47690
47766
  const shownSignature = JSON.stringify(shownReport);
47691
- const reportRef = (0, import_react269.useRef)(onShownViewChange);
47767
+ const reportRef = (0, import_react271.useRef)(onShownViewChange);
47692
47768
  reportRef.current = onShownViewChange;
47693
- (0, import_react269.useEffect)(() => {
47769
+ (0, import_react271.useEffect)(() => {
47694
47770
  reportRef.current?.(JSON.parse(shownSignature));
47695
47771
  }, [shownSignature]);
47696
47772
  const pickLayout = (next) => {
@@ -47707,18 +47783,18 @@ function TablePage({
47707
47783
  setSurface((now) => ({ ...now, main: "records" }));
47708
47784
  onViewChanged?.(id);
47709
47785
  };
47710
- (0, import_react269.useEffect)(() => {
47786
+ (0, import_react271.useEffect)(() => {
47711
47787
  if (!activeRecordId) return;
47712
47788
  setOpenRecord(activeRecordId);
47713
47789
  setSurface((now) => ({ ...now, rail: "record" }));
47714
47790
  }, [activeRecordId]);
47715
- (0, import_react269.useEffect)(() => {
47791
+ (0, import_react271.useEffect)(() => {
47716
47792
  if (activeRecordId) return;
47717
47793
  const named = railFromParam(activeRail);
47718
47794
  if (named === null || named === "share") return;
47719
47795
  setSurface((now) => ({ ...now, rail: named }));
47720
47796
  }, [activeRail, activeRecordId]);
47721
- (0, import_react269.useEffect)(() => {
47797
+ (0, import_react271.useEffect)(() => {
47722
47798
  const host = hostLayoutFor(activeView);
47723
47799
  if (host) {
47724
47800
  setHostLayout(host);
@@ -47732,8 +47808,8 @@ function TablePage({
47732
47808
  setLayoutFromLink(isLayout ? named : null);
47733
47809
  setSurface((now) => ({ ...now, main: isLayout ? "records" : named }));
47734
47810
  }, [activeView]);
47735
- const [viewSaveRefused, setViewSaveRefused] = (0, import_react269.useState)(null);
47736
- const patchView = (0, import_react269.useCallback)(
47811
+ const [viewSaveRefused, setViewSaveRefused] = (0, import_react271.useState)(null);
47812
+ const patchView = (0, import_react271.useCallback)(
47737
47813
  async (asked3) => {
47738
47814
  const current = view;
47739
47815
  if (!current) return;
@@ -47749,19 +47825,19 @@ function TablePage({
47749
47825
  },
47750
47826
  [client, tableId, view, looks]
47751
47827
  );
47752
- const arrival = (0, import_react269.useRef)(viewAddress ?? null);
47753
- const [gridQuery, setGridQuery] = (0, import_react269.useState)(null);
47754
- const [addressResetEpoch, setAddressResetEpoch] = (0, import_react269.useState)(0);
47755
- const reportGrid = (0, import_react269.useCallback)((q) => {
47828
+ const arrival = (0, import_react271.useRef)(viewAddress ?? null);
47829
+ const [gridQuery, setGridQuery] = (0, import_react271.useState)(null);
47830
+ const [addressResetEpoch, setAddressResetEpoch] = (0, import_react271.useState)(0);
47831
+ const reportGrid = (0, import_react271.useCallback)((q) => {
47756
47832
  const next = { sort: q.sort, filters: q.filters, search: q.search, page: q.page };
47757
47833
  setGridQuery((held) => sameViewAddress(held, next) ? held : next);
47758
47834
  }, []);
47759
- const addressPort = (0, import_react269.useMemo)(
47835
+ const addressPort = (0, import_react271.useMemo)(
47760
47836
  () => ({ initial: arrival.current, report: reportGrid, resetEpoch: addressResetEpoch }),
47761
47837
  [reportGrid, addressResetEpoch]
47762
47838
  );
47763
- const hiddenApplied = (0, import_react269.useRef)(false);
47764
- (0, import_react269.useEffect)(() => {
47839
+ const hiddenApplied = (0, import_react271.useRef)(false);
47840
+ (0, import_react271.useEffect)(() => {
47765
47841
  const hidden = arrival.current?.hidden;
47766
47842
  if (hiddenApplied.current || !view || !looks || !hidden || hidden.length === 0) return;
47767
47843
  hiddenApplied.current = true;
@@ -47781,10 +47857,10 @@ function TablePage({
47781
47857
  const gridPending = !isViewAddressEmpty({ ...arrival.current ?? {}, hidden: [] });
47782
47858
  const addressReady = Boolean(view && looks) && (gridQuery !== null || !gridPending);
47783
47859
  const addressSignature = JSON.stringify(viewAddressToParams(addressNow));
47784
- const addressReportRef = (0, import_react269.useRef)(onViewAddressChange);
47860
+ const addressReportRef = (0, import_react271.useRef)(onViewAddressChange);
47785
47861
  addressReportRef.current = onViewAddressChange;
47786
- const addressSent = (0, import_react269.useRef)(null);
47787
- (0, import_react269.useEffect)(() => {
47862
+ const addressSent = (0, import_react271.useRef)(null);
47863
+ (0, import_react271.useEffect)(() => {
47788
47864
  if (!addressReady) return;
47789
47865
  if (addressSent.current === null && addressSignature === JSON.stringify(viewAddressToParams(arrival.current))) {
47790
47866
  addressSent.current = addressSignature;
@@ -47796,9 +47872,9 @@ function TablePage({
47796
47872
  }, [addressReady, addressSignature]);
47797
47873
  const queryShowing = !isViewAddressEmpty({ ...gridQuery ?? {}, hidden: [] });
47798
47874
  const lookShowing = Boolean(view && looks && (lookDiffers(view, looks[view.id]) || queryShowing));
47799
- const [lookRefused, setLookRefused] = (0, import_react269.useState)(null);
47800
- const [namingLook, setNamingLook] = (0, import_react269.useState)(false);
47801
- const [lookName, setLookName] = (0, import_react269.useState)("");
47875
+ const [lookRefused, setLookRefused] = (0, import_react271.useState)(null);
47876
+ const [namingLook, setNamingLook] = (0, import_react271.useState)(false);
47877
+ const [lookName, setLookName] = (0, import_react271.useState)("");
47802
47878
  const resetLook = async () => {
47803
47879
  const current = view;
47804
47880
  setAddressResetEpoch((n) => n + 1);
@@ -47857,7 +47933,7 @@ function TablePage({
47857
47933
  setPickedViewId(written.data);
47858
47934
  setViewsEpoch((n) => n + 1);
47859
47935
  };
47860
- const [designateRefused, setDesignateRefused] = (0, import_react269.useState)(null);
47936
+ const [designateRefused, setDesignateRefused] = (0, import_react271.useState)(null);
47861
47937
  const opensAs = view?.isDefault ? openingLayoutOf(view) : null;
47862
47938
  const canDesignate = Boolean(
47863
47939
  rights.write && view && layoutShowing && layoutShowing !== opensAs && (storeKeepsLayout(layoutShowing) || hostLayouts.some((h) => h.id === layoutShowing))
@@ -48036,14 +48112,14 @@ function TablePage({
48036
48112
  }
48037
48113
  });
48038
48114
  const openedEntry = ACTION_PRESS.find((entry) => entry.press.main !== void 0 && entry.press.main === main) ?? ACTION_PRESS.find((entry) => entry.press.rail !== void 0 && entry.press.rail === rail) ?? null;
48039
- const actionsRef = (0, import_react269.useRef)(actions);
48115
+ const actionsRef = (0, import_react271.useRef)(actions);
48040
48116
  actionsRef.current = actions;
48041
- const onActionsRef = (0, import_react269.useRef)(onActions);
48117
+ const onActionsRef = (0, import_react271.useRef)(onActions);
48042
48118
  onActionsRef.current = onActions;
48043
- (0, import_react269.useEffect)(() => {
48119
+ (0, import_react271.useEffect)(() => {
48044
48120
  onActionsRef.current?.(actionsRef.current);
48045
48121
  });
48046
- (0, import_react269.useEffect)(() => {
48122
+ (0, import_react271.useEffect)(() => {
48047
48123
  const onKey = (event) => {
48048
48124
  const asked3 = objectActionForKey(actionsRef.current, event);
48049
48125
  if (!asked3) return;
@@ -48272,7 +48348,7 @@ function TablePage({
48272
48348
  ] })
48273
48349
  ] }) }),
48274
48350
  /* @__PURE__ */ (0, import_jsx_runtime155.jsxs)(import_design_system140.DropdownMenuContent, { align: "start", className: "w-60", "data-view-look-menu-content": "", children: [
48275
- /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(import_design_system140.DropdownMenuLabel, { className: "text-xs font-normal text-muted-foreground", children: LOOK_WORDS.yours }),
48351
+ /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(import_design_system140.DropdownMenuLabel, { className: "text-xs font-normal text-muted-foreground", title: LOOK_WORDS.yours, children: LOOK_WORDS.yoursLabel }),
48276
48352
  lookSavable ? /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(import_design_system140.DropdownMenuItem, { onSelect: () => void saveLookToView(), "data-view-look-save": "", children: LOOK_WORDS.saveToView }) : null,
48277
48353
  rights.write ? /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(import_design_system140.DropdownMenuItem, { onSelect: () => setNamingLook(true), "data-view-look-save-new": "", children: LOOK_WORDS.saveAsNew }) : null,
48278
48354
  /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(import_design_system140.DropdownMenuItem, { onSelect: () => void resetLook(), "data-view-look-reset": "", children: LOOK_WORDS.reset })
@@ -48438,7 +48514,17 @@ function TablePage({
48438
48514
  children: cameFromLine(cameFrom, activeGroupField ?? null, askedInWords)
48439
48515
  }
48440
48516
  ) : null,
48441
- faceUnknown ? /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(RecordsSkeleton, { layout: skeletonLayoutFor(shownLayout), embedded }) : /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(
48517
+ faceUnknown ? (
48518
+ /* REVIEW-FIX 10: a full page paints the rows this table showed last time (else fills). */
48519
+ /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(
48520
+ RecordsSkeleton,
48521
+ {
48522
+ layout: skeletonLayoutFor(shownLayout),
48523
+ embedded,
48524
+ ...embedded ? {} : { rows: rememberedRowCount(`${tableId}:page:last`, 100, "fill") }
48525
+ }
48526
+ )
48527
+ ) : /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(
48442
48528
  ViewSwitcher,
48443
48529
  {
48444
48530
  chooser: false,
@@ -48584,8 +48670,8 @@ var PUBLIC_READ_ONLY = "Public \xB7 read only";
48584
48670
  function usePublicReadOnly(client, organizationId, tableId, table, rights) {
48585
48671
  const readOnly = rights.known && rights.read && !rights.write;
48586
48672
  const marked = table?.published_to_web;
48587
- const [isPublic, setIsPublic] = (0, import_react269.useState)(false);
48588
- (0, import_react269.useEffect)(() => {
48673
+ const [isPublic, setIsPublic] = (0, import_react271.useState)(false);
48674
+ (0, import_react271.useEffect)(() => {
48589
48675
  if (!readOnly || !table) {
48590
48676
  setIsPublic(false);
48591
48677
  return;
@@ -48610,9 +48696,9 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
48610
48696
  // src/entityViews.tsx
48611
48697
  var import_design_system141 = require("@ai-matrx/design-system");
48612
48698
  var import_data_table23 = require("@ai-matrx/design-system/data-table");
48613
- var import_react271 = require("react");
48699
+ var import_react273 = require("react");
48614
48700
  var import_design_system142 = require("@ai-matrx/design-system");
48615
- var import_react272 = require("@ai-matrx/records/react");
48701
+ var import_react274 = require("@ai-matrx/records/react");
48616
48702
  var import_jsx_runtime156 = require("react/jsx-runtime");
48617
48703
  var entityTitleColumn = entityNameColumn;
48618
48704
  function shown3(v) {
@@ -48623,12 +48709,12 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
48623
48709
  const choiceColumns = entityChoiceColumns(entity.columns);
48624
48710
  const column = (groupBy ? choiceColumns.find((c) => c.key === groupBy) : void 0) ?? choiceColumns[0] ?? null;
48625
48711
  const title = entityTitleColumn(entity.columns);
48626
- const extra = (0, import_react271.useMemo)(
48712
+ const extra = (0, import_react273.useMemo)(
48627
48713
  () => cardFields ? entity.columns.filter((c) => cardFields.includes(c.key)) : entity.columns.filter((c) => c !== title && c !== column && c.type !== "choice").slice(0, 2),
48628
48714
  [cardFields, entity.columns, title, column]
48629
48715
  );
48630
- const [refused, setRefused] = (0, import_react271.useState)(null);
48631
- const [over, setOver] = (0, import_react271.useState)(null);
48716
+ const [refused, setRefused] = (0, import_react273.useState)(null);
48717
+ const [over, setOver] = (0, import_react273.useState)(null);
48632
48718
  if (entity.error) return /* @__PURE__ */ (0, import_jsx_runtime156.jsx)("p", { className: "px-1 py-3 text-xs text-muted-foreground", children: `This board could not be read: ${entity.error}` });
48633
48719
  if (!entity.loading && !column) {
48634
48720
  return /* @__PURE__ */ (0, import_jsx_runtime156.jsx)("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.` });
@@ -48693,11 +48779,11 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
48693
48779
  }) });
48694
48780
  }
48695
48781
  function EntityChartBlock({ source, kind, by, measure, title, where, organization, centerValue, variant, className }) {
48696
- const client = (0, import_react272.useRecordsClient)();
48782
+ const client = (0, import_react274.useRecordsClient)();
48697
48783
  const m = measure ?? { op: "count" };
48698
48784
  const ask = JSON.stringify([source.token, by ?? null, m, where ?? null, organization ?? null]);
48699
- const [block, setBlock] = (0, import_react271.useState)(null);
48700
- (0, import_react271.useEffect)(() => {
48785
+ const [block, setBlock] = (0, import_react273.useState)(null);
48786
+ (0, import_react273.useEffect)(() => {
48701
48787
  let cancelled = false;
48702
48788
  const question = {
48703
48789
  ...by ? { by: [by] } : {},
@@ -48760,20 +48846,20 @@ function EntityTablePageBody({
48760
48846
  actions,
48761
48847
  className
48762
48848
  }) {
48763
- const [typed2, setTyped] = (0, import_react271.useState)("");
48849
+ const [typed2, setTyped] = (0, import_react273.useState)("");
48764
48850
  const term = searchOverride ?? typed2;
48765
48851
  const entity = useEntityTable(source.token, { pageSize, search: term });
48766
- const [layout, setLayout] = (0, import_react271.useState)(opened);
48767
- (0, import_react271.useEffect)(() => setLayout(opened), [opened]);
48852
+ const [layout, setLayout] = (0, import_react273.useState)(opened);
48853
+ (0, import_react273.useEffect)(() => setLayout(opened), [opened]);
48768
48854
  const choose = (next) => {
48769
48855
  setLayout(next);
48770
48856
  onLayoutChange?.(next);
48771
48857
  };
48772
48858
  const boardable = entityChoiceColumns(entity.columns).length > 0;
48773
48859
  const nameColumn = entityNameColumn(entity.columns);
48774
- const [naming, setNaming] = (0, import_react271.useState)(null);
48775
- const [adding, setAdding] = (0, import_react271.useState)(false);
48776
- const [addRefused, setAddRefused] = (0, import_react271.useState)(null);
48860
+ const [naming, setNaming] = (0, import_react273.useState)(null);
48861
+ const [adding, setAdding] = (0, import_react273.useState)(false);
48862
+ const [addRefused, setAddRefused] = (0, import_react273.useState)(null);
48777
48863
  const add = async () => {
48778
48864
  const name = (naming ?? "").trim();
48779
48865
  if (!name || !nameColumn || adding) return;
@@ -48785,7 +48871,7 @@ function EntityTablePageBody({
48785
48871
  setNaming(null);
48786
48872
  onOpenRecord?.(made.id);
48787
48873
  };
48788
- const [question, setQuestion] = (0, import_react271.useState)(() => questionFromGrouping(void 0));
48874
+ const [question, setQuestion] = (0, import_react273.useState)(() => questionFromGrouping(void 0));
48789
48875
  const { config: drill } = useDrill({
48790
48876
  source,
48791
48877
  question,
@@ -48888,9 +48974,9 @@ function TablePage2(props) {
48888
48974
  }
48889
48975
 
48890
48976
  // src/DataBindingPicker.tsx
48891
- var import_react273 = require("react");
48977
+ var import_react275 = require("react");
48892
48978
  var import_records64 = require("@ai-matrx/records");
48893
- var import_react274 = require("@ai-matrx/records/react");
48979
+ var import_react276 = require("@ai-matrx/records/react");
48894
48980
  var import_design_system143 = require("@ai-matrx/design-system");
48895
48981
  var import_jsx_runtime158 = require("react/jsx-runtime");
48896
48982
  var DATA_BINDING_SHAPES = [
@@ -48980,11 +49066,11 @@ function BindingDetails({
48980
49066
  disabled,
48981
49067
  defaultRowLimit
48982
49068
  }) {
48983
- const table = (0, import_react274.useTable)(tableId);
48984
- const fields = (0, import_react274.useFields)(tableId);
48985
- const fieldList = (0, import_react273.useMemo)(() => fields.data ?? [], [fields.data]);
49069
+ const table = (0, import_react276.useTable)(tableId);
49070
+ const fields = (0, import_react276.useFields)(tableId);
49071
+ const fieldList = (0, import_react275.useMemo)(() => fields.data ?? [], [fields.data]);
48986
49072
  const shape = binding.semantic_type;
48987
- (0, import_react273.useEffect)(() => {
49073
+ (0, import_react275.useEffect)(() => {
48988
49074
  if (disabled || shape === "value" || binding.transform || fields.loading || fieldList.length === 0) return;
48989
49075
  onChange({
48990
49076
  ...binding,
@@ -49129,7 +49215,7 @@ function BindingDetails({
49129
49215
  }
49130
49216
 
49131
49217
  // src/PickedSummaries.tsx
49132
- var import_react275 = require("@ai-matrx/records/react");
49218
+ var import_react277 = require("@ai-matrx/records/react");
49133
49219
  var import_jsx_runtime159 = require("react/jsx-runtime");
49134
49220
  function TableNameText({ dataSource, tableId }) {
49135
49221
  const tables = useTablesAnywhere(dataSource);
@@ -49158,7 +49244,7 @@ function ColumnValuesText({
49158
49244
  );
49159
49245
  }
49160
49246
  function ColumnValuesWords({ tableId, value }) {
49161
- const fields = (0, import_react275.useFields)(tableId);
49247
+ const fields = (0, import_react277.useFields)(tableId);
49162
49248
  const labels = useRecordLabels(fields.data ?? void 0);
49163
49249
  if (fields.loading) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "\u2026" });
49164
49250
  if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "Couldn't load this table's columns" });
@@ -49197,8 +49283,8 @@ function RecordNameText({
49197
49283
  );
49198
49284
  }
49199
49285
  function RecordNameWords({ tableId, recordId }) {
49200
- const table = (0, import_react275.useTable)(tableId);
49201
- const record = (0, import_react275.useRecord)(recordId);
49286
+ const table = (0, import_react277.useTable)(tableId);
49287
+ const record = (0, import_react277.useRecord)(recordId);
49202
49288
  if (record.loading || table.loading) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "\u2026" });
49203
49289
  if (record.error) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "Couldn't load this record" });
49204
49290
  if (!record.data) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "A record you cannot open" });
@@ -49206,19 +49292,19 @@ function RecordNameWords({ tableId, recordId }) {
49206
49292
  }
49207
49293
 
49208
49294
  // src/HeldChangeDecision.tsx
49209
- var import_react276 = require("react");
49210
- var import_react277 = require("@ai-matrx/records/react");
49295
+ var import_react278 = require("react");
49296
+ var import_react279 = require("@ai-matrx/records/react");
49211
49297
  var import_design_system144 = require("@ai-matrx/design-system");
49212
49298
  var import_jsx_runtime160 = require("react/jsx-runtime");
49213
49299
  function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, onDecided }) {
49214
- return /* @__PURE__ */ (0, import_jsx_runtime160.jsx)(import_react277.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ (0, import_jsx_runtime160.jsx)(Decision, { approvalId, onDecided }) });
49300
+ return /* @__PURE__ */ (0, import_jsx_runtime160.jsx)(import_react279.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ (0, import_jsx_runtime160.jsx)(Decision, { approvalId, onDecided }) });
49215
49301
  }
49216
49302
  function Decision({ approvalId, onDecided }) {
49217
- const client = (0, import_react277.useRecordsClient)();
49218
- const [may, setMay] = (0, import_react276.useState)(null);
49219
- const [busy, setBusy] = (0, import_react276.useState)(null);
49220
- const [error, setError] = (0, import_react276.useState)(null);
49221
- (0, import_react276.useEffect)(() => {
49303
+ const client = (0, import_react279.useRecordsClient)();
49304
+ const [may, setMay] = (0, import_react278.useState)(null);
49305
+ const [busy, setBusy] = (0, import_react278.useState)(null);
49306
+ const [error, setError] = (0, import_react278.useState)(null);
49307
+ (0, import_react278.useEffect)(() => {
49222
49308
  let live = true;
49223
49309
  void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
49224
49310
  if (!live) return;
@@ -49251,18 +49337,18 @@ function Decision({ approvalId, onDecided }) {
49251
49337
  }
49252
49338
 
49253
49339
  // src/TemplatePreview.tsx
49254
- var import_react278 = require("react");
49340
+ var import_react280 = require("react");
49255
49341
  var import_memory = require("@ai-matrx/records/memory");
49256
- var import_react279 = require("@ai-matrx/records/react");
49342
+ var import_react281 = require("@ai-matrx/records/react");
49257
49343
  var import_jsx_runtime161 = require("react/jsx-runtime");
49258
49344
  function useTemplatePreview(spec, today) {
49259
- return (0, import_react278.useMemo)(() => (0, import_memory.templatePreview)(spec, today ? { today } : {}), [spec, today]);
49345
+ return (0, import_react280.useMemo)(() => (0, import_memory.templatePreview)(spec, today ? { today } : {}), [spec, today]);
49260
49346
  }
49261
49347
  function TemplatePreview({ spec, today, initialTable, host, aside, booking, className }) {
49262
49348
  const preview = useTemplatePreview(spec, today);
49263
- const bound2 = (0, import_react278.useMemo)(() => ({ ...host, sayLevelNeeded: false }), [host]);
49349
+ const bound2 = (0, import_react280.useMemo)(() => ({ ...host, sayLevelNeeded: false }), [host]);
49264
49350
  const first = preview.tables.find((t) => t.token === initialTable) ?? preview.tables[0];
49265
- const [active, setActive] = (0, import_react278.useState)(first?.id ?? null);
49351
+ const [active, setActive] = (0, import_react280.useState)(first?.id ?? null);
49266
49352
  const table = preview.tables.find((t) => t.id === active) ?? first;
49267
49353
  if (!table) return null;
49268
49354
  return /* @__PURE__ */ (0, import_jsx_runtime161.jsxs)("div", { className: ["flex min-w-0 flex-col gap-3", className].filter(Boolean).join(" "), "data-template-preview": preview.tables.length, children: [
@@ -49299,10 +49385,10 @@ function TemplatePreview({ spec, today, initialTable, host, aside, booking, clas
49299
49385
  ] });
49300
49386
  }
49301
49387
  function PreviewForms({ preview, booking }) {
49302
- const client = (0, import_react279.useRecordsClient)();
49303
- const [forms, setForms] = (0, import_react278.useState)(null);
49304
- const [pages, setPages] = (0, import_react278.useState)([]);
49305
- (0, import_react278.useEffect)(() => {
49388
+ const client = (0, import_react281.useRecordsClient)();
49389
+ const [forms, setForms] = (0, import_react280.useState)(null);
49390
+ const [pages, setPages] = (0, import_react280.useState)([]);
49391
+ (0, import_react280.useEffect)(() => {
49306
49392
  let gone = false;
49307
49393
  void client.forms().then((answered) => {
49308
49394
  if (!gone) setForms(answered.ok ? answered.data.map(formFromSummary) : []);