@ai-matrx/records-ui 0.93.29 → 0.93.33

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
@@ -976,7 +976,7 @@ var import_design_system11 = require("@ai-matrx/design-system");
976
976
 
977
977
  // src/editors.tsx
978
978
  var import_react18 = require("react");
979
- var import_records5 = require("@ai-matrx/records");
979
+ var import_records6 = require("@ai-matrx/records");
980
980
  var import_react19 = require("@ai-matrx/records/react");
981
981
  var import_design_system10 = require("@ai-matrx/design-system");
982
982
 
@@ -1684,6 +1684,7 @@ var import_design_system6 = require("@ai-matrx/design-system");
1684
1684
  // src/labels.tsx
1685
1685
  var import_react8 = require("react");
1686
1686
  var import_react9 = require("@ai-matrx/records/react");
1687
+ var import_records4 = require("@ai-matrx/records");
1687
1688
  var import_jsx_runtime6 = require("react/jsx-runtime");
1688
1689
  var LabelContext = (0, import_react8.createContext)({
1689
1690
  // With no provider the resolver is ABSENT, not silently empty: a caller gets
@@ -1704,6 +1705,9 @@ function idsOf(value) {
1704
1705
  return [];
1705
1706
  }
1706
1707
  var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1708
+ function choiceKeyName(fieldId, key) {
1709
+ return `${fieldId}\0key\0${key}`;
1710
+ }
1707
1711
  function isId(value) {
1708
1712
  return typeof value === "string" && UUID.test(value);
1709
1713
  }
@@ -1770,7 +1774,10 @@ function RecordLabelProvider({ children }) {
1770
1774
  setNames((current) => {
1771
1775
  const next = { ...current };
1772
1776
  for (const option of result.data ?? []) {
1773
- next[option.id] = recordName(option.data, null, "Unnamed choice");
1777
+ const words2 = recordName(option.data, null, "Unnamed choice");
1778
+ next[option.id] = words2;
1779
+ const key = (0, import_records4.optionKey)(option);
1780
+ if (key) next[choiceKeyName(field2.id, key)] = words2;
1774
1781
  }
1775
1782
  return next;
1776
1783
  });
@@ -1834,14 +1841,26 @@ function RecordLabelProvider({ children }) {
1834
1841
  },
1835
1842
  []
1836
1843
  );
1844
+ const rereadFor = (0, import_react8.useRef)(/* @__PURE__ */ new Set());
1837
1845
  const lookup = (0, import_react8.useCallback)(
1838
1846
  (field2, id) => {
1847
+ if (field2.type === "list" && !isId(id)) {
1848
+ const named = names[choiceKeyName(field2.id, id)];
1849
+ if (named !== void 0) return named;
1850
+ const once = choiceKeyName(field2.id, id);
1851
+ if (settled[field2.id] && !rereadFor.current.has(once)) {
1852
+ rereadFor.current.add(once);
1853
+ asked2.current.delete(field2.id);
1854
+ want(field2);
1855
+ }
1856
+ return null;
1857
+ }
1839
1858
  const known = names[id];
1840
1859
  if (known !== void 0) return known;
1841
1860
  if (settled[field2.id]) chase(field2, id);
1842
1861
  return null;
1843
1862
  },
1844
- [names, settled, chase]
1863
+ [names, settled, chase, want]
1845
1864
  );
1846
1865
  const waiting = (0, import_react8.useCallback)((field2) => waitingLines[field2.id] ?? null, [waitingLines]);
1847
1866
  const value = (0, import_react8.useMemo)(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
@@ -2110,14 +2129,14 @@ function AttachmentControl({
2110
2129
 
2111
2130
  // src/EntityReferenceControl.tsx
2112
2131
  var import_react13 = require("react");
2113
- var import_records4 = require("@ai-matrx/records");
2132
+ var import_records5 = require("@ai-matrx/records");
2114
2133
  var import_react14 = require("@ai-matrx/records/react");
2115
2134
  var import_design_system7 = require("@ai-matrx/design-system");
2116
2135
  var import_jsx_runtime9 = require("react/jsx-runtime");
2117
2136
  var WITHHELD_ENTITY_LABEL = "Something you have not been given access to";
2118
2137
  var ENTITY_REFERENCE_EMPTY = "Nothing is pointed at yet. A reference is added from the thing itself, by an agent, or by an import.";
2119
2138
  function entityReferenceText(value) {
2120
- const refs = (0, import_records4.entityRefsOf)(value);
2139
+ const refs = (0, import_records5.entityRefsOf)(value);
2121
2140
  if (refs.length === 0) return "\u2014";
2122
2141
  return refs.map((r) => r.label ?? WITHHELD_ENTITY_LABEL).join(", ");
2123
2142
  }
@@ -2126,13 +2145,13 @@ function EntityReferenceControl(props) {
2126
2145
  return client ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(WithWords, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Chips, { ...props, words: null });
2127
2146
  }
2128
2147
  function WithWords(props) {
2129
- const refs = (0, import_react13.useMemo)(() => (0, import_records4.entityRefsOf)(props.value), [props.value]);
2148
+ const refs = (0, import_react13.useMemo)(() => (0, import_records5.entityRefsOf)(props.value), [props.value]);
2130
2149
  const unlabelled = (0, import_react13.useMemo)(() => refs.filter((r) => r.label === null).map((r) => ({ token: r.token, id: r.id })), [refs]);
2131
2150
  const words2 = (0, import_react14.useEntityReferenceWords)(unlabelled);
2132
2151
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Chips, { ...props, words: words2 });
2133
2152
  }
2134
2153
  function Chips({ field: field2, value, onChange, disabled, id, className, words: words2 }) {
2135
- const refs = (0, import_react13.useMemo)(() => (0, import_records4.entityRefsOf)(value), [value]);
2154
+ const refs = (0, import_react13.useMemo)(() => (0, import_records5.entityRefsOf)(value), [value]);
2136
2155
  const labelOf = (token, refId, own2) => {
2137
2156
  if (own2) return own2;
2138
2157
  const read = words2?.data?.find((w) => w.token === token && w.id === refId)?.label;
@@ -2156,7 +2175,7 @@ function Chips({ field: field2, value, onChange, disabled, id, className, words:
2156
2175
  "aria-label": `Take ${label} off`,
2157
2176
  onClick: () => {
2158
2177
  const rest = refs.filter((x) => !(x.token === r.token && x.id === r.id));
2159
- onChange((0, import_records4.entityRefsToWrite)(rest, multi));
2178
+ onChange((0, import_records5.entityRefsToWrite)(rest, multi));
2160
2179
  },
2161
2180
  children: "\xD7"
2162
2181
  }
@@ -2809,14 +2828,14 @@ function judgeTyped(field2, text, choices, nudge) {
2809
2828
  if (!choices || nudge === null) return null;
2810
2829
  const several = field2.multi || kind === "multi_select";
2811
2830
  const words2 = several ? trimmed.split(/\s*[,;\n]\s*/).filter(Boolean) : [trimmed];
2812
- const allowOther = (0, import_records5.allowsOtherValues)(field2);
2831
+ const allowOther = (0, import_records6.allowsOtherValues)(field2);
2813
2832
  const parts = [];
2814
2833
  const add = [];
2815
2834
  const ask = [];
2816
2835
  const notChoices = [];
2817
2836
  let keepOffered = allowOther;
2818
2837
  for (const word of words2) {
2819
- const decided = (0, import_records5.decideTypedChoice)({ words: word, options: choices, allowOther, nudge });
2838
+ const decided = (0, import_records6.decideTypedChoice)({ words: word, options: choices, allowOther, nudge });
2820
2839
  if (decided.decision === "empty") continue;
2821
2840
  if (decided.decision === "chosen") parts.push(decided.key);
2822
2841
  else {
@@ -2843,7 +2862,7 @@ function judgeTyped(field2, text, choices, nudge) {
2843
2862
  const max = format.options?.ratingMax ?? 5;
2844
2863
  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.` };
2845
2864
  }
2846
- const read = (0, import_records5.coerceTypedAnswer)(field2, text, { label: fieldName(field2) });
2865
+ const read = (0, import_records6.coerceTypedAnswer)(field2, text, { label: fieldName(field2) });
2847
2866
  if ("refusal" in read) return { refusal: read.refusal };
2848
2867
  if (typeof read.value === "number" && format && (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction") {
2849
2868
  return { value: Math.round(read.value / 100 * 1e9) / 1e9 };
@@ -2919,7 +2938,7 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
2919
2938
  " ",
2920
2939
  needsChoices ? String(
2921
2940
  (Array.isArray(withoutAddition(judged.value).value) ? withoutAddition(judged.value).value : [withoutAddition(judged.value).value]).map((k) => {
2922
- const option = choices?.find((o) => (0, import_records5.optionKey)(o) === k);
2941
+ const option = choices?.find((o) => (0, import_records6.optionKey)(o) === k);
2923
2942
  return option ? recordName(option.data, null, String(k)) : String(k);
2924
2943
  }).join(", ")
2925
2944
  ) : (() => {
@@ -3180,7 +3199,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
3180
3199
  onClose,
3181
3200
  initialSearch,
3182
3201
  addsChoices,
3183
- allowOther: (0, import_records5.allowsOtherValues)(field2),
3202
+ allowOther: (0, import_records6.allowsOtherValues)(field2),
3184
3203
  onChoicesChanged: () => setReread((n) => n + 1)
3185
3204
  }
3186
3205
  );
@@ -3190,19 +3209,19 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
3190
3209
  }
3191
3210
  const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
3192
3211
  if (field2.multi) {
3193
- const chosen = options.filter((option) => (0, import_records5.choiceValuesOf)(value).some((v) => (0, import_records5.isTheChosen)(option, v)));
3194
- const picked = new Set(chosen.map((option) => (0, import_records5.optionKey)(option)));
3212
+ const chosen = options.filter((option) => (0, import_records6.choiceValuesOf)(value).some((v) => (0, import_records6.isTheChosen)(option, v)));
3213
+ const picked = new Set(chosen.map((option) => (0, import_records6.optionKey)(option)));
3195
3214
  const toggles = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3196
3215
  import_design_system10.Button,
3197
3216
  {
3198
3217
  type: "button",
3199
3218
  size: "sm",
3200
- variant: picked.has((0, import_records5.optionKey)(option)) ? "default" : "outline",
3219
+ variant: picked.has((0, import_records6.optionKey)(option)) ? "default" : "outline",
3201
3220
  disabled,
3202
3221
  onClick: () => {
3203
3222
  const next = new Set(picked);
3204
- if (next.has((0, import_records5.optionKey)(option))) next.delete((0, import_records5.optionKey)(option));
3205
- else next.add((0, import_records5.optionKey)(option));
3223
+ if (next.has((0, import_records6.optionKey)(option))) next.delete((0, import_records6.optionKey)(option));
3224
+ else next.add((0, import_records6.optionKey)(option));
3206
3225
  onChange(next.size === 0 ? null : [...next]);
3207
3226
  },
3208
3227
  children: titleOf(option)
@@ -3224,11 +3243,11 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
3224
3243
  }
3225
3244
  );
3226
3245
  }
3227
- const current = options.find((option) => (0, import_records5.isTheChosen)(option, value));
3246
+ const current = options.find((option) => (0, import_records6.isTheChosen)(option, value));
3228
3247
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3229
3248
  import_design_system10.Select,
3230
3249
  {
3231
- value: current ? (0, import_records5.optionKey)(current) : "",
3250
+ value: current ? (0, import_records6.optionKey)(current) : "",
3232
3251
  disabled: disabled ?? false,
3233
3252
  onValueChange: (next) => onChange(next === "" ? null : next),
3234
3253
  ...autoOpen ? {
@@ -3240,7 +3259,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
3240
3259
  } : {},
3241
3260
  children: [
3242
3261
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system10.SelectTrigger, { id, size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system10.SelectValue, { placeholder: "Choose" }) }),
3243
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system10.SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system10.SelectItem, { value: (0, import_records5.optionKey)(option), children: titleOf(option) }, option.id)) })
3262
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system10.SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system10.SelectItem, { value: (0, import_records6.optionKey)(option), children: titleOf(option) }, option.id)) })
3244
3263
  ]
3245
3264
  }
3246
3265
  );
@@ -3273,22 +3292,22 @@ function OpenChoicePicker({
3273
3292
  const [addRefused, setAddRefused] = (0, import_react18.useState)(null);
3274
3293
  const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
3275
3294
  const held = withoutAddition(value);
3276
- const current = (0, import_records5.choiceValuesOf)(held.value);
3295
+ const current = (0, import_records6.choiceValuesOf)(held.value);
3277
3296
  const pickedWords = current.map((v) => {
3278
- const option = options.find((o) => (0, import_records5.isTheChosen)(o, v));
3297
+ const option = options.find((o) => (0, import_records6.isTheChosen)(o, v));
3279
3298
  return option ? titleOf(option) : String(v);
3280
3299
  });
3281
3300
  const q = search.trim();
3282
3301
  const visible = options.filter((o) => q === "" || titleOf(o).toLowerCase().includes(q.toLowerCase()));
3283
- const decided = (0, import_records5.decideTypedChoice)({ words: q, options, allowOther, nudge: nudge ?? "ask" });
3302
+ const decided = (0, import_records6.decideTypedChoice)({ words: q, options, allowOther, nudge: nudge ?? "ask" });
3284
3303
  const choose = (word, addingIt = false) => {
3285
3304
  const pending = held.add.filter((w) => w.toLowerCase() !== word.toLowerCase());
3286
3305
  let next;
3287
3306
  let add2 = [...pending];
3288
3307
  if (field2.multi) {
3289
3308
  const existing = current.map((v) => {
3290
- const option = options.find((o) => (0, import_records5.isTheChosen)(o, v));
3291
- return option ? (0, import_records5.optionKey)(option) : String(v);
3309
+ const option = options.find((o) => (0, import_records6.isTheChosen)(o, v));
3310
+ return option ? (0, import_records6.optionKey)(option) : String(v);
3292
3311
  });
3293
3312
  const has = existing.some((v) => v.toLowerCase() === word.toLowerCase());
3294
3313
  const list = has ? existing.filter((v) => v.toLowerCase() !== word.toLowerCase()) : [...existing, word];
@@ -3357,11 +3376,11 @@ function OpenChoicePicker({
3357
3376
  items: visible.map((option) => ({
3358
3377
  id: option.id,
3359
3378
  label: titleOf(option),
3360
- picked: current.some((v) => (0, import_records5.isTheChosen)(option, v))
3379
+ picked: current.some((v) => (0, import_records6.isTheChosen)(option, v))
3361
3380
  })),
3362
3381
  onPick: (optionId) => {
3363
3382
  const option = options.find((o) => o.id === optionId);
3364
- if (option) choose((0, import_records5.optionKey)(option));
3383
+ if (option) choose((0, import_records6.optionKey)(option));
3365
3384
  },
3366
3385
  empty: q === "" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
3367
3386
  add,
@@ -4284,6 +4303,10 @@ function scalarText(field2, value, labels, stillWaitingFor) {
4284
4303
  if (isId(value) && (field2.type === "list" || field2.type === "relation")) {
4285
4304
  return labels?.(field2, String(value)) ?? stillWaitingFor ?? "Loading\u2026";
4286
4305
  }
4306
+ if (field2.type === "list" && typeof value === "string" && labels) {
4307
+ const words2 = labels(field2, value);
4308
+ if (words2) return words2;
4309
+ }
4287
4310
  const shownAs = shownAsOf(field2);
4288
4311
  if (shownAs) {
4289
4312
  const said = (0, import_field_formats6.formatFieldValue)(value, shownAs);
@@ -4884,6 +4907,13 @@ function GridCell({
4884
4907
  onAskWhoChanged
4885
4908
  }) {
4886
4909
  const ui = useRecordsUi();
4910
+ const saidAt = (0, import_react25.useRef)(0);
4911
+ const sayWhyNot = () => {
4912
+ if (Date.now() - saidAt.current < 4e3) return;
4913
+ saidAt.current = Date.now();
4914
+ const why = fieldIsEditable(field2) ? `${fieldName(field2)} \u2014 ${whyNot ?? "you cannot change this record"}` : `${fieldName(field2)} is worked out by the system, so it cannot be typed in`;
4915
+ ui.notify?.error(why);
4916
+ };
4887
4917
  const open = Boolean(
4888
4918
  editing && editing.editing?.rowId === row.id && editing.editing.key === field2.key
4889
4919
  );
@@ -5002,6 +5032,7 @@ function GridCell({
5002
5032
  event.preventDefault();
5003
5033
  event.stopPropagation();
5004
5034
  if (editable) editing?.begin({ rowId: row.id, key: field2.key });
5035
+ else sayWhyNot();
5005
5036
  },
5006
5037
  onKeyDown: (event) => {
5007
5038
  if (editable && (event.key === "Enter" || event.key === "F2")) {
@@ -5017,7 +5048,9 @@ function GridCell({
5017
5048
  if (editable && isTypedCharacter(event) && typingOpens(field2) !== "none") {
5018
5049
  event.preventDefault();
5019
5050
  editing?.begin({ rowId: row.id, key: field2.key }, event.key);
5051
+ return;
5020
5052
  }
5053
+ if (!editable && (event.key === "Enter" || event.key === "F2" || isTypedCharacter(event))) sayWhyNot();
5021
5054
  },
5022
5055
  tabIndex: editable || onAskWhoChanged ? 0 : void 0,
5023
5056
  children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
@@ -5261,7 +5294,7 @@ function OpenCell({
5261
5294
  // src/Grid.tsx
5262
5295
  var import_react72 = require("react");
5263
5296
  var import_react73 = require("@ai-matrx/records/react");
5264
- var import_records17 = require("@ai-matrx/records");
5297
+ var import_records18 = require("@ai-matrx/records");
5265
5298
  var import_data_table9 = require("@ai-matrx/design-system/data-table");
5266
5299
  var import_core9 = require("@ai-matrx/records/core");
5267
5300
 
@@ -5297,11 +5330,11 @@ function useTableDecorations(tableId, revision) {
5297
5330
  }
5298
5331
 
5299
5332
  // src/emptyState.tsx
5300
- var import_records7 = require("@ai-matrx/records");
5333
+ var import_records8 = require("@ai-matrx/records");
5301
5334
  var import_design_system15 = require("@ai-matrx/design-system");
5302
5335
 
5303
5336
  // src/gridPage.ts
5304
- var import_records6 = require("@ai-matrx/records");
5337
+ var import_records7 = require("@ai-matrx/records");
5305
5338
  var import_data_table5 = require("@ai-matrx/design-system/data-table");
5306
5339
  function sortRefusal(f) {
5307
5340
  if (!computedOnRead(f)) return null;
@@ -5402,7 +5435,7 @@ function storeQuestion(fields, base, columnFilters, now = /* @__PURE__ */ new Da
5402
5435
  const refused = [];
5403
5436
  const flat = {};
5404
5437
  const rules = [];
5405
- if (base && (0, import_records6.isRuleFilter)(base)) rules.push(base);
5438
+ if (base && (0, import_records7.isRuleFilter)(base)) rules.push(base);
5406
5439
  else if (base) Object.assign(flat, base);
5407
5440
  for (const [key, value] of Object.entries(columnFilters)) {
5408
5441
  if (!value) continue;
@@ -5449,7 +5482,7 @@ var import_jsx_runtime19 = require("react/jsx-runtime");
5449
5482
  function questionIsAsked(args) {
5450
5483
  if ((args.search ?? "").trim() !== "") return true;
5451
5484
  if (Object.values(args.columnFilters ?? {}).some((value) => value !== void 0 && value !== null)) return true;
5452
- if (args.filter && (0, import_records7.stableFilterKey)(args.filter) !== "{}") return true;
5485
+ if (args.filter && (0, import_records8.stableFilterKey)(args.filter) !== "{}") return true;
5453
5486
  return Boolean(args.ruled);
5454
5487
  }
5455
5488
  function emptyCauseOf(args) {
@@ -5514,10 +5547,10 @@ var import_design_system22 = require("@ai-matrx/design-system");
5514
5547
  // src/FormulaTextEditor.tsx
5515
5548
  var import_react29 = require("react");
5516
5549
  var import_react30 = require("@ai-matrx/records/react");
5517
- var import_records8 = require("@ai-matrx/records");
5550
+ var import_records9 = require("@ai-matrx/records");
5518
5551
  var import_design_system16 = require("@ai-matrx/design-system");
5519
5552
  var import_jsx_runtime20 = require("react/jsx-runtime");
5520
- var FORMULA_FUNCTIONS = import_records8.RULE_NODE_KINDS.map((row) => row.node).filter((node) => node.startsWith("fx.")).map((node) => node.slice(3).toUpperCase()).filter((name) => !["ADD", "SUB", "MUL", "DIV", "EQ", "NEQ", "GT", "GTE", "LT", "LTE", "NEG", "FIELD", "CONST"].includes(name)).sort();
5553
+ var FORMULA_FUNCTIONS = import_records9.RULE_NODE_KINDS.map((row) => row.node).filter((node) => node.startsWith("fx.")).map((node) => node.slice(3).toUpperCase()).filter((name) => !["ADD", "SUB", "MUL", "DIV", "EQ", "NEQ", "GT", "GTE", "LT", "LTE", "NEG", "FIELD", "CONST"].includes(name)).sort();
5521
5554
  var RESULT_WORD = {
5522
5555
  number: "a number",
5523
5556
  text: "text",
@@ -5739,7 +5772,7 @@ function EntityReferenceKindPicker({ value, onChange, locked = false, className
5739
5772
 
5740
5773
  // src/FieldRetype.tsx
5741
5774
  var import_react33 = require("react");
5742
- var import_records9 = require("@ai-matrx/records");
5775
+ var import_records10 = require("@ai-matrx/records");
5743
5776
  var import_react34 = require("@ai-matrx/records/react");
5744
5777
  var import_design_system18 = require("@ai-matrx/design-system");
5745
5778
  var import_jsx_runtime22 = require("react/jsx-runtime");
@@ -5779,7 +5812,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
5779
5812
  return;
5780
5813
  }
5781
5814
  const groups = answer.data.map((row) => ({ value: row.groups[field2.key] ?? null, count: row.row_count }));
5782
- setPreview((0, import_records9.previewRetype)({ type: to.behaviour }, groups, answer.data.length >= PREVIEW_GROUPS));
5815
+ setPreview((0, import_records10.previewRetype)({ type: to.behaviour }, groups, answer.data.length >= PREVIEW_GROUPS));
5783
5816
  });
5784
5817
  return () => {
5785
5818
  cancelled = true;
@@ -5970,14 +6003,14 @@ function ChoiceColorsEditor({
5970
6003
 
5971
6004
  // src/ChoiceListEditor.tsx
5972
6005
  var import_react37 = require("react");
5973
- var import_records10 = require("@ai-matrx/records");
6006
+ var import_records11 = require("@ai-matrx/records");
5974
6007
  var import_react38 = require("@ai-matrx/records/react");
5975
6008
  var import_design_system20 = require("@ai-matrx/design-system");
5976
6009
  var import_jsx_runtime24 = require("react/jsx-runtime");
5977
6010
  var rowSeed = 0;
5978
6011
  var nextRow = () => `new-${rowSeed += 1}`;
5979
6012
  function choiceRowsFrom(options) {
5980
- return inTheStoresOrder([...options]).map((option) => ({ id: option.id, words: (0, import_records10.optionLabel)(option), row: option.id }));
6013
+ return inTheStoresOrder([...options]).map((option) => ({ id: option.id, words: (0, import_records11.optionLabel)(option), row: option.id }));
5981
6014
  }
5982
6015
  function choiceListPatch(start, rows) {
5983
6016
  const kept = rows.filter((r) => r.words.trim() !== "");
@@ -6112,11 +6145,11 @@ function ChoiceListEditor({
6112
6145
  "div",
6113
6146
  {
6114
6147
  role: "group",
6115
- "aria-label": (0, import_records10.recordsUseSentence)(heldBy(asking), asking.words.trim()),
6148
+ "aria-label": (0, import_records11.recordsUseSentence)(heldBy(asking), asking.words.trim()),
6116
6149
  "data-records-choice-removal-ask": "",
6117
6150
  className: "flex flex-col gap-1 rounded border bg-muted/40 p-2",
6118
6151
  children: [
6119
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs", children: (0, import_records10.recordsUseSentence)(heldBy(asking), asking.words.trim()) }),
6152
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs", children: (0, import_records11.recordsUseSentence)(heldBy(asking), asking.words.trim()) }),
6120
6153
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
6121
6154
  targets.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
6122
6155
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_design_system20.Button, { type: "button", size: "sm", className: "h-7 px-2 text-xs", disabled: moveTo === "", onClick: () => answer({ then: "move", to: moveTo }), children: "Move them to" }),
@@ -6135,7 +6168,7 @@ function ChoiceListEditor({
6135
6168
  ) : null,
6136
6169
  Object.entries(rehome).map(
6137
6170
  ([id, spec]) => removed[id] ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-between gap-2 text-[11px] text-muted-foreground", "data-records-choice-rehome": "", children: [
6138
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: (0, import_records10.rehomeSentence)(usage?.[id]?.records ?? 0, removed[id].row.words.trim(), spec, spec.then === "move" ? wordsOf(spec.to) : void 0) }),
6171
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: (0, import_records11.rehomeSentence)(usage?.[id]?.records ?? 0, removed[id].row.words.trim(), spec, spec.then === "move" ? wordsOf(spec.to) : void 0) }),
6139
6172
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_design_system20.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-1.5 text-[11px]", onClick: () => putBack(id), children: "Put it back" })
6140
6173
  ] }, id) : null
6141
6174
  ),
@@ -6799,11 +6832,11 @@ function nextFieldSort(fields) {
6799
6832
  }
6800
6833
 
6801
6834
  // src/FieldEditor.tsx
6802
- var import_records11 = require("@ai-matrx/records");
6835
+ var import_records12 = require("@ai-matrx/records");
6803
6836
  var import_jsx_runtime26 = require("react/jsx-runtime");
6804
6837
  var RULE_KINDS = FIELD_RULE_KIND_VALUES.map((kind) => ({ kind, label: FIELD_RULE_KIND_LABEL[kind] }));
6805
- var SENSITIVITIES = import_records11.FIELD_SENSITIVITIES.map((value) => ({ value, label: FIELD_SENSITIVITY_LABEL[value] }));
6806
- var AGENT_VISIBILITY = import_records11.CONTEXT_POLICIES.map((value) => ({ value, label: CONTEXT_POLICY_LABEL[value] }));
6838
+ var SENSITIVITIES = import_records12.FIELD_SENSITIVITIES.map((value) => ({ value, label: FIELD_SENSITIVITY_LABEL[value] }));
6839
+ var AGENT_VISIBILITY = import_records12.CONTEXT_POLICIES.map((value) => ({ value, label: CONTEXT_POLICY_LABEL[value] }));
6807
6840
  var ROLLUP_OPERATIONS = ROLLUP_AGG_VALUES.map((value) => ({
6808
6841
  value,
6809
6842
  label: ROLLUP_AGG_LABEL[value]
@@ -7628,7 +7661,7 @@ function entityReferenceKindsOf(field2) {
7628
7661
 
7629
7662
  // src/gridColors.tsx
7630
7663
  var import_react41 = require("react");
7631
- var import_records12 = require("@ai-matrx/records");
7664
+ var import_records13 = require("@ai-matrx/records");
7632
7665
  var import_react42 = require("@ai-matrx/records/react");
7633
7666
  var import_design_system23 = require("@ai-matrx/design-system");
7634
7667
  var import_data_table7 = require("@ai-matrx/design-system/data-table");
@@ -7687,7 +7720,9 @@ function useChoiceOptions(fields, keys) {
7687
7720
  return index;
7688
7721
  }
7689
7722
  function lookOf(option) {
7690
- return { id: String(option.id), key: (0, import_records12.optionKey)(option), label: (0, import_records12.optionLabel)(option) };
7723
+ const raw = option.data?.["color"];
7724
+ const color = typeof raw === "string" && import_data_table7.STYLE_COLORS.includes(raw) ? raw : void 0;
7725
+ return { id: String(option.id), key: (0, import_records13.optionKey)(option), label: (0, import_records13.optionLabel)(option), ...color ? { color } : {} };
7691
7726
  }
7692
7727
  function paintByOption(style, fields, index, lookup) {
7693
7728
  if (index.size === 0) return { style, documentOf: (doc) => doc, choiceColorFor: lookup };
@@ -7711,10 +7746,13 @@ function paintByOption(style, fields, index, lookup) {
7711
7746
  }
7712
7747
  return out ?? doc;
7713
7748
  },
7749
+ // A CHOICE PAINTS IN ITS OWN COLOUR (DATA-V2-BASICS-2 C1b): an option kept in its own Table
7750
+ // carries the colour its owner gave it; coloured by Status, a "Verified" (green) row was tinted
7751
+ // pink by the hash. The option's colour first, then the column's stored colours, then the hash.
7714
7752
  choiceColorFor: (fieldKey, value) => {
7715
7753
  const option = optionFor(index.get(fieldKey), value);
7716
7754
  if (!option) return lookup(fieldKey, value);
7717
- return lookup(fieldKey, option.label) ?? lookup(fieldKey, option.key);
7755
+ return option.color ?? lookup(fieldKey, option.label) ?? lookup(fieldKey, option.key);
7718
7756
  }
7719
7757
  };
7720
7758
  }
@@ -8150,7 +8188,7 @@ function RowLabelPicker({
8150
8188
  // src/gridSummaries.tsx
8151
8189
  var import_react45 = require("react");
8152
8190
  var import_react46 = require("@ai-matrx/records/react");
8153
- var import_records13 = require("@ai-matrx/records");
8191
+ var import_records14 = require("@ai-matrx/records");
8154
8192
  var import_design_system25 = require("@ai-matrx/design-system");
8155
8193
  var import_jsx_runtime29 = require("react/jsx-runtime");
8156
8194
  var SUMMARY_ROW_ID = "__records_ui_summary__";
@@ -8195,7 +8233,7 @@ function useColumnSummaries(args) {
8195
8233
  const out = {};
8196
8234
  for (const [key, op2] of entries) {
8197
8235
  const measure = op2 === "count" ? { op: "count" } : { op: op2, key };
8198
- out[key] = row?.measures?.[(0, import_records13.measureKey)(measure)] ?? null;
8236
+ out[key] = row?.measures?.[(0, import_records14.measureKey)(measure)] ?? null;
8199
8237
  }
8200
8238
  setValues(out);
8201
8239
  setRowCount(row?.row_count ?? 0);
@@ -8349,7 +8387,7 @@ function SummarySheetControls({
8349
8387
 
8350
8388
  // src/pasteValues.ts
8351
8389
  var import_core5 = require("@ai-matrx/records/core");
8352
- var import_records14 = require("@ai-matrx/records");
8390
+ var import_records15 = require("@ai-matrx/records");
8353
8391
  function wordForStoredChoice(options, value) {
8354
8392
  if (options === void 0 || typeof value !== "string" || value === "") return null;
8355
8393
  for (const label of options.labels) {
@@ -8362,7 +8400,7 @@ function choiceOptionsOf(options) {
8362
8400
  const labels = [];
8363
8401
  for (const option of options) {
8364
8402
  const id = option.id;
8365
- const key = (0, import_records14.optionKey)(option);
8403
+ const key = (0, import_records15.optionKey)(option);
8366
8404
  const label = recordName(option.data, null, "");
8367
8405
  if (label) {
8368
8406
  labels.push(label);
@@ -8374,7 +8412,7 @@ function choiceOptionsOf(options) {
8374
8412
  return { byWord, labels };
8375
8413
  }
8376
8414
  function valueFromPastedText(field2, raw, options) {
8377
- return (0, import_records14.coerceTypedAnswer)(field2, raw, {
8415
+ return (0, import_records15.coerceTypedAnswer)(field2, raw, {
8378
8416
  label: fieldName(field2),
8379
8417
  ...options ? { options } : {}
8380
8418
  });
@@ -9949,7 +9987,7 @@ function confirmLabel(plan, noun, nounPlural) {
9949
9987
  // src/gridActions.tsx
9950
9988
  var import_react54 = require("react");
9951
9989
  var import_react55 = require("@ai-matrx/records/react");
9952
- var import_records15 = require("@ai-matrx/records");
9990
+ var import_records16 = require("@ai-matrx/records");
9953
9991
  var import_design_system31 = require("@ai-matrx/design-system");
9954
9992
  var import_jsx_runtime35 = require("react/jsx-runtime");
9955
9993
  var actionListeners = /* @__PURE__ */ new Map();
@@ -10042,7 +10080,7 @@ function useActionRunner(args) {
10042
10080
  const answered = await client.actionRun({ action_id: action.id, record_ids: ids });
10043
10081
  setBusy(null);
10044
10082
  if (!answered.ok) {
10045
- const refusals = (0, import_records15.actionRefusals)(answered.error);
10083
+ const refusals = (0, import_records16.actionRefusals)(answered.error);
10046
10084
  setOutcome({
10047
10085
  kind: "refused",
10048
10086
  action,
@@ -11959,7 +11997,7 @@ function BulkActions({
11959
11997
  // src/handOrder.tsx
11960
11998
  var import_react70 = require("react");
11961
11999
  var import_react71 = require("@ai-matrx/records/react");
11962
- var import_records16 = require("@ai-matrx/records");
12000
+ var import_records17 = require("@ai-matrx/records");
11963
12001
  var import_design_system39 = require("@ai-matrx/design-system");
11964
12002
 
11965
12003
  // src/viewKeys.ts
@@ -12387,7 +12425,7 @@ function useHandOrderRows(args) {
12387
12425
  const client = (0, import_react71.useRecordsClient)();
12388
12426
  const { viewId, active, page, pageSize } = args;
12389
12427
  const filter = args.filter && Object.keys(args.filter).length > 0 ? args.filter : null;
12390
- const filterKey = filter ? (0, import_records16.stableFilterKey)(filter) : "";
12428
+ const filterKey = filter ? (0, import_records17.stableFilterKey)(filter) : "";
12391
12429
  const filterNow = (0, import_react70.useRef)(filter);
12392
12430
  filterNow.current = filter;
12393
12431
  const [answer, setAnswer] = (0, import_react70.useState)(null);
@@ -13094,7 +13132,7 @@ function Grid({
13094
13132
  tableName: table.data ? tableName(table.data) : "",
13095
13133
  fields: fields.data ?? [],
13096
13134
  document: row.document ?? {},
13097
- level: (0, import_records17.asPermissionLevel)(row.level)
13135
+ level: (0, import_records18.asPermissionLevel)(row.level)
13098
13136
  }),
13099
13137
  [host, tableId, table.data, fields.data]
13100
13138
  );
@@ -16976,14 +17014,14 @@ var LOOK_WORDS = {
16976
17014
  // src/ViewSwitcher.tsx
16977
17015
  var import_react98 = require("react");
16978
17016
  var import_react99 = require("@ai-matrx/records/react");
16979
- var import_records19 = require("@ai-matrx/records");
17017
+ var import_records20 = require("@ai-matrx/records");
16980
17018
  var import_design_system52 = require("@ai-matrx/design-system");
16981
17019
  var import_data_table11 = require("@ai-matrx/design-system/data-table");
16982
17020
 
16983
17021
  // src/Pipeline.tsx
16984
17022
  var import_react96 = require("react");
16985
17023
  var import_react97 = require("@ai-matrx/records/react");
16986
- var import_records18 = require("@ai-matrx/records");
17024
+ var import_records19 = require("@ai-matrx/records");
16987
17025
  var import_design_system51 = require("@ai-matrx/design-system");
16988
17026
  var import_data_table10 = require("@ai-matrx/design-system/data-table");
16989
17027
 
@@ -17090,7 +17128,7 @@ function PipelineBoard({
17090
17128
  alive.current = false;
17091
17129
  };
17092
17130
  }, []);
17093
- const filterKey = (0, import_records18.stableFilterKey)(filter);
17131
+ const filterKey = (0, import_records19.stableFilterKey)(filter);
17094
17132
  const reload = (0, import_react96.useCallback)(async () => {
17095
17133
  setLoading(true);
17096
17134
  const [read, board, held] = await Promise.all([
@@ -17737,8 +17775,8 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
17737
17775
  cancelled = true;
17738
17776
  };
17739
17777
  }, [client, ruleId, pageSize]);
17740
- const asked2 = (0, import_records19.stableFilterKey)(filter ?? null);
17741
- const fromView = asked2 !== "{}" && (asked2 === (0, import_records19.stableFilterKey)(view.where ?? null) || asked2 === (0, import_records19.stableFilterKey)(view.filters ?? null));
17778
+ const asked2 = (0, import_records20.stableFilterKey)(filter ?? null);
17779
+ const fromView = asked2 !== "{}" && (asked2 === (0, import_records20.stableFilterKey)(view.where ?? null) || asked2 === (0, import_records20.stableFilterKey)(view.filters ?? null));
17742
17780
  const tableRows = (0, import_react98.useMemo)(() => table.data?.rows ?? [], [table.data]);
17743
17781
  const manual = view.order === "manual" && Boolean(viewId) && !ruleId;
17744
17782
  const hand = useHandOrderRows({
@@ -18331,7 +18369,7 @@ function Card2({
18331
18369
 
18332
18370
  // src/ArchivedView.tsx
18333
18371
  var import_react100 = require("react");
18334
- var import_records20 = require("@ai-matrx/records");
18372
+ var import_records21 = require("@ai-matrx/records");
18335
18373
  var import_react101 = require("@ai-matrx/records/react");
18336
18374
  var import_design_system53 = require("@ai-matrx/design-system");
18337
18375
  var import_jsx_runtime61 = require("react/jsx-runtime");
@@ -18341,7 +18379,7 @@ function mayNotRestoreLine(why) {
18341
18379
  return said === "" ? "Bringing a record back needs permission to edit this table. Ask somebody who has it." : said;
18342
18380
  }
18343
18381
  function archivedRowLine(row, titleKey) {
18344
- return `${recordName(row.document, titleKey)} \u2014 ${(0, import_records20.archivedByLine)(row)}`;
18382
+ return `${recordName(row.document, titleKey)} \u2014 ${(0, import_records21.archivedByLine)(row)}`;
18345
18383
  }
18346
18384
  function ArchivedView({
18347
18385
  tableId,
@@ -18355,7 +18393,7 @@ function ArchivedView({
18355
18393
  const table = (0, import_react101.useTable)(tableId);
18356
18394
  const rights = useTableRights(table.data);
18357
18395
  const fields = (0, import_react101.useFields)(tableId);
18358
- const [lane, setLane] = (0, import_react100.useState)(laneFromHost ?? import_records20.DEFAULT_ARCHIVE_LANE);
18396
+ const [lane, setLane] = (0, import_react100.useState)(laneFromHost ?? import_records21.DEFAULT_ARCHIVE_LANE);
18359
18397
  const [rows, setRows] = (0, import_react100.useState)([]);
18360
18398
  const [loading, setLoading] = (0, import_react100.useState)(true);
18361
18399
  const [error, setError] = (0, import_react100.useState)(null);
@@ -18402,15 +18440,15 @@ function ArchivedView({
18402
18440
  return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: (0, import_design_system53.cn)("flex min-h-0 flex-col gap-2", className), "data-testid": "archived-view", children: [
18403
18441
  /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
18404
18442
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-sm font-medium", children: "Archived" }),
18405
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "ml-auto flex items-center gap-0.5", role: "group", "aria-label": "Archived by", children: import_records20.ARCHIVE_LANES.map((option) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
18443
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "ml-auto flex items-center gap-0.5", role: "group", "aria-label": "Archived by", children: import_records21.ARCHIVE_LANES.map((option) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
18406
18444
  import_design_system53.Button,
18407
18445
  {
18408
18446
  size: "sm",
18409
18447
  variant: option === lane ? "secondary" : "ghost",
18410
18448
  "aria-pressed": option === lane,
18411
- title: import_records20.ARCHIVE_LANE_MEANS[option],
18449
+ title: import_records21.ARCHIVE_LANE_MEANS[option],
18412
18450
  onClick: () => pick(option),
18413
- children: import_records20.ARCHIVE_LANE_LABEL[option]
18451
+ children: import_records21.ARCHIVE_LANE_LABEL[option]
18414
18452
  },
18415
18453
  option
18416
18454
  )) })
@@ -18426,7 +18464,7 @@ function ArchivedView({
18426
18464
  ),
18427
18465
  error ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(RefusalNotice, { error }) : null,
18428
18466
  loading && !error ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_design_system53.Skeleton, { className: "h-24 w-full" }) : null,
18429
- !loading && !error && rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { "data-testid": "archived-empty", className: "rounded-md border border-dashed px-3 py-6 text-xs text-muted-foreground", children: (0, import_records20.emptyArchiveLine)(lane) }) : null,
18467
+ !loading && !error && rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { "data-testid": "archived-empty", className: "rounded-md border border-dashed px-3 py-6 text-xs text-muted-foreground", children: (0, import_records21.emptyArchiveLine)(lane) }) : null,
18430
18468
  !loading && !error && rows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("ul", { className: "flex flex-col gap-1", "data-testid": "archived-rows", children: rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
18431
18469
  "li",
18432
18470
  {
@@ -18436,7 +18474,7 @@ function ArchivedView({
18436
18474
  children: [
18437
18475
  /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
18438
18476
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "truncate text-sm", children: recordName(row.document, titleKey) }),
18439
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "truncate text-xs text-muted-foreground", "data-testid": "archived-who", children: (0, import_records20.archivedByLine)(row) }),
18477
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "truncate text-xs text-muted-foreground", "data-testid": "archived-who", children: (0, import_records21.archivedByLine)(row) }),
18440
18478
  refusal2 && refusal2.recordId === row.id ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(RefusalNotice, { error: refusal2.error, className: "mt-2" }) : null
18441
18479
  ] }),
18442
18480
  mayRestore ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
@@ -18459,7 +18497,7 @@ function ArchivedView({
18459
18497
 
18460
18498
  // src/ArchivedDisclosure.tsx
18461
18499
  var import_react102 = require("react");
18462
- var import_records21 = require("@ai-matrx/records");
18500
+ var import_records22 = require("@ai-matrx/records");
18463
18501
  var import_react103 = require("@ai-matrx/records/react");
18464
18502
  var import_design_system54 = require("@ai-matrx/design-system");
18465
18503
  var import_jsx_runtime62 = require("react/jsx-runtime");
@@ -18559,10 +18597,10 @@ function ArchivedPortals({
18559
18597
  error ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(RefusalNotice, { error }) : null,
18560
18598
  rows === null && !error ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_design_system54.Skeleton, { className: "h-16 w-full" }) : null,
18561
18599
  said ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "rounded-md border border-border px-3 py-2 text-xs", "data-testid": "archived-portal-said", children: said }) : null,
18562
- rows !== null && !error && rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { "data-testid": "archived-portals-empty", className: "text-xs text-muted-foreground", children: (0, import_records21.emptyPortalArchiveLine)() }) : null,
18600
+ rows !== null && !error && rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { "data-testid": "archived-portals-empty", className: "text-xs text-muted-foreground", children: (0, import_records22.emptyPortalArchiveLine)() }) : null,
18563
18601
  rows !== null && rows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("ul", { className: "flex flex-col gap-1.5", "data-testid": "archived-portals", children: rows.map((portal) => {
18564
18602
  const asking = confirming === portal.portal_id;
18565
- const matches2 = (0, import_records21.portalTitleTypedBack)(typed, portal.title);
18603
+ const matches2 = (0, import_records22.portalTitleTypedBack)(typed, portal.title);
18566
18604
  return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
18567
18605
  "li",
18568
18606
  {
@@ -18601,7 +18639,7 @@ function ArchivedPortals({
18601
18639
  ] }),
18602
18640
  asking ? /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
18603
18641
  /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
18604
- (0, import_records21.portalConfirmLine)(portal.title),
18642
+ (0, import_records22.portalConfirmLine)(portal.title),
18605
18643
  " Restoring it puts it back exactly as it was: everyone who was invited can sign in again, and it shows the same Tables."
18606
18644
  ] }),
18607
18645
  /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5", children: [
@@ -21559,7 +21597,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
21559
21597
  // src/PortalsPanel.tsx
21560
21598
  var import_react124 = require("react");
21561
21599
  var import_react125 = require("@ai-matrx/records/react");
21562
- var import_records22 = require("@ai-matrx/records");
21600
+ var import_records23 = require("@ai-matrx/records");
21563
21601
  var import_design_system65 = require("@ai-matrx/design-system");
21564
21602
 
21565
21603
  // src/BuildOrAsk.tsx
@@ -22023,7 +22061,7 @@ function PortalsPanel({ tableId, activePortalId, className }) {
22023
22061
  ] }) : null,
22024
22062
  activePortalId && !shown3.some((p) => p.portal_id === activePortalId) ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "rounded-md border border-amber-600/40 bg-amber-500/5 px-3 py-2 text-xs leading-relaxed text-amber-700 dark:border-amber-400/40 dark:text-amber-300", children: PORTAL_NOT_HERE_LINE }) : null,
22025
22063
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("ul", { className: "flex flex-col gap-2", children: shown3.map((portal) => {
22026
- const url = `${origin}${(0, import_records22.portalPath)(portal.slug)}`;
22064
+ const url = `${origin}${(0, import_records23.portalPath)(portal.slug)}`;
22027
22065
  const open = openId === portal.portal_id;
22028
22066
  const linked = portal.portal_id === activePortalId;
22029
22067
  return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
@@ -22138,8 +22176,8 @@ function ArchivePortalControl({
22138
22176
  }
22139
22177
  ),
22140
22178
  asking ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "mt-1.5 flex w-full flex-col gap-1.5 rounded-md border border-dashed border-border p-2.5", children: [
22141
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "text-xs text-muted-foreground", "data-testid": "portal-archive-consequence", children: (0, import_records22.portalArchiveConsequence)(portal.title, portal.signed_in, portal.invited) }),
22142
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "text-xs text-muted-foreground", children: (0, import_records22.portalConfirmLine)(portal.title) }),
22179
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "text-xs text-muted-foreground", "data-testid": "portal-archive-consequence", children: (0, import_records23.portalArchiveConsequence)(portal.title, portal.signed_in, portal.invited) }),
22180
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "text-xs text-muted-foreground", children: (0, import_records23.portalConfirmLine)(portal.title) }),
22143
22181
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5", children: [
22144
22182
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
22145
22183
  import_design_system65.BasicInput,
@@ -22157,7 +22195,7 @@ function ArchivePortalControl({
22157
22195
  size: "sm",
22158
22196
  variant: "destructive",
22159
22197
  "data-testid": "portal-archive-do",
22160
- disabled: busy || !(0, import_records22.portalTitleTypedBack)(typed, portal.title),
22198
+ disabled: busy || !(0, import_records23.portalTitleTypedBack)(typed, portal.title),
22161
22199
  onClick: () => void go(),
22162
22200
  children: busy ? "Archiving\u2026" : "Archive it"
22163
22201
  }
@@ -23316,7 +23354,7 @@ function usePublishGate() {
23316
23354
  }
23317
23355
 
23318
23356
  // src/FormBuilder.tsx
23319
- var import_records23 = require("@ai-matrx/records");
23357
+ var import_records24 = require("@ai-matrx/records");
23320
23358
  var import_design_system71 = require("@ai-matrx/design-system");
23321
23359
 
23322
23360
  // src/FormRunner.tsx
@@ -24192,7 +24230,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
24192
24230
  /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
24193
24231
  PublishRow,
24194
24232
  {
24195
- url: `${publicOrigin}${(0, import_records23.publicFormPath)(draft.id)}`,
24233
+ url: `${publicOrigin}${(0, import_records24.publicFormPath)(draft.id)}`,
24196
24234
  state: draft.state,
24197
24235
  mayPublish: rights.structure && !publishGate.blocked,
24198
24236
  why: publishGate.why ?? rights.why("structure"),
@@ -25210,7 +25248,7 @@ function SignBlock({ tableId, recordId, render, className }) {
25210
25248
  // src/ChartBlock.tsx
25211
25249
  var import_react148 = require("react");
25212
25250
  var import_recharts = require("recharts");
25213
- var import_records24 = require("@ai-matrx/records");
25251
+ var import_records25 = require("@ai-matrx/records");
25214
25252
  var import_core15 = require("@ai-matrx/records/core");
25215
25253
  var import_design_system76 = require("@ai-matrx/design-system");
25216
25254
  var import_jsx_runtime84 = require("react/jsx-runtime");
@@ -25281,7 +25319,7 @@ function ChartBlock({ block, subject, className }) {
25281
25319
  const kind = block.kind;
25282
25320
  const tableId = block.table_id ?? subject;
25283
25321
  const measures = block.measures && block.measures.length > 0 ? block.measures : [{ op: "count" }];
25284
- const primary = (0, import_records24.measureKey)(measures[0]);
25322
+ const primary = (0, import_records25.measureKey)(measures[0]);
25285
25323
  const windows = kind === "stuck" ? null : block.compare ?? null;
25286
25324
  const compared = !!windows;
25287
25325
  const grain = block.bucket?.by ?? null;
@@ -26213,7 +26251,7 @@ function TargetControl({
26213
26251
  // src/FormsPanel.tsx
26214
26252
  var import_react151 = require("react");
26215
26253
  var import_react152 = require("@ai-matrx/records/react");
26216
- var import_records25 = require("@ai-matrx/records");
26254
+ var import_records26 = require("@ai-matrx/records");
26217
26255
  var import_design_system78 = require("@ai-matrx/design-system");
26218
26256
  var import_jsx_runtime86 = require("react/jsx-runtime");
26219
26257
  var FORM_NOT_HERE_LINE = "The link named a form this table does not have \u2014 it may have been removed, or it belongs to another table. The forms this table does have are listed here.";
@@ -26317,7 +26355,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
26317
26355
  }
26318
26356
  ) : null,
26319
26357
  /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("ul", { className: "flex flex-col gap-2", children: forms.map((form) => {
26320
- const url = `${origin}${(0, import_records25.publicFormPath)(form.form_id)}`;
26358
+ const url = `${origin}${(0, import_records26.publicFormPath)(form.form_id)}`;
26321
26359
  return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
26322
26360
  "li",
26323
26361
  {
@@ -26382,7 +26420,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
26382
26420
  // src/BookingBuilder.tsx
26383
26421
  var import_react153 = require("react");
26384
26422
  var import_react154 = require("@ai-matrx/records/react");
26385
- var import_records26 = require("@ai-matrx/records");
26423
+ var import_records27 = require("@ai-matrx/records");
26386
26424
  var import_design_system79 = require("@ai-matrx/design-system");
26387
26425
  var import_jsx_runtime87 = require("react/jsx-runtime");
26388
26426
  var STORE_ANSWERS_THESE = ["slot", "status", "booked_with"];
@@ -26526,7 +26564,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
26526
26564
  if (!rights.structure) {
26527
26565
  return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { className: (0, import_design_system79.cn)("text-xs text-muted-foreground", className), children: rights.why("structure") ?? "Making a booking page needs the admin level on this table, because it lets people with no account take time in your calendar." });
26528
26566
  }
26529
- const url = formId ? `${publicOrigin}${(0, import_records26.bookingPath)(formId)}` : null;
26567
+ const url = formId ? `${publicOrigin}${(0, import_records27.bookingPath)(formId)}` : null;
26530
26568
  const shown3 = offer ?? null;
26531
26569
  return (
26532
26570
  // THE RAIL IS 384px WIDE AND THE VIEWPORT IS NOT (walk 1, 2026-09-21):
@@ -26728,7 +26766,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
26728
26766
  // src/BookingSlots.tsx
26729
26767
  var import_react155 = require("react");
26730
26768
  var import_react156 = require("@ai-matrx/records/react");
26731
- var import_records27 = require("@ai-matrx/records");
26769
+ var import_records28 = require("@ai-matrx/records");
26732
26770
  var import_design_system80 = require("@ai-matrx/design-system");
26733
26771
  var import_jsx_runtime88 = require("react/jsx-runtime");
26734
26772
  var BOOKING_NOT_HERE_LINE = "The link named a booking page this table does not have \u2014 it may have been closed for good, or it writes into another table. The booking pages this table does have are listed here.";
@@ -26845,7 +26883,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
26845
26883
  " Open the table the appointments should land in to make one."
26846
26884
  ] }) : null,
26847
26885
  /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("ul", { className: "flex flex-col gap-2", children: pages.map((page) => {
26848
- const url = `${origin}${(0, import_records27.bookingPath)(page.form_id)}`;
26886
+ const url = `${origin}${(0, import_records28.bookingPath)(page.form_id)}`;
26849
26887
  const mayOpen = levels.data?.[page.table_id] === "admin";
26850
26888
  const open = page.published_at !== null && page.closed_at === null;
26851
26889
  return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
@@ -26947,7 +26985,7 @@ var import_design_system82 = require("@ai-matrx/design-system");
26947
26985
 
26948
26986
  // src/CaptureRun.tsx
26949
26987
  var import_react157 = require("react");
26950
- var import_records28 = require("@ai-matrx/records");
26988
+ var import_records29 = require("@ai-matrx/records");
26951
26989
  var import_react158 = require("@ai-matrx/records/react");
26952
26990
  var import_design_system81 = require("@ai-matrx/design-system");
26953
26991
  var import_jsx_runtime89 = require("react/jsx-runtime");
@@ -27002,7 +27040,7 @@ function CaptureRun({ sheetId, face: given, className }) {
27002
27040
  const [sending, setSending] = (0, import_react157.useState)(false);
27003
27041
  const queueRef = (0, import_react157.useRef)(null);
27004
27042
  (0, import_react157.useEffect)(() => {
27005
- const q2 = (0, import_records28.openCaptureQueue)({
27043
+ const q2 = (0, import_records29.openCaptureQueue)({
27006
27044
  onChange: (c, all) => {
27007
27045
  setCounts(c);
27008
27046
  setItems(all);
@@ -27269,7 +27307,7 @@ function CaptureRun({ sheetId, face: given, className }) {
27269
27307
  value: String(answers[q.field] ?? ""),
27270
27308
  onChange: (e) => {
27271
27309
  const raw = e.target.value;
27272
- const answered2 = field2 ? (0, import_records28.coerceTypedAnswer)(field2, raw, { label: q.ask ?? (0, import_records28.coercionLabel)(field2) }) : { value: raw };
27310
+ const answered2 = field2 ? (0, import_records29.coerceTypedAnswer)(field2, raw, { label: q.ask ?? (0, import_records29.coercionLabel)(field2) }) : { value: raw };
27273
27311
  setAnswers((held) => ({
27274
27312
  ...held,
27275
27313
  [q.field]: raw === "" ? "" : "refusal" in answered2 ? raw : answered2.value
@@ -27943,7 +27981,7 @@ function recordsDataSource(client, fallbackSchema = "custom") {
27943
27981
  var import_react174 = require("react");
27944
27982
  var import_react175 = require("@ai-matrx/records/react");
27945
27983
  var import_core17 = require("@ai-matrx/records/core");
27946
- var import_records30 = require("@ai-matrx/records");
27984
+ var import_records31 = require("@ai-matrx/records");
27947
27985
  var import_design_system88 = require("@ai-matrx/design-system");
27948
27986
 
27949
27987
  // src/ExampleTables.tsx
@@ -28041,7 +28079,7 @@ var import_core16 = require("@ai-matrx/records/core");
28041
28079
 
28042
28080
  // src/WhereItLives.tsx
28043
28081
  var import_react172 = require("react");
28044
- var import_records29 = require("@ai-matrx/records");
28082
+ var import_records30 = require("@ai-matrx/records");
28045
28083
  var import_react173 = require("@ai-matrx/records/react");
28046
28084
  var import_design_system87 = require("@ai-matrx/design-system");
28047
28085
  var import_jsx_runtime96 = require("react/jsx-runtime");
@@ -28167,7 +28205,7 @@ function WhereItLives({ tableId, knownOrganizationName, onMoved, variant = "head
28167
28205
  /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(SharedNameAddress, { to: choosing, all: answer.home.destinations }),
28168
28206
  "?"
28169
28207
  ] }),
28170
- /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("p", { className: "text-muted-foreground", children: (0, import_records29.moveConsequence)(answer.home, choosing) }),
28208
+ /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("p", { className: "text-muted-foreground", children: (0, import_records30.moveConsequence)(answer.home, choosing) }),
28171
28209
  said?.tone === "refused" ? /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
28172
28210
  import_design_system87.ErrorBox,
28173
28211
  {
@@ -28315,7 +28353,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
28315
28353
  alive = false;
28316
28354
  };
28317
28355
  }, [client]);
28318
- const listed = facts.phase === "read" ? (0, import_records30.withTablePlacement)(
28356
+ const listed = facts.phase === "read" ? (0, import_records31.withTablePlacement)(
28319
28357
  (0, import_core17.withTableFacts)(tables.data ?? [], facts.rows, me),
28320
28358
  facts.rows
28321
28359
  ) : tables.data ?? [];
@@ -28529,7 +28567,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
28529
28567
 
28530
28568
  // src/TablePage.tsx
28531
28569
  var import_react179 = require("react");
28532
- var import_records31 = require("@ai-matrx/records");
28570
+ var import_records32 = require("@ai-matrx/records");
28533
28571
  var import_react180 = require("@ai-matrx/records/react");
28534
28572
  var import_design_system90 = require("@ai-matrx/design-system");
28535
28573
 
@@ -28904,7 +28942,7 @@ function TableNotHere({
28904
28942
  return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: (0, import_design_system90.cn)("flex flex-col items-start gap-2 rounded-md border border-dashed p-6", className), children: [
28905
28943
  /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "text-sm font-medium", children: "This table is archived" }),
28906
28944
  /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "max-w-prose text-xs text-muted-foreground", children: TABLE_IS_ARCHIVED }),
28907
- /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "text-xs text-muted-foreground", children: (0, import_records31.archivedByLine)(row) }),
28945
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "text-xs text-muted-foreground", children: (0, import_records32.archivedByLine)(row) }),
28908
28946
  refusal2 ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(RefusalNotice, { error: refusal2 }) : null,
28909
28947
  /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "flex gap-2", children: [
28910
28948
  /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(