@ai-matrx/records-ui 0.102.11 → 0.102.14

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,23 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.102.14
4
+
5
+ - 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.
6
+
7
+ **Consumer action:** none.
8
+
9
+ ## 0.102.13
10
+
11
+ - Copying a record reference handles a refused copy in the kit copy's `false` branch (it was a `throw` into a catch).
12
+
13
+ **Consumer action:** none.
14
+
15
+ ## 0.102.12
16
+
17
+ - `refusedRowsCsv` writes through THE one writer, `@ai-matrx/kit/delimited` (AP-2): spreadsheet-safe by default, trailing line ending kept.
18
+
19
+ **Consumer action:** none.
20
+
3
21
  ## 0.102.11
4
22
 
5
23
  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) => {
@@ -12250,10 +12253,10 @@ function useGridColours(args) {
12250
12253
  submenu: swatches("sel-highlight", void 0, (color) => {
12251
12254
  void (async () => {
12252
12255
  let kept = 0;
12253
- for (const cell of cells) {
12254
- const field2 = idOf(cell.columnKey);
12256
+ for (const cell2 of cells) {
12257
+ const field2 = idOf(cell2.columnKey);
12255
12258
  if (!field2) continue;
12256
- const answer = await client.tableDecorate({ table_id: tableId, path: ["cells", cell.rowId, field2.id], value: color });
12259
+ const answer = await client.tableDecorate({ table_id: tableId, path: ["cells", cell2.rowId, field2.id], value: color });
12257
12260
  if (!answer.ok) {
12258
12261
  notify?.error(`The colour was not kept: ${refusalSentence(answer.error)}`);
12259
12262
  return;
@@ -12686,15 +12689,15 @@ function ActionRowPreview({
12686
12689
  }) {
12687
12690
  const formulas = preview.cells.map((c) => c.formula ?? "").filter((f) => f.trim() !== "");
12688
12691
  const readings = useFormulaReadings(tableId, formulas);
12689
- const afterWords = (cell) => {
12690
- if (cell.how === "compute") {
12691
- const reading = cell.formula ? readings[cell.formula] : void 0;
12692
+ const afterWords = (cell2) => {
12693
+ if (cell2.how === "compute") {
12694
+ const reading = cell2.formula ? readings[cell2.formula] : void 0;
12692
12695
  if (reading && reading.ok === false) return { text: `The store cannot read this formula: ${reading.error}`, note: true };
12693
12696
  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 };
12697
+ return { text: `Worked out when it runs \u2014 ${kind}${cell2.formula ? ` from ${cell2.formula}` : ""}`, note: true };
12695
12698
  }
12696
- if (cell.computed && cell.how === null) return { text: words(cell.before) || "empty", note: false };
12697
- return { text: words(cell.after) || "empty", note: false };
12699
+ if (cell2.computed && cell2.how === null) return { text: words(cell2.before) || "empty", note: false };
12700
+ return { text: words(cell2.after) || "empty", note: false };
12698
12701
  };
12699
12702
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-col gap-1", "data-records-action-row-preview": "", children: [
12700
12703
  /* @__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 +12710,38 @@ function ActionRowPreview({
12707
12710
  children: [
12708
12711
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { role: "row", className: "contents", children: [
12709
12712
  /* @__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)(
12713
+ preview.cells.map((cell2) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12711
12714
  "span",
12712
12715
  {
12713
12716
  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
12717
+ title: cell2.name,
12718
+ 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"),
12719
+ children: cell2.name
12717
12720
  },
12718
- cell.key
12721
+ cell2.key
12719
12722
  ))
12720
12723
  ] }),
12721
12724
  ["before", "after"].map((which) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { role: "row", className: "contents", "data-preview-row": which, children: [
12722
12725
  /* @__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);
12726
+ preview.cells.map((cell2) => {
12727
+ const shown4 = which === "before" ? { text: words(cell2.before) || "empty", note: false } : afterWords(cell2);
12725
12728
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12726
12729
  "span",
12727
12730
  {
12728
12731
  role: "cell",
12729
- "data-changed": cell.changed ? "true" : void 0,
12730
- "data-records-preview-cell": cell.key,
12732
+ "data-changed": cell2.changed ? "true" : void 0,
12733
+ "data-records-preview-cell": cell2.key,
12731
12734
  title: shown4.text,
12732
12735
  className: (0, import_design_system38.cn)(
12733
12736
  "truncate border-l border-t px-2 py-1",
12734
12737
  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",
12738
+ cell2.changed && which === "before" && "bg-destructive/10 text-destructive line-through",
12739
+ cell2.changed && which === "after" && "bg-primary/10 font-medium",
12737
12740
  shown4.note && "italic"
12738
12741
  ),
12739
12742
  children: shown4.text
12740
12743
  },
12741
- cell.key
12744
+ cell2.key
12742
12745
  );
12743
12746
  })
12744
12747
  ] }, which))
@@ -14208,15 +14211,15 @@ function planPastedBlock(args) {
14208
14211
  for (const refusal4 of predicted) {
14209
14212
  const key = refusal4.field_key;
14210
14213
  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;
14214
+ const cell2 = built.find((b) => b.key === key && b.refusal === null);
14215
+ if (!cell2) continue;
14216
+ cell2.refusal = refusal4.message;
14217
+ cell2.value = null;
14215
14218
  delete accepted[key];
14216
14219
  refusals.push({
14217
14220
  fromLine,
14218
14221
  column: fieldName(byKey.get(key) ?? { key }),
14219
- raw: cell.raw,
14222
+ raw: cell2.raw,
14220
14223
  why: refusal4.message
14221
14224
  });
14222
14225
  }
@@ -14244,7 +14247,7 @@ function planPastedBlock(args) {
14244
14247
  }
14245
14248
  function documentOf(row) {
14246
14249
  const out = {};
14247
- for (const cell of row.cells) if (cell.refusal === null) out[cell.key] = cell.value;
14250
+ for (const cell2 of row.cells) if (cell2.refusal === null) out[cell2.key] = cell2.value;
14248
14251
  return out;
14249
14252
  }
14250
14253
  var sameWords = (text) => text.trim().replace(/\s+/g, " ").toLowerCase();
@@ -14265,11 +14268,11 @@ function readPasteHeader(args) {
14265
14268
  let named = 0;
14266
14269
  let filled = 0;
14267
14270
  columnKeys.forEach((_, c) => {
14268
- const cell = head[c];
14269
- if (cell === void 0 || cell.trim() === "") return;
14271
+ const cell2 = head[c];
14272
+ if (cell2 === void 0 || cell2.trim() === "") return;
14270
14273
  filled += 1;
14271
- const hits = [...new Set(byName.get(sameWords(cell)) ?? [])];
14272
- const named1 = hits.filter((f) => sameWords(fieldName(f)) === sameWords(cell));
14274
+ const hits = [...new Set(byName.get(sameWords(cell2)) ?? [])];
14275
+ const named1 = hits.filter((f) => sameWords(fieldName(f)) === sameWords(cell2));
14273
14276
  const pick = named1.length > 0 ? named1 : hits;
14274
14277
  if (pick.length !== 1) return;
14275
14278
  const only = pick[0];
@@ -14280,8 +14283,8 @@ function readPasteHeader(args) {
14280
14283
  });
14281
14284
  if (named === 0 || named * 2 < filled) return null;
14282
14285
  const unmatched = columnKeys.flatMap((_, c) => {
14283
- const cell = head[c];
14284
- return mapped[c] === null && cell !== void 0 && cell.trim() !== "" ? [cell.trim()] : [];
14286
+ const cell2 = head[c];
14287
+ return mapped[c] === null && cell2 !== void 0 && cell2.trim() !== "" ? [cell2.trim()] : [];
14285
14288
  });
14286
14289
  return { columnKeys: mapped, unmatched, lines: lines.slice(1) };
14287
14290
  }
@@ -14618,7 +14621,7 @@ function useMergedGridControls(args) {
14618
14621
  }
14619
14622
  } : {},
14620
14623
  clearCells: (cells) => {
14621
- for (const cell of cells) editing.setCell(cell.rowId, cell.columnId, null);
14624
+ for (const cell2 of cells) editing.setCell(cell2.rowId, cell2.columnId, null);
14622
14625
  },
14623
14626
  fillDown: (rowIds, columnIds) => {
14624
14627
  const byId = new Map(rows.map((r) => [r.id, r]));
@@ -16496,22 +16499,22 @@ var import_design_system51 = require("@ai-matrx/design-system");
16496
16499
  var import_format4 = require("@ai-matrx/kit/format");
16497
16500
  var import_jsx_runtime57 = require("react/jsx-runtime");
16498
16501
  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";
16502
+ function cellState(cell2) {
16503
+ if (!cell2 || !cell2.agent_owned) return "none";
16504
+ if (cell2.pinned) return "yours";
16505
+ if (cell2.absent_reason === "conflicting") return "unsure";
16506
+ if (cell2.actor === "agent") return "agent";
16504
16507
  return "none";
16505
16508
  }
16506
16509
  function ago(at) {
16507
16510
  return at ? (0, import_format4.formatRelativeTime)(at, { style: "intl", fallback: "" }) : "";
16508
16511
  }
16509
- function EnrichBadge({ cell, onPin, className }) {
16510
- const state = cellState(cell);
16511
- if (!cell || state === "none") return null;
16512
- const source = cell.source ?? {};
16512
+ function EnrichBadge({ cell: cell2, onPin, className }) {
16513
+ const state = cellState(cell2);
16514
+ if (!cell2 || state === "none") return null;
16515
+ const source = cell2.source ?? {};
16513
16516
  const read = Array.isArray(source.read) ? source.read : [];
16514
- const alternates = cell.alternates ?? [];
16517
+ const alternates = cell2.alternates ?? [];
16515
16518
  const word = state === "yours" ? "yours" : state === "unsure" ? "unsure" : "agent";
16516
16519
  return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_design_system51.HoverCard, { openDelay: 120, children: [
16517
16520
  /* @__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 +16526,18 @@ function EnrichBadge({ cell, onPin, className }) {
16523
16526
  children: word
16524
16527
  }
16525
16528
  ),
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
16529
+ 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
16530
  ] }) }),
16528
16531
  /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_design_system51.HoverCardContent, { className: "w-80 space-y-2 text-xs", children: [
16529
16532
  /* @__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: [
16533
+ state !== "yours" && cell2.on_behalf_of ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16531
16534
  "Acting for ",
16532
- cell.on_behalf_of,
16533
- cell.written_at ? `, ${ago(cell.written_at)}` : "",
16535
+ cell2.on_behalf_of,
16536
+ cell2.written_at ? `, ${ago(cell2.written_at)}` : "",
16534
16537
  "."
16535
- ] }) : cell.written_at ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16538
+ ] }) : cell2.written_at ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16536
16539
  "Written ",
16537
- ago(cell.written_at),
16540
+ ago(cell2.written_at),
16538
16541
  "."
16539
16542
  ] }) : null,
16540
16543
  source.model ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
@@ -16551,9 +16554,9 @@ function EnrichBadge({ cell, onPin, className }) {
16551
16554
  /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "text-muted-foreground", children: state === "unsure" ? "What it considered" : "What it nearly said instead" }),
16552
16555
  /* @__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
16556
  ] }) : null,
16554
- cell.stale && cell.due_at ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16557
+ cell2.stale && cell2.due_at ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "text-muted-foreground", children: [
16555
16558
  "Past its date \u2014 it was due to be looked at again ",
16556
- ago(cell.due_at),
16559
+ ago(cell2.due_at),
16557
16560
  ". The value is still here; nothing was overwritten."
16558
16561
  ] }) : null,
16559
16562
  onPin ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
@@ -16562,8 +16565,8 @@ function EnrichBadge({ cell, onPin, className }) {
16562
16565
  size: "sm",
16563
16566
  variant: "outline",
16564
16567
  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"
16568
+ onClick: () => void onPin(!cell2.pinned),
16569
+ children: cell2.pinned ? "Let the model fill this in again" : "Keep this one \u2014 stop the model changing it"
16567
16570
  }
16568
16571
  ) : null
16569
16572
  ] })
@@ -16586,7 +16589,7 @@ function useEnrichCells(tableId, recordIds) {
16586
16589
  }
16587
16590
  setError(null);
16588
16591
  const next = /* @__PURE__ */ new Map();
16589
- for (const cell of answered.data) next.set(`${cell.record_id}:${cell.field_key}`, cell);
16592
+ for (const cell2 of answered.data) next.set(`${cell2.record_id}:${cell2.field_key}`, cell2);
16590
16593
  setCells(next);
16591
16594
  }, [client, tableId, key]);
16592
16595
  (0, import_react91.useEffect)(() => {
@@ -17056,7 +17059,7 @@ function columnForField(field2, editing, mayWriteRow, whyNotRow, look, onAskWhoC
17056
17059
  filter: filterRefusal(field2) !== null ? false : editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? "select" : holdsNumbers(field2) ? "number" : "auto",
17057
17060
  // THE MENU'S VALUE LIST WEARS THE CHOICES' COLOURS (lane CELL-EDITORS, night walk 2026-10-06): the
17058
17061
  // 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 } : {},
17062
+ ...editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? { filterValueClass: (value, label) => choiceChipLookOf(field2, value, label).className } : {},
17060
17063
  cell: (row) => (
17061
17064
  /*
17062
17065
  * 🚨 A READING QUESTION IS NOT AN EDITING RIGHT. This used to read
@@ -17529,7 +17532,7 @@ function PlanTable({ plan }) {
17529
17532
  const keys = Array.from(new Set(shown4.flatMap((row) => row.cells.map((c) => c.key))));
17530
17533
  if (shown4.length === 0 || keys.length === 0) return null;
17531
17534
  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);
17535
+ for (const row of shown4) for (const cell2 of row.cells) if (!columnName.has(cell2.key)) columnName.set(cell2.key, cell2.column);
17533
17536
  return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "overflow-auto rounded border", children: [
17534
17537
  /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("table", { className: "w-full text-xs", "data-matrx-paste-plan": true, children: [
17535
17538
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("tr", { children: [
@@ -17542,18 +17545,18 @@ function PlanTable({ plan }) {
17542
17545
  row.recordId === null ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_design_system54.Badge, { variant: "outline", className: "ml-1", children: "new" }) : null
17543
17546
  ] }),
17544
17547
  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);
17548
+ const cell2 = row.cells.find((c) => c.key === key);
17549
+ if (!cell2) return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("td", { className: "px-2 py-1" }, key);
17550
+ if (cell2.refusal !== null) {
17551
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("td", { className: "px-2 py-1 text-muted-foreground line-through", children: cell2.raw }, key);
17549
17552
  }
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" }) : (
17553
+ 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
17554
  // THE WORDS, NOT THE ID. A choice column stores the option
17552
17555
  // record's id and the person pasted a word; showing the id
17553
17556
  // here made this panel print
17554
17557
  // `530808bf-9f2d-4062-bc09-b8cc3b162f2a` where they had
17555
17558
  // written Drain Cleaning (FIX-10C F8).
17556
- cell.display ?? String(cell.value)
17559
+ cell2.display ?? String(cell2.value)
17557
17560
  ) }, key);
17558
17561
  })
17559
17562
  ] }, row.fromLine)) })
@@ -17854,6 +17857,7 @@ function combineRows(rows, header) {
17854
17857
 
17855
17858
  // src/importRefusals.ts
17856
17859
  var import_download = require("@ai-matrx/kit/download");
17860
+ var import_delimited = require("@ai-matrx/kit/delimited");
17857
17861
  function reasonShape(reason) {
17858
17862
  return reason.replace(/"[^"]*"/g, '"\u2026"').replace(/“[^”]*”/g, "\u201C\u2026\u201D").replace(/\b\d+(?:[.,]\d+)*\b/g, "N").replace(/\s+/g, " ").trim();
17859
17863
  }
@@ -17869,21 +17873,24 @@ function groupReasons(reasons) {
17869
17873
  }
17870
17874
  return [...groups.values()].sort((a, b) => b.count - a.count);
17871
17875
  }
17872
- function csvCell(value) {
17873
- const text = value === null || value === void 0 ? "" : String(value);
17874
- return /[",\n\r]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
17876
+ function cell(value) {
17877
+ if (value === null || value === void 0) return null;
17878
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : String(value);
17875
17879
  }
17876
17880
  function refusedRowsCsv(rows, lineOf = (n) => n + 1) {
17877
17881
  const headers = [];
17878
17882
  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";
17883
+ return (0, import_delimited.toDelimited)(
17884
+ [
17885
+ [...headers, "Line in your file", "Why it was not added"],
17886
+ ...rows.map((r) => [
17887
+ ...headers.map((h) => cell((r.source ?? {})[h])),
17888
+ typeof r.row === "number" ? lineOf(r.row) : "",
17889
+ r.reason ?? ""
17890
+ ])
17891
+ ],
17892
+ { trailingNewline: true }
17893
+ );
17887
17894
  }
17888
17895
  function offerDownload(name, text, type = "text/csv") {
17889
17896
  if (typeof document === "undefined" || typeof URL === "undefined" || typeof URL.createObjectURL !== "function") return false;
@@ -19387,18 +19394,18 @@ function splitPipes(line) {
19387
19394
  if (text.startsWith("|")) text = text.slice(1);
19388
19395
  if (text.endsWith("|") && !text.endsWith("\\|")) text = text.slice(0, -1);
19389
19396
  const cells = [];
19390
- let cell = "";
19397
+ let cell2 = "";
19391
19398
  for (let i = 0; i < text.length; i += 1) {
19392
19399
  const ch = text[i];
19393
19400
  if (ch === "\\" && text[i + 1] === "|") {
19394
- cell += "\\|";
19401
+ cell2 += "\\|";
19395
19402
  i += 1;
19396
19403
  } else if (ch === "|") {
19397
- cells.push(cell);
19398
- cell = "";
19399
- } else cell += ch;
19404
+ cells.push(cell2);
19405
+ cell2 = "";
19406
+ } else cell2 += ch;
19400
19407
  }
19401
- cells.push(cell);
19408
+ cells.push(cell2);
19402
19409
  return cells.map(cellWords);
19403
19410
  }
19404
19411
  var LIST_ITEM = /^(\s*)(?:[-*+•]|\d{1,3}[.)])\s+(?:\[[ xX]\]\s+)?(.*)$/;
@@ -19515,33 +19522,33 @@ function shapeFromList(items, name, at) {
19515
19522
  function parseDelimited(text, delimiter) {
19516
19523
  const rows = [];
19517
19524
  let row = [];
19518
- let cell = "";
19525
+ let cell2 = "";
19519
19526
  let quoted2 = false;
19520
19527
  for (let i = 0; i < text.length; i += 1) {
19521
19528
  const ch = text[i];
19522
19529
  if (quoted2) {
19523
19530
  if (ch === '"') {
19524
19531
  if (text[i + 1] === '"') {
19525
- cell += '"';
19532
+ cell2 += '"';
19526
19533
  i += 1;
19527
19534
  } else quoted2 = false;
19528
- } else cell += ch;
19535
+ } else cell2 += ch;
19529
19536
  continue;
19530
19537
  }
19531
- if (ch === '"' && cell.trim() === "") quoted2 = true;
19538
+ if (ch === '"' && cell2.trim() === "") quoted2 = true;
19532
19539
  else if (ch === delimiter) {
19533
- row.push(cell);
19534
- cell = "";
19540
+ row.push(cell2);
19541
+ cell2 = "";
19535
19542
  } else if (ch === "\n" || ch === "\r") {
19536
19543
  if (ch === "\r" && text[i + 1] === "\n") i += 1;
19537
- row.push(cell);
19544
+ row.push(cell2);
19538
19545
  rows.push(row);
19539
19546
  row = [];
19540
- cell = "";
19541
- } else cell += ch;
19547
+ cell2 = "";
19548
+ } else cell2 += ch;
19542
19549
  }
19543
- if (cell.length > 0 || row.length > 0) {
19544
- row.push(cell);
19550
+ if (cell2.length > 0 || row.length > 0) {
19551
+ row.push(cell2);
19545
19552
  rows.push(row);
19546
19553
  }
19547
19554
  return rows.filter((r) => r.some((c) => c.trim() !== ""));
@@ -19844,10 +19851,10 @@ function shapeTextOfNode(node) {
19844
19851
  flushLine();
19845
19852
  const width = Math.max(...rows.map((r) => r.length));
19846
19853
  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(" | ")} |`);
19854
+ const cell2 = (c) => c.replace(/\|/g, "\\|").replace(/\s+/g, " ").trim();
19855
+ out.push(`| ${pad4(rows[0]).map(cell2).join(" | ")} |`);
19849
19856
  out.push(`|${Array.from({ length: width }, () => "---").join("|")}|`);
19850
- for (const r of rows.slice(1)) out.push(`| ${pad4(r).map(cell).join(" | ")} |`);
19857
+ for (const r of rows.slice(1)) out.push(`| ${pad4(r).map(cell2).join(" | ")} |`);
19851
19858
  rows = [];
19852
19859
  };
19853
19860
  const textOf = (n) => (n.textContent ?? "").replace(/\s+/g, " ").trim();
@@ -20262,12 +20269,12 @@ var import_data_table10 = require("@ai-matrx/design-system/data-table");
20262
20269
  var import_jsx_runtime66 = require("react/jsx-runtime");
20263
20270
  function changesFor(step2, direction, versions = /* @__PURE__ */ new Map()) {
20264
20271
  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);
20272
+ for (const cell2 of step2.cells) {
20273
+ if (step2.created?.includes(cell2.rowId)) continue;
20274
+ const patch = byRow.get(cell2.rowId) ?? {};
20275
+ const value = direction === "undo" ? cell2.before : cell2.after;
20276
+ patch[cell2.key] = value === void 0 ? null : value;
20277
+ byRow.set(cell2.rowId, patch);
20271
20278
  }
20272
20279
  const changes = [...byRow].map(([record_id, patch]) => ({
20273
20280
  op: "update",
@@ -20295,7 +20302,7 @@ function useGridUndo(args) {
20295
20302
  const dismiss = (0, import_react104.useCallback)(() => setNotice(null), []);
20296
20303
  const push = (0, import_react104.useCallback)((step2) => {
20297
20304
  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);
20305
+ for (const cell2 of step2.cells) if (typeof cell2.version === "number") known.current.set(cell2.rowId, cell2.version);
20299
20306
  counter.current += 1;
20300
20307
  const id = String(counter.current);
20301
20308
  setHeld((was) => {
@@ -20624,13 +20631,12 @@ function useGridAssist(args) {
20624
20631
  const copyRecordReference = (0, import_react106.useCallback)(
20625
20632
  (rowId) => {
20626
20633
  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));
20634
+ const text = JSON.stringify({ __kind: (0, import_core14.tableKindSlug)(tableId), _record_id: rowId });
20635
+ if (!await (0, import_clipboard2.copyText)(text)) {
20636
+ say2(false, "This browser did not let the page write to the clipboard.");
20637
+ return;
20633
20638
  }
20639
+ say2(true, "The record reference is copied.");
20634
20640
  })();
20635
20641
  },
20636
20642
  [tableId, say2]
@@ -20797,9 +20803,9 @@ function planBulk(args) {
20797
20803
  before: (row.document ?? {})[field2.key] ?? null,
20798
20804
  after: value
20799
20805
  }));
20800
- const changes = cells.map((cell) => ({
20806
+ const changes = cells.map((cell2) => ({
20801
20807
  op: "update",
20802
- record_id: cell.rowId,
20808
+ record_id: cell2.rowId,
20803
20809
  patch: { [field2.key]: value }
20804
20810
  }));
20805
20811
  const many = countOf(cells.length, args.noun, args.nounPlural);
@@ -22235,8 +22241,8 @@ function GridBody({
22235
22241
  pastedNames.set(
22236
22242
  field2.key,
22237
22243
  lines.flatMap((line) => {
22238
- const cell = line[at];
22239
- return typeof cell === "string" ? (0, import_records36.relationNamesIn)(field2, cell) : [];
22244
+ const cell2 = line[at];
22245
+ return typeof cell2 === "string" ? (0, import_records36.relationNamesIn)(field2, cell2) : [];
22240
22246
  })
22241
22247
  );
22242
22248
  }
@@ -31180,8 +31186,8 @@ function CalendarView({
31180
31186
  }
31181
31187
  });
31182
31188
  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 };
31189
+ const cell2 = e.target.closest?.("[data-calendar-day]");
31190
+ return { day: cell2?.getAttribute("data-calendar-day") ?? fallback, minute: null };
31185
31191
  });
31186
31192
  const minuteAt = (e) => {
31187
31193
  const slot = e.target?.closest?.("[data-calendar-slot]");