@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 +18 -0
- package/dist/index.cjs +123 -117
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +123 -117
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7082,11 +7082,11 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
|
|
|
7082
7082
|
discard,
|
|
7083
7083
|
forget: (cells) => {
|
|
7084
7084
|
if (cells.length === 0) return;
|
|
7085
|
-
for (const
|
|
7085
|
+
for (const cell2 of cells) versions.current.delete(cell2.rowId);
|
|
7086
7086
|
setOptimistic((held) => {
|
|
7087
7087
|
let next = null;
|
|
7088
|
-
for (const
|
|
7089
|
-
const id = cellKey(
|
|
7088
|
+
for (const cell2 of cells) {
|
|
7089
|
+
const id = cellKey(cell2.rowId, cell2.key);
|
|
7090
7090
|
if (!(id in held)) continue;
|
|
7091
7091
|
next = next ?? { ...held };
|
|
7092
7092
|
delete next[id];
|
|
@@ -7562,7 +7562,10 @@ function OpenCell({
|
|
|
7562
7562
|
tabIndex: -1,
|
|
7563
7563
|
className: cn19(
|
|
7564
7564
|
"relative z-[25] flex w-full min-w-0 max-w-full flex-col gap-1 outline-none",
|
|
7565
|
-
FLOATING_EDITOR_NOTE_CLASS
|
|
7565
|
+
FLOATING_EDITOR_NOTE_CLASS,
|
|
7566
|
+
// A field's own input is 36px (h-9); in a 35px row it grew the row 4px. In the cell it is
|
|
7567
|
+
// the row action strip's 32px, so opening a cell never changes the row (STABLE-TABLES).
|
|
7568
|
+
"[&_input:not([type=checkbox]):not([type=radio])]:h-8 [&_input:not([type=checkbox]):not([type=radio])]:py-0"
|
|
7566
7569
|
),
|
|
7567
7570
|
onDoubleClick: (event) => event.stopPropagation(),
|
|
7568
7571
|
onKeyDown: (event) => {
|
|
@@ -11799,10 +11802,10 @@ function useGridColours(args) {
|
|
|
11799
11802
|
submenu: swatches("sel-highlight", void 0, (color) => {
|
|
11800
11803
|
void (async () => {
|
|
11801
11804
|
let kept = 0;
|
|
11802
|
-
for (const
|
|
11803
|
-
const field2 = idOf(
|
|
11805
|
+
for (const cell2 of cells) {
|
|
11806
|
+
const field2 = idOf(cell2.columnKey);
|
|
11804
11807
|
if (!field2) continue;
|
|
11805
|
-
const answer = await client.tableDecorate({ table_id: tableId, path: ["cells",
|
|
11808
|
+
const answer = await client.tableDecorate({ table_id: tableId, path: ["cells", cell2.rowId, field2.id], value: color });
|
|
11806
11809
|
if (!answer.ok) {
|
|
11807
11810
|
notify?.error(`The colour was not kept: ${refusalSentence(answer.error)}`);
|
|
11808
11811
|
return;
|
|
@@ -12256,15 +12259,15 @@ function ActionRowPreview({
|
|
|
12256
12259
|
}) {
|
|
12257
12260
|
const formulas = preview.cells.map((c) => c.formula ?? "").filter((f) => f.trim() !== "");
|
|
12258
12261
|
const readings = useFormulaReadings(tableId, formulas);
|
|
12259
|
-
const afterWords = (
|
|
12260
|
-
if (
|
|
12261
|
-
const reading =
|
|
12262
|
+
const afterWords = (cell2) => {
|
|
12263
|
+
if (cell2.how === "compute") {
|
|
12264
|
+
const reading = cell2.formula ? readings[cell2.formula] : void 0;
|
|
12262
12265
|
if (reading && reading.ok === false) return { text: `The store cannot read this formula: ${reading.error}`, note: true };
|
|
12263
12266
|
const kind = reading && reading.ok ? RESULT_WORDS[reading.result_type] ?? "a value" : "the result";
|
|
12264
|
-
return { text: `Worked out when it runs \u2014 ${kind}${
|
|
12267
|
+
return { text: `Worked out when it runs \u2014 ${kind}${cell2.formula ? ` from ${cell2.formula}` : ""}`, note: true };
|
|
12265
12268
|
}
|
|
12266
|
-
if (
|
|
12267
|
-
return { text: words(
|
|
12269
|
+
if (cell2.computed && cell2.how === null) return { text: words(cell2.before) || "empty", note: false };
|
|
12270
|
+
return { text: words(cell2.after) || "empty", note: false };
|
|
12268
12271
|
};
|
|
12269
12272
|
return /* @__PURE__ */ jsxs39("div", { className: "flex flex-col gap-1", "data-records-action-row-preview": "", children: [
|
|
12270
12273
|
/* @__PURE__ */ jsx44("div", { className: "max-w-full overflow-x-auto rounded border", children: /* @__PURE__ */ jsxs39(
|
|
@@ -12277,38 +12280,38 @@ function ActionRowPreview({
|
|
|
12277
12280
|
children: [
|
|
12278
12281
|
/* @__PURE__ */ jsxs39("div", { role: "row", className: "contents", children: [
|
|
12279
12282
|
/* @__PURE__ */ jsx44("span", { role: "columnheader", className: "sticky left-0 bg-muted/60 px-2 py-1" }),
|
|
12280
|
-
preview.cells.map((
|
|
12283
|
+
preview.cells.map((cell2) => /* @__PURE__ */ jsx44(
|
|
12281
12284
|
"span",
|
|
12282
12285
|
{
|
|
12283
12286
|
role: "columnheader",
|
|
12284
|
-
title:
|
|
12285
|
-
className: cn25("truncate border-l bg-muted/60 px-2 py-1 font-medium",
|
|
12286
|
-
children:
|
|
12287
|
+
title: cell2.name,
|
|
12288
|
+
className: cn25("truncate border-l bg-muted/60 px-2 py-1 font-medium", cell2.changed ? "text-foreground" : "text-muted-foreground"),
|
|
12289
|
+
children: cell2.name
|
|
12287
12290
|
},
|
|
12288
|
-
|
|
12291
|
+
cell2.key
|
|
12289
12292
|
))
|
|
12290
12293
|
] }),
|
|
12291
12294
|
["before", "after"].map((which) => /* @__PURE__ */ jsxs39("div", { role: "row", className: "contents", "data-preview-row": which, children: [
|
|
12292
12295
|
/* @__PURE__ */ jsx44("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" }),
|
|
12293
|
-
preview.cells.map((
|
|
12294
|
-
const shown4 = which === "before" ? { text: words(
|
|
12296
|
+
preview.cells.map((cell2) => {
|
|
12297
|
+
const shown4 = which === "before" ? { text: words(cell2.before) || "empty", note: false } : afterWords(cell2);
|
|
12295
12298
|
return /* @__PURE__ */ jsx44(
|
|
12296
12299
|
"span",
|
|
12297
12300
|
{
|
|
12298
12301
|
role: "cell",
|
|
12299
|
-
"data-changed":
|
|
12300
|
-
"data-records-preview-cell":
|
|
12302
|
+
"data-changed": cell2.changed ? "true" : void 0,
|
|
12303
|
+
"data-records-preview-cell": cell2.key,
|
|
12301
12304
|
title: shown4.text,
|
|
12302
12305
|
className: cn25(
|
|
12303
12306
|
"truncate border-l border-t px-2 py-1",
|
|
12304
12307
|
shown4.text === "empty" && "italic text-muted-foreground",
|
|
12305
|
-
|
|
12306
|
-
|
|
12308
|
+
cell2.changed && which === "before" && "bg-destructive/10 text-destructive line-through",
|
|
12309
|
+
cell2.changed && which === "after" && "bg-primary/10 font-medium",
|
|
12307
12310
|
shown4.note && "italic"
|
|
12308
12311
|
),
|
|
12309
12312
|
children: shown4.text
|
|
12310
12313
|
},
|
|
12311
|
-
|
|
12314
|
+
cell2.key
|
|
12312
12315
|
);
|
|
12313
12316
|
})
|
|
12314
12317
|
] }, which))
|
|
@@ -13818,15 +13821,15 @@ function planPastedBlock(args) {
|
|
|
13818
13821
|
for (const refusal4 of predicted) {
|
|
13819
13822
|
const key = refusal4.field_key;
|
|
13820
13823
|
if (key === void 0) continue;
|
|
13821
|
-
const
|
|
13822
|
-
if (!
|
|
13823
|
-
|
|
13824
|
-
|
|
13824
|
+
const cell2 = built.find((b) => b.key === key && b.refusal === null);
|
|
13825
|
+
if (!cell2) continue;
|
|
13826
|
+
cell2.refusal = refusal4.message;
|
|
13827
|
+
cell2.value = null;
|
|
13825
13828
|
delete accepted[key];
|
|
13826
13829
|
refusals.push({
|
|
13827
13830
|
fromLine,
|
|
13828
13831
|
column: fieldName(byKey.get(key) ?? { key }),
|
|
13829
|
-
raw:
|
|
13832
|
+
raw: cell2.raw,
|
|
13830
13833
|
why: refusal4.message
|
|
13831
13834
|
});
|
|
13832
13835
|
}
|
|
@@ -13854,7 +13857,7 @@ function planPastedBlock(args) {
|
|
|
13854
13857
|
}
|
|
13855
13858
|
function documentOf(row) {
|
|
13856
13859
|
const out = {};
|
|
13857
|
-
for (const
|
|
13860
|
+
for (const cell2 of row.cells) if (cell2.refusal === null) out[cell2.key] = cell2.value;
|
|
13858
13861
|
return out;
|
|
13859
13862
|
}
|
|
13860
13863
|
var sameWords = (text) => text.trim().replace(/\s+/g, " ").toLowerCase();
|
|
@@ -13875,11 +13878,11 @@ function readPasteHeader(args) {
|
|
|
13875
13878
|
let named = 0;
|
|
13876
13879
|
let filled = 0;
|
|
13877
13880
|
columnKeys.forEach((_, c) => {
|
|
13878
|
-
const
|
|
13879
|
-
if (
|
|
13881
|
+
const cell2 = head[c];
|
|
13882
|
+
if (cell2 === void 0 || cell2.trim() === "") return;
|
|
13880
13883
|
filled += 1;
|
|
13881
|
-
const hits = [...new Set(byName.get(sameWords(
|
|
13882
|
-
const named1 = hits.filter((f) => sameWords(fieldName(f)) === sameWords(
|
|
13884
|
+
const hits = [...new Set(byName.get(sameWords(cell2)) ?? [])];
|
|
13885
|
+
const named1 = hits.filter((f) => sameWords(fieldName(f)) === sameWords(cell2));
|
|
13883
13886
|
const pick = named1.length > 0 ? named1 : hits;
|
|
13884
13887
|
if (pick.length !== 1) return;
|
|
13885
13888
|
const only = pick[0];
|
|
@@ -13890,8 +13893,8 @@ function readPasteHeader(args) {
|
|
|
13890
13893
|
});
|
|
13891
13894
|
if (named === 0 || named * 2 < filled) return null;
|
|
13892
13895
|
const unmatched = columnKeys.flatMap((_, c) => {
|
|
13893
|
-
const
|
|
13894
|
-
return mapped[c] === null &&
|
|
13896
|
+
const cell2 = head[c];
|
|
13897
|
+
return mapped[c] === null && cell2 !== void 0 && cell2.trim() !== "" ? [cell2.trim()] : [];
|
|
13895
13898
|
});
|
|
13896
13899
|
return { columnKeys: mapped, unmatched, lines: lines.slice(1) };
|
|
13897
13900
|
}
|
|
@@ -14228,7 +14231,7 @@ function useMergedGridControls(args) {
|
|
|
14228
14231
|
}
|
|
14229
14232
|
} : {},
|
|
14230
14233
|
clearCells: (cells) => {
|
|
14231
|
-
for (const
|
|
14234
|
+
for (const cell2 of cells) editing.setCell(cell2.rowId, cell2.columnId, null);
|
|
14232
14235
|
},
|
|
14233
14236
|
fillDown: (rowIds, columnIds) => {
|
|
14234
14237
|
const byId = new Map(rows.map((r) => [r.id, r]));
|
|
@@ -16149,22 +16152,22 @@ import {
|
|
|
16149
16152
|
import { formatRelativeTime as formatRelativeTime2 } from "@ai-matrx/kit/format";
|
|
16150
16153
|
import { Fragment as Fragment16, jsx as jsx57, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
16151
16154
|
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.";
|
|
16152
|
-
function cellState(
|
|
16153
|
-
if (!
|
|
16154
|
-
if (
|
|
16155
|
-
if (
|
|
16156
|
-
if (
|
|
16155
|
+
function cellState(cell2) {
|
|
16156
|
+
if (!cell2 || !cell2.agent_owned) return "none";
|
|
16157
|
+
if (cell2.pinned) return "yours";
|
|
16158
|
+
if (cell2.absent_reason === "conflicting") return "unsure";
|
|
16159
|
+
if (cell2.actor === "agent") return "agent";
|
|
16157
16160
|
return "none";
|
|
16158
16161
|
}
|
|
16159
16162
|
function ago(at) {
|
|
16160
16163
|
return at ? formatRelativeTime2(at, { style: "intl", fallback: "" }) : "";
|
|
16161
16164
|
}
|
|
16162
|
-
function EnrichBadge({ cell, onPin, className }) {
|
|
16163
|
-
const state = cellState(
|
|
16164
|
-
if (!
|
|
16165
|
-
const source =
|
|
16165
|
+
function EnrichBadge({ cell: cell2, onPin, className }) {
|
|
16166
|
+
const state = cellState(cell2);
|
|
16167
|
+
if (!cell2 || state === "none") return null;
|
|
16168
|
+
const source = cell2.source ?? {};
|
|
16166
16169
|
const read = Array.isArray(source.read) ? source.read : [];
|
|
16167
|
-
const alternates =
|
|
16170
|
+
const alternates = cell2.alternates ?? [];
|
|
16168
16171
|
const word = state === "yours" ? "yours" : state === "unsure" ? "unsure" : "agent";
|
|
16169
16172
|
return /* @__PURE__ */ jsxs52(HoverCard, { openDelay: 120, children: [
|
|
16170
16173
|
/* @__PURE__ */ jsx57(HoverCardTrigger, { asChild: true, children: /* @__PURE__ */ jsxs52("span", { className: cn32("inline-flex items-center gap-1 align-middle", className), children: [
|
|
@@ -16176,18 +16179,18 @@ function EnrichBadge({ cell, onPin, className }) {
|
|
|
16176
16179
|
children: word
|
|
16177
16180
|
}
|
|
16178
16181
|
),
|
|
16179
|
-
|
|
16182
|
+
cell2.stale ? /* @__PURE__ */ jsx57(Badge8, { variant: "outline", className: "text-[10px] font-normal leading-none opacity-70", children: "stale" }) : null
|
|
16180
16183
|
] }) }),
|
|
16181
16184
|
/* @__PURE__ */ jsxs52(HoverCardContent, { className: "w-80 space-y-2 text-xs", children: [
|
|
16182
16185
|
/* @__PURE__ */ jsx57("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" }),
|
|
16183
|
-
state !== "yours" &&
|
|
16186
|
+
state !== "yours" && cell2.on_behalf_of ? /* @__PURE__ */ jsxs52("p", { className: "text-muted-foreground", children: [
|
|
16184
16187
|
"Acting for ",
|
|
16185
|
-
|
|
16186
|
-
|
|
16188
|
+
cell2.on_behalf_of,
|
|
16189
|
+
cell2.written_at ? `, ${ago(cell2.written_at)}` : "",
|
|
16187
16190
|
"."
|
|
16188
|
-
] }) :
|
|
16191
|
+
] }) : cell2.written_at ? /* @__PURE__ */ jsxs52("p", { className: "text-muted-foreground", children: [
|
|
16189
16192
|
"Written ",
|
|
16190
|
-
ago(
|
|
16193
|
+
ago(cell2.written_at),
|
|
16191
16194
|
"."
|
|
16192
16195
|
] }) : null,
|
|
16193
16196
|
source.model ? /* @__PURE__ */ jsxs52("p", { className: "text-muted-foreground", children: [
|
|
@@ -16204,9 +16207,9 @@ function EnrichBadge({ cell, onPin, className }) {
|
|
|
16204
16207
|
/* @__PURE__ */ jsx57("p", { className: "text-muted-foreground", children: state === "unsure" ? "What it considered" : "What it nearly said instead" }),
|
|
16205
16208
|
/* @__PURE__ */ jsx57("ul", { className: "list-inside list-decimal", children: alternates.slice(0, 4).map((a, i) => /* @__PURE__ */ jsx57("li", { children: String(a.value ?? "") }, i)) })
|
|
16206
16209
|
] }) : null,
|
|
16207
|
-
|
|
16210
|
+
cell2.stale && cell2.due_at ? /* @__PURE__ */ jsxs52("p", { className: "text-muted-foreground", children: [
|
|
16208
16211
|
"Past its date \u2014 it was due to be looked at again ",
|
|
16209
|
-
ago(
|
|
16212
|
+
ago(cell2.due_at),
|
|
16210
16213
|
". The value is still here; nothing was overwritten."
|
|
16211
16214
|
] }) : null,
|
|
16212
16215
|
onPin ? /* @__PURE__ */ jsx57(
|
|
@@ -16215,8 +16218,8 @@ function EnrichBadge({ cell, onPin, className }) {
|
|
|
16215
16218
|
size: "sm",
|
|
16216
16219
|
variant: "outline",
|
|
16217
16220
|
className: "w-full",
|
|
16218
|
-
onClick: () => void onPin(!
|
|
16219
|
-
children:
|
|
16221
|
+
onClick: () => void onPin(!cell2.pinned),
|
|
16222
|
+
children: cell2.pinned ? "Let the model fill this in again" : "Keep this one \u2014 stop the model changing it"
|
|
16220
16223
|
}
|
|
16221
16224
|
) : null
|
|
16222
16225
|
] })
|
|
@@ -16239,7 +16242,7 @@ function useEnrichCells(tableId, recordIds) {
|
|
|
16239
16242
|
}
|
|
16240
16243
|
setError(null);
|
|
16241
16244
|
const next = /* @__PURE__ */ new Map();
|
|
16242
|
-
for (const
|
|
16245
|
+
for (const cell2 of answered.data) next.set(`${cell2.record_id}:${cell2.field_key}`, cell2);
|
|
16243
16246
|
setCells(next);
|
|
16244
16247
|
}, [client, tableId, key]);
|
|
16245
16248
|
useEffect39(() => {
|
|
@@ -16709,7 +16712,7 @@ function columnForField(field2, editing, mayWriteRow, whyNotRow, look, onAskWhoC
|
|
|
16709
16712
|
filter: filterRefusal(field2) !== null ? false : editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? "select" : holdsNumbers(field2) ? "number" : "auto",
|
|
16710
16713
|
// THE MENU'S VALUE LIST WEARS THE CHOICES' COLOURS (lane CELL-EDITORS, night walk 2026-10-06): the
|
|
16711
16714
|
// same chip the cell draws, never bare words beside a coloured column.
|
|
16712
|
-
...editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? { filterValueClass: (value) => choiceChipLookOf(field2, value).className } : {},
|
|
16715
|
+
...editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? { filterValueClass: (value, label) => choiceChipLookOf(field2, value, label).className } : {},
|
|
16713
16716
|
cell: (row) => (
|
|
16714
16717
|
/*
|
|
16715
16718
|
* 🚨 A READING QUESTION IS NOT AN EDITING RIGHT. This used to read
|
|
@@ -17182,7 +17185,7 @@ function PlanTable({ plan }) {
|
|
|
17182
17185
|
const keys = Array.from(new Set(shown4.flatMap((row) => row.cells.map((c) => c.key))));
|
|
17183
17186
|
if (shown4.length === 0 || keys.length === 0) return null;
|
|
17184
17187
|
const columnName = /* @__PURE__ */ new Map();
|
|
17185
|
-
for (const row of shown4) for (const
|
|
17188
|
+
for (const row of shown4) for (const cell2 of row.cells) if (!columnName.has(cell2.key)) columnName.set(cell2.key, cell2.column);
|
|
17186
17189
|
return /* @__PURE__ */ jsxs55("div", { className: "overflow-auto rounded border", children: [
|
|
17187
17190
|
/* @__PURE__ */ jsxs55("table", { className: "w-full text-xs", "data-matrx-paste-plan": true, children: [
|
|
17188
17191
|
/* @__PURE__ */ jsx60("thead", { className: "bg-muted/50", children: /* @__PURE__ */ jsxs55("tr", { children: [
|
|
@@ -17195,18 +17198,18 @@ function PlanTable({ plan }) {
|
|
|
17195
17198
|
row.recordId === null ? /* @__PURE__ */ jsx60(Badge9, { variant: "outline", className: "ml-1", children: "new" }) : null
|
|
17196
17199
|
] }),
|
|
17197
17200
|
keys.map((key) => {
|
|
17198
|
-
const
|
|
17199
|
-
if (!
|
|
17200
|
-
if (
|
|
17201
|
-
return /* @__PURE__ */ jsx60("td", { className: "px-2 py-1 text-muted-foreground line-through", children:
|
|
17201
|
+
const cell2 = row.cells.find((c) => c.key === key);
|
|
17202
|
+
if (!cell2) return /* @__PURE__ */ jsx60("td", { className: "px-2 py-1" }, key);
|
|
17203
|
+
if (cell2.refusal !== null) {
|
|
17204
|
+
return /* @__PURE__ */ jsx60("td", { className: "px-2 py-1 text-muted-foreground line-through", children: cell2.raw }, key);
|
|
17202
17205
|
}
|
|
17203
|
-
return /* @__PURE__ */ jsx60("td", { className: "px-2 py-1", children:
|
|
17206
|
+
return /* @__PURE__ */ jsx60("td", { className: "px-2 py-1", children: cell2.value === null ? /* @__PURE__ */ jsx60("span", { className: "text-muted-foreground", children: "cleared" }) : (
|
|
17204
17207
|
// THE WORDS, NOT THE ID. A choice column stores the option
|
|
17205
17208
|
// record's id and the person pasted a word; showing the id
|
|
17206
17209
|
// here made this panel print
|
|
17207
17210
|
// `530808bf-9f2d-4062-bc09-b8cc3b162f2a` where they had
|
|
17208
17211
|
// written Drain Cleaning (FIX-10C F8).
|
|
17209
|
-
|
|
17212
|
+
cell2.display ?? String(cell2.value)
|
|
17210
17213
|
) }, key);
|
|
17211
17214
|
})
|
|
17212
17215
|
] }, row.fromLine)) })
|
|
@@ -17520,6 +17523,7 @@ function combineRows(rows, header) {
|
|
|
17520
17523
|
|
|
17521
17524
|
// src/importRefusals.ts
|
|
17522
17525
|
import { downloadFile } from "@ai-matrx/kit/download";
|
|
17526
|
+
import { toDelimited } from "@ai-matrx/kit/delimited";
|
|
17523
17527
|
function reasonShape(reason) {
|
|
17524
17528
|
return reason.replace(/"[^"]*"/g, '"\u2026"').replace(/“[^”]*”/g, "\u201C\u2026\u201D").replace(/\b\d+(?:[.,]\d+)*\b/g, "N").replace(/\s+/g, " ").trim();
|
|
17525
17529
|
}
|
|
@@ -17535,21 +17539,24 @@ function groupReasons(reasons) {
|
|
|
17535
17539
|
}
|
|
17536
17540
|
return [...groups.values()].sort((a, b) => b.count - a.count);
|
|
17537
17541
|
}
|
|
17538
|
-
function
|
|
17539
|
-
|
|
17540
|
-
return
|
|
17542
|
+
function cell(value) {
|
|
17543
|
+
if (value === null || value === void 0) return null;
|
|
17544
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : String(value);
|
|
17541
17545
|
}
|
|
17542
17546
|
function refusedRowsCsv(rows, lineOf = (n) => n + 1) {
|
|
17543
17547
|
const headers = [];
|
|
17544
17548
|
for (const r of rows) for (const h of Object.keys(r.source ?? {})) if (!headers.includes(h)) headers.push(h);
|
|
17545
|
-
|
|
17546
|
-
|
|
17547
|
-
|
|
17548
|
-
|
|
17549
|
-
|
|
17550
|
-
|
|
17551
|
-
|
|
17552
|
-
|
|
17549
|
+
return toDelimited(
|
|
17550
|
+
[
|
|
17551
|
+
[...headers, "Line in your file", "Why it was not added"],
|
|
17552
|
+
...rows.map((r) => [
|
|
17553
|
+
...headers.map((h) => cell((r.source ?? {})[h])),
|
|
17554
|
+
typeof r.row === "number" ? lineOf(r.row) : "",
|
|
17555
|
+
r.reason ?? ""
|
|
17556
|
+
])
|
|
17557
|
+
],
|
|
17558
|
+
{ trailingNewline: true }
|
|
17559
|
+
);
|
|
17553
17560
|
}
|
|
17554
17561
|
function offerDownload(name, text, type = "text/csv") {
|
|
17555
17562
|
if (typeof document === "undefined" || typeof URL === "undefined" || typeof URL.createObjectURL !== "function") return false;
|
|
@@ -19053,18 +19060,18 @@ function splitPipes(line) {
|
|
|
19053
19060
|
if (text.startsWith("|")) text = text.slice(1);
|
|
19054
19061
|
if (text.endsWith("|") && !text.endsWith("\\|")) text = text.slice(0, -1);
|
|
19055
19062
|
const cells = [];
|
|
19056
|
-
let
|
|
19063
|
+
let cell2 = "";
|
|
19057
19064
|
for (let i = 0; i < text.length; i += 1) {
|
|
19058
19065
|
const ch = text[i];
|
|
19059
19066
|
if (ch === "\\" && text[i + 1] === "|") {
|
|
19060
|
-
|
|
19067
|
+
cell2 += "\\|";
|
|
19061
19068
|
i += 1;
|
|
19062
19069
|
} else if (ch === "|") {
|
|
19063
|
-
cells.push(
|
|
19064
|
-
|
|
19065
|
-
} else
|
|
19070
|
+
cells.push(cell2);
|
|
19071
|
+
cell2 = "";
|
|
19072
|
+
} else cell2 += ch;
|
|
19066
19073
|
}
|
|
19067
|
-
cells.push(
|
|
19074
|
+
cells.push(cell2);
|
|
19068
19075
|
return cells.map(cellWords);
|
|
19069
19076
|
}
|
|
19070
19077
|
var LIST_ITEM = /^(\s*)(?:[-*+•]|\d{1,3}[.)])\s+(?:\[[ xX]\]\s+)?(.*)$/;
|
|
@@ -19181,33 +19188,33 @@ function shapeFromList(items, name, at) {
|
|
|
19181
19188
|
function parseDelimited(text, delimiter) {
|
|
19182
19189
|
const rows = [];
|
|
19183
19190
|
let row = [];
|
|
19184
|
-
let
|
|
19191
|
+
let cell2 = "";
|
|
19185
19192
|
let quoted2 = false;
|
|
19186
19193
|
for (let i = 0; i < text.length; i += 1) {
|
|
19187
19194
|
const ch = text[i];
|
|
19188
19195
|
if (quoted2) {
|
|
19189
19196
|
if (ch === '"') {
|
|
19190
19197
|
if (text[i + 1] === '"') {
|
|
19191
|
-
|
|
19198
|
+
cell2 += '"';
|
|
19192
19199
|
i += 1;
|
|
19193
19200
|
} else quoted2 = false;
|
|
19194
|
-
} else
|
|
19201
|
+
} else cell2 += ch;
|
|
19195
19202
|
continue;
|
|
19196
19203
|
}
|
|
19197
|
-
if (ch === '"' &&
|
|
19204
|
+
if (ch === '"' && cell2.trim() === "") quoted2 = true;
|
|
19198
19205
|
else if (ch === delimiter) {
|
|
19199
|
-
row.push(
|
|
19200
|
-
|
|
19206
|
+
row.push(cell2);
|
|
19207
|
+
cell2 = "";
|
|
19201
19208
|
} else if (ch === "\n" || ch === "\r") {
|
|
19202
19209
|
if (ch === "\r" && text[i + 1] === "\n") i += 1;
|
|
19203
|
-
row.push(
|
|
19210
|
+
row.push(cell2);
|
|
19204
19211
|
rows.push(row);
|
|
19205
19212
|
row = [];
|
|
19206
|
-
|
|
19207
|
-
} else
|
|
19213
|
+
cell2 = "";
|
|
19214
|
+
} else cell2 += ch;
|
|
19208
19215
|
}
|
|
19209
|
-
if (
|
|
19210
|
-
row.push(
|
|
19216
|
+
if (cell2.length > 0 || row.length > 0) {
|
|
19217
|
+
row.push(cell2);
|
|
19211
19218
|
rows.push(row);
|
|
19212
19219
|
}
|
|
19213
19220
|
return rows.filter((r) => r.some((c) => c.trim() !== ""));
|
|
@@ -19510,10 +19517,10 @@ function shapeTextOfNode(node) {
|
|
|
19510
19517
|
flushLine();
|
|
19511
19518
|
const width = Math.max(...rows.map((r) => r.length));
|
|
19512
19519
|
const pad4 = (r) => [...r, ...Array.from({ length: width - r.length }, () => "")];
|
|
19513
|
-
const
|
|
19514
|
-
out.push(`| ${pad4(rows[0]).map(
|
|
19520
|
+
const cell2 = (c) => c.replace(/\|/g, "\\|").replace(/\s+/g, " ").trim();
|
|
19521
|
+
out.push(`| ${pad4(rows[0]).map(cell2).join(" | ")} |`);
|
|
19515
19522
|
out.push(`|${Array.from({ length: width }, () => "---").join("|")}|`);
|
|
19516
|
-
for (const r of rows.slice(1)) out.push(`| ${pad4(r).map(
|
|
19523
|
+
for (const r of rows.slice(1)) out.push(`| ${pad4(r).map(cell2).join(" | ")} |`);
|
|
19517
19524
|
rows = [];
|
|
19518
19525
|
};
|
|
19519
19526
|
const textOf = (n) => (n.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
@@ -19939,12 +19946,12 @@ import { createUndoStack, popRedo, popUndo, pushUndo } from "@ai-matrx/design-sy
|
|
|
19939
19946
|
import { Fragment as Fragment22, jsx as jsx66, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
19940
19947
|
function changesFor(step2, direction, versions = /* @__PURE__ */ new Map()) {
|
|
19941
19948
|
const byRow = /* @__PURE__ */ new Map();
|
|
19942
|
-
for (const
|
|
19943
|
-
if (step2.created?.includes(
|
|
19944
|
-
const patch = byRow.get(
|
|
19945
|
-
const value = direction === "undo" ?
|
|
19946
|
-
patch[
|
|
19947
|
-
byRow.set(
|
|
19949
|
+
for (const cell2 of step2.cells) {
|
|
19950
|
+
if (step2.created?.includes(cell2.rowId)) continue;
|
|
19951
|
+
const patch = byRow.get(cell2.rowId) ?? {};
|
|
19952
|
+
const value = direction === "undo" ? cell2.before : cell2.after;
|
|
19953
|
+
patch[cell2.key] = value === void 0 ? null : value;
|
|
19954
|
+
byRow.set(cell2.rowId, patch);
|
|
19948
19955
|
}
|
|
19949
19956
|
const changes = [...byRow].map(([record_id, patch]) => ({
|
|
19950
19957
|
op: "update",
|
|
@@ -19972,7 +19979,7 @@ function useGridUndo(args) {
|
|
|
19972
19979
|
const dismiss = useCallback23(() => setNotice(null), []);
|
|
19973
19980
|
const push = useCallback23((step2) => {
|
|
19974
19981
|
if (step2.cells.length === 0 && !step2.created?.length && !step2.archived?.length && !step2.retiredField) return;
|
|
19975
|
-
for (const
|
|
19982
|
+
for (const cell2 of step2.cells) if (typeof cell2.version === "number") known.current.set(cell2.rowId, cell2.version);
|
|
19976
19983
|
counter.current += 1;
|
|
19977
19984
|
const id = String(counter.current);
|
|
19978
19985
|
setHeld((was) => {
|
|
@@ -20301,13 +20308,12 @@ function useGridAssist(args) {
|
|
|
20301
20308
|
const copyRecordReference = useCallback24(
|
|
20302
20309
|
(rowId) => {
|
|
20303
20310
|
void (async () => {
|
|
20304
|
-
|
|
20305
|
-
|
|
20306
|
-
|
|
20307
|
-
|
|
20308
|
-
} catch (thrown) {
|
|
20309
|
-
say2(false, thrown instanceof Error ? thrown.message : String(thrown));
|
|
20311
|
+
const text = JSON.stringify({ __kind: tableKindSlug(tableId), _record_id: rowId });
|
|
20312
|
+
if (!await copyText(text)) {
|
|
20313
|
+
say2(false, "This browser did not let the page write to the clipboard.");
|
|
20314
|
+
return;
|
|
20310
20315
|
}
|
|
20316
|
+
say2(true, "The record reference is copied.");
|
|
20311
20317
|
})();
|
|
20312
20318
|
},
|
|
20313
20319
|
[tableId, say2]
|
|
@@ -20484,9 +20490,9 @@ function planBulk(args) {
|
|
|
20484
20490
|
before: (row.document ?? {})[field2.key] ?? null,
|
|
20485
20491
|
after: value
|
|
20486
20492
|
}));
|
|
20487
|
-
const changes = cells.map((
|
|
20493
|
+
const changes = cells.map((cell2) => ({
|
|
20488
20494
|
op: "update",
|
|
20489
|
-
record_id:
|
|
20495
|
+
record_id: cell2.rowId,
|
|
20490
20496
|
patch: { [field2.key]: value }
|
|
20491
20497
|
}));
|
|
20492
20498
|
const many = countOf(cells.length, args.noun, args.nounPlural);
|
|
@@ -21922,8 +21928,8 @@ function GridBody({
|
|
|
21922
21928
|
pastedNames.set(
|
|
21923
21929
|
field2.key,
|
|
21924
21930
|
lines.flatMap((line) => {
|
|
21925
|
-
const
|
|
21926
|
-
return typeof
|
|
21931
|
+
const cell2 = line[at];
|
|
21932
|
+
return typeof cell2 === "string" ? relationNamesIn2(field2, cell2) : [];
|
|
21927
21933
|
})
|
|
21928
21934
|
);
|
|
21929
21935
|
}
|
|
@@ -30969,8 +30975,8 @@ function CalendarView({
|
|
|
30969
30975
|
}
|
|
30970
30976
|
});
|
|
30971
30977
|
const dayDrop = (fallback) => dropOn((e) => {
|
|
30972
|
-
const
|
|
30973
|
-
return { day:
|
|
30978
|
+
const cell2 = e.target.closest?.("[data-calendar-day]");
|
|
30979
|
+
return { day: cell2?.getAttribute("data-calendar-day") ?? fallback, minute: null };
|
|
30974
30980
|
});
|
|
30975
30981
|
const minuteAt = (e) => {
|
|
30976
30982
|
const slot = e.target?.closest?.("[data-calendar-slot]");
|