@ai-matrx/records-ui 0.102.14 → 0.102.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,46 @@ 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.jsx)("span", { "aria-hidden": "true", "data-records-cell-ghost": "", className: "pointer-events-none invisible block select-none truncate px-1 py-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7767
+ RecordValue,
7768
+ {
7769
+ inCell: true,
7770
+ field: field2,
7771
+ value: row.document?.[field2.key],
7772
+ document: row.document,
7773
+ recordId: row.id,
7774
+ withheld: withheldNoticeOf(row.hidden, field2.key),
7775
+ ...format ? { format } : {}
7776
+ }
7777
+ ) }),
7778
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7779
+ OpenCell,
7780
+ {
7781
+ field: field2,
7782
+ draft: editing.draft,
7783
+ initialSearch: editing.searchSeed,
7784
+ onType: editing.type,
7785
+ onCommit: (move, via) => editing.commit(move, via),
7786
+ onCancel: (via) => editing.cancel(via),
7787
+ below: (
7788
+ // KEPT EDITING: the refusal stays beside the value it is about, so the
7789
+ // person reads what to change while changing it. Keep editing is the
7790
+ // state they are in, so only Discard is offered. It is INSIDE the open
7791
+ // cell, so pressing Discard is not "focus left the cell" — which would
7792
+ // commit the refused value one more time on its way out.
7793
+ refusal4 && !refusal4.conflict ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
7794
+ RefusalNotice,
7795
+ {
7796
+ error: refusal4.error,
7797
+ className: "py-1.5 text-left",
7798
+ onDiscard: () => editing.discard(row.id, field2.key)
7799
+ }
7800
+ ) : null
7801
+ )
7802
+ }
7803
+ )
7804
+ ] });
7753
7805
  }
7754
7806
  if (editorKindFor(field2) === "checkbox") {
7755
7807
  const answered = value === true || value === false;
@@ -8099,8 +8151,9 @@ function OpenCell({
8099
8151
  "data-matrx-cell-editor": "",
8100
8152
  tabIndex: -1,
8101
8153
  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,
8154
+ // OVER the cell's ghost (see `data-records-open-cell`), never in the table's measuring.
8155
+ "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",
8156
+ FLOATING_CELL_NOTE_CLASS,
8104
8157
  // A field's own input is 36px (h-9); in a 35px row it grew the row 4px. In the cell it is
8105
8158
  // the row action strip's 32px, so opening a cell never changes the row (STABLE-TABLES).
8106
8159
  "[&_input:not([type=checkbox]):not([type=radio])]:h-8 [&_input:not([type=checkbox]):not([type=radio])]:py-0"
@@ -8159,11 +8212,13 @@ function OpenCell({
8159
8212
  addsChoices: true
8160
8213
  }
8161
8214
  ),
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
8215
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { "data-records-cell-tray": "", className: FLOATING_CELL_TRAY_CLASS, children: [
8216
+ 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: [
8217
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_design_system23.Button, { size: "sm", onClick: () => once(() => onCommit(null, "pick")), children: "Save" }),
8218
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_design_system23.Button, { size: "sm", variant: "ghost", onClick: () => once(() => onCancel("pick")), children: "Cancel" })
8219
+ ] }),
8220
+ below ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "block bg-popover shadow-md", children: below }) : null
8221
+ ] })
8167
8222
  ]
8168
8223
  }
8169
8224
  );
@@ -8286,15 +8341,28 @@ function BodySkeleton({ layout, embedded, rows }) {
8286
8341
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex h-9 items-center gap-6 border-b border-border px-3", children: Array.from({ length: 6 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "line", width: "sm", className: "w-16" }, i)) }),
8287
8342
  Array.from({ length: Math.min(lineCount, 8) }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex h-10 items-center border-b border-border/60 px-3", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { className: "h-6 rounded-md", style: { marginLeft: `${i * 13 % 45}%`, width: `${20 + i * 7 % 25}%` } }) }, i))
8288
8343
  ] });
8289
- case "form":
8290
8344
  case "record":
8345
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-h-0 flex-1 flex-col gap-2 overflow-hidden", "data-records-skeleton-part": "body", children: [
8346
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "title", width: "1/2", className: "h-8", "data-records-skeleton-part": "title" }),
8347
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex h-[38px] items-center gap-2", "data-records-skeleton-part": "actions", children: [
8348
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "control", width: "sm", className: "h-8" }),
8349
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "control", width: "sm", className: "h-8" })
8350
+ ] }),
8351
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px w-full shrink-0 bg-border" }),
8352
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "grid grid-cols-[minmax(6rem,12rem)_1fr] gap-x-3 gap-y-0.5", "data-records-skeleton-part": "fields", children: Array.from({ length: 6 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "contents", children: [
8353
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "line", width: "2/3", className: "my-[7px]" }),
8354
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "row", className: "h-7" })
8355
+ ] }, i)) }),
8356
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "block", height: "lg" })
8357
+ ] });
8358
+ case "form":
8291
8359
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-h-0 flex-1 flex-col gap-4 overflow-hidden", "data-records-skeleton-part": "body", children: [
8292
8360
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "title", width: "1/2" }),
8293
8361
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "grid grid-cols-[minmax(6rem,12rem)_1fr] gap-x-3 gap-y-1.5", children: Array.from({ length: 6 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "contents", children: [
8294
8362
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "line", width: "2/3", className: "my-1.5" }),
8295
8363
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "row", className: "h-7" })
8296
8364
  ] }, i)) }),
8297
- layout === "record" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "block", height: "lg" }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "control", width: "sm" })
8365
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "control", width: "sm" })
8298
8366
  ] });
8299
8367
  case "chart":
8300
8368
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-2", "data-records-skeleton-part": "body", children: [
@@ -11351,11 +11419,11 @@ function FieldEditor(props) {
11351
11419
  import_design_system34.Checkbox,
11352
11420
  {
11353
11421
  checked: required,
11354
- "aria-label": "Every record has to have one",
11422
+ "aria-label": "Required",
11355
11423
  onCheckedChange: (v) => setRequired(v === true)
11356
11424
  }
11357
11425
  ),
11358
- "Every record has to have one"
11426
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { title: "Every record has to have one", children: "Required" })
11359
11427
  ] }),
11360
11428
  offersMany ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("label", { className: "flex items-center gap-1.5", children: [
11361
11429
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
@@ -14881,7 +14949,7 @@ function useMergedGridControls(args) {
14881
14949
  children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_design_system46.DialogContent, { className: "max-h-[85vh] overflow-y-auto sm:max-w-2xl", children: [
14882
14950
  /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_design_system46.DialogHeader, { children: [
14883
14951
  /* @__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 }),
14884
- /* @__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." })
14952
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_design_system46.DialogDescription, { className: "sr-only", children: "Name, type and look" })
14885
14953
  ] }),
14886
14954
  dialog?.kind === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
14887
14955
  FieldEditor,
@@ -19343,6 +19411,7 @@ function ImportWizard({ tableId, source, onDone, onWrote, className }) {
19343
19411
  // src/tableShape.ts
19344
19412
  var import_source2 = require("@ai-matrx/content-ir/source");
19345
19413
  var import_text_case9 = require("@ai-matrx/kit/text-case");
19414
+ var import_delimited2 = require("@ai-matrx/kit/delimited");
19346
19415
  var FEWEST_LIST_ITEMS = 2;
19347
19416
  var FEWEST_KEY_VALUE_PAIRS = 2;
19348
19417
  var LONGEST_TEXT_READ = 2e6;
@@ -19520,38 +19589,7 @@ function shapeFromList(items, name, at) {
19520
19589
  };
19521
19590
  }
19522
19591
  function parseDelimited(text, delimiter) {
19523
- const rows = [];
19524
- let row = [];
19525
- let cell2 = "";
19526
- let quoted2 = false;
19527
- for (let i = 0; i < text.length; i += 1) {
19528
- const ch = text[i];
19529
- if (quoted2) {
19530
- if (ch === '"') {
19531
- if (text[i + 1] === '"') {
19532
- cell2 += '"';
19533
- i += 1;
19534
- } else quoted2 = false;
19535
- } else cell2 += ch;
19536
- continue;
19537
- }
19538
- if (ch === '"' && cell2.trim() === "") quoted2 = true;
19539
- else if (ch === delimiter) {
19540
- row.push(cell2);
19541
- cell2 = "";
19542
- } else if (ch === "\n" || ch === "\r") {
19543
- if (ch === "\r" && text[i + 1] === "\n") i += 1;
19544
- row.push(cell2);
19545
- rows.push(row);
19546
- row = [];
19547
- cell2 = "";
19548
- } else cell2 += ch;
19549
- }
19550
- if (cell2.length > 0 || row.length > 0) {
19551
- row.push(cell2);
19552
- rows.push(row);
19553
- }
19554
- return rows.filter((r) => r.some((c) => c.trim() !== ""));
19592
+ return (0, import_delimited2.parseDelimited)(text, { delimiter, skipEmptyLines: "greedy" }).data;
19555
19593
  }
19556
19594
  function delimitedShape(text, delimiter, fenced, at, name) {
19557
19595
  const matrix = parseDelimited(text.trim(), delimiter);
@@ -23504,7 +23542,7 @@ function GridBody({
23504
23542
  {
23505
23543
  ...fills ? { className: "min-h-0 flex-1" } : {},
23506
23544
  frameHeight: fills ? "fill" : "content",
23507
- loadingRows: fills ? "fill" : rememberedRowCount(rowMemoryKey, pageSize, 5),
23545
+ loadingRows: rememberedRowCount(rowMemoryKey, pageSize, fills ? "fill" : 5),
23508
23546
  ...!look.rowHeight ? { loadingRowHeight: RECORDS_GRID_ROW_PX } : {},
23509
23547
  data: rows,
23510
23548
  columns: tableColumns,
@@ -27443,7 +27481,7 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
27443
27481
  },
27444
27482
  variant: "destructive",
27445
27483
  title: `Move every row of \u201C${writable.find((t) => t.id === tableId)?.name ?? "this table"}\u201D to the archive?`,
27446
- description: "They stay restorable from the table's Archived items. Then the rows you are saving go in, through the import below.",
27484
+ description: "Restorable from Archived items",
27447
27485
  confirmLabel: replacing ? "Archiving\u2026" : "Archive them",
27448
27486
  cancelLabel: "Keep them",
27449
27487
  busy: replacing,
@@ -28930,18 +28968,25 @@ function RecordFieldsInPlace({
28930
28968
  const format = formatForField(field2);
28931
28969
  return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "contents", children: [
28932
28970
  /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("dt", { className: "flex items-baseline gap-1 truncate py-1 text-muted-foreground", children: renderLabel(field2) }),
28933
- /* @__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)(
28934
- GridCell,
28971
+ /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
28972
+ "dd",
28935
28973
  {
28936
- field: field2,
28937
- row,
28938
- editing: canWrite ? editing : null,
28939
- canWrite,
28940
- whyNot,
28941
- clickOpens: true,
28942
- ...format ? { format } : {}
28974
+ className: "min-w-0 rounded hover:bg-muted/50 [&_[data-matrx-cell-editor]_input:not([type=checkbox]):not([type=radio])]:!h-7",
28975
+ "data-records-in-place-field": field2.key,
28976
+ children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
28977
+ GridCell,
28978
+ {
28979
+ field: field2,
28980
+ row,
28981
+ editing: canWrite ? editing : null,
28982
+ canWrite,
28983
+ whyNot,
28984
+ clickOpens: true,
28985
+ ...format ? { format } : {}
28986
+ }
28987
+ )
28943
28988
  }
28944
- ) })
28989
+ )
28945
28990
  ] }, field2.id);
28946
28991
  }) }),
28947
28992
  /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(UndoNotice, { undo })
@@ -29138,7 +29183,7 @@ function AddBody({ tableId }) {
29138
29183
  const made = await mutation.declare({ table_id: tableId, spec: { label: BODY_COLUMN_NAME, type: "rich_text" } });
29139
29184
  if (made) (0, import_react160.tableShapeChanged)(tableId);
29140
29185
  },
29141
- children: "Write on this page"
29186
+ children: "Add notes"
29142
29187
  }
29143
29188
  ),
29144
29189
  mutation.error ? /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(RefusalNotice, { error: mutation.error }) : null
@@ -29283,7 +29328,7 @@ function computedInPlainWords(row, field2) {
29283
29328
  const shown4 = row.value === null || row.value === void 0 || row.value === "" ? "nothing" : field2 ? scalarText(field2, row.value) : String(row.value);
29284
29329
  const when = new Date(row.computed_at);
29285
29330
  const at = Number.isNaN(when.getTime()) ? "" : ` on ${when.toLocaleDateString()}`;
29286
- return `${name} was worked out as ${shown4}${at}.`;
29331
+ return `${name}: ${shown4}${at}`;
29287
29332
  }
29288
29333
 
29289
29334
  // src/systemTable.ts
@@ -29513,7 +29558,10 @@ async function keepLook(client, tableId, viewId, look) {
29513
29558
  return client.viewLookSet({ table_id: tableId, view_id: viewId, look: doc && Object.keys(doc).length > 0 ? doc : null });
29514
29559
  }
29515
29560
  var LOOK_WORDS = {
29561
+ /** The reason, for a tooltip or a screen reader — never a line on the page (interface-text). */
29516
29562
  yours: "You changed how this view looks. Only you see it.",
29563
+ /** The visible label for the same fact. */
29564
+ yoursLabel: "Only you see this",
29517
29565
  saveToView: "Save to view",
29518
29566
  saveAsNew: "Save as new view",
29519
29567
  reset: "Reset to view",
@@ -39183,7 +39231,7 @@ function WebhooksPanel({ tableId, className }) {
39183
39231
  if (!next && !busy) setStopping(null);
39184
39232
  },
39185
39233
  title: `Stop sending to ${stopping?.description ?? stopping?.target_url ?? "this address"}?`,
39186
- description: "Changes from now on are not sent there. The webhook is kept, switched off \u2014 nothing about it is deleted.",
39234
+ description: "Kept, switched off",
39187
39235
  confirmLabel: "Switch off",
39188
39236
  cancelLabel: "Keep sending",
39189
39237
  busy,
@@ -41577,7 +41625,7 @@ function SignBlock({ tableId, recordId, render, className }) {
41577
41625
  }
41578
41626
 
41579
41627
  // src/ChartBlock.tsx
41580
- var import_react232 = require("react");
41628
+ var import_react234 = require("react");
41581
41629
  var import_recharts = require("recharts");
41582
41630
  var import_records57 = require("@ai-matrx/records");
41583
41631
  var import_core21 = require("@ai-matrx/records/core");
@@ -41637,6 +41685,39 @@ function useLinkGroupNamer(block, tableId) {
41637
41685
  }, [named, choices, labels]);
41638
41686
  }
41639
41687
 
41688
+ // src/measureWords.ts
41689
+ var import_react232 = require("react");
41690
+ var import_react233 = require("@ai-matrx/records/react");
41691
+ var import_text_case18 = require("@ai-matrx/kit/text-case");
41692
+ var OP_WORD = { sum: "Total", avg: "Average", min: "Lowest", max: "Highest" };
41693
+ function measureWords(key, fields) {
41694
+ if (key === "count") return "How many";
41695
+ const at = key.indexOf("_");
41696
+ if (at < 0) return (0, import_text_case18.humanizeIdentifier)(key);
41697
+ const op2 = key.slice(0, at);
41698
+ const column = key.slice(at + 1);
41699
+ const field2 = fields?.find((f) => f.key === column);
41700
+ const name = field2 ? fieldName(field2) : (0, import_text_case18.humanizeIdentifier)(column);
41701
+ const word = OP_WORD[op2];
41702
+ return word ? `${word} ${name.charAt(0).toLowerCase()}${name.slice(1)}` : `${(0, import_text_case18.humanizeIdentifier)(op2)} ${name}`;
41703
+ }
41704
+ function useMeasureWords(key, tableId) {
41705
+ const client = (0, import_react233.useOptionalRecordsClient)();
41706
+ const [fields, setFields] = (0, import_react232.useState)(null);
41707
+ const needs = key !== "count";
41708
+ (0, import_react232.useEffect)(() => {
41709
+ if (!client || !tableId || !needs) return;
41710
+ let cancelled = false;
41711
+ void client.fields({ table_id: tableId }).then((result) => {
41712
+ if (!cancelled && result.ok) setFields(result.data);
41713
+ });
41714
+ return () => {
41715
+ cancelled = true;
41716
+ };
41717
+ }, [client, tableId, needs]);
41718
+ return measureWords(key, fields);
41719
+ }
41720
+
41640
41721
  // src/ChartBlock.tsx
41641
41722
  var import_jsx_runtime134 = require("react/jsx-runtime");
41642
41723
  var priorKey = (key) => `prior__${key}`;
@@ -41715,7 +41796,8 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41715
41796
  const series = compared ? [primary, priorKey(primary)] : [primary];
41716
41797
  const target = kind === "stuck" ? null : block.target ?? null;
41717
41798
  const named = useLinkGroupNamer(source ? NO_GROUPS : block, tableId);
41718
- const points = (0, import_react232.useMemo)(() => {
41799
+ const measureName = useMeasureWords(primary, tableId);
41800
+ const points = (0, import_react234.useMemo)(() => {
41719
41801
  if (kind === "stuck") return [];
41720
41802
  const rows = block.rows ?? [];
41721
41803
  return rows.map((row, index) => {
@@ -41739,10 +41821,10 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41739
41821
  };
41740
41822
  });
41741
41823
  }, [block.rows, kind, primary, compared, grain, windows, named]);
41742
- const config = (0, import_react232.useMemo)(() => {
41824
+ const config = (0, import_react234.useMemo)(() => {
41743
41825
  const out = {};
41744
41826
  out[primary] = {
41745
- label: windows ? windowName(windows.window, windows.period) : primary.replace("_", " of "),
41827
+ label: windows ? windowName(windows.window, windows.period) : measureName,
41746
41828
  color: SERIES_COLORS[0]
41747
41829
  };
41748
41830
  if (windows) {
@@ -41755,7 +41837,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41755
41837
  out[point.label] ??= { label: point.label, color: SERIES_COLORS[index % SERIES_COLORS.length] };
41756
41838
  });
41757
41839
  return out;
41758
- }, [primary, windows, points]);
41840
+ }, [primary, measureName, windows, points]);
41759
41841
  const goal = target && typeof target.value === "number" ? {
41760
41842
  value: typeof target.pace === "number" ? target.pace : block.bucket ? null : target.value,
41761
41843
  label: typeof target.pace === "number" && target.per !== "bucket" ? `${target.label} pace` : target.label
@@ -41800,7 +41882,7 @@ function ChartBlock({ block, subject, tableName: tableName2, className, centerVa
41800
41882
  /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { children: pretty(block.totals.current) }),
41801
41883
  /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(Trend, { pct: block.totals.change_pct, aimingUp: !!target })
41802
41884
  ] }) : null,
41803
- /* @__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 ") })
41885
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { className: "ml-auto shrink-0 text-muted-foreground", children: kind === "stuck" ? `${block.days ?? 14} days` : measureName })
41804
41886
  ] }),
41805
41887
  block.compare_refused ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: block.compare_refused }) : null,
41806
41888
  !block.refused && targetNote(target) ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: targetNote(target) }) : null,
@@ -42097,8 +42179,8 @@ function onlyWholeNumbers(rows) {
42097
42179
  }
42098
42180
 
42099
42181
  // src/DashboardCanvas.tsx
42100
- var import_react239 = require("react");
42101
- var import_react240 = require("@ai-matrx/records/react");
42182
+ var import_react241 = require("react");
42183
+ var import_react242 = require("@ai-matrx/records/react");
42102
42184
  var import_design_system124 = require("@ai-matrx/design-system");
42103
42185
 
42104
42186
  // src/DashboardGrid.tsx
@@ -42240,18 +42322,18 @@ function GridCell2({
42240
42322
  }
42241
42323
 
42242
42324
  // src/AddChart.tsx
42243
- var import_react237 = require("react");
42244
- var import_react238 = require("@ai-matrx/records/react");
42325
+ var import_react239 = require("react");
42326
+ var import_react240 = require("@ai-matrx/records/react");
42245
42327
  var import_design_system123 = require("@ai-matrx/design-system");
42246
42328
 
42247
42329
  // src/TablePickers.tsx
42248
- var import_react235 = require("react");
42249
- var import_react236 = require("@ai-matrx/records/react");
42330
+ var import_react237 = require("react");
42331
+ var import_react238 = require("@ai-matrx/records/react");
42250
42332
  var import_design_system122 = require("@ai-matrx/design-system");
42251
42333
 
42252
42334
  // src/RecordsMount.tsx
42253
- var import_react233 = require("react");
42254
- var import_react234 = require("@ai-matrx/records/react");
42335
+ var import_react235 = require("react");
42336
+ var import_react236 = require("@ai-matrx/records/react");
42255
42337
  var import_jsx_runtime136 = require("react/jsx-runtime");
42256
42338
  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.";
42257
42339
  function storeDecidesRights(_table) {
@@ -42265,10 +42347,10 @@ function RecordsMount({
42265
42347
  }) {
42266
42348
  const bound2 = useShallowStableHost(host);
42267
42349
  void letTheStoreDecideRights;
42268
- 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 }) }) });
42350
+ 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 }) }) });
42269
42351
  }
42270
42352
  function useShallowStableHost(host) {
42271
- const held = (0, import_react233.useRef)(null);
42353
+ const held = (0, import_react235.useRef)(null);
42272
42354
  const next = host ?? {};
42273
42355
  const previous = held.current;
42274
42356
  if (previous !== null && sameParts(previous, next)) return previous;
@@ -42363,8 +42445,8 @@ function readTablesAnywhere(dataSource) {
42363
42445
  return read;
42364
42446
  }
42365
42447
  function useTablesAnywhere(dataSource) {
42366
- const [state, setState] = (0, import_react235.useState)({ loading: true, error: null, rows: [] });
42367
- (0, import_react235.useEffect)(() => {
42448
+ const [state, setState] = (0, import_react237.useState)({ loading: true, error: null, rows: [] });
42449
+ (0, import_react237.useEffect)(() => {
42368
42450
  let live = true;
42369
42451
  void readTablesAnywhere(dataSource).then((result) => {
42370
42452
  if (live) setState(result);
@@ -42434,14 +42516,14 @@ function TableScope({ dataSource, userId, tableId, children, fallback = null, un
42434
42516
  const organizationId = list.rows.find((t) => t.table_id === tableId)?.organization_id ?? null;
42435
42517
  if (tableId && !organizationId && !list.loading) return /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_jsx_runtime137.Fragment, { children: unavailable ?? fallback });
42436
42518
  if (!tableId || !organizationId) return /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_jsx_runtime137.Fragment, { children: fallback });
42437
- return /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_react236.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children });
42519
+ return /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_react238.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children });
42438
42520
  }
42439
42521
  function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
42440
- const fields = (0, import_react236.useFields)(tableId);
42441
- const all = (0, import_react235.useMemo)(() => fields.data ?? [], [fields.data]);
42442
- const byKey = (0, import_react235.useMemo)(() => new Map(all.map((f) => [f.key, f])), [all]);
42522
+ const fields = (0, import_react238.useFields)(tableId);
42523
+ const all = (0, import_react237.useMemo)(() => fields.data ?? [], [fields.data]);
42524
+ const byKey = (0, import_react237.useMemo)(() => new Map(all.map((f) => [f.key, f])), [all]);
42443
42525
  const keys = Object.keys(value);
42444
- const [adding, setAdding] = (0, import_react235.useState)(false);
42526
+ const [adding, setAdding] = (0, import_react237.useState)(false);
42445
42527
  const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
42446
42528
  const rename = (from, to) => {
42447
42529
  if (from === to) return;
@@ -42529,8 +42611,8 @@ function ColumnValueRow({
42529
42611
  ] });
42530
42612
  }
42531
42613
  function RecordPicker({ tableId, value, onChange, disabled }) {
42532
- const table = (0, import_react236.useTable)(tableId);
42533
- const records = (0, import_react236.useRecords)(tableId, { pageSize: 200 });
42614
+ const table = (0, import_react238.useTable)(tableId);
42615
+ const records = (0, import_react238.useRecords)(tableId, { pageSize: 200 });
42534
42616
  const rows = records.data?.rows ?? [];
42535
42617
  const options = rows.map((row) => ({
42536
42618
  value: row.id,
@@ -42596,20 +42678,20 @@ function chartSpecFrom(args) {
42596
42678
  };
42597
42679
  }
42598
42680
  function AddChart({ subject, onAdd, onClose }) {
42599
- const client = (0, import_react238.useRecordsClient)();
42600
- const [tableId, setTableId] = (0, import_react237.useState)(subject);
42601
- const fields = (0, import_react238.useFields)(tableId);
42602
- const all = (0, import_react237.useMemo)(() => onePerKey(fields.data ?? []), [fields.data]);
42681
+ const client = (0, import_react240.useRecordsClient)();
42682
+ const [tableId, setTableId] = (0, import_react239.useState)(subject);
42683
+ const fields = (0, import_react240.useFields)(tableId);
42684
+ const all = (0, import_react239.useMemo)(() => onePerKey(fields.data ?? []), [fields.data]);
42603
42685
  const labels = useRecordLabels(all);
42604
42686
  const wordsFor2 = (key, value) => {
42605
42687
  const field2 = all.find((f) => f.key === key);
42606
42688
  return field2 ? scalarText(field2, value, labels) : String(value);
42607
42689
  };
42608
- const [measureKey5, setMeasureKey] = (0, import_react237.useState)("count");
42609
- const [splitKey, setSplitKey] = (0, import_react237.useState)("none");
42610
- const [kind, setKind] = (0, import_react237.useState)("auto");
42611
- const [filter, setFilter] = (0, import_react237.useState)({});
42612
- const [saving, setSaving] = (0, import_react237.useState)(false);
42690
+ const [measureKey5, setMeasureKey] = (0, import_react239.useState)("count");
42691
+ const [splitKey, setSplitKey] = (0, import_react239.useState)("none");
42692
+ const [kind, setKind] = (0, import_react239.useState)("auto");
42693
+ const [filter, setFilter] = (0, import_react239.useState)({});
42694
+ const [saving, setSaving] = (0, import_react239.useState)(false);
42613
42695
  const numbers = numberColumns(all);
42614
42696
  const choices = offerableFields(all, "choice");
42615
42697
  const dates = offerableFields(all, "date");
@@ -42751,31 +42833,31 @@ function combineFilter(base, extra, fieldIdOf) {
42751
42833
  // src/DashboardCanvas.tsx
42752
42834
  var import_jsx_runtime139 = require("react/jsx-runtime");
42753
42835
  function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, onCreated, className }) {
42754
- const client = (0, import_react240.useRecordsClient)();
42836
+ const client = (0, import_react242.useRecordsClient)();
42755
42837
  const host = useRecordsUi();
42756
- const table = (0, import_react240.useTable)(tableId);
42838
+ const table = (0, import_react242.useTable)(tableId);
42757
42839
  const rights = useTableRights(table.data);
42758
- const fields = (0, import_react240.useFields)(tableId);
42759
- const [boards, setBoards] = (0, import_react239.useState)(null);
42760
- const [pages, setPages] = (0, import_react239.useState)([]);
42761
- const [error, setError] = (0, import_react239.useState)(null);
42762
- const [activeId, setActiveId] = (0, import_react239.useState)(activeDashboardId ?? null);
42763
- const [madeOnMount, setMadeOnMount] = (0, import_react239.useState)("waiting");
42764
- const [askingToRemove, setAskingToRemove] = (0, import_react239.useState)(null);
42765
- const [run, setRun] = (0, import_react239.useState)(null);
42766
- const [running, setRunning] = (0, import_react239.useState)(false);
42767
- const [question, setQuestion] = (0, import_react239.useState)("");
42768
- const [asking, setAsking] = (0, import_react239.useState)(false);
42769
- const [scheduling, setScheduling] = (0, import_react239.useState)(false);
42770
- const [arranging, setArranging] = (0, import_react239.useState)(false);
42771
- const [adding, setAdding] = (0, import_react239.useState)(false);
42772
- const [grain, setGrain] = (0, import_react239.useState)(null);
42840
+ const fields = (0, import_react242.useFields)(tableId);
42841
+ const [boards, setBoards] = (0, import_react241.useState)(null);
42842
+ const [pages, setPages] = (0, import_react241.useState)([]);
42843
+ const [error, setError] = (0, import_react241.useState)(null);
42844
+ const [activeId, setActiveId] = (0, import_react241.useState)(activeDashboardId ?? null);
42845
+ const [madeOnMount, setMadeOnMount] = (0, import_react241.useState)("waiting");
42846
+ const [askingToRemove, setAskingToRemove] = (0, import_react241.useState)(null);
42847
+ const [run, setRun] = (0, import_react241.useState)(null);
42848
+ const [running, setRunning] = (0, import_react241.useState)(false);
42849
+ const [question, setQuestion] = (0, import_react241.useState)("");
42850
+ const [asking, setAsking] = (0, import_react241.useState)(false);
42851
+ const [scheduling, setScheduling] = (0, import_react241.useState)(false);
42852
+ const [arranging, setArranging] = (0, import_react241.useState)(false);
42853
+ const [adding, setAdding] = (0, import_react241.useState)(false);
42854
+ const [grain, setGrain] = (0, import_react241.useState)(null);
42773
42855
  const runArgs = (dashboard_id) => ({
42774
42856
  dashboard_id,
42775
42857
  ...filter ? { filter } : {},
42776
42858
  ...grain ? { grain } : {}
42777
42859
  });
42778
- const load = (0, import_react239.useCallback)(async () => {
42860
+ const load = (0, import_react241.useCallback)(async () => {
42779
42861
  const answered = await client.dashboards({ table_id: tableId });
42780
42862
  if (!answered.ok) {
42781
42863
  setError(answered.error);
@@ -42787,19 +42869,19 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42787
42869
  setBoards(read);
42788
42870
  return read;
42789
42871
  }, [client, tableId]);
42790
- const [notKept, setNotKept] = (0, import_react239.useState)(null);
42791
- (0, import_react239.useEffect)(() => {
42872
+ const [notKept, setNotKept] = (0, import_react241.useState)(null);
42873
+ (0, import_react241.useEffect)(() => {
42792
42874
  void load();
42793
42875
  }, [load]);
42794
- (0, import_react239.useEffect)(() => {
42876
+ (0, import_react241.useEffect)(() => {
42795
42877
  if (!boards || boards.length === 0) return;
42796
42878
  if (createOnMount && madeOnMount !== "done") return;
42797
42879
  const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
42798
42880
  if (chosen.id !== activeId) setActiveId(chosen.id);
42799
42881
  }, [boards, activeDashboardId, madeOnMount]);
42800
- const board = (0, import_react239.useMemo)(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
42882
+ const board = (0, import_react241.useMemo)(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
42801
42883
  const filterKey = JSON.stringify(filter ?? {});
42802
- (0, import_react239.useEffect)(() => {
42884
+ (0, import_react241.useEffect)(() => {
42803
42885
  if (!activeId) {
42804
42886
  setRun(null);
42805
42887
  return;
@@ -42817,7 +42899,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42817
42899
  cancelled = true;
42818
42900
  };
42819
42901
  }, [client, activeId, filterKey, grain]);
42820
- const declare2 = (0, import_react239.useCallback)(
42902
+ const declare2 = (0, import_react241.useCallback)(
42821
42903
  async (next, blocks) => {
42822
42904
  const written = await client.dashboardDeclare(
42823
42905
  // Every block leaves with its own id — kept, or minted here (v6 lane 11).
@@ -42869,12 +42951,12 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
42869
42951
  ]
42870
42952
  );
42871
42953
  }
42872
- (0, import_react239.useEffect)(() => {
42954
+ (0, import_react241.useEffect)(() => {
42873
42955
  if (!createOnMount || madeOnMount !== "waiting" || boards === null || !fields.data) return;
42874
42956
  setMadeOnMount("making");
42875
42957
  void create().then(() => setMadeOnMount("done"));
42876
42958
  }, [createOnMount, madeOnMount, boards, fields.data]);
42877
- const refresh = (0, import_react239.useCallback)(async () => {
42959
+ const refresh = (0, import_react241.useCallback)(async () => {
42878
42960
  if (!activeId) return;
42879
42961
  setRunning(true);
42880
42962
  const again = await client.dashboardRun(runArgs(activeId));
@@ -43086,7 +43168,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
43086
43168
  ] });
43087
43169
  }
43088
43170
  function ChartOfTable({ block, subject, table }) {
43089
- const named = (0, import_react240.useTable)(table);
43171
+ const named = (0, import_react242.useTable)(table);
43090
43172
  return /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(ChartBlock, { block, subject, tableName: named.data?.name ?? "\u2014" });
43091
43173
  }
43092
43174
  function BlockSettingsMenu({
@@ -43116,7 +43198,7 @@ function BlockSettings({
43116
43198
  title,
43117
43199
  onChange
43118
43200
  }) {
43119
- const own3 = (0, import_react240.useFields)(spec.subject);
43201
+ const own3 = (0, import_react242.useFields)(spec.subject);
43120
43202
  const fields = own3.data ?? [];
43121
43203
  return /* @__PURE__ */ (0, import_jsx_runtime139.jsxs)("div", { className: "flex flex-col items-stretch gap-1.5 text-xs", children: [
43122
43204
  /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(
@@ -43314,10 +43396,10 @@ function TargetControl({
43314
43396
  onChange
43315
43397
  }) {
43316
43398
  const saved = !block.target ? "none" : "field" in block.target && block.target.field ? "field" : "value";
43317
- const [mode, setMode] = (0, import_react239.useState)(saved);
43399
+ const [mode, setMode] = (0, import_react241.useState)(saved);
43318
43400
  const savedValue = block.target && "value" in block.target && typeof block.target.value === "number" ? block.target.value : null;
43319
- const [draft, setDraft] = (0, import_react239.useState)(savedValue === null ? "" : String(savedValue));
43320
- (0, import_react239.useEffect)(() => {
43401
+ const [draft, setDraft] = (0, import_react241.useState)(savedValue === null ? "" : String(savedValue));
43402
+ (0, import_react241.useEffect)(() => {
43321
43403
  setMode(saved);
43322
43404
  setDraft(savedValue === null ? "" : String(savedValue));
43323
43405
  }, [saved, savedValue]);
@@ -43385,9 +43467,9 @@ function TargetControl({
43385
43467
 
43386
43468
  // src/QuestionPanel.tsx
43387
43469
  var import_clipboard9 = require("@ai-matrx/kit/clipboard");
43388
- var import_react241 = require("react");
43470
+ var import_react243 = require("react");
43389
43471
  var import_design_system125 = require("@ai-matrx/design-system");
43390
- var import_react242 = require("@ai-matrx/records/react");
43472
+ var import_react244 = require("@ai-matrx/records/react");
43391
43473
 
43392
43474
  // src/question.ts
43393
43475
  var import_records59 = require("@ai-matrx/records");
@@ -43798,13 +43880,13 @@ function fromLocalInput(value) {
43798
43880
  return Number.isNaN(d.getTime()) ? null : d.toISOString();
43799
43881
  }
43800
43882
  function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43801
- const client = (0, import_react242.useRecordsClient)();
43802
- const fields = (0, import_react242.useFields)(tableId);
43803
- const all = (0, import_react241.useMemo)(() => fields.data ?? [], [fields.data]);
43883
+ const client = (0, import_react244.useRecordsClient)();
43884
+ const fields = (0, import_react244.useFields)(tableId);
43885
+ const all = (0, import_react243.useMemo)(() => fields.data ?? [], [fields.data]);
43804
43886
  const me = client.config.actor?.user_id ?? null;
43805
- const [hidden, setHidden] = (0, import_react241.useState)(null);
43806
- const [related, setRelated] = (0, import_react241.useState)({});
43807
- (0, import_react241.useEffect)(() => {
43887
+ const [hidden, setHidden] = (0, import_react243.useState)(null);
43888
+ const [related, setRelated] = (0, import_react243.useState)({});
43889
+ (0, import_react243.useEffect)(() => {
43808
43890
  if (all.length === 0) {
43809
43891
  if (!fields.loading) setHidden(/* @__PURE__ */ new Set());
43810
43892
  return;
@@ -43827,18 +43909,18 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43827
43909
  live = false;
43828
43910
  };
43829
43911
  }, [client, tableId, all, fields.loading]);
43830
- const offered = (0, import_react241.useMemo)(() => hidden ? all.filter((f) => !hidden.has(f.key)) : [], [all, hidden]);
43831
- const [saved, setSaved] = (0, import_react241.useState)(null);
43832
- const [savedEpoch, setSavedEpoch] = (0, import_react241.useState)(0);
43833
- const [current, setCurrent] = (0, import_react241.useState)(null);
43834
- const [spec, setSpec] = (0, import_react241.useState)(newQuestion);
43835
- const [name, setName] = (0, import_react241.useState)("");
43836
- const [shared, setShared] = (0, import_react241.useState)(true);
43837
- const [saveError, setSaveError] = (0, import_react241.useState)(null);
43838
- const [saving, setSaving] = (0, import_react241.useState)(false);
43839
- const [linkMissed, setLinkMissed] = (0, import_react241.useState)(false);
43840
- const openedFromLink = (0, import_react241.useRef)(false);
43841
- (0, import_react241.useEffect)(() => {
43912
+ const offered = (0, import_react243.useMemo)(() => hidden ? all.filter((f) => !hidden.has(f.key)) : [], [all, hidden]);
43913
+ const [saved, setSaved] = (0, import_react243.useState)(null);
43914
+ const [savedEpoch, setSavedEpoch] = (0, import_react243.useState)(0);
43915
+ const [current, setCurrent] = (0, import_react243.useState)(null);
43916
+ const [spec, setSpec] = (0, import_react243.useState)(newQuestion);
43917
+ const [name, setName] = (0, import_react243.useState)("");
43918
+ const [shared, setShared] = (0, import_react243.useState)(true);
43919
+ const [saveError, setSaveError] = (0, import_react243.useState)(null);
43920
+ const [saving, setSaving] = (0, import_react243.useState)(false);
43921
+ const [linkMissed, setLinkMissed] = (0, import_react243.useState)(false);
43922
+ const openedFromLink = (0, import_react243.useRef)(false);
43923
+ (0, import_react243.useEffect)(() => {
43842
43924
  let live = true;
43843
43925
  void questionsOf(client, tableId).then((answer2) => {
43844
43926
  if (!live) return;
@@ -43861,16 +43943,16 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
43861
43943
  setShared(q ? q.shared : true);
43862
43944
  setSaveError(null);
43863
43945
  };
43864
- (0, import_react241.useEffect)(() => {
43946
+ (0, import_react243.useEffect)(() => {
43865
43947
  if (!draft) return;
43866
43948
  open(null);
43867
43949
  setSpec(draft);
43868
43950
  }, [draft]);
43869
43951
  const mine = !current || me !== null && current.createdBy === me;
43870
- const [answer, setAnswer] = (0, import_react241.useState)(null);
43871
- const [asking, setAsking] = (0, import_react241.useState)(false);
43952
+ const [answer, setAnswer] = (0, import_react243.useState)(null);
43953
+ const [asking, setAsking] = (0, import_react243.useState)(false);
43872
43954
  const specKey = JSON.stringify(spec);
43873
- (0, import_react241.useEffect)(() => {
43955
+ (0, import_react243.useEffect)(() => {
43874
43956
  if (all.length === 0) return;
43875
43957
  let live = true;
43876
43958
  setAsking(true);
@@ -44216,7 +44298,7 @@ function formatValue(key, value, fields) {
44216
44298
  return new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(value);
44217
44299
  }
44218
44300
  function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATED }) {
44219
- const block = (0, import_react241.useMemo)(
44301
+ const block = (0, import_react243.useMemo)(
44220
44302
  () => ({
44221
44303
  kind: "table",
44222
44304
  group_by: answer.groupKey && spec.group?.kind === "field" ? [answer.groupKey] : [],
@@ -44312,10 +44394,10 @@ function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATE
44312
44394
  }
44313
44395
 
44314
44396
  // src/TableAsk.tsx
44315
- var import_react243 = require("react");
44397
+ var import_react245 = require("react");
44316
44398
  var import_design_system126 = require("@ai-matrx/design-system");
44317
44399
  var import_records60 = require("@ai-matrx/records");
44318
- var import_react244 = require("@ai-matrx/records/react");
44400
+ var import_react246 = require("@ai-matrx/records/react");
44319
44401
 
44320
44402
  // src/askWords.ts
44321
44403
  var ASK_EXAMPLE = "count where Status is Open by Unit";
@@ -44532,12 +44614,12 @@ function askExampleFor(fields) {
44532
44614
  return by ? `count by ${fieldName(by)}` : "count";
44533
44615
  }
44534
44616
  function TableAsk({ tableId, onOpenInQuestions }) {
44535
- const client = (0, import_react244.useRecordsClient)();
44536
- const fields = (0, import_react244.useFields)(tableId);
44617
+ const client = (0, import_react246.useRecordsClient)();
44618
+ const fields = (0, import_react246.useFields)(tableId);
44537
44619
  const all = fields.data ?? [];
44538
- const [open, setOpen] = (0, import_react243.useState)(false);
44539
- const [words2, setWords] = (0, import_react243.useState)("");
44540
- const [said, setSaid] = (0, import_react243.useState)({ kind: "idle" });
44620
+ const [open, setOpen] = (0, import_react245.useState)(false);
44621
+ const [words2, setWords] = (0, import_react245.useState)("");
44622
+ const [said, setSaid] = (0, import_react245.useState)({ kind: "idle" });
44541
44623
  const ask = async () => {
44542
44624
  if (words2.trim() === "" || all.length === 0) return;
44543
44625
  const choices = {};
@@ -44610,8 +44692,8 @@ function TableAsk({ tableId, onOpenInQuestions }) {
44610
44692
  }
44611
44693
 
44612
44694
  // src/PageScreen.tsx
44613
- var import_react245 = require("react");
44614
- var import_react246 = require("@ai-matrx/records/react");
44695
+ var import_react247 = require("react");
44696
+ var import_react248 = require("@ai-matrx/records/react");
44615
44697
  var import_core24 = require("@ai-matrx/records/core");
44616
44698
  var import_design_system127 = require("@ai-matrx/design-system");
44617
44699
  var import_jsx_runtime142 = require("react/jsx-runtime");
@@ -44626,23 +44708,23 @@ function PageScreen({
44626
44708
  header,
44627
44709
  className
44628
44710
  }) {
44629
- const client = (0, import_react246.useRecordsClient)();
44711
+ const client = (0, import_react248.useRecordsClient)();
44630
44712
  const host = useRecordsUi();
44631
44713
  const organizationId = client.config.organizationId;
44632
- const [page, setPage] = (0, import_react245.useState)(null);
44633
- const [missing, setMissing] = (0, import_react245.useState)(false);
44634
- const [error, setError] = (0, import_react245.useState)(null);
44635
- const [level, setLevel] = (0, import_react245.useState)(null);
44636
- const [editing, setEditing] = (0, import_react245.useState)(startEditing);
44637
- const [run, setRun] = (0, import_react245.useState)(null);
44638
- const [saveError, setSaveError] = (0, import_react245.useState)(null);
44639
- const [askingToArchive, setAskingToArchive] = (0, import_react245.useState)(false);
44640
- const [selected, setSelected] = (0, import_react245.useState)({});
44641
- const [filterValues, setFilterValues] = (0, import_react245.useState)({});
44642
- const [mine, setMine] = (0, import_react245.useState)({});
44643
- const [making, setMaking] = (0, import_react245.useState)("waiting");
44714
+ const [page, setPage] = (0, import_react247.useState)(null);
44715
+ const [missing, setMissing] = (0, import_react247.useState)(false);
44716
+ const [error, setError] = (0, import_react247.useState)(null);
44717
+ const [level, setLevel] = (0, import_react247.useState)(null);
44718
+ const [editing, setEditing] = (0, import_react247.useState)(startEditing);
44719
+ const [run, setRun] = (0, import_react247.useState)(null);
44720
+ const [saveError, setSaveError] = (0, import_react247.useState)(null);
44721
+ const [askingToArchive, setAskingToArchive] = (0, import_react247.useState)(false);
44722
+ const [selected, setSelected] = (0, import_react247.useState)({});
44723
+ const [filterValues, setFilterValues] = (0, import_react247.useState)({});
44724
+ const [mine, setMine] = (0, import_react247.useState)({});
44725
+ const [making, setMaking] = (0, import_react247.useState)("waiting");
44644
44726
  const id = page?.id ?? pageId ?? null;
44645
- const load = (0, import_react245.useCallback)(
44727
+ const load = (0, import_react247.useCallback)(
44646
44728
  async (want) => {
44647
44729
  const answered = await client.dashboards({ table_id: null });
44648
44730
  if (!answered.ok) {
@@ -44661,7 +44743,7 @@ function PageScreen({
44661
44743
  },
44662
44744
  [client]
44663
44745
  );
44664
- (0, import_react245.useEffect)(() => {
44746
+ (0, import_react247.useEffect)(() => {
44665
44747
  if (!newOnTable || pageId || making !== "waiting") return;
44666
44748
  setMaking("making");
44667
44749
  void client.dashboardDeclare({
@@ -44681,11 +44763,11 @@ function PageScreen({
44681
44763
  onCreated?.(made.data);
44682
44764
  });
44683
44765
  }, [client, newOnTable, pageId, making, load, onCreated]);
44684
- (0, import_react245.useEffect)(() => {
44766
+ (0, import_react247.useEffect)(() => {
44685
44767
  if (!pageId) return;
44686
44768
  void load(pageId);
44687
44769
  }, [pageId, load]);
44688
- (0, import_react245.useEffect)(() => {
44770
+ (0, import_react247.useEffect)(() => {
44689
44771
  if (!id) return;
44690
44772
  let live = true;
44691
44773
  void client.myLevels({ ids: [id], subject: "record" }).then((answered) => {
@@ -44697,7 +44779,7 @@ function PageScreen({
44697
44779
  }, [client, id]);
44698
44780
  const canEdit = level !== null && EDIT_LEVELS.has(level);
44699
44781
  const chartKey = page ? JSON.stringify(page.blocks.map((b) => b.id)) + page.version : "";
44700
- (0, import_react245.useEffect)(() => {
44782
+ (0, import_react247.useEffect)(() => {
44701
44783
  if (!page || page.blocks.length === 0) {
44702
44784
  setRun(null);
44703
44785
  return;
@@ -44712,11 +44794,11 @@ function PageScreen({
44712
44794
  live = false;
44713
44795
  };
44714
44796
  }, [client, chartKey]);
44715
- const blocks = (0, import_react245.useMemo)(
44797
+ const blocks = (0, import_react247.useMemo)(
44716
44798
  () => page ? pageBlocksOf(page.presentation, page.blocks.map((b) => b.id ?? "").filter(Boolean)) : [],
44717
44799
  [page]
44718
44800
  );
44719
- const save = (0, import_react245.useCallback)(
44801
+ const save = (0, import_react247.useCallback)(
44720
44802
  async (next) => {
44721
44803
  if (!page) return;
44722
44804
  const charts = withBlockIds(next.charts ?? page.blocks);
@@ -44740,7 +44822,7 @@ function PageScreen({
44740
44822
  },
44741
44823
  [client, page, blocks, load]
44742
44824
  );
44743
- const archive = (0, import_react245.useCallback)(async () => {
44825
+ const archive = (0, import_react247.useCallback)(async () => {
44744
44826
  if (!page) return;
44745
44827
  setAskingToArchive(false);
44746
44828
  const gone = await client.dashboardDelete({ dashboard_id: page.id });
@@ -44942,8 +45024,8 @@ function AppletBlockView({ block }) {
44942
45024
  }
44943
45025
  function AppletPick({ value, onChange }) {
44944
45026
  const host = useRecordsUi();
44945
- const [options, setOptions] = (0, import_react245.useState)(null);
44946
- (0, import_react245.useEffect)(() => {
45027
+ const [options, setOptions] = (0, import_react247.useState)(null);
45028
+ (0, import_react247.useEffect)(() => {
44947
45029
  let live = true;
44948
45030
  host.applets?.list().then((apps) => live && setOptions(apps.map((a) => ({ value: a.id, label: a.name })))).catch(() => live && setOptions([]));
44949
45031
  return () => {
@@ -44975,12 +45057,12 @@ function ListBlockView({
44975
45057
  mine,
44976
45058
  onMine
44977
45059
  }) {
44978
- const client = (0, import_react246.useRecordsClient)();
44979
- const table = (0, import_react246.useTable)(block.table_id);
44980
- const fields = (0, import_react246.useFields)(block.table_id);
44981
- const all = (0, import_react245.useMemo)(() => onePerKey3(fields.data ?? []), [fields.data]);
44982
- const [view, setView] = (0, import_react245.useState)(block.view_id ? "reading" : null);
44983
- (0, import_react245.useEffect)(() => {
45060
+ const client = (0, import_react248.useRecordsClient)();
45061
+ const table = (0, import_react248.useTable)(block.table_id);
45062
+ const fields = (0, import_react248.useFields)(block.table_id);
45063
+ const all = (0, import_react247.useMemo)(() => onePerKey3(fields.data ?? []), [fields.data]);
45064
+ const [view, setView] = (0, import_react247.useState)(block.view_id ? "reading" : null);
45065
+ (0, import_react247.useEffect)(() => {
44984
45066
  if (!block.view_id) {
44985
45067
  setView(null);
44986
45068
  return;
@@ -44997,8 +45079,8 @@ function ListBlockView({
44997
45079
  };
44998
45080
  }, [client, block.table_id, block.view_id]);
44999
45081
  const meField = block.me_field ? all.find((f) => f.key === block.me_field) : void 0;
45000
- const [me, setMe] = (0, import_react245.useState)(null);
45001
- (0, import_react245.useEffect)(() => {
45082
+ const [me, setMe] = (0, import_react247.useState)(null);
45083
+ (0, import_react247.useEffect)(() => {
45002
45084
  if (!mine || !meField?.relation_target || !viewerUserId) {
45003
45085
  setMe(null);
45004
45086
  return;
@@ -45022,18 +45104,18 @@ function ListBlockView({
45022
45104
  const sort = view && view !== "reading" ? (view.sorts ?? []).map((s) => ({ field: s.field, direction: s.direction })) : [];
45023
45105
  const nobodyIsMe = mine && !!meField && me !== null && me !== "reading" && me.id === null;
45024
45106
  const waiting = view === "reading" || mine && !!meField && (me === "reading" || me === null) && !!viewerUserId;
45025
- const page = (0, import_react246.useRecordPage)(waiting || nobodyIsMe ? null : block.table_id, {
45107
+ const page = (0, import_react248.useRecordPage)(waiting || nobodyIsMe ? null : block.table_id, {
45026
45108
  pageSize: block.limit ?? 50,
45027
45109
  ...filter ? { filter } : {},
45028
45110
  ...sort.length > 0 ? { sort } : {}
45029
45111
  });
45030
45112
  const reload = page.reload;
45031
- (0, import_react245.useEffect)(() => (0, import_core24.onRecordChanged)(() => reload()), [reload]);
45113
+ (0, import_react247.useEffect)(() => (0, import_core24.onRecordChanged)(() => reload()), [reload]);
45032
45114
  const rows = nobodyIsMe ? [] : page.data?.rows ?? [];
45033
45115
  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);
45034
45116
  const firstId = rows[0]?.id ?? null;
45035
45117
  const stillThere = selected !== null && rows.some((r) => r.id === selected);
45036
- (0, import_react245.useEffect)(() => {
45118
+ (0, import_react247.useEffect)(() => {
45037
45119
  if (page.loading || waiting) return;
45038
45120
  if (!stillThere) onSelect(firstId);
45039
45121
  }, [firstId, stillThere, page.loading, waiting]);
@@ -45093,14 +45175,14 @@ function ListBlockView({
45093
45175
  ] });
45094
45176
  }
45095
45177
  function ActionButton2({ block, recordId }) {
45096
- const client = (0, import_react246.useRecordsClient)();
45097
- const actionsRead = (0, import_react246.useRowActions)(block.action_id ? block.table_id : null);
45178
+ const client = (0, import_react248.useRecordsClient)();
45179
+ const actionsRead = (0, import_react248.useRowActions)(block.action_id ? block.table_id : null);
45098
45180
  const action3 = !block.action_id ? null : actionsRead.data ? actionsRead.data.actions.find((a) => a.id === block.action_id) ?? null : actionsRead.loading ? "reading" : null;
45099
- const [asking, setAsking] = (0, import_react245.useState)(false);
45100
- const [running, setRunning] = (0, import_react245.useState)(false);
45101
- const [done, setDone] = (0, import_react245.useState)(null);
45102
- const [error, setError] = (0, import_react245.useState)(null);
45103
- (0, import_react245.useEffect)(() => {
45181
+ const [asking, setAsking] = (0, import_react247.useState)(false);
45182
+ const [running, setRunning] = (0, import_react247.useState)(false);
45183
+ const [done, setDone] = (0, import_react247.useState)(null);
45184
+ const [error, setError] = (0, import_react247.useState)(null);
45185
+ (0, import_react247.useEffect)(() => {
45104
45186
  setDone(null);
45105
45187
  setError(null);
45106
45188
  setAsking(false);
@@ -45138,10 +45220,10 @@ function ActionButton2({ block, recordId }) {
45138
45220
  ] });
45139
45221
  }
45140
45222
  function FormBlockView({ block }) {
45141
- const client = (0, import_react246.useRecordsClient)();
45142
- const [form, setForm] = (0, import_react245.useState)("reading");
45143
- const [sent, setSent] = (0, import_react245.useState)(0);
45144
- (0, import_react245.useEffect)(() => {
45223
+ const client = (0, import_react248.useRecordsClient)();
45224
+ const [form, setForm] = (0, import_react247.useState)("reading");
45225
+ const [sent, setSent] = (0, import_react247.useState)(0);
45226
+ (0, import_react247.useEffect)(() => {
45145
45227
  if (!block.form_id) {
45146
45228
  setForm(null);
45147
45229
  return;
@@ -45159,7 +45241,7 @@ function FormBlockView({ block }) {
45159
45241
  return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(FormRunner, { form: formFromSummary(form), onSubmitted: () => setSent((n) => n + 1) }, sent);
45160
45242
  }
45161
45243
  function FilterBlockView({ block, value, onChange }) {
45162
- const fields = (0, import_react246.useFields)(block.table_id);
45244
+ const fields = (0, import_react248.useFields)(block.table_id);
45163
45245
  const field2 = (fields.data ?? []).find((f) => f.key === block.field);
45164
45246
  if (!block.field) return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(BlockNote, { children: "Choose the column this filter narrows by." });
45165
45247
  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." });
@@ -45254,7 +45336,7 @@ function FieldPick({
45254
45336
  onChange,
45255
45337
  allowNone
45256
45338
  }) {
45257
- const fields = (0, import_react246.useFields)(tableId);
45339
+ const fields = (0, import_react248.useFields)(tableId);
45258
45340
  const all = onePerKey3(fields.data ?? []);
45259
45341
  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;
45260
45342
  const seen = /* @__PURE__ */ new Set();
@@ -45265,11 +45347,11 @@ function FieldPick({
45265
45347
  return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(PickOne, { label, placeholder: label, value, options, onChange, className: "h-7 w-40" });
45266
45348
  }
45267
45349
  function ListSettings({ block, onChange }) {
45268
- const client = (0, import_react246.useRecordsClient)();
45269
- const [views, setViews] = (0, import_react245.useState)([]);
45270
- const fields = (0, import_react246.useFields)(block.table_id);
45350
+ const client = (0, import_react248.useRecordsClient)();
45351
+ const [views, setViews] = (0, import_react247.useState)([]);
45352
+ const fields = (0, import_react248.useFields)(block.table_id);
45271
45353
  const all = onePerKey3(fields.data ?? []);
45272
- (0, import_react245.useEffect)(() => {
45354
+ (0, import_react247.useEffect)(() => {
45273
45355
  let live = true;
45274
45356
  void client.views({ table_id: block.table_id }).then((answered) => {
45275
45357
  if (live) setViews(answered.ok ? answered.data : []);
@@ -45339,14 +45421,14 @@ function ListSettings({ block, onChange }) {
45339
45421
  ] });
45340
45422
  }
45341
45423
  function ActionPicker({ tableId, value, onChange }) {
45342
- const actions = (0, import_react246.useRowActions)(tableId).data?.actions ?? [];
45424
+ const actions = (0, import_react248.useRowActions)(tableId).data?.actions ?? [];
45343
45425
  const options = actions.filter((a) => a.id && a.kind !== "agent").map((a) => ({ value: a.id, label: a.name }));
45344
45426
  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" });
45345
45427
  }
45346
45428
  function FormPicker({ tableId, value, onChange }) {
45347
- const client = (0, import_react246.useRecordsClient)();
45348
- const [forms, setForms] = (0, import_react245.useState)([]);
45349
- (0, import_react245.useEffect)(() => {
45429
+ const client = (0, import_react248.useRecordsClient)();
45430
+ const [forms, setForms] = (0, import_react247.useState)([]);
45431
+ (0, import_react247.useEffect)(() => {
45350
45432
  let live = true;
45351
45433
  void client.forms({ table_id: tableId }).then((answered) => {
45352
45434
  if (live) setForms(answered.ok ? answered.data : []);
@@ -45392,8 +45474,8 @@ function onePerKey3(all) {
45392
45474
 
45393
45475
  // src/FormsPanel.tsx
45394
45476
  var import_clipboard10 = require("@ai-matrx/kit/clipboard");
45395
- var import_react247 = require("react");
45396
- var import_react248 = require("@ai-matrx/records/react");
45477
+ var import_react249 = require("react");
45478
+ var import_react250 = require("@ai-matrx/records/react");
45397
45479
  var import_records61 = require("@ai-matrx/records");
45398
45480
  var import_design_system128 = require("@ai-matrx/design-system");
45399
45481
  var import_jsx_runtime143 = require("react/jsx-runtime");
@@ -45405,22 +45487,22 @@ function formSuggestion(tableName2) {
45405
45487
  return `Make me a form that collects new ${subject} entries and tells me when somebody answers.`;
45406
45488
  }
45407
45489
  function FormsPanel({ tableId, activeFormId, className }) {
45408
- const client = (0, import_react248.useRecordsClient)();
45490
+ const client = (0, import_react250.useRecordsClient)();
45409
45491
  const host = useRecordsUi();
45410
- const table = (0, import_react248.useTable)(tableId);
45492
+ const table = (0, import_react250.useTable)(tableId);
45411
45493
  const rights = useTableRights(table.data);
45412
- const [forms, setForms] = (0, import_react247.useState)(null);
45413
- const [error, setError] = (0, import_react247.useState)(null);
45414
- const [busy, setBusy] = (0, import_react247.useState)(null);
45415
- const [copied, setCopied] = (0, import_react247.useState)(null);
45416
- const [building, setBuilding] = (0, import_react247.useState)(false);
45417
- const [archivedSaid, setArchivedSaid] = (0, import_react247.useState)(null);
45494
+ const [forms, setForms] = (0, import_react249.useState)(null);
45495
+ const [error, setError] = (0, import_react249.useState)(null);
45496
+ const [busy, setBusy] = (0, import_react249.useState)(null);
45497
+ const [copied, setCopied] = (0, import_react249.useState)(null);
45498
+ const [building, setBuilding] = (0, import_react249.useState)(false);
45499
+ const [archivedSaid, setArchivedSaid] = (0, import_react249.useState)(null);
45418
45500
  const linked = activeFormId && forms !== null ? forms.find((f) => f.form_id === activeFormId) ?? null : null;
45419
45501
  const linkedMissing = Boolean(activeFormId) && forms !== null && linked === null;
45420
- (0, import_react247.useEffect)(() => {
45502
+ (0, import_react249.useEffect)(() => {
45421
45503
  if (linked && rights.structure) setBuilding(true);
45422
45504
  }, [linked, rights.structure]);
45423
- const load = (0, import_react247.useCallback)(async () => {
45505
+ const load = (0, import_react249.useCallback)(async () => {
45424
45506
  const answered = await client.forms({ table_id: tableId });
45425
45507
  if (!answered.ok) {
45426
45508
  setError(answered.error);
@@ -45430,10 +45512,10 @@ function FormsPanel({ tableId, activeFormId, className }) {
45430
45512
  setError(null);
45431
45513
  setForms(answered.data);
45432
45514
  }, [client, tableId]);
45433
- (0, import_react247.useEffect)(() => {
45515
+ (0, import_react249.useEffect)(() => {
45434
45516
  void load();
45435
45517
  }, [load]);
45436
- const toggle = (0, import_react247.useCallback)(
45518
+ const toggle = (0, import_react249.useCallback)(
45437
45519
  async (form) => {
45438
45520
  setBusy(form.form_id);
45439
45521
  const wanted = form.published_at === null || form.closed_at !== null;
@@ -45447,8 +45529,8 @@ function FormsPanel({ tableId, activeFormId, className }) {
45447
45529
  },
45448
45530
  [client, load]
45449
45531
  );
45450
- const [shown4, setShown] = (0, import_react247.useState)(null);
45451
- const copy = (0, import_react247.useCallback)(async (url, formId) => {
45532
+ const [shown4, setShown] = (0, import_react249.useState)(null);
45533
+ const copy = (0, import_react249.useCallback)(async (url, formId) => {
45452
45534
  if (await (0, import_clipboard10.copyText)(url)) {
45453
45535
  setCopied(formId);
45454
45536
  setShown(null);
@@ -45575,14 +45657,14 @@ function FormsPanel({ tableId, activeFormId, className }) {
45575
45657
  }
45576
45658
 
45577
45659
  // src/CaptureSheet.tsx
45578
- var import_react251 = require("react");
45579
- var import_react252 = require("@ai-matrx/records/react");
45660
+ var import_react253 = require("react");
45661
+ var import_react254 = require("@ai-matrx/records/react");
45580
45662
  var import_design_system130 = require("@ai-matrx/design-system");
45581
45663
 
45582
45664
  // src/CaptureRun.tsx
45583
- var import_react249 = require("react");
45665
+ var import_react251 = require("react");
45584
45666
  var import_records62 = require("@ai-matrx/records");
45585
- var import_react250 = require("@ai-matrx/records/react");
45667
+ var import_react252 = require("@ai-matrx/records/react");
45586
45668
  var import_design_system129 = require("@ai-matrx/design-system");
45587
45669
  var import_jsx_runtime144 = require("react/jsx-runtime");
45588
45670
  function controlFor(field2) {
@@ -45621,21 +45703,21 @@ function whereWeAre(timeoutMs = 4e3) {
45621
45703
  });
45622
45704
  }
45623
45705
  function CaptureRun({ sheetId, face: given, className }) {
45624
- const client = (0, import_react250.useRecordsClient)();
45706
+ const client = (0, import_react252.useRecordsClient)();
45625
45707
  const host = useRecordsUi();
45626
- const [face, setFace] = (0, import_react249.useState)(given);
45627
- const [loadFailed, setLoadFailed] = (0, import_react249.useState)(null);
45628
- const [at, setAt] = (0, import_react249.useState)(0);
45629
- const [answers, setAnswers] = (0, import_react249.useState)({});
45630
- const [files, setFiles] = (0, import_react249.useState)({});
45631
- const [missing, setMissing] = (0, import_react249.useState)(null);
45632
- const [done, setDone] = (0, import_react249.useState)(null);
45633
- const [counts, setCounts] = (0, import_react249.useState)({ waiting: 0, sending: 0, refused: 0, landed: 0 });
45634
- const [items, setItems] = (0, import_react249.useState)([]);
45635
- const [lastSynced, setLastSynced] = (0, import_react249.useState)(null);
45636
- const [sending, setSending] = (0, import_react249.useState)(false);
45637
- const queueRef = (0, import_react249.useRef)(null);
45638
- (0, import_react249.useEffect)(() => {
45708
+ const [face, setFace] = (0, import_react251.useState)(given);
45709
+ const [loadFailed, setLoadFailed] = (0, import_react251.useState)(null);
45710
+ const [at, setAt] = (0, import_react251.useState)(0);
45711
+ const [answers, setAnswers] = (0, import_react251.useState)({});
45712
+ const [files, setFiles] = (0, import_react251.useState)({});
45713
+ const [missing, setMissing] = (0, import_react251.useState)(null);
45714
+ const [done, setDone] = (0, import_react251.useState)(null);
45715
+ const [counts, setCounts] = (0, import_react251.useState)({ waiting: 0, sending: 0, refused: 0, landed: 0 });
45716
+ const [items, setItems] = (0, import_react251.useState)([]);
45717
+ const [lastSynced, setLastSynced] = (0, import_react251.useState)(null);
45718
+ const [sending, setSending] = (0, import_react251.useState)(false);
45719
+ const queueRef = (0, import_react251.useRef)(null);
45720
+ (0, import_react251.useEffect)(() => {
45639
45721
  const q2 = (0, import_records62.openCaptureQueue)({
45640
45722
  onChange: (c, all) => {
45641
45723
  setCounts(c);
@@ -45673,7 +45755,7 @@ function CaptureRun({ sheetId, face: given, className }) {
45673
45755
  void q2.sync().then(() => void q2.lastSyncedAt().then(setLastSynced));
45674
45756
  return () => q2.dispose();
45675
45757
  }, [client, host]);
45676
- (0, import_react249.useEffect)(() => {
45758
+ (0, import_react251.useEffect)(() => {
45677
45759
  if (given !== void 0) return;
45678
45760
  let cancelled = false;
45679
45761
  void client.captureOpen({ sheet_id: sheetId }).then((res) => {
@@ -45685,7 +45767,7 @@ function CaptureRun({ sheetId, face: given, className }) {
45685
45767
  cancelled = true;
45686
45768
  };
45687
45769
  }, [client, given, sheetId]);
45688
- const questions = (0, import_react249.useMemo)(() => {
45770
+ const questions = (0, import_react251.useMemo)(() => {
45689
45771
  const asked3 = face?.presentation?.questions ?? [];
45690
45772
  if (asked3.length > 0) return asked3;
45691
45773
  return (face?.fields ?? []).map((f) => ({
@@ -45695,11 +45777,11 @@ function CaptureRun({ sheetId, face: given, className }) {
45695
45777
  required: f.required
45696
45778
  }));
45697
45779
  }, [face]);
45698
- const fieldOf2 = (0, import_react249.useCallback)(
45780
+ const fieldOf2 = (0, import_react251.useCallback)(
45699
45781
  (key) => (face?.fields ?? []).find((f) => f.key === key),
45700
45782
  [face]
45701
45783
  );
45702
- const sync = (0, import_react249.useCallback)(async () => {
45784
+ const sync = (0, import_react251.useCallback)(async () => {
45703
45785
  const q2 = queueRef.current;
45704
45786
  if (!q2) return;
45705
45787
  setSending(true);
@@ -45712,7 +45794,7 @@ function CaptureRun({ sheetId, face: given, className }) {
45712
45794
  setSending(false);
45713
45795
  }
45714
45796
  }, []);
45715
- const answered = (0, import_react249.useCallback)(
45797
+ const answered = (0, import_react251.useCallback)(
45716
45798
  (key) => {
45717
45799
  if (files[key]) return true;
45718
45800
  const v = answers[key];
@@ -46001,21 +46083,21 @@ function AdHocCaptureSheet({
46001
46083
  attachmentField,
46002
46084
  className
46003
46085
  }) {
46004
- const client = (0, import_react252.useRecordsClient)();
46086
+ const client = (0, import_react254.useRecordsClient)();
46005
46087
  const host = useRecordsUi();
46006
- const table = (0, import_react252.useTable)(tableId);
46007
- const fields = (0, import_react252.useFields)(tableId);
46008
- const [mode, setMode] = (0, import_react251.useState)("reading");
46009
- const [reading, setReading] = (0, import_react251.useState)("");
46010
- const [note, setNote] = (0, import_react251.useState)("");
46011
- const [fileId, setFileId] = (0, import_react251.useState)(null);
46012
- const [pending, setPending] = (0, import_react251.useState)(null);
46013
- const [saved, setSaved] = (0, import_react251.useState)([]);
46014
- const [error, setError] = (0, import_react251.useState)(null);
46015
- const [uploadError, setUploadError] = (0, import_react251.useState)(null);
46016
- const [flushing, setFlushing] = (0, import_react251.useState)(false);
46017
- const queue = (0, import_react251.useRef)([]);
46018
- const keep = (0, import_react251.useCallback)(
46088
+ const table = (0, import_react254.useTable)(tableId);
46089
+ const fields = (0, import_react254.useFields)(tableId);
46090
+ const [mode, setMode] = (0, import_react253.useState)("reading");
46091
+ const [reading, setReading] = (0, import_react253.useState)("");
46092
+ const [note, setNote] = (0, import_react253.useState)("");
46093
+ const [fileId, setFileId] = (0, import_react253.useState)(null);
46094
+ const [pending, setPending] = (0, import_react253.useState)(null);
46095
+ const [saved, setSaved] = (0, import_react253.useState)([]);
46096
+ const [error, setError] = (0, import_react253.useState)(null);
46097
+ const [uploadError, setUploadError] = (0, import_react253.useState)(null);
46098
+ const [flushing, setFlushing] = (0, import_react253.useState)(false);
46099
+ const queue = (0, import_react253.useRef)([]);
46100
+ const keep = (0, import_react253.useCallback)(
46019
46101
  async (next) => {
46020
46102
  queue.current = next;
46021
46103
  setPending(next);
@@ -46023,7 +46105,7 @@ function AdHocCaptureSheet({
46023
46105
  },
46024
46106
  [host]
46025
46107
  );
46026
- (0, import_react251.useEffect)(() => {
46108
+ (0, import_react253.useEffect)(() => {
46027
46109
  let cancelled = false;
46028
46110
  void (async () => {
46029
46111
  const held = host.captureQueue ? await host.captureQueue.load() : [];
@@ -46035,7 +46117,7 @@ function AdHocCaptureSheet({
46035
46117
  cancelled = true;
46036
46118
  };
46037
46119
  }, [host]);
46038
- const resolved = (0, import_react251.useCallback)(() => {
46120
+ const resolved = (0, import_react253.useCallback)(() => {
46039
46121
  const all = fields.data ?? [];
46040
46122
  return {
46041
46123
  reading: readingField ?? all.find((f) => f.type === "range")?.key ?? null,
@@ -46043,7 +46125,7 @@ function AdHocCaptureSheet({
46043
46125
  attachment: attachmentField ?? all.find((f) => f.format === "file" || f.format === "image")?.key ?? null
46044
46126
  };
46045
46127
  }, [attachmentField, fields.data, noteField, readingField, table.data]);
46046
- const flush = (0, import_react251.useCallback)(async () => {
46128
+ const flush = (0, import_react253.useCallback)(async () => {
46047
46129
  if (flushing || queue.current.length === 0) return;
46048
46130
  setFlushing(true);
46049
46131
  const left = [];
@@ -46202,18 +46284,18 @@ function AdHocCaptureSheet({
46202
46284
  }
46203
46285
 
46204
46286
  // src/PortalShell.tsx
46205
- var import_react253 = require("react");
46206
- var import_react254 = require("@ai-matrx/records/react");
46287
+ var import_react255 = require("react");
46288
+ var import_react256 = require("@ai-matrx/records/react");
46207
46289
  var import_design_system131 = require("@ai-matrx/design-system");
46208
46290
  var import_jsx_runtime146 = require("react/jsx-runtime");
46209
46291
  function PortalShell({ tableId, form, resourceType = "record", className }) {
46210
- const client = (0, import_react254.useRecordsClient)();
46211
- const [card, setCard] = (0, import_react253.useState)(null);
46212
- const [reach, setReach] = (0, import_react253.useState)(null);
46213
- const [error, setError] = (0, import_react253.useState)(null);
46214
- const [open, setOpen] = (0, import_react253.useState)(null);
46215
- const [sending, setSending] = (0, import_react253.useState)(false);
46216
- const load = (0, import_react253.useCallback)(async () => {
46292
+ const client = (0, import_react256.useRecordsClient)();
46293
+ const [card, setCard] = (0, import_react255.useState)(null);
46294
+ const [reach, setReach] = (0, import_react255.useState)(null);
46295
+ const [error, setError] = (0, import_react255.useState)(null);
46296
+ const [open, setOpen] = (0, import_react255.useState)(null);
46297
+ const [sending, setSending] = (0, import_react255.useState)(false);
46298
+ const load = (0, import_react255.useCallback)(async () => {
46217
46299
  const who = await client.externalPrincipalCard();
46218
46300
  if (!who.ok) {
46219
46301
  setError(who.error);
@@ -46228,7 +46310,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
46228
46310
  }
46229
46311
  setReach(reached.data.map((row) => row.resource_id));
46230
46312
  }, [client, resourceType]);
46231
- (0, import_react253.useEffect)(() => {
46313
+ (0, import_react255.useEffect)(() => {
46232
46314
  void load();
46233
46315
  }, [load]);
46234
46316
  if (error) {
@@ -46286,9 +46368,9 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
46286
46368
  ] });
46287
46369
  }
46288
46370
  function PortalRow({ tableId, recordId }) {
46289
- const client = (0, import_react254.useRecordsClient)();
46290
- const [title, setTitle] = (0, import_react253.useState)(null);
46291
- (0, import_react253.useEffect)(() => {
46371
+ const client = (0, import_react256.useRecordsClient)();
46372
+ const [title, setTitle] = (0, import_react255.useState)(null);
46373
+ (0, import_react255.useEffect)(() => {
46292
46374
  let cancelled = false;
46293
46375
  void client.recordRead({ record_id: recordId }).then((answered) => {
46294
46376
  if (cancelled) return;
@@ -46308,8 +46390,8 @@ function PortalRow({ tableId, recordId }) {
46308
46390
  }
46309
46391
 
46310
46392
  // src/PublicViewPage.tsx
46311
- var import_react255 = require("react");
46312
- var import_react256 = require("@ai-matrx/records/react");
46393
+ var import_react257 = require("react");
46394
+ var import_react258 = require("@ai-matrx/records/react");
46313
46395
  var import_design_system132 = require("@ai-matrx/design-system");
46314
46396
 
46315
46397
  // src/publicBinding.ts
@@ -46325,14 +46407,14 @@ function publicReadOf(binding) {
46325
46407
  // src/PublicViewPage.tsx
46326
46408
  var import_jsx_runtime147 = require("react/jsx-runtime");
46327
46409
  function PublicViewPage({ slug, className }) {
46328
- const client = (0, import_react256.useRecordsClient)();
46329
- const [binding, setBinding] = (0, import_react255.useState)(null);
46330
- const [rows, setRows] = (0, import_react255.useState)(null);
46331
- const [fields, setFields] = (0, import_react255.useState)(null);
46332
- const [error, setError] = (0, import_react255.useState)(null);
46333
- const [plan, setPlan] = (0, import_react255.useState)(null);
46334
- const [gap, setGap] = (0, import_react255.useState)(null);
46335
- const load = (0, import_react255.useCallback)(async () => {
46410
+ const client = (0, import_react258.useRecordsClient)();
46411
+ const [binding, setBinding] = (0, import_react257.useState)(null);
46412
+ const [rows, setRows] = (0, import_react257.useState)(null);
46413
+ const [fields, setFields] = (0, import_react257.useState)(null);
46414
+ const [error, setError] = (0, import_react257.useState)(null);
46415
+ const [plan, setPlan] = (0, import_react257.useState)(null);
46416
+ const [gap, setGap] = (0, import_react257.useState)(null);
46417
+ const load = (0, import_react257.useCallback)(async () => {
46336
46418
  const notice = await client.worldPublishGapNotice();
46337
46419
  if (notice.ok) setGap(notice.data);
46338
46420
  const resolved = await client.resolvePublishBindingKind({ slug });
@@ -46382,7 +46464,7 @@ function PublicViewPage({ slug, className }) {
46382
46464
  }
46383
46465
  setRows([{ id: chosen.recordId, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
46384
46466
  }, [client, slug]);
46385
- (0, import_react255.useEffect)(() => {
46467
+ (0, import_react257.useEffect)(() => {
46386
46468
  void load();
46387
46469
  }, [load]);
46388
46470
  if (error) return /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(RefusalNotice, { error, className });
@@ -46420,10 +46502,10 @@ function PublicRow({ row, fields }) {
46420
46502
 
46421
46503
  // src/EmbedFrame.tsx
46422
46504
  var import_clipboard11 = require("@ai-matrx/kit/clipboard");
46423
- var import_react257 = require("react");
46424
- var import_react258 = require("@ai-matrx/records/react");
46505
+ var import_react259 = require("react");
46506
+ var import_react260 = require("@ai-matrx/records/react");
46425
46507
  var import_design_system133 = require("@ai-matrx/design-system");
46426
- var import_react259 = require("@ai-matrx/records/react");
46508
+ var import_react261 = require("@ai-matrx/records/react");
46427
46509
  var import_jsx_runtime148 = require("react/jsx-runtime");
46428
46510
  function EmbedFrame({
46429
46511
  tableId,
@@ -46433,18 +46515,18 @@ function EmbedFrame({
46433
46515
  embedUrl,
46434
46516
  className
46435
46517
  }) {
46436
- const client = (0, import_react258.useRecordsClient)();
46518
+ const client = (0, import_react260.useRecordsClient)();
46437
46519
  const host = useRecordsUi();
46438
- const table = (0, import_react259.useTable)(tableId);
46520
+ const table = (0, import_react261.useTable)(tableId);
46439
46521
  const rights = useTableRights(table.data);
46440
- const [origins, setOrigins] = (0, import_react257.useState)("");
46441
- const [secret, setSecret] = (0, import_react257.useState)(null);
46442
- const [tokenId, setTokenId] = (0, import_react257.useState)(null);
46443
- const [error, setError] = (0, import_react257.useState)(null);
46444
- const [busy, setBusy] = (0, import_react257.useState)(false);
46522
+ const [origins, setOrigins] = (0, import_react259.useState)("");
46523
+ const [secret, setSecret] = (0, import_react259.useState)(null);
46524
+ const [tokenId, setTokenId] = (0, import_react259.useState)(null);
46525
+ const [error, setError] = (0, import_react259.useState)(null);
46526
+ const [busy, setBusy] = (0, import_react259.useState)(false);
46445
46527
  const mode = formId ? "write" : "read";
46446
46528
  const parsed = origins.split(/[\s,]+/).map((o) => o.trim()).filter((o) => o.length > 0);
46447
- const issue = (0, import_react257.useCallback)(async () => {
46529
+ const issue = (0, import_react259.useCallback)(async () => {
46448
46530
  setBusy(true);
46449
46531
  setError(null);
46450
46532
  const minted = await client.anonTokenIssue({
@@ -46463,7 +46545,7 @@ function EmbedFrame({
46463
46545
  setTokenId(minted.data.token_id);
46464
46546
  host.notify?.success("Embed token issued. Copy it now \u2014 it is never shown again.");
46465
46547
  }, [client, formId, host, mode, parsed, recordId, savedViewId]);
46466
- const revoke = (0, import_react257.useCallback)(async () => {
46548
+ const revoke = (0, import_react259.useCallback)(async () => {
46467
46549
  if (!tokenId) return;
46468
46550
  setBusy(true);
46469
46551
  const done = await client.anonTokenRevoke({ token_id: tokenId });
@@ -46527,13 +46609,13 @@ function EmbedFrame({
46527
46609
  ] });
46528
46610
  }
46529
46611
  function useEmbedHandshake(args) {
46530
- const client = (0, import_react258.useRecordsClient)();
46531
- const [binding, setBinding] = (0, import_react257.useState)(null);
46532
- const [error, setError] = (0, import_react257.useState)(null);
46533
- const [loading, setLoading] = (0, import_react257.useState)(true);
46612
+ const client = (0, import_react260.useRecordsClient)();
46613
+ const [binding, setBinding] = (0, import_react259.useState)(null);
46614
+ const [error, setError] = (0, import_react259.useState)(null);
46615
+ const [loading, setLoading] = (0, import_react259.useState)(true);
46534
46616
  const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
46535
46617
  const { secret, requiredMode } = args;
46536
- (0, import_react257.useEffect)(() => {
46618
+ (0, import_react259.useEffect)(() => {
46537
46619
  let cancelled = false;
46538
46620
  setLoading(true);
46539
46621
  setError(null);
@@ -46556,11 +46638,11 @@ function useEmbedHandshake(args) {
46556
46638
 
46557
46639
  // src/TablePage.tsx
46558
46640
  var import_clipboard13 = require("@ai-matrx/kit/clipboard");
46559
- var import_react269 = require("react");
46641
+ var import_react271 = require("react");
46560
46642
  var import_records63 = require("@ai-matrx/records");
46561
- var import_react270 = require("@ai-matrx/records/react");
46643
+ var import_react272 = require("@ai-matrx/records/react");
46562
46644
  var import_design_system140 = require("@ai-matrx/design-system");
46563
- var import_text_case18 = require("@ai-matrx/kit/text-case");
46645
+ var import_text_case19 = require("@ai-matrx/kit/text-case");
46564
46646
 
46565
46647
  // src/viewShare.ts
46566
46648
  var import_core25 = require("@ai-matrx/records/core");
@@ -46604,13 +46686,13 @@ async function downloadViewCsv(args) {
46604
46686
  }
46605
46687
 
46606
46688
  // src/RecordPanel.tsx
46607
- var import_react260 = require("react");
46689
+ var import_react262 = require("react");
46608
46690
  var import_design_system134 = require("@ai-matrx/design-system");
46609
- var import_react261 = require("@ai-matrx/records/react");
46691
+ var import_react263 = require("@ai-matrx/records/react");
46610
46692
  var import_jsx_runtime149 = require("react/jsx-runtime");
46611
46693
  function RecordPanel({ tableId, recordId, onClose, onAskAboutField, onPage = false }) {
46612
46694
  const host = useRecordsUi();
46613
- const [asking, setAsking] = (0, import_react260.useState)(null);
46695
+ const [asking, setAsking] = (0, import_react262.useState)(null);
46614
46696
  return /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { className: "space-y-3", "data-record-panel": recordId, children: [
46615
46697
  /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(Peek, { tableId, recordId, onPage, ...onClose ? { onClose } : {} }),
46616
46698
  onPage ? /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)(import_jsx_runtime149.Fragment, { children: [
@@ -46629,7 +46711,7 @@ function RecordPanel({ tableId, recordId, onClose, onAskAboutField, onPage = fal
46629
46711
  }
46630
46712
  ),
46631
46713
  !onAskAboutField && asking ? /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(FieldHistoryPanel, { tableId, fieldKey: asking, recordId, onClose: () => setAsking(null) }) : null,
46632
- host.recordSections ? /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)(import_react260.Fragment, { children: [
46714
+ host.recordSections ? /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)(import_react262.Fragment, { children: [
46633
46715
  /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(import_design_system134.Separator, {}),
46634
46716
  host.recordSections({ tableId, recordId })
46635
46717
  ] }) : null,
@@ -46640,8 +46722,8 @@ function RecordPanel({ tableId, recordId, onClose, onAskAboutField, onPage = fal
46640
46722
  ] });
46641
46723
  }
46642
46724
  function LinkedLists({ tableId, recordId }) {
46643
- const fields = (0, import_react261.useFields)(tableId);
46644
- const record = (0, import_react261.useRecord)(recordId, true, { tableId });
46725
+ const fields = (0, import_react263.useFields)(tableId);
46726
+ const record = (0, import_react263.useRecord)(recordId, true, { tableId });
46645
46727
  const links = (fields.data ?? []).filter((field2) => editorKindFor(field2) === "relation");
46646
46728
  const labels = useRecordLabels(links);
46647
46729
  const document2 = record.data?.document;
@@ -46688,7 +46770,7 @@ function LinkedLists({ tableId, recordId }) {
46688
46770
  }
46689
46771
  function RecordAsk({ tableId, recordId }) {
46690
46772
  const host = useRecordsUi();
46691
- const [open, setOpen] = (0, import_react260.useState)(false);
46773
+ const [open, setOpen] = (0, import_react262.useState)(false);
46692
46774
  if (!host.chat) return null;
46693
46775
  return /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("section", { className: "flex min-w-0 flex-col gap-1.5", "data-record-ask": open ? "open" : "", children: [
46694
46776
  /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(import_design_system134.Separator, {}),
@@ -46697,7 +46779,7 @@ function RecordAsk({ tableId, recordId }) {
46697
46779
  }
46698
46780
 
46699
46781
  // src/breakDown.tsx
46700
- var import_react262 = require("react");
46782
+ var import_react264 = require("react");
46701
46783
  var import_design_system135 = require("@ai-matrx/design-system");
46702
46784
  var import_jsx_runtime150 = require("react/jsx-runtime");
46703
46785
  var BREAK_DOWN_ACTION_ID = "break-down";
@@ -46723,10 +46805,10 @@ function BreakDownDialog({
46723
46805
  onOpenChange,
46724
46806
  onApply
46725
46807
  }) {
46726
- const source = (0, import_react262.useMemo)(() => ({ kind: "table", id: tableId }), [tableId]);
46808
+ const source = (0, import_react264.useMemo)(() => ({ kind: "table", id: tableId }), [tableId]);
46727
46809
  const { def } = useDrillDefinition(open ? source : null);
46728
- const dimensions = (0, import_react262.useMemo)(() => drillDimensionsOf(def, NO_LABELS), [def]);
46729
- const [picked, setPicked] = (0, import_react262.useState)(null);
46810
+ const dimensions = (0, import_react264.useMemo)(() => drillDimensionsOf(def, NO_LABELS), [def]);
46811
+ const [picked, setPicked] = (0, import_react264.useState)(null);
46730
46812
  const key = picked ?? held?.field ?? dimensions[0]?.key ?? "";
46731
46813
  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: [
46732
46814
  /* @__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" }) }),
@@ -46753,7 +46835,7 @@ function BreakDownDialog({
46753
46835
 
46754
46836
  // src/TableReference.tsx
46755
46837
  var import_clipboard12 = require("@ai-matrx/kit/clipboard");
46756
- var import_react263 = require("react");
46838
+ var import_react265 = require("react");
46757
46839
  var import_workspace2 = require("@ai-matrx/alchemy/react/workspace");
46758
46840
  var import_design_system136 = require("@ai-matrx/design-system");
46759
46841
  var import_jsx_runtime151 = require("react/jsx-runtime");
@@ -46781,12 +46863,12 @@ function TableReferenceDialog({
46781
46863
  }) {
46782
46864
  const port = (0, import_workspace2.useContentTransferCapabilities)().reference;
46783
46865
  const notify = useRecordsUi().notify;
46784
- const [copied, setCopied] = (0, import_react263.useState)(null);
46785
- const choices = (0, import_react263.useMemo)(
46866
+ const [copied, setCopied] = (0, import_react265.useState)(null);
46867
+ const choices = (0, import_react265.useMemo)(
46786
46868
  () => tableReferenceChoices(table.id, tableName(table)).filter((c) => port?.supports(c.reference)),
46787
46869
  [table, port]
46788
46870
  );
46789
- const copy = (0, import_react263.useCallback)(
46871
+ const copy = (0, import_react265.useCallback)(
46790
46872
  async (choice) => {
46791
46873
  if (!port) return;
46792
46874
  try {
@@ -46809,8 +46891,8 @@ function TableReferenceDialog({
46809
46891
  }
46810
46892
 
46811
46893
  // src/TableDuplicate.tsx
46812
- var import_react264 = require("react");
46813
- var import_react265 = require("@ai-matrx/records/react");
46894
+ var import_react266 = require("react");
46895
+ var import_react267 = require("@ai-matrx/records/react");
46814
46896
  var import_design_system137 = require("@ai-matrx/design-system");
46815
46897
  var import_jsx_runtime152 = require("react/jsx-runtime");
46816
46898
  function copyNameFor(name) {
@@ -46822,11 +46904,11 @@ function duplicateProgressWords(p) {
46822
46904
  return "Copying columns\u2026";
46823
46905
  }
46824
46906
  function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated }) {
46825
- const client = (0, import_react265.useRecordsClient)();
46907
+ const client = (0, import_react267.useRecordsClient)();
46826
46908
  const host = useRecordsUi();
46827
- const [typed2, setTyped] = (0, import_react264.useState)(() => copyNameFor(name));
46828
- const [withRecords, setWithRecords] = (0, import_react264.useState)(true);
46829
- const [phase, setPhase] = (0, import_react264.useState)({ kind: "asking" });
46909
+ const [typed2, setTyped] = (0, import_react266.useState)(() => copyNameFor(name));
46910
+ const [withRecords, setWithRecords] = (0, import_react266.useState)(true);
46911
+ const [phase, setPhase] = (0, import_react266.useState)({ kind: "asking" });
46830
46912
  const problem = tableNameProblem(typed2);
46831
46913
  const copying = phase.kind === "copying";
46832
46914
  const close = (next) => {
@@ -46850,7 +46932,7 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
46850
46932
  setPhase({ kind: "refused", sentence: refusalSentence(made.error) });
46851
46933
  return;
46852
46934
  }
46853
- (0, import_react265.tableShapeChanged)(made.data.table.id);
46935
+ (0, import_react267.tableShapeChanged)(made.data.table.id);
46854
46936
  setPhase({ kind: "done", copy: made.data });
46855
46937
  host.notify?.success(`Made ${made.data.table.name}`);
46856
46938
  };
@@ -46911,9 +46993,9 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
46911
46993
  }
46912
46994
 
46913
46995
  // src/ViewFilter.tsx
46914
- var import_react266 = require("react");
46996
+ var import_react268 = require("react");
46915
46997
  var import_design_system138 = require("@ai-matrx/design-system");
46916
- var import_react267 = require("@ai-matrx/records/react");
46998
+ var import_react269 = require("@ai-matrx/records/react");
46917
46999
  var import_jsx_runtime153 = require("react/jsx-runtime");
46918
47000
  function conditionCount(expr) {
46919
47001
  if (!expr || typeof expr !== "object" || Array.isArray(expr)) return 0;
@@ -46924,15 +47006,15 @@ function conditionCount(expr) {
46924
47006
  return 1;
46925
47007
  }
46926
47008
  function ViewFilter({ tableId, view, onApply, className }) {
46927
- const fields = (0, import_react267.useFields)(tableId);
46928
- const [open, setOpen] = (0, import_react266.useState)(false);
47009
+ const fields = (0, import_react269.useFields)(tableId);
47010
+ const [open, setOpen] = (0, import_react268.useState)(false);
46929
47011
  const saved = view?.where ?? null;
46930
- const [draft, setDraft] = (0, import_react266.useState)(saved);
47012
+ const [draft, setDraft] = (0, import_react268.useState)(saved);
46931
47013
  const savedKey = JSON.stringify(saved);
46932
- (0, import_react266.useEffect)(() => {
47014
+ (0, import_react268.useEffect)(() => {
46933
47015
  setDraft(saved);
46934
47016
  }, [view?.id, savedKey]);
46935
- const conditionFields = (0, import_react266.useMemo)(
47017
+ const conditionFields = (0, import_react268.useMemo)(
46936
47018
  () => (fields.data ?? []).map((f) => ({ id: f.id, key: f.key, label: f.label || f.key, field: f })),
46937
47019
  [fields.data]
46938
47020
  );
@@ -46977,7 +47059,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
46977
47059
  ConditionGroup,
46978
47060
  {
46979
47061
  lead: "Show records where",
46980
- emptyLabel: "every record",
47062
+ emptyLabel: "Pick a field",
46981
47063
  expr: draft,
46982
47064
  fields: conditionFields,
46983
47065
  onChange: setDraft
@@ -47013,8 +47095,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
47013
47095
  /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(import_design_system138.Button, { size: "sm", variant: "ghost", onClick: () => {
47014
47096
  setDraft(saved);
47015
47097
  setOpen(false);
47016
- }, children: "Cancel" }),
47017
- changed ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)("span", { className: "text-muted-foreground", children: "Not applied yet." }) : null
47098
+ }, children: "Cancel" })
47018
47099
  ] })
47019
47100
  ]
47020
47101
  }
@@ -47105,7 +47186,7 @@ function phoneTableActions(actions) {
47105
47186
  }
47106
47187
 
47107
47188
  // src/toolbarFit.ts
47108
- var import_react268 = require("react");
47189
+ var import_react270 = require("react");
47109
47190
  var FOLDED_GUESS = { look: 104, chooser: 96, tools: 120 };
47110
47191
  var SLOT_MIN = 36;
47111
47192
  function toolbarFold(input) {
@@ -47162,8 +47243,8 @@ function rowNeeds(row) {
47162
47243
  return { needs: needs + gap * Math.max(0, pieces.length - 1), gap };
47163
47244
  }
47164
47245
  function useToolbarFit(row) {
47165
- const [fold, setFold] = (0, import_react268.useState)(0);
47166
- (0, import_react268.useEffect)(() => {
47246
+ const [fold, setFold] = (0, import_react270.useState)(0);
47247
+ (0, import_react270.useEffect)(() => {
47167
47248
  if (!row) return;
47168
47249
  const widths = {
47169
47250
  look: { full: null, folded: null },
@@ -47247,8 +47328,8 @@ function clippedEnds(scrollLeft, clientWidth, scrollWidth) {
47247
47328
  return start && end ? "both" : start ? "start" : end ? "end" : "none";
47248
47329
  }
47249
47330
  function useSlotScroll(slot) {
47250
- const [ends, setEnds] = (0, import_react268.useState)("none");
47251
- (0, import_react268.useEffect)(() => {
47331
+ const [ends, setEnds] = (0, import_react270.useState)("none");
47332
+ (0, import_react270.useEffect)(() => {
47252
47333
  if (!slot) return;
47253
47334
  let pending = 0;
47254
47335
  const read = () => {
@@ -47331,7 +47412,7 @@ function RailFrame({
47331
47412
  function filterInWords(filter, fields) {
47332
47413
  const nameOf2 = (key) => {
47333
47414
  const field2 = fields.find((f) => f.key === key);
47334
- return field2 ? fieldName(field2) : (0, import_text_case18.humanizeIdentifier)(key);
47415
+ return field2 ? fieldName(field2) : (0, import_text_case19.humanizeIdentifier)(key);
47335
47416
  };
47336
47417
  const parts = Object.keys(filter).map((key) => {
47337
47418
  const value = filter[key];
@@ -47365,11 +47446,11 @@ function TableNotHere({
47365
47446
  leaveLabel,
47366
47447
  className
47367
47448
  }) {
47368
- const client = (0, import_react270.useRecordsClient)();
47369
- const [archived, setArchived] = (0, import_react269.useState)({ phase: "asking" });
47370
- const [restoring, setRestoring] = (0, import_react269.useState)(false);
47371
- const [refusal4, setRefusal] = (0, import_react269.useState)(null);
47372
- (0, import_react269.useEffect)(() => {
47449
+ const client = (0, import_react272.useRecordsClient)();
47450
+ const [archived, setArchived] = (0, import_react271.useState)({ phase: "asking" });
47451
+ const [restoring, setRestoring] = (0, import_react271.useState)(false);
47452
+ const [refusal4, setRefusal] = (0, import_react271.useState)(null);
47453
+ (0, import_react271.useEffect)(() => {
47373
47454
  let alive = true;
47374
47455
  void client.tableArchived({ table_id: tableId }).then((answered) => {
47375
47456
  if (!alive) return;
@@ -47567,18 +47648,18 @@ function TablePage({
47567
47648
  onViewAddressChange,
47568
47649
  className
47569
47650
  }) {
47570
- const client = (0, import_react270.useRecordsClient)();
47571
- const table = (0, import_react270.useTable)(tableId);
47651
+ const client = (0, import_react272.useRecordsClient)();
47652
+ const table = (0, import_react272.useTable)(tableId);
47572
47653
  const rights = useTableRights(table.data);
47573
- const pageFields = (0, import_react270.useFields)(filter ? tableId : null);
47574
- const allFields = (0, import_react270.useFields)(tableId);
47654
+ const pageFields = (0, import_react272.useFields)(filter ? tableId : null);
47655
+ const allFields = (0, import_react272.useFields)(tableId);
47575
47656
  const viewLabels = useRecordLabels(allFields.data ?? void 0);
47576
47657
  const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
47577
- const organizationId = (0, import_react270.useRecordsClient)().config.organizationId;
47658
+ const organizationId = (0, import_react272.useRecordsClient)().config.organizationId;
47578
47659
  const publicReadOnly = usePublicReadOnly(client, organizationId, tableId, table.data, rights);
47579
- const [view, setView] = (0, import_react269.useState)(null);
47580
- const [looks, setLooks] = (0, import_react269.useState)(void 0);
47581
- (0, import_react269.useEffect)(() => {
47660
+ const [view, setView] = (0, import_react271.useState)(null);
47661
+ const [looks, setLooks] = (0, import_react271.useState)(void 0);
47662
+ (0, import_react271.useEffect)(() => {
47582
47663
  let live = true;
47583
47664
  setLooks(void 0);
47584
47665
  void readLooks(client, tableId).then((answered) => {
@@ -47591,7 +47672,7 @@ function TablePage({
47591
47672
  }, [client, tableId]);
47592
47673
  const look = view && looks ? looks[view.id] : void 0;
47593
47674
  const shown4 = view ? applyLook(view, look) : null;
47594
- const [viewsEpoch, setViewsEpoch] = (0, import_react269.useState)(0);
47675
+ const [viewsEpoch, setViewsEpoch] = (0, import_react271.useState)(0);
47595
47676
  const opening = openingRail(activeRecordId, activeRail);
47596
47677
  const recordsUi = useRecordsUi();
47597
47678
  const hostLayouts = recordsUi.layouts ?? [];
@@ -47601,39 +47682,39 @@ function TablePage({
47601
47682
  const questionsFromLink = questionsFromParam(activeView);
47602
47683
  const openedByPackage = openingView(hostFromLink || savedFromLink || questionsFromLink ? null : activeView, activeDashboardId);
47603
47684
  const opened = hostFromLink ? { ...openedByPackage, main: "records" } : questionsFromLink ? { ...openedByPackage, main: "questions" } : openedByPackage;
47604
- const [hostLayout, setHostLayout] = (0, import_react269.useState)(hostFromLink);
47605
- const [views, setViews] = (0, import_react269.useState)(void 0);
47606
- const [pickedViewId, setPickedViewId] = (0, import_react269.useState)(savedFromLink);
47607
- const viewSeen = (0, import_react269.useRef)(null);
47608
- const [viewLinkMissed, setViewLinkMissed] = (0, import_react269.useState)(false);
47609
- const [layoutChosen, setLayoutChosen] = (0, import_react269.useState)(false);
47685
+ const [hostLayout, setHostLayout] = (0, import_react271.useState)(hostFromLink);
47686
+ const [views, setViews] = (0, import_react271.useState)(void 0);
47687
+ const [pickedViewId, setPickedViewId] = (0, import_react271.useState)(savedFromLink);
47688
+ const viewSeen = (0, import_react271.useRef)(null);
47689
+ const [viewLinkMissed, setViewLinkMissed] = (0, import_react271.useState)(false);
47690
+ const [layoutChosen, setLayoutChosen] = (0, import_react271.useState)(false);
47610
47691
  const railAsked = typeof activeRail === "string" ? activeRail.trim() : "";
47611
47692
  const railUnknown = railAsked !== "" && railFromParam(railAsked) === null ? railAsked : null;
47612
47693
  const shareFromLink = railFromParam(activeRail) === "share";
47613
47694
  const canShare = useCanShare();
47614
47695
  const itemFor = (which) => railFromParam(activeRail) === which ? activeItemId ?? null : null;
47615
- const [asking, setAsking] = (0, import_react269.useState)(null);
47616
- const [layoutFromLink, setLayoutFromLink] = (0, import_react269.useState)(opened.layout);
47617
- const [surface, setSurface] = (0, import_react269.useState)({
47696
+ const [asking, setAsking] = (0, import_react271.useState)(null);
47697
+ const [layoutFromLink, setLayoutFromLink] = (0, import_react271.useState)(opened.layout);
47698
+ const [surface, setSurface] = (0, import_react271.useState)({
47618
47699
  main: opened.main,
47619
47700
  rail: opening.rail
47620
47701
  });
47621
47702
  const { main, rail } = surface;
47622
- const [questionDraft, setQuestionDraft] = (0, import_react269.useState)(null);
47703
+ const [questionDraft, setQuestionDraft] = (0, import_react271.useState)(null);
47623
47704
  const setRail = (next) => setSurface((now) => ({ ...now, rail: next }));
47624
- const [importEpoch, setImportEpoch] = (0, import_react269.useState)(0);
47625
- const [openRecord, setOpenRecord] = (0, import_react269.useState)(opening.record);
47705
+ const [importEpoch, setImportEpoch] = (0, import_react271.useState)(0);
47706
+ const [openRecord, setOpenRecord] = (0, import_react271.useState)(opening.record);
47626
47707
  const phone = (0, import_design_system140.useIsMobile)();
47627
- const [shareAsked, setShareAsked] = (0, import_react269.useState)(0);
47708
+ const [shareAsked, setShareAsked] = (0, import_react271.useState)(0);
47628
47709
  const { open: renameOpen, setOpen: setRenameOpen, ask: askRename, menuContentProps: renameMenuProps } = useRenameFromMenu();
47629
- const [archiveAsked, setArchiveAsked] = (0, import_react269.useState)(0);
47630
- const [moveAsked, setMoveAsked] = (0, import_react269.useState)(0);
47631
- const [duplicateOpen, setDuplicateOpen] = (0, import_react269.useState)(false);
47632
- const [referenceOpen, setReferenceOpen] = (0, import_react269.useState)(false);
47633
- const [breakDownOpen, setBreakDownOpen] = (0, import_react269.useState)(false);
47710
+ const [archiveAsked, setArchiveAsked] = (0, import_react271.useState)(0);
47711
+ const [moveAsked, setMoveAsked] = (0, import_react271.useState)(0);
47712
+ const [duplicateOpen, setDuplicateOpen] = (0, import_react271.useState)(false);
47713
+ const [referenceOpen, setReferenceOpen] = (0, import_react271.useState)(false);
47714
+ const [breakDownOpen, setBreakDownOpen] = (0, import_react271.useState)(false);
47634
47715
  const canGetReference = useCanGetReference();
47635
- const [toolbarSlot, setToolbarSlot] = (0, import_react269.useState)(null);
47636
- const [toolbarRow, setToolbarRow] = (0, import_react269.useState)(null);
47716
+ const [toolbarSlot, setToolbarSlot] = (0, import_react271.useState)(null);
47717
+ const [toolbarRow, setToolbarRow] = (0, import_react271.useState)(null);
47637
47718
  const toolbarFold2 = useToolbarFit(toolbarRow);
47638
47719
  const slotClipped = useSlotScroll(toolbarSlot);
47639
47720
  const face = tableOpening(view, hostLayouts.map((h) => h.id));
@@ -47644,7 +47725,7 @@ function TablePage({
47644
47725
  const chooserCompact = !embedded && !designated && !phone && toolbarFold2 >= 2;
47645
47726
  const controlsInSheet = phone && !designated;
47646
47727
  const shareInMenu = phone || toolbarFold2 >= 4;
47647
- (0, import_react269.useEffect)(() => {
47728
+ (0, import_react271.useEffect)(() => {
47648
47729
  if (face.kind !== "designated") return;
47649
47730
  if (hostFromLink || opened.layout || layoutChosen) return;
47650
47731
  setHostLayout(face.hostLayout);
@@ -47675,9 +47756,9 @@ function TablePage({
47675
47756
  lookDiffers: view ? lookDiffers(view, look) : false
47676
47757
  };
47677
47758
  const shownSignature = JSON.stringify(shownReport);
47678
- const reportRef = (0, import_react269.useRef)(onShownViewChange);
47759
+ const reportRef = (0, import_react271.useRef)(onShownViewChange);
47679
47760
  reportRef.current = onShownViewChange;
47680
- (0, import_react269.useEffect)(() => {
47761
+ (0, import_react271.useEffect)(() => {
47681
47762
  reportRef.current?.(JSON.parse(shownSignature));
47682
47763
  }, [shownSignature]);
47683
47764
  const pickLayout = (next) => {
@@ -47694,18 +47775,18 @@ function TablePage({
47694
47775
  setSurface((now) => ({ ...now, main: "records" }));
47695
47776
  onViewChanged?.(id);
47696
47777
  };
47697
- (0, import_react269.useEffect)(() => {
47778
+ (0, import_react271.useEffect)(() => {
47698
47779
  if (!activeRecordId) return;
47699
47780
  setOpenRecord(activeRecordId);
47700
47781
  setSurface((now) => ({ ...now, rail: "record" }));
47701
47782
  }, [activeRecordId]);
47702
- (0, import_react269.useEffect)(() => {
47783
+ (0, import_react271.useEffect)(() => {
47703
47784
  if (activeRecordId) return;
47704
47785
  const named = railFromParam(activeRail);
47705
47786
  if (named === null || named === "share") return;
47706
47787
  setSurface((now) => ({ ...now, rail: named }));
47707
47788
  }, [activeRail, activeRecordId]);
47708
- (0, import_react269.useEffect)(() => {
47789
+ (0, import_react271.useEffect)(() => {
47709
47790
  const host = hostLayoutFor(activeView);
47710
47791
  if (host) {
47711
47792
  setHostLayout(host);
@@ -47719,8 +47800,8 @@ function TablePage({
47719
47800
  setLayoutFromLink(isLayout ? named : null);
47720
47801
  setSurface((now) => ({ ...now, main: isLayout ? "records" : named }));
47721
47802
  }, [activeView]);
47722
- const [viewSaveRefused, setViewSaveRefused] = (0, import_react269.useState)(null);
47723
- const patchView = (0, import_react269.useCallback)(
47803
+ const [viewSaveRefused, setViewSaveRefused] = (0, import_react271.useState)(null);
47804
+ const patchView = (0, import_react271.useCallback)(
47724
47805
  async (asked3) => {
47725
47806
  const current = view;
47726
47807
  if (!current) return;
@@ -47736,19 +47817,19 @@ function TablePage({
47736
47817
  },
47737
47818
  [client, tableId, view, looks]
47738
47819
  );
47739
- const arrival = (0, import_react269.useRef)(viewAddress ?? null);
47740
- const [gridQuery, setGridQuery] = (0, import_react269.useState)(null);
47741
- const [addressResetEpoch, setAddressResetEpoch] = (0, import_react269.useState)(0);
47742
- const reportGrid = (0, import_react269.useCallback)((q) => {
47820
+ const arrival = (0, import_react271.useRef)(viewAddress ?? null);
47821
+ const [gridQuery, setGridQuery] = (0, import_react271.useState)(null);
47822
+ const [addressResetEpoch, setAddressResetEpoch] = (0, import_react271.useState)(0);
47823
+ const reportGrid = (0, import_react271.useCallback)((q) => {
47743
47824
  const next = { sort: q.sort, filters: q.filters, search: q.search, page: q.page };
47744
47825
  setGridQuery((held) => sameViewAddress(held, next) ? held : next);
47745
47826
  }, []);
47746
- const addressPort = (0, import_react269.useMemo)(
47827
+ const addressPort = (0, import_react271.useMemo)(
47747
47828
  () => ({ initial: arrival.current, report: reportGrid, resetEpoch: addressResetEpoch }),
47748
47829
  [reportGrid, addressResetEpoch]
47749
47830
  );
47750
- const hiddenApplied = (0, import_react269.useRef)(false);
47751
- (0, import_react269.useEffect)(() => {
47831
+ const hiddenApplied = (0, import_react271.useRef)(false);
47832
+ (0, import_react271.useEffect)(() => {
47752
47833
  const hidden = arrival.current?.hidden;
47753
47834
  if (hiddenApplied.current || !view || !looks || !hidden || hidden.length === 0) return;
47754
47835
  hiddenApplied.current = true;
@@ -47768,10 +47849,10 @@ function TablePage({
47768
47849
  const gridPending = !isViewAddressEmpty({ ...arrival.current ?? {}, hidden: [] });
47769
47850
  const addressReady = Boolean(view && looks) && (gridQuery !== null || !gridPending);
47770
47851
  const addressSignature = JSON.stringify(viewAddressToParams(addressNow));
47771
- const addressReportRef = (0, import_react269.useRef)(onViewAddressChange);
47852
+ const addressReportRef = (0, import_react271.useRef)(onViewAddressChange);
47772
47853
  addressReportRef.current = onViewAddressChange;
47773
- const addressSent = (0, import_react269.useRef)(null);
47774
- (0, import_react269.useEffect)(() => {
47854
+ const addressSent = (0, import_react271.useRef)(null);
47855
+ (0, import_react271.useEffect)(() => {
47775
47856
  if (!addressReady) return;
47776
47857
  if (addressSent.current === null && addressSignature === JSON.stringify(viewAddressToParams(arrival.current))) {
47777
47858
  addressSent.current = addressSignature;
@@ -47783,9 +47864,9 @@ function TablePage({
47783
47864
  }, [addressReady, addressSignature]);
47784
47865
  const queryShowing = !isViewAddressEmpty({ ...gridQuery ?? {}, hidden: [] });
47785
47866
  const lookShowing = Boolean(view && looks && (lookDiffers(view, looks[view.id]) || queryShowing));
47786
- const [lookRefused, setLookRefused] = (0, import_react269.useState)(null);
47787
- const [namingLook, setNamingLook] = (0, import_react269.useState)(false);
47788
- const [lookName, setLookName] = (0, import_react269.useState)("");
47867
+ const [lookRefused, setLookRefused] = (0, import_react271.useState)(null);
47868
+ const [namingLook, setNamingLook] = (0, import_react271.useState)(false);
47869
+ const [lookName, setLookName] = (0, import_react271.useState)("");
47789
47870
  const resetLook = async () => {
47790
47871
  const current = view;
47791
47872
  setAddressResetEpoch((n) => n + 1);
@@ -47844,7 +47925,7 @@ function TablePage({
47844
47925
  setPickedViewId(written.data);
47845
47926
  setViewsEpoch((n) => n + 1);
47846
47927
  };
47847
- const [designateRefused, setDesignateRefused] = (0, import_react269.useState)(null);
47928
+ const [designateRefused, setDesignateRefused] = (0, import_react271.useState)(null);
47848
47929
  const opensAs = view?.isDefault ? openingLayoutOf(view) : null;
47849
47930
  const canDesignate = Boolean(
47850
47931
  rights.write && view && layoutShowing && layoutShowing !== opensAs && (storeKeepsLayout(layoutShowing) || hostLayouts.some((h) => h.id === layoutShowing))
@@ -48023,14 +48104,14 @@ function TablePage({
48023
48104
  }
48024
48105
  });
48025
48106
  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;
48026
- const actionsRef = (0, import_react269.useRef)(actions);
48107
+ const actionsRef = (0, import_react271.useRef)(actions);
48027
48108
  actionsRef.current = actions;
48028
- const onActionsRef = (0, import_react269.useRef)(onActions);
48109
+ const onActionsRef = (0, import_react271.useRef)(onActions);
48029
48110
  onActionsRef.current = onActions;
48030
- (0, import_react269.useEffect)(() => {
48111
+ (0, import_react271.useEffect)(() => {
48031
48112
  onActionsRef.current?.(actionsRef.current);
48032
48113
  });
48033
- (0, import_react269.useEffect)(() => {
48114
+ (0, import_react271.useEffect)(() => {
48034
48115
  const onKey = (event) => {
48035
48116
  const asked3 = objectActionForKey(actionsRef.current, event);
48036
48117
  if (!asked3) return;
@@ -48259,7 +48340,7 @@ function TablePage({
48259
48340
  ] })
48260
48341
  ] }) }),
48261
48342
  /* @__PURE__ */ (0, import_jsx_runtime155.jsxs)(import_design_system140.DropdownMenuContent, { align: "start", className: "w-60", "data-view-look-menu-content": "", children: [
48262
- /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(import_design_system140.DropdownMenuLabel, { className: "text-xs font-normal text-muted-foreground", children: LOOK_WORDS.yours }),
48343
+ /* @__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 }),
48263
48344
  lookSavable ? /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(import_design_system140.DropdownMenuItem, { onSelect: () => void saveLookToView(), "data-view-look-save": "", children: LOOK_WORDS.saveToView }) : null,
48264
48345
  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,
48265
48346
  /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(import_design_system140.DropdownMenuItem, { onSelect: () => void resetLook(), "data-view-look-reset": "", children: LOOK_WORDS.reset })
@@ -48571,8 +48652,8 @@ var PUBLIC_READ_ONLY = "Public \xB7 read only";
48571
48652
  function usePublicReadOnly(client, organizationId, tableId, table, rights) {
48572
48653
  const readOnly = rights.known && rights.read && !rights.write;
48573
48654
  const marked = table?.published_to_web;
48574
- const [isPublic, setIsPublic] = (0, import_react269.useState)(false);
48575
- (0, import_react269.useEffect)(() => {
48655
+ const [isPublic, setIsPublic] = (0, import_react271.useState)(false);
48656
+ (0, import_react271.useEffect)(() => {
48576
48657
  if (!readOnly || !table) {
48577
48658
  setIsPublic(false);
48578
48659
  return;
@@ -48597,9 +48678,9 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
48597
48678
  // src/entityViews.tsx
48598
48679
  var import_design_system141 = require("@ai-matrx/design-system");
48599
48680
  var import_data_table23 = require("@ai-matrx/design-system/data-table");
48600
- var import_react271 = require("react");
48681
+ var import_react273 = require("react");
48601
48682
  var import_design_system142 = require("@ai-matrx/design-system");
48602
- var import_react272 = require("@ai-matrx/records/react");
48683
+ var import_react274 = require("@ai-matrx/records/react");
48603
48684
  var import_jsx_runtime156 = require("react/jsx-runtime");
48604
48685
  var entityTitleColumn = entityNameColumn;
48605
48686
  function shown3(v) {
@@ -48610,12 +48691,12 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
48610
48691
  const choiceColumns = entityChoiceColumns(entity.columns);
48611
48692
  const column = (groupBy ? choiceColumns.find((c) => c.key === groupBy) : void 0) ?? choiceColumns[0] ?? null;
48612
48693
  const title = entityTitleColumn(entity.columns);
48613
- const extra = (0, import_react271.useMemo)(
48694
+ const extra = (0, import_react273.useMemo)(
48614
48695
  () => cardFields ? entity.columns.filter((c) => cardFields.includes(c.key)) : entity.columns.filter((c) => c !== title && c !== column && c.type !== "choice").slice(0, 2),
48615
48696
  [cardFields, entity.columns, title, column]
48616
48697
  );
48617
- const [refused, setRefused] = (0, import_react271.useState)(null);
48618
- const [over, setOver] = (0, import_react271.useState)(null);
48698
+ const [refused, setRefused] = (0, import_react273.useState)(null);
48699
+ const [over, setOver] = (0, import_react273.useState)(null);
48619
48700
  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}` });
48620
48701
  if (!entity.loading && !column) {
48621
48702
  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.` });
@@ -48680,11 +48761,11 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
48680
48761
  }) });
48681
48762
  }
48682
48763
  function EntityChartBlock({ source, kind, by, measure, title, where, organization, centerValue, variant, className }) {
48683
- const client = (0, import_react272.useRecordsClient)();
48764
+ const client = (0, import_react274.useRecordsClient)();
48684
48765
  const m = measure ?? { op: "count" };
48685
48766
  const ask = JSON.stringify([source.token, by ?? null, m, where ?? null, organization ?? null]);
48686
- const [block, setBlock] = (0, import_react271.useState)(null);
48687
- (0, import_react271.useEffect)(() => {
48767
+ const [block, setBlock] = (0, import_react273.useState)(null);
48768
+ (0, import_react273.useEffect)(() => {
48688
48769
  let cancelled = false;
48689
48770
  const question = {
48690
48771
  ...by ? { by: [by] } : {},
@@ -48747,20 +48828,20 @@ function EntityTablePageBody({
48747
48828
  actions,
48748
48829
  className
48749
48830
  }) {
48750
- const [typed2, setTyped] = (0, import_react271.useState)("");
48831
+ const [typed2, setTyped] = (0, import_react273.useState)("");
48751
48832
  const term = searchOverride ?? typed2;
48752
48833
  const entity = useEntityTable(source.token, { pageSize, search: term });
48753
- const [layout, setLayout] = (0, import_react271.useState)(opened);
48754
- (0, import_react271.useEffect)(() => setLayout(opened), [opened]);
48834
+ const [layout, setLayout] = (0, import_react273.useState)(opened);
48835
+ (0, import_react273.useEffect)(() => setLayout(opened), [opened]);
48755
48836
  const choose = (next) => {
48756
48837
  setLayout(next);
48757
48838
  onLayoutChange?.(next);
48758
48839
  };
48759
48840
  const boardable = entityChoiceColumns(entity.columns).length > 0;
48760
48841
  const nameColumn = entityNameColumn(entity.columns);
48761
- const [naming, setNaming] = (0, import_react271.useState)(null);
48762
- const [adding, setAdding] = (0, import_react271.useState)(false);
48763
- const [addRefused, setAddRefused] = (0, import_react271.useState)(null);
48842
+ const [naming, setNaming] = (0, import_react273.useState)(null);
48843
+ const [adding, setAdding] = (0, import_react273.useState)(false);
48844
+ const [addRefused, setAddRefused] = (0, import_react273.useState)(null);
48764
48845
  const add = async () => {
48765
48846
  const name = (naming ?? "").trim();
48766
48847
  if (!name || !nameColumn || adding) return;
@@ -48772,7 +48853,7 @@ function EntityTablePageBody({
48772
48853
  setNaming(null);
48773
48854
  onOpenRecord?.(made.id);
48774
48855
  };
48775
- const [question, setQuestion] = (0, import_react271.useState)(() => questionFromGrouping(void 0));
48856
+ const [question, setQuestion] = (0, import_react273.useState)(() => questionFromGrouping(void 0));
48776
48857
  const { config: drill } = useDrill({
48777
48858
  source,
48778
48859
  question,
@@ -48875,9 +48956,9 @@ function TablePage2(props) {
48875
48956
  }
48876
48957
 
48877
48958
  // src/DataBindingPicker.tsx
48878
- var import_react273 = require("react");
48959
+ var import_react275 = require("react");
48879
48960
  var import_records64 = require("@ai-matrx/records");
48880
- var import_react274 = require("@ai-matrx/records/react");
48961
+ var import_react276 = require("@ai-matrx/records/react");
48881
48962
  var import_design_system143 = require("@ai-matrx/design-system");
48882
48963
  var import_jsx_runtime158 = require("react/jsx-runtime");
48883
48964
  var DATA_BINDING_SHAPES = [
@@ -48967,11 +49048,11 @@ function BindingDetails({
48967
49048
  disabled,
48968
49049
  defaultRowLimit
48969
49050
  }) {
48970
- const table = (0, import_react274.useTable)(tableId);
48971
- const fields = (0, import_react274.useFields)(tableId);
48972
- const fieldList = (0, import_react273.useMemo)(() => fields.data ?? [], [fields.data]);
49051
+ const table = (0, import_react276.useTable)(tableId);
49052
+ const fields = (0, import_react276.useFields)(tableId);
49053
+ const fieldList = (0, import_react275.useMemo)(() => fields.data ?? [], [fields.data]);
48973
49054
  const shape = binding.semantic_type;
48974
- (0, import_react273.useEffect)(() => {
49055
+ (0, import_react275.useEffect)(() => {
48975
49056
  if (disabled || shape === "value" || binding.transform || fields.loading || fieldList.length === 0) return;
48976
49057
  onChange({
48977
49058
  ...binding,
@@ -49116,7 +49197,7 @@ function BindingDetails({
49116
49197
  }
49117
49198
 
49118
49199
  // src/PickedSummaries.tsx
49119
- var import_react275 = require("@ai-matrx/records/react");
49200
+ var import_react277 = require("@ai-matrx/records/react");
49120
49201
  var import_jsx_runtime159 = require("react/jsx-runtime");
49121
49202
  function TableNameText({ dataSource, tableId }) {
49122
49203
  const tables = useTablesAnywhere(dataSource);
@@ -49145,7 +49226,7 @@ function ColumnValuesText({
49145
49226
  );
49146
49227
  }
49147
49228
  function ColumnValuesWords({ tableId, value }) {
49148
- const fields = (0, import_react275.useFields)(tableId);
49229
+ const fields = (0, import_react277.useFields)(tableId);
49149
49230
  const labels = useRecordLabels(fields.data ?? void 0);
49150
49231
  if (fields.loading) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "\u2026" });
49151
49232
  if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "Couldn't load this table's columns" });
@@ -49184,8 +49265,8 @@ function RecordNameText({
49184
49265
  );
49185
49266
  }
49186
49267
  function RecordNameWords({ tableId, recordId }) {
49187
- const table = (0, import_react275.useTable)(tableId);
49188
- const record = (0, import_react275.useRecord)(recordId);
49268
+ const table = (0, import_react277.useTable)(tableId);
49269
+ const record = (0, import_react277.useRecord)(recordId);
49189
49270
  if (record.loading || table.loading) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "\u2026" });
49190
49271
  if (record.error) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "Couldn't load this record" });
49191
49272
  if (!record.data) return /* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_jsx_runtime159.Fragment, { children: "A record you cannot open" });
@@ -49193,19 +49274,19 @@ function RecordNameWords({ tableId, recordId }) {
49193
49274
  }
49194
49275
 
49195
49276
  // src/HeldChangeDecision.tsx
49196
- var import_react276 = require("react");
49197
- var import_react277 = require("@ai-matrx/records/react");
49277
+ var import_react278 = require("react");
49278
+ var import_react279 = require("@ai-matrx/records/react");
49198
49279
  var import_design_system144 = require("@ai-matrx/design-system");
49199
49280
  var import_jsx_runtime160 = require("react/jsx-runtime");
49200
49281
  function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, onDecided }) {
49201
- 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 }) });
49282
+ 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 }) });
49202
49283
  }
49203
49284
  function Decision({ approvalId, onDecided }) {
49204
- const client = (0, import_react277.useRecordsClient)();
49205
- const [may, setMay] = (0, import_react276.useState)(null);
49206
- const [busy, setBusy] = (0, import_react276.useState)(null);
49207
- const [error, setError] = (0, import_react276.useState)(null);
49208
- (0, import_react276.useEffect)(() => {
49285
+ const client = (0, import_react279.useRecordsClient)();
49286
+ const [may, setMay] = (0, import_react278.useState)(null);
49287
+ const [busy, setBusy] = (0, import_react278.useState)(null);
49288
+ const [error, setError] = (0, import_react278.useState)(null);
49289
+ (0, import_react278.useEffect)(() => {
49209
49290
  let live = true;
49210
49291
  void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
49211
49292
  if (!live) return;
@@ -49238,18 +49319,18 @@ function Decision({ approvalId, onDecided }) {
49238
49319
  }
49239
49320
 
49240
49321
  // src/TemplatePreview.tsx
49241
- var import_react278 = require("react");
49322
+ var import_react280 = require("react");
49242
49323
  var import_memory = require("@ai-matrx/records/memory");
49243
- var import_react279 = require("@ai-matrx/records/react");
49324
+ var import_react281 = require("@ai-matrx/records/react");
49244
49325
  var import_jsx_runtime161 = require("react/jsx-runtime");
49245
49326
  function useTemplatePreview(spec, today) {
49246
- return (0, import_react278.useMemo)(() => (0, import_memory.templatePreview)(spec, today ? { today } : {}), [spec, today]);
49327
+ return (0, import_react280.useMemo)(() => (0, import_memory.templatePreview)(spec, today ? { today } : {}), [spec, today]);
49247
49328
  }
49248
49329
  function TemplatePreview({ spec, today, initialTable, host, aside, booking, className }) {
49249
49330
  const preview = useTemplatePreview(spec, today);
49250
- const bound2 = (0, import_react278.useMemo)(() => ({ ...host, sayLevelNeeded: false }), [host]);
49331
+ const bound2 = (0, import_react280.useMemo)(() => ({ ...host, sayLevelNeeded: false }), [host]);
49251
49332
  const first = preview.tables.find((t) => t.token === initialTable) ?? preview.tables[0];
49252
- const [active, setActive] = (0, import_react278.useState)(first?.id ?? null);
49333
+ const [active, setActive] = (0, import_react280.useState)(first?.id ?? null);
49253
49334
  const table = preview.tables.find((t) => t.id === active) ?? first;
49254
49335
  if (!table) return null;
49255
49336
  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: [
@@ -49286,10 +49367,10 @@ function TemplatePreview({ spec, today, initialTable, host, aside, booking, clas
49286
49367
  ] });
49287
49368
  }
49288
49369
  function PreviewForms({ preview, booking }) {
49289
- const client = (0, import_react279.useRecordsClient)();
49290
- const [forms, setForms] = (0, import_react278.useState)(null);
49291
- const [pages, setPages] = (0, import_react278.useState)([]);
49292
- (0, import_react278.useEffect)(() => {
49370
+ const client = (0, import_react281.useRecordsClient)();
49371
+ const [forms, setForms] = (0, import_react280.useState)(null);
49372
+ const [pages, setPages] = (0, import_react280.useState)([]);
49373
+ (0, import_react280.useEffect)(() => {
49293
49374
  let gone = false;
49294
49375
  void client.forms().then((answered) => {
49295
49376
  if (!gone) setForms(answered.ok ? answered.data.map(formFromSummary) : []);