@ai-matrx/records-ui 0.102.11 → 0.102.15

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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.102.15
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/records-ui/v0.102.14..npm/records-ui/v0.102.15 -- apps/shared/records-ui`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.102.14
10
+
11
+ - Republish of 0.102.13: its publish run built a commit from before the empty-screen test was updated to the value chip's true shape (label + count sibling), so the release gate failed. No code change.
12
+
13
+ **Consumer action:** none.
14
+
15
+ ## 0.102.13
16
+
17
+ - Copying a record reference handles a refused copy in the kit copy's `false` branch (it was a `throw` into a catch).
18
+
19
+ **Consumer action:** none.
20
+
21
+ ## 0.102.12
22
+
23
+ - `refusedRowsCsv` writes through THE one writer, `@ai-matrx/kit/delimited` (AP-2): spreadsheet-safe by default, trailing line ending kept.
24
+
25
+ **Consumer action:** none.
26
+
3
27
  ## 0.102.11
4
28
 
5
29
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/index.cjs CHANGED
@@ -7620,11 +7620,11 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
7620
7620
  discard,
7621
7621
  forget: (cells) => {
7622
7622
  if (cells.length === 0) return;
7623
- for (const cell of cells) versions.current.delete(cell.rowId);
7623
+ for (const cell2 of cells) versions.current.delete(cell2.rowId);
7624
7624
  setOptimistic((held) => {
7625
7625
  let next = null;
7626
- for (const cell of cells) {
7627
- const id = cellKey(cell.rowId, cell.key);
7626
+ for (const cell2 of cells) {
7627
+ const id = cellKey(cell2.rowId, cell2.key);
7628
7628
  if (!(id in held)) continue;
7629
7629
  next = next ?? { ...held };
7630
7630
  delete next[id];
@@ -8100,7 +8100,10 @@ function OpenCell({
8100
8100
  tabIndex: -1,
8101
8101
  className: (0, import_design_system23.cn)(
8102
8102
  "relative z-[25] flex w-full min-w-0 max-w-full flex-col gap-1 outline-none",
8103
- FLOATING_EDITOR_NOTE_CLASS
8103
+ FLOATING_EDITOR_NOTE_CLASS,
8104
+ // A field's own input is 36px (h-9); in a 35px row it grew the row 4px. In the cell it is
8105
+ // the row action strip's 32px, so opening a cell never changes the row (STABLE-TABLES).
8106
+ "[&_input:not([type=checkbox]):not([type=radio])]:h-8 [&_input:not([type=checkbox]):not([type=radio])]:py-0"
8104
8107
  ),
8105
8108
  onDoubleClick: (event) => event.stopPropagation(),
8106
8109
  onKeyDown: (event) => {
@@ -8283,15 +8286,28 @@ function BodySkeleton({ layout, embedded, rows }) {
8283
8286
  /* @__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)) }),
8284
8287
  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))
8285
8288
  ] });
8286
- case "form":
8287
8289
  case "record":
8290
+ 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: [
8291
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "title", width: "1/2", className: "h-8", "data-records-skeleton-part": "title" }),
8292
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex h-[38px] items-center gap-2", "data-records-skeleton-part": "actions", children: [
8293
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "control", width: "sm", className: "h-8" }),
8294
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "control", width: "sm", className: "h-8" })
8295
+ ] }),
8296
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px w-full shrink-0 bg-border" }),
8297
+ /* @__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: [
8298
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "line", width: "2/3", className: "my-[7px]" }),
8299
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "row", className: "h-7" })
8300
+ ] }, i)) }),
8301
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "block", height: "lg" })
8302
+ ] });
8303
+ case "form":
8288
8304
  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: [
8289
8305
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "title", width: "1/2" }),
8290
8306
  /* @__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: [
8291
8307
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "line", width: "2/3", className: "my-1.5" }),
8292
8308
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "row", className: "h-7" })
8293
8309
  ] }, i)) }),
8294
- 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" })
8310
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_design_system24.Skeleton, { shape: "control", width: "sm" })
8295
8311
  ] });
8296
8312
  case "chart":
8297
8313
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-2", "data-records-skeleton-part": "body", children: [
@@ -12250,10 +12266,10 @@ function useGridColours(args) {
12250
12266
  submenu: swatches("sel-highlight", void 0, (color) => {
12251
12267
  void (async () => {
12252
12268
  let kept = 0;
12253
- for (const cell of cells) {
12254
- const field2 = idOf(cell.columnKey);
12269
+ for (const cell2 of cells) {
12270
+ const field2 = idOf(cell2.columnKey);
12255
12271
  if (!field2) continue;
12256
- const answer = await client.tableDecorate({ table_id: tableId, path: ["cells", cell.rowId, field2.id], value: color });
12272
+ const answer = await client.tableDecorate({ table_id: tableId, path: ["cells", cell2.rowId, field2.id], value: color });
12257
12273
  if (!answer.ok) {
12258
12274
  notify?.error(`The colour was not kept: ${refusalSentence(answer.error)}`);
12259
12275
  return;
@@ -12686,15 +12702,15 @@ function ActionRowPreview({
12686
12702
  }) {
12687
12703
  const formulas = preview.cells.map((c) => c.formula ?? "").filter((f) => f.trim() !== "");
12688
12704
  const readings = useFormulaReadings(tableId, formulas);
12689
- const afterWords = (cell) => {
12690
- if (cell.how === "compute") {
12691
- const reading = cell.formula ? readings[cell.formula] : void 0;
12705
+ const afterWords = (cell2) => {
12706
+ if (cell2.how === "compute") {
12707
+ const reading = cell2.formula ? readings[cell2.formula] : void 0;
12692
12708
  if (reading && reading.ok === false) return { text: `The store cannot read this formula: ${reading.error}`, note: true };
12693
12709
  const kind = reading && reading.ok ? RESULT_WORDS[reading.result_type] ?? "a value" : "the result";
12694
- return { text: `Worked out when it runs \u2014 ${kind}${cell.formula ? ` from ${cell.formula}` : ""}`, note: true };
12710
+ return { text: `Worked out when it runs \u2014 ${kind}${cell2.formula ? ` from ${cell2.formula}` : ""}`, note: true };
12695
12711
  }
12696
- if (cell.computed && cell.how === null) return { text: words(cell.before) || "empty", note: false };
12697
- return { text: words(cell.after) || "empty", note: false };
12712
+ if (cell2.computed && cell2.how === null) return { text: words(cell2.before) || "empty", note: false };
12713
+ return { text: words(cell2.after) || "empty", note: false };
12698
12714
  };
12699
12715
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-col gap-1", "data-records-action-row-preview": "", children: [
12700
12716
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "max-w-full overflow-x-auto rounded border", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
@@ -12707,38 +12723,38 @@ function ActionRowPreview({
12707
12723
  children: [
12708
12724
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { role: "row", className: "contents", children: [
12709
12725
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { role: "columnheader", className: "sticky left-0 bg-muted/60 px-2 py-1" }),
12710
- preview.cells.map((cell) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12726
+ preview.cells.map((cell2) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12711
12727
  "span",
12712
12728
  {
12713
12729
  role: "columnheader",
12714
- title: cell.name,
12715
- className: (0, import_design_system38.cn)("truncate border-l bg-muted/60 px-2 py-1 font-medium", cell.changed ? "text-foreground" : "text-muted-foreground"),
12716
- children: cell.name
12730
+ title: cell2.name,
12731
+ className: (0, import_design_system38.cn)("truncate border-l bg-muted/60 px-2 py-1 font-medium", cell2.changed ? "text-foreground" : "text-muted-foreground"),
12732
+ children: cell2.name
12717
12733
  },
12718
- cell.key
12734
+ cell2.key
12719
12735
  ))
12720
12736
  ] }),
12721
12737
  ["before", "after"].map((which) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { role: "row", className: "contents", "data-preview-row": which, children: [
12722
12738
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { role: "rowheader", className: "sticky left-0 border-t bg-background px-2 py-1 font-medium text-muted-foreground", children: which === "before" ? "Now" : "After" }),
12723
- preview.cells.map((cell) => {
12724
- const shown4 = which === "before" ? { text: words(cell.before) || "empty", note: false } : afterWords(cell);
12739
+ preview.cells.map((cell2) => {
12740
+ const shown4 = which === "before" ? { text: words(cell2.before) || "empty", note: false } : afterWords(cell2);
12725
12741
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12726
12742
  "span",
12727
12743
  {
12728
12744
  role: "cell",
12729
- "data-changed": cell.changed ? "true" : void 0,
12730
- "data-records-preview-cell": cell.key,
12745
+ "data-changed": cell2.changed ? "true" : void 0,
12746
+ "data-records-preview-cell": cell2.key,
12731
12747
  title: shown4.text,
12732
12748
  className: (0, import_design_system38.cn)(
12733
12749
  "truncate border-l border-t px-2 py-1",
12734
12750
  shown4.text === "empty" && "italic text-muted-foreground",
12735
- cell.changed && which === "before" && "bg-destructive/10 text-destructive line-through",
12736
- cell.changed && which === "after" && "bg-primary/10 font-medium",
12751
+ cell2.changed && which === "before" && "bg-destructive/10 text-destructive line-through",
12752
+ cell2.changed && which === "after" && "bg-primary/10 font-medium",
12737
12753
  shown4.note && "italic"
12738
12754
  ),
12739
12755
  children: shown4.text
12740
12756
  },
12741
- cell.key
12757
+ cell2.key
12742
12758
  );
12743
12759
  })
12744
12760
  ] }, which))
@@ -14208,15 +14224,15 @@ function planPastedBlock(args) {
14208
14224
  for (const refusal4 of predicted) {
14209
14225
  const key = refusal4.field_key;
14210
14226
  if (key === void 0) continue;
14211
- const cell = built.find((b) => b.key === key && b.refusal === null);
14212
- if (!cell) continue;
14213
- cell.refusal = refusal4.message;
14214
- cell.value = null;
14227
+ const cell2 = built.find((b) => b.key === key && b.refusal === null);
14228
+ if (!cell2) continue;
14229
+ cell2.refusal = refusal4.message;
14230
+ cell2.value = null;
14215
14231
  delete accepted[key];
14216
14232
  refusals.push({
14217
14233
  fromLine,
14218
14234
  column: fieldName(byKey.get(key) ?? { key }),
14219
- raw: cell.raw,
14235
+ raw: cell2.raw,
14220
14236
  why: refusal4.message
14221
14237
  });
14222
14238
  }
@@ -14244,7 +14260,7 @@ function planPastedBlock(args) {
14244
14260
  }
14245
14261
  function documentOf(row) {
14246
14262
  const out = {};
14247
- for (const cell of row.cells) if (cell.refusal === null) out[cell.key] = cell.value;
14263
+ for (const cell2 of row.cells) if (cell2.refusal === null) out[cell2.key] = cell2.value;
14248
14264
  return out;
14249
14265
  }
14250
14266
  var sameWords = (text) => text.trim().replace(/\s+/g, " ").toLowerCase();
@@ -14265,11 +14281,11 @@ function readPasteHeader(args) {
14265
14281
  let named = 0;
14266
14282
  let filled = 0;
14267
14283
  columnKeys.forEach((_, c) => {
14268
- const cell = head[c];
14269
- if (cell === void 0 || cell.trim() === "") return;
14284
+ const cell2 = head[c];
14285
+ if (cell2 === void 0 || cell2.trim() === "") return;
14270
14286
  filled += 1;
14271
- const hits = [...new Set(byName.get(sameWords(cell)) ?? [])];
14272
- const named1 = hits.filter((f) => sameWords(fieldName(f)) === sameWords(cell));
14287
+ const hits = [...new Set(byName.get(sameWords(cell2)) ?? [])];
14288
+ const named1 = hits.filter((f) => sameWords(fieldName(f)) === sameWords(cell2));
14273
14289
  const pick = named1.length > 0 ? named1 : hits;
14274
14290
  if (pick.length !== 1) return;
14275
14291
  const only = pick[0];
@@ -14280,8 +14296,8 @@ function readPasteHeader(args) {
14280
14296
  });
14281
14297
  if (named === 0 || named * 2 < filled) return null;
14282
14298
  const unmatched = columnKeys.flatMap((_, c) => {
14283
- const cell = head[c];
14284
- return mapped[c] === null && cell !== void 0 && cell.trim() !== "" ? [cell.trim()] : [];
14299
+ const cell2 = head[c];
14300
+ return mapped[c] === null && cell2 !== void 0 && cell2.trim() !== "" ? [cell2.trim()] : [];
14285
14301
  });
14286
14302
  return { columnKeys: mapped, unmatched, lines: lines.slice(1) };
14287
14303
  }
@@ -14618,7 +14634,7 @@ function useMergedGridControls(args) {
14618
14634
  }
14619
14635
  } : {},
14620
14636
  clearCells: (cells) => {
14621
- for (const cell of cells) editing.setCell(cell.rowId, cell.columnId, null);
14637
+ for (const cell2 of cells) editing.setCell(cell2.rowId, cell2.columnId, null);
14622
14638
  },
14623
14639
  fillDown: (rowIds, columnIds) => {
14624
14640
  const byId = new Map(rows.map((r) => [r.id, r]));
@@ -16496,22 +16512,22 @@ var import_design_system51 = require("@ai-matrx/design-system");
16496
16512
  var import_format4 = require("@ai-matrx/kit/format");
16497
16513
  var import_jsx_runtime57 = require("react/jsx-runtime");
16498
16514
  var NO_ENRICH_REASON = "Having an agent fill this column is not switched on here yet, so this panel does not offer it rather than offering something that cannot happen. Everything else on this panel works. It is on our list, not yours.";
16499
- function cellState(cell) {
16500
- if (!cell || !cell.agent_owned) return "none";
16501
- if (cell.pinned) return "yours";
16502
- if (cell.absent_reason === "conflicting") return "unsure";
16503
- if (cell.actor === "agent") return "agent";
16515
+ function cellState(cell2) {
16516
+ if (!cell2 || !cell2.agent_owned) return "none";
16517
+ if (cell2.pinned) return "yours";
16518
+ if (cell2.absent_reason === "conflicting") return "unsure";
16519
+ if (cell2.actor === "agent") return "agent";
16504
16520
  return "none";
16505
16521
  }
16506
16522
  function ago(at) {
16507
16523
  return at ? (0, import_format4.formatRelativeTime)(at, { style: "intl", fallback: "" }) : "";
16508
16524
  }
16509
- function EnrichBadge({ cell, onPin, className }) {
16510
- const state = cellState(cell);
16511
- if (!cell || state === "none") return null;
16512
- const source = cell.source ?? {};
16525
+ function EnrichBadge({ cell: cell2, onPin, className }) {
16526
+ const state = cellState(cell2);
16527
+ if (!cell2 || state === "none") return null;
16528
+ const source = cell2.source ?? {};
16513
16529
  const read = Array.isArray(source.read) ? source.read : [];
16514
- const alternates = cell.alternates ?? [];
16530
+ const alternates = cell2.alternates ?? [];
16515
16531
  const word = state === "yours" ? "yours" : state === "unsure" ? "unsure" : "agent";
16516
16532
  return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_design_system51.HoverCard, { openDelay: 120, children: [
16517
16533
  /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_design_system51.HoverCardTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: (0, import_design_system51.cn)("inline-flex items-center gap-1 align-middle", className), children: [
@@ -16523,18 +16539,18 @@ function EnrichBadge({ cell, onPin, className }) {
16523
16539
  children: word
16524
16540
  }
16525
16541
  ),
16526
- cell.stale ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_design_system51.Badge, { variant: "outline", className: "text-[10px] font-normal leading-none opacity-70", children: "stale" }) : null
16542
+ cell2.stale ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_design_system51.Badge, { variant: "outline", className: "text-[10px] font-normal leading-none opacity-70", children: "stale" }) : null
16527
16543
  ] }) }),
16528
16544
  /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_design_system51.HoverCardContent, { className: "w-80 space-y-2 text-xs", children: [
16529
16545
  /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "font-medium", children: state === "yours" ? "You typed this one in" : state === "unsure" ? "A model had candidates and committed to none" : "Filled in by a model" }),
16530
- state !== "yours" && cell.on_behalf_of ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16546
+ state !== "yours" && cell2.on_behalf_of ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16531
16547
  "Acting for ",
16532
- cell.on_behalf_of,
16533
- cell.written_at ? `, ${ago(cell.written_at)}` : "",
16548
+ cell2.on_behalf_of,
16549
+ cell2.written_at ? `, ${ago(cell2.written_at)}` : "",
16534
16550
  "."
16535
- ] }) : cell.written_at ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16551
+ ] }) : cell2.written_at ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16536
16552
  "Written ",
16537
- ago(cell.written_at),
16553
+ ago(cell2.written_at),
16538
16554
  "."
16539
16555
  ] }) : null,
16540
16556
  source.model ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
@@ -16551,9 +16567,9 @@ function EnrichBadge({ cell, onPin, className }) {
16551
16567
  /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "text-muted-foreground", children: state === "unsure" ? "What it considered" : "What it nearly said instead" }),
16552
16568
  /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("ul", { className: "list-inside list-decimal", children: alternates.slice(0, 4).map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("li", { children: String(a.value ?? "") }, i)) })
16553
16569
  ] }) : null,
16554
- cell.stale && cell.due_at ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16570
+ cell2.stale && cell2.due_at ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16555
16571
  "Past its date \u2014 it was due to be looked at again ",
16556
- ago(cell.due_at),
16572
+ ago(cell2.due_at),
16557
16573
  ". The value is still here; nothing was overwritten."
16558
16574
  ] }) : null,
16559
16575
  onPin ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
@@ -16562,8 +16578,8 @@ function EnrichBadge({ cell, onPin, className }) {
16562
16578
  size: "sm",
16563
16579
  variant: "outline",
16564
16580
  className: "w-full",
16565
- onClick: () => void onPin(!cell.pinned),
16566
- children: cell.pinned ? "Let the model fill this in again" : "Keep this one \u2014 stop the model changing it"
16581
+ onClick: () => void onPin(!cell2.pinned),
16582
+ children: cell2.pinned ? "Let the model fill this in again" : "Keep this one \u2014 stop the model changing it"
16567
16583
  }
16568
16584
  ) : null
16569
16585
  ] })
@@ -16586,7 +16602,7 @@ function useEnrichCells(tableId, recordIds) {
16586
16602
  }
16587
16603
  setError(null);
16588
16604
  const next = /* @__PURE__ */ new Map();
16589
- for (const cell of answered.data) next.set(`${cell.record_id}:${cell.field_key}`, cell);
16605
+ for (const cell2 of answered.data) next.set(`${cell2.record_id}:${cell2.field_key}`, cell2);
16590
16606
  setCells(next);
16591
16607
  }, [client, tableId, key]);
16592
16608
  (0, import_react91.useEffect)(() => {
@@ -17056,7 +17072,7 @@ function columnForField(field2, editing, mayWriteRow, whyNotRow, look, onAskWhoC
17056
17072
  filter: filterRefusal(field2) !== null ? false : editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? "select" : holdsNumbers(field2) ? "number" : "auto",
17057
17073
  // THE MENU'S VALUE LIST WEARS THE CHOICES' COLOURS (lane CELL-EDITORS, night walk 2026-10-06): the
17058
17074
  // same chip the cell draws, never bare words beside a coloured column.
17059
- ...editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? { filterValueClass: (value) => choiceChipLookOf(field2, value).className } : {},
17075
+ ...editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? { filterValueClass: (value, label) => choiceChipLookOf(field2, value, label).className } : {},
17060
17076
  cell: (row) => (
17061
17077
  /*
17062
17078
  * 🚨 A READING QUESTION IS NOT AN EDITING RIGHT. This used to read
@@ -17529,7 +17545,7 @@ function PlanTable({ plan }) {
17529
17545
  const keys = Array.from(new Set(shown4.flatMap((row) => row.cells.map((c) => c.key))));
17530
17546
  if (shown4.length === 0 || keys.length === 0) return null;
17531
17547
  const columnName = /* @__PURE__ */ new Map();
17532
- for (const row of shown4) for (const cell of row.cells) if (!columnName.has(cell.key)) columnName.set(cell.key, cell.column);
17548
+ for (const row of shown4) for (const cell2 of row.cells) if (!columnName.has(cell2.key)) columnName.set(cell2.key, cell2.column);
17533
17549
  return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "overflow-auto rounded border", children: [
17534
17550
  /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("table", { className: "w-full text-xs", "data-matrx-paste-plan": true, children: [
17535
17551
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("tr", { children: [
@@ -17542,18 +17558,18 @@ function PlanTable({ plan }) {
17542
17558
  row.recordId === null ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_design_system54.Badge, { variant: "outline", className: "ml-1", children: "new" }) : null
17543
17559
  ] }),
17544
17560
  keys.map((key) => {
17545
- const cell = row.cells.find((c) => c.key === key);
17546
- if (!cell) return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("td", { className: "px-2 py-1" }, key);
17547
- if (cell.refusal !== null) {
17548
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("td", { className: "px-2 py-1 text-muted-foreground line-through", children: cell.raw }, key);
17561
+ const cell2 = row.cells.find((c) => c.key === key);
17562
+ if (!cell2) return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("td", { className: "px-2 py-1" }, key);
17563
+ if (cell2.refusal !== null) {
17564
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("td", { className: "px-2 py-1 text-muted-foreground line-through", children: cell2.raw }, key);
17549
17565
  }
17550
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("td", { className: "px-2 py-1", children: cell.value === null ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "text-muted-foreground", children: "cleared" }) : (
17566
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("td", { className: "px-2 py-1", children: cell2.value === null ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "text-muted-foreground", children: "cleared" }) : (
17551
17567
  // THE WORDS, NOT THE ID. A choice column stores the option
17552
17568
  // record's id and the person pasted a word; showing the id
17553
17569
  // here made this panel print
17554
17570
  // `530808bf-9f2d-4062-bc09-b8cc3b162f2a` where they had
17555
17571
  // written Drain Cleaning (FIX-10C F8).
17556
- cell.display ?? String(cell.value)
17572
+ cell2.display ?? String(cell2.value)
17557
17573
  ) }, key);
17558
17574
  })
17559
17575
  ] }, row.fromLine)) })
@@ -17854,6 +17870,7 @@ function combineRows(rows, header) {
17854
17870
 
17855
17871
  // src/importRefusals.ts
17856
17872
  var import_download = require("@ai-matrx/kit/download");
17873
+ var import_delimited = require("@ai-matrx/kit/delimited");
17857
17874
  function reasonShape(reason) {
17858
17875
  return reason.replace(/"[^"]*"/g, '"\u2026"').replace(/“[^”]*”/g, "\u201C\u2026\u201D").replace(/\b\d+(?:[.,]\d+)*\b/g, "N").replace(/\s+/g, " ").trim();
17859
17876
  }
@@ -17869,21 +17886,24 @@ function groupReasons(reasons) {
17869
17886
  }
17870
17887
  return [...groups.values()].sort((a, b) => b.count - a.count);
17871
17888
  }
17872
- function csvCell(value) {
17873
- const text = value === null || value === void 0 ? "" : String(value);
17874
- return /[",\n\r]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
17889
+ function cell(value) {
17890
+ if (value === null || value === void 0) return null;
17891
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : String(value);
17875
17892
  }
17876
17893
  function refusedRowsCsv(rows, lineOf = (n) => n + 1) {
17877
17894
  const headers = [];
17878
17895
  for (const r of rows) for (const h of Object.keys(r.source ?? {})) if (!headers.includes(h)) headers.push(h);
17879
- const lines = [[...headers, "Line in your file", "Why it was not added"].map(csvCell).join(",")];
17880
- for (const r of rows) {
17881
- const cells = headers.map((h) => csvCell((r.source ?? {})[h]));
17882
- cells.push(csvCell(typeof r.row === "number" ? lineOf(r.row) : ""));
17883
- cells.push(csvCell(r.reason ?? ""));
17884
- lines.push(cells.join(","));
17885
- }
17886
- return lines.join("\n") + "\n";
17896
+ return (0, import_delimited.toDelimited)(
17897
+ [
17898
+ [...headers, "Line in your file", "Why it was not added"],
17899
+ ...rows.map((r) => [
17900
+ ...headers.map((h) => cell((r.source ?? {})[h])),
17901
+ typeof r.row === "number" ? lineOf(r.row) : "",
17902
+ r.reason ?? ""
17903
+ ])
17904
+ ],
17905
+ { trailingNewline: true }
17906
+ );
17887
17907
  }
17888
17908
  function offerDownload(name, text, type = "text/csv") {
17889
17909
  if (typeof document === "undefined" || typeof URL === "undefined" || typeof URL.createObjectURL !== "function") return false;
@@ -19387,18 +19407,18 @@ function splitPipes(line) {
19387
19407
  if (text.startsWith("|")) text = text.slice(1);
19388
19408
  if (text.endsWith("|") && !text.endsWith("\\|")) text = text.slice(0, -1);
19389
19409
  const cells = [];
19390
- let cell = "";
19410
+ let cell2 = "";
19391
19411
  for (let i = 0; i < text.length; i += 1) {
19392
19412
  const ch = text[i];
19393
19413
  if (ch === "\\" && text[i + 1] === "|") {
19394
- cell += "\\|";
19414
+ cell2 += "\\|";
19395
19415
  i += 1;
19396
19416
  } else if (ch === "|") {
19397
- cells.push(cell);
19398
- cell = "";
19399
- } else cell += ch;
19417
+ cells.push(cell2);
19418
+ cell2 = "";
19419
+ } else cell2 += ch;
19400
19420
  }
19401
- cells.push(cell);
19421
+ cells.push(cell2);
19402
19422
  return cells.map(cellWords);
19403
19423
  }
19404
19424
  var LIST_ITEM = /^(\s*)(?:[-*+•]|\d{1,3}[.)])\s+(?:\[[ xX]\]\s+)?(.*)$/;
@@ -19515,33 +19535,33 @@ function shapeFromList(items, name, at) {
19515
19535
  function parseDelimited(text, delimiter) {
19516
19536
  const rows = [];
19517
19537
  let row = [];
19518
- let cell = "";
19538
+ let cell2 = "";
19519
19539
  let quoted2 = false;
19520
19540
  for (let i = 0; i < text.length; i += 1) {
19521
19541
  const ch = text[i];
19522
19542
  if (quoted2) {
19523
19543
  if (ch === '"') {
19524
19544
  if (text[i + 1] === '"') {
19525
- cell += '"';
19545
+ cell2 += '"';
19526
19546
  i += 1;
19527
19547
  } else quoted2 = false;
19528
- } else cell += ch;
19548
+ } else cell2 += ch;
19529
19549
  continue;
19530
19550
  }
19531
- if (ch === '"' && cell.trim() === "") quoted2 = true;
19551
+ if (ch === '"' && cell2.trim() === "") quoted2 = true;
19532
19552
  else if (ch === delimiter) {
19533
- row.push(cell);
19534
- cell = "";
19553
+ row.push(cell2);
19554
+ cell2 = "";
19535
19555
  } else if (ch === "\n" || ch === "\r") {
19536
19556
  if (ch === "\r" && text[i + 1] === "\n") i += 1;
19537
- row.push(cell);
19557
+ row.push(cell2);
19538
19558
  rows.push(row);
19539
19559
  row = [];
19540
- cell = "";
19541
- } else cell += ch;
19560
+ cell2 = "";
19561
+ } else cell2 += ch;
19542
19562
  }
19543
- if (cell.length > 0 || row.length > 0) {
19544
- row.push(cell);
19563
+ if (cell2.length > 0 || row.length > 0) {
19564
+ row.push(cell2);
19545
19565
  rows.push(row);
19546
19566
  }
19547
19567
  return rows.filter((r) => r.some((c) => c.trim() !== ""));
@@ -19844,10 +19864,10 @@ function shapeTextOfNode(node) {
19844
19864
  flushLine();
19845
19865
  const width = Math.max(...rows.map((r) => r.length));
19846
19866
  const pad4 = (r) => [...r, ...Array.from({ length: width - r.length }, () => "")];
19847
- const cell = (c) => c.replace(/\|/g, "\\|").replace(/\s+/g, " ").trim();
19848
- out.push(`| ${pad4(rows[0]).map(cell).join(" | ")} |`);
19867
+ const cell2 = (c) => c.replace(/\|/g, "\\|").replace(/\s+/g, " ").trim();
19868
+ out.push(`| ${pad4(rows[0]).map(cell2).join(" | ")} |`);
19849
19869
  out.push(`|${Array.from({ length: width }, () => "---").join("|")}|`);
19850
- for (const r of rows.slice(1)) out.push(`| ${pad4(r).map(cell).join(" | ")} |`);
19870
+ for (const r of rows.slice(1)) out.push(`| ${pad4(r).map(cell2).join(" | ")} |`);
19851
19871
  rows = [];
19852
19872
  };
19853
19873
  const textOf = (n) => (n.textContent ?? "").replace(/\s+/g, " ").trim();
@@ -20262,12 +20282,12 @@ var import_data_table10 = require("@ai-matrx/design-system/data-table");
20262
20282
  var import_jsx_runtime66 = require("react/jsx-runtime");
20263
20283
  function changesFor(step2, direction, versions = /* @__PURE__ */ new Map()) {
20264
20284
  const byRow = /* @__PURE__ */ new Map();
20265
- for (const cell of step2.cells) {
20266
- if (step2.created?.includes(cell.rowId)) continue;
20267
- const patch = byRow.get(cell.rowId) ?? {};
20268
- const value = direction === "undo" ? cell.before : cell.after;
20269
- patch[cell.key] = value === void 0 ? null : value;
20270
- byRow.set(cell.rowId, patch);
20285
+ for (const cell2 of step2.cells) {
20286
+ if (step2.created?.includes(cell2.rowId)) continue;
20287
+ const patch = byRow.get(cell2.rowId) ?? {};
20288
+ const value = direction === "undo" ? cell2.before : cell2.after;
20289
+ patch[cell2.key] = value === void 0 ? null : value;
20290
+ byRow.set(cell2.rowId, patch);
20271
20291
  }
20272
20292
  const changes = [...byRow].map(([record_id, patch]) => ({
20273
20293
  op: "update",
@@ -20295,7 +20315,7 @@ function useGridUndo(args) {
20295
20315
  const dismiss = (0, import_react104.useCallback)(() => setNotice(null), []);
20296
20316
  const push = (0, import_react104.useCallback)((step2) => {
20297
20317
  if (step2.cells.length === 0 && !step2.created?.length && !step2.archived?.length && !step2.retiredField) return;
20298
- for (const cell of step2.cells) if (typeof cell.version === "number") known.current.set(cell.rowId, cell.version);
20318
+ for (const cell2 of step2.cells) if (typeof cell2.version === "number") known.current.set(cell2.rowId, cell2.version);
20299
20319
  counter.current += 1;
20300
20320
  const id = String(counter.current);
20301
20321
  setHeld((was) => {
@@ -20624,13 +20644,12 @@ function useGridAssist(args) {
20624
20644
  const copyRecordReference = (0, import_react106.useCallback)(
20625
20645
  (rowId) => {
20626
20646
  void (async () => {
20627
- try {
20628
- const text = JSON.stringify({ __kind: (0, import_core14.tableKindSlug)(tableId), _record_id: rowId });
20629
- if (!await (0, import_clipboard2.copyText)(text)) throw new Error("This browser did not let the page write to the clipboard.");
20630
- say2(true, "The record reference is copied.");
20631
- } catch (thrown) {
20632
- say2(false, thrown instanceof Error ? thrown.message : String(thrown));
20647
+ const text = JSON.stringify({ __kind: (0, import_core14.tableKindSlug)(tableId), _record_id: rowId });
20648
+ if (!await (0, import_clipboard2.copyText)(text)) {
20649
+ say2(false, "This browser did not let the page write to the clipboard.");
20650
+ return;
20633
20651
  }
20652
+ say2(true, "The record reference is copied.");
20634
20653
  })();
20635
20654
  },
20636
20655
  [tableId, say2]
@@ -20797,9 +20816,9 @@ function planBulk(args) {
20797
20816
  before: (row.document ?? {})[field2.key] ?? null,
20798
20817
  after: value
20799
20818
  }));
20800
- const changes = cells.map((cell) => ({
20819
+ const changes = cells.map((cell2) => ({
20801
20820
  op: "update",
20802
- record_id: cell.rowId,
20821
+ record_id: cell2.rowId,
20803
20822
  patch: { [field2.key]: value }
20804
20823
  }));
20805
20824
  const many = countOf(cells.length, args.noun, args.nounPlural);
@@ -22235,8 +22254,8 @@ function GridBody({
22235
22254
  pastedNames.set(
22236
22255
  field2.key,
22237
22256
  lines.flatMap((line) => {
22238
- const cell = line[at];
22239
- return typeof cell === "string" ? (0, import_records36.relationNamesIn)(field2, cell) : [];
22257
+ const cell2 = line[at];
22258
+ return typeof cell2 === "string" ? (0, import_records36.relationNamesIn)(field2, cell2) : [];
22240
22259
  })
22241
22260
  );
22242
22261
  }
@@ -31180,8 +31199,8 @@ function CalendarView({
31180
31199
  }
31181
31200
  });
31182
31201
  const dayDrop = (fallback) => dropOn((e) => {
31183
- const cell = e.target.closest?.("[data-calendar-day]");
31184
- return { day: cell?.getAttribute("data-calendar-day") ?? fallback, minute: null };
31202
+ const cell2 = e.target.closest?.("[data-calendar-day]");
31203
+ return { day: cell2?.getAttribute("data-calendar-day") ?? fallback, minute: null };
31185
31204
  });
31186
31205
  const minuteAt = (e) => {
31187
31206
  const slot = e.target?.closest?.("[data-calendar-slot]");