@ai-matrx/records-ui 0.113.27 → 0.113.29
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 +30 -0
- package/dist/index.cjs +104 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.js +105 -32
- package/dist/index.js.map +1 -1
- package/dist/pickers.cjs +9 -6
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.js +9 -6
- package/dist/pickers.js.map +1 -1
- package/package.json +7 -7
package/dist/index.d.cts
CHANGED
|
@@ -3242,8 +3242,13 @@ interface RelationPickerProps {
|
|
|
3242
3242
|
onClose?: (() => void) | undefined;
|
|
3243
3243
|
/** Escape in a grid cell's list: the cell's cancel — nothing is written (`PickOrAdd.onEscape`). */
|
|
3244
3244
|
onCancel?: (() => void) | undefined;
|
|
3245
|
+
/**
|
|
3246
|
+
* THE RECORD BEING EDITED (walk 2026-10-08 D11): never offered in its own list — a row cannot be
|
|
3247
|
+
* blocked by, or the parent of, itself (the store refuses it too).
|
|
3248
|
+
*/
|
|
3249
|
+
excludeId?: string | undefined;
|
|
3245
3250
|
}
|
|
3246
|
-
declare function RelationPicker({ field, value, onChange, disabled, id, className, allowCreate, onPicked, autoOpen, onClose, onCancel }: RelationPickerProps): react.JSX.Element;
|
|
3251
|
+
declare function RelationPicker({ field, value, onChange, disabled, id, className, allowCreate, onPicked, autoOpen, onClose, onCancel, excludeId }: RelationPickerProps): react.JSX.Element;
|
|
3247
3252
|
|
|
3248
3253
|
interface PickOrAddItem {
|
|
3249
3254
|
id: string;
|
|
@@ -3451,6 +3456,8 @@ interface FieldEditorControlProps {
|
|
|
3451
3456
|
asForm?: boolean | undefined;
|
|
3452
3457
|
/** A FORM'S SINGLE CHOICE WAS PICKED (lane TYPEFORM-2): the runner may go on to the next question. */
|
|
3453
3458
|
onChosen?: (() => void) | undefined;
|
|
3459
|
+
/** The record whose value this is: a link picker never offers it (walk 2026-10-08 D11). */
|
|
3460
|
+
recordId?: string | undefined;
|
|
3454
3461
|
}
|
|
3455
3462
|
/** The label row every editor shares: one line, the label, the unit, the required mark. */
|
|
3456
3463
|
declare function FieldLabel({ field, htmlFor, children }: {
|
|
@@ -3458,7 +3465,7 @@ declare function FieldLabel({ field, htmlFor, children }: {
|
|
|
3458
3465
|
htmlFor: string;
|
|
3459
3466
|
children?: ReactNode;
|
|
3460
3467
|
}): react.JSX.Element;
|
|
3461
|
-
declare function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose, onCommit, onCancel, addsChoices, initialSearch, asForm, onChosen }: FieldEditorControlProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element | null;
|
|
3468
|
+
declare function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose, onCommit, onCancel, addsChoices, initialSearch, asForm, onChosen, recordId }: FieldEditorControlProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element | null;
|
|
3462
3469
|
/** The chip a picked record shows as — REC-2's "a record is a chip" in one place. */
|
|
3463
3470
|
declare function RecordChip({ title, onRemove, className, }: {
|
|
3464
3471
|
title: string;
|
|
@@ -4461,10 +4468,6 @@ interface ViewBarProps {
|
|
|
4461
4468
|
* still works and a longer sentence would suggest otherwise.
|
|
4462
4469
|
*/
|
|
4463
4470
|
declare const SAVED_VIEWS_UNAVAILABLE: string;
|
|
4464
|
-
/**
|
|
4465
|
-
* WHETHER A SEED IS ALREADY THERE. A view by the seed's name always satisfies it; a DEFAULT seed
|
|
4466
|
-
* is also satisfied by any view the table already marks as its default, whatever it is called.
|
|
4467
|
-
*/
|
|
4468
4471
|
declare function seedIsSatisfied(seed: SavedViewSpec, views: readonly SavedView[]): boolean;
|
|
4469
4472
|
declare function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews, initialViews, className }: ViewBarProps): react.JSX.Element;
|
|
4470
4473
|
|
package/dist/index.d.ts
CHANGED
|
@@ -3242,8 +3242,13 @@ interface RelationPickerProps {
|
|
|
3242
3242
|
onClose?: (() => void) | undefined;
|
|
3243
3243
|
/** Escape in a grid cell's list: the cell's cancel — nothing is written (`PickOrAdd.onEscape`). */
|
|
3244
3244
|
onCancel?: (() => void) | undefined;
|
|
3245
|
+
/**
|
|
3246
|
+
* THE RECORD BEING EDITED (walk 2026-10-08 D11): never offered in its own list — a row cannot be
|
|
3247
|
+
* blocked by, or the parent of, itself (the store refuses it too).
|
|
3248
|
+
*/
|
|
3249
|
+
excludeId?: string | undefined;
|
|
3245
3250
|
}
|
|
3246
|
-
declare function RelationPicker({ field, value, onChange, disabled, id, className, allowCreate, onPicked, autoOpen, onClose, onCancel }: RelationPickerProps): react.JSX.Element;
|
|
3251
|
+
declare function RelationPicker({ field, value, onChange, disabled, id, className, allowCreate, onPicked, autoOpen, onClose, onCancel, excludeId }: RelationPickerProps): react.JSX.Element;
|
|
3247
3252
|
|
|
3248
3253
|
interface PickOrAddItem {
|
|
3249
3254
|
id: string;
|
|
@@ -3451,6 +3456,8 @@ interface FieldEditorControlProps {
|
|
|
3451
3456
|
asForm?: boolean | undefined;
|
|
3452
3457
|
/** A FORM'S SINGLE CHOICE WAS PICKED (lane TYPEFORM-2): the runner may go on to the next question. */
|
|
3453
3458
|
onChosen?: (() => void) | undefined;
|
|
3459
|
+
/** The record whose value this is: a link picker never offers it (walk 2026-10-08 D11). */
|
|
3460
|
+
recordId?: string | undefined;
|
|
3454
3461
|
}
|
|
3455
3462
|
/** The label row every editor shares: one line, the label, the unit, the required mark. */
|
|
3456
3463
|
declare function FieldLabel({ field, htmlFor, children }: {
|
|
@@ -3458,7 +3465,7 @@ declare function FieldLabel({ field, htmlFor, children }: {
|
|
|
3458
3465
|
htmlFor: string;
|
|
3459
3466
|
children?: ReactNode;
|
|
3460
3467
|
}): react.JSX.Element;
|
|
3461
|
-
declare function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose, onCommit, onCancel, addsChoices, initialSearch, asForm, onChosen }: FieldEditorControlProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element | null;
|
|
3468
|
+
declare function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose, onCommit, onCancel, addsChoices, initialSearch, asForm, onChosen, recordId }: FieldEditorControlProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element | null;
|
|
3462
3469
|
/** The chip a picked record shows as — REC-2's "a record is a chip" in one place. */
|
|
3463
3470
|
declare function RecordChip({ title, onRemove, className, }: {
|
|
3464
3471
|
title: string;
|
|
@@ -4461,10 +4468,6 @@ interface ViewBarProps {
|
|
|
4461
4468
|
* still works and a longer sentence would suggest otherwise.
|
|
4462
4469
|
*/
|
|
4463
4470
|
declare const SAVED_VIEWS_UNAVAILABLE: string;
|
|
4464
|
-
/**
|
|
4465
|
-
* WHETHER A SEED IS ALREADY THERE. A view by the seed's name always satisfies it; a DEFAULT seed
|
|
4466
|
-
* is also satisfied by any view the table already marks as its default, whatever it is called.
|
|
4467
|
-
*/
|
|
4468
4471
|
declare function seedIsSatisfied(seed: SavedViewSpec, views: readonly SavedView[]): boolean;
|
|
4469
4472
|
declare function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews, initialViews, className }: ViewBarProps): react.JSX.Element;
|
|
4470
4473
|
|
package/dist/index.js
CHANGED
|
@@ -4603,8 +4603,11 @@ function tellApart(rows, nameOf2) {
|
|
|
4603
4603
|
|
|
4604
4604
|
// src/RelationPicker.tsx
|
|
4605
4605
|
import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4606
|
+
function withoutSelf(rows, selfId) {
|
|
4607
|
+
return selfId ? rows.filter((row) => row.id !== selfId) : rows;
|
|
4608
|
+
}
|
|
4606
4609
|
var NO_STORE_ON_THIS_SCREEN_REASON = "This question points at a record in somebody's own data, and a page answered without an account is never allowed to search that. Leave it blank \u2014 whoever receives your answer will fill it in.";
|
|
4607
|
-
function RelationPicker({ field: field2, value, onChange, disabled, id, className, allowCreate = true, onPicked, autoOpen, onClose, onCancel }) {
|
|
4610
|
+
function RelationPicker({ field: field2, value, onChange, disabled, id, className, allowCreate = true, onPicked, autoOpen, onClose, onCancel, excludeId }) {
|
|
4608
4611
|
const client = useOptionalRecordsClient3();
|
|
4609
4612
|
const [rows, setRows] = useState11(null);
|
|
4610
4613
|
const [words2, setWords] = useState11({});
|
|
@@ -4633,7 +4636,7 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
|
|
|
4633
4636
|
let cancelled = false;
|
|
4634
4637
|
void client.list({ table_id: target2, limit: 200 }).then((result) => {
|
|
4635
4638
|
if (cancelled) return;
|
|
4636
|
-
if (result.ok) setRows(result.data.rows);
|
|
4639
|
+
if (result.ok) setRows(withoutSelf(result.data.rows, excludeId));
|
|
4637
4640
|
else setRefusal(result.error);
|
|
4638
4641
|
});
|
|
4639
4642
|
return () => {
|
|
@@ -4743,7 +4746,7 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
|
|
|
4743
4746
|
}
|
|
4744
4747
|
const createdId = String(written.data);
|
|
4745
4748
|
const refreshed = await client.list({ table_id: tableId, limit: 200 });
|
|
4746
|
-
if (refreshed.ok) setRows(refreshed.data.rows);
|
|
4749
|
+
if (refreshed.ok) setRows(withoutSelf(refreshed.data.rows, excludeId));
|
|
4747
4750
|
setBusy(false);
|
|
4748
4751
|
setCreating(false);
|
|
4749
4752
|
setNewTitle("");
|
|
@@ -10920,7 +10923,7 @@ function isPersonsName(field2) {
|
|
|
10920
10923
|
const words2 = `${field2.key} ${field2.label ?? ""}`.toLowerCase();
|
|
10921
10924
|
return /(^|[\s_])(full[\s_]?)?name(\s|$)/.test(words2) && !/(therapist|doctor|physician|company|business|pet|room)/.test(words2);
|
|
10922
10925
|
}
|
|
10923
|
-
function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, onCommit, onCancel, addsChoices, initialSearch, asForm, onChosen }) {
|
|
10926
|
+
function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, onCommit, onCancel, addsChoices, initialSearch, asForm, onChosen, recordId }) {
|
|
10924
10927
|
const host = useRecordsUi();
|
|
10925
10928
|
const kind = editorKindFor(field2);
|
|
10926
10929
|
const inputId = id ?? `field-${field2.key}`;
|
|
@@ -11005,9 +11008,9 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
|
|
|
11005
11008
|
if (hostTakesFiles(host)) {
|
|
11006
11009
|
return /* @__PURE__ */ jsx41(AttachmentControl, { field: field2, value, onChange, disabled, id: inputId, autoOpen, onClose });
|
|
11007
11010
|
}
|
|
11008
|
-
return /* @__PURE__ */ jsx41(RelationPicker, { field: field2, value, onChange, disabled, id: inputId });
|
|
11011
|
+
return /* @__PURE__ */ jsx41(RelationPicker, { field: field2, value, onChange, disabled, id: inputId, excludeId: recordId });
|
|
11009
11012
|
case "relation":
|
|
11010
|
-
return /* @__PURE__ */ jsx41(RelationPicker, { field: field2, value, onChange, disabled, id: inputId, onPicked: onCommit, autoOpen, onClose, onCancel });
|
|
11013
|
+
return /* @__PURE__ */ jsx41(RelationPicker, { field: field2, value, onChange, disabled, id: inputId, onPicked: onCommit, autoOpen, onClose, onCancel, excludeId: recordId });
|
|
11011
11014
|
default:
|
|
11012
11015
|
if (typeof value === "boolean" || field2.config?.["kind"] === "boolean") {
|
|
11013
11016
|
return /* @__PURE__ */ jsx41(
|
|
@@ -12415,6 +12418,7 @@ function GridCell({
|
|
|
12415
12418
|
OpenCell,
|
|
12416
12419
|
{
|
|
12417
12420
|
field: field2,
|
|
12421
|
+
recordId: row.id,
|
|
12418
12422
|
draft: editing.draft,
|
|
12419
12423
|
initialSearch: editing.searchSeed,
|
|
12420
12424
|
onType: editing.type,
|
|
@@ -12760,7 +12764,8 @@ function OpenCell({
|
|
|
12760
12764
|
onCommit,
|
|
12761
12765
|
onCancel,
|
|
12762
12766
|
below,
|
|
12763
|
-
initialSearch
|
|
12767
|
+
initialSearch,
|
|
12768
|
+
recordId
|
|
12764
12769
|
}) {
|
|
12765
12770
|
const multiline = takesANewline(field2);
|
|
12766
12771
|
const picker = opensAsAList(field2, hostTakesFiles(useRecordsUi()));
|
|
@@ -12883,7 +12888,8 @@ function OpenCell({
|
|
|
12883
12888
|
...picker && ahead ? { initialSearch: ahead } : {},
|
|
12884
12889
|
onCommit: () => once(() => onCommit(null, "pick")),
|
|
12885
12890
|
onCancel: () => once(() => onCancel("pick")),
|
|
12886
|
-
addsChoices: true
|
|
12891
|
+
addsChoices: true,
|
|
12892
|
+
recordId
|
|
12887
12893
|
}
|
|
12888
12894
|
),
|
|
12889
12895
|
/* @__PURE__ */ jsxs38("span", { "data-records-cell-tray": "", className: FLOATING_CELL_TRAY_CLASS, children: [
|
|
@@ -14960,6 +14966,7 @@ function ActionsHeaderControls({ onAddColumn }) {
|
|
|
14960
14966
|
"aria-label": ADD_COLUMN_LABEL,
|
|
14961
14967
|
title: ADD_COLUMN_LABEL,
|
|
14962
14968
|
"data-records-actions-header-add": "",
|
|
14969
|
+
"data-records-add-column": "",
|
|
14963
14970
|
onClick: (event) => {
|
|
14964
14971
|
event.stopPropagation();
|
|
14965
14972
|
onAddColumn();
|
|
@@ -17399,6 +17406,7 @@ function CustomRecordForm({
|
|
|
17399
17406
|
/* @__PURE__ */ jsx60("div", { className: "grid gap-3 sm:grid-cols-2", children: (fields.data ?? []).map((field2) => /* @__PURE__ */ jsx60(
|
|
17400
17407
|
FieldRow,
|
|
17401
17408
|
{
|
|
17409
|
+
recordId,
|
|
17402
17410
|
field: field2,
|
|
17403
17411
|
value: draft[field2.key],
|
|
17404
17412
|
document: existing.data?.document,
|
|
@@ -17473,7 +17481,8 @@ function FieldRow({
|
|
|
17473
17481
|
problems,
|
|
17474
17482
|
onChange,
|
|
17475
17483
|
onKeepEditing,
|
|
17476
|
-
onDiscard
|
|
17484
|
+
onDiscard,
|
|
17485
|
+
recordId
|
|
17477
17486
|
}) {
|
|
17478
17487
|
const id = `field-${field2.id}`;
|
|
17479
17488
|
const storedWords = document2?.[field2.key];
|
|
@@ -17484,7 +17493,7 @@ function FieldRow({
|
|
|
17484
17493
|
// A TEXT KEPT AS A FILE opens WHOLE, never as the 1000 characters its cell holds —
|
|
17485
17494
|
// saving those would cut the value (lane BIG-VALUES-WRITE).
|
|
17486
17495
|
/* @__PURE__ */ jsx60(WholeValueEditor, { field: field2, pointer: whole, words: String(storedWords ?? ""), value, onChange, id })
|
|
17487
|
-
) : /* @__PURE__ */ jsx60(FieldControl, { field: field2, value, onChange, id }),
|
|
17496
|
+
) : /* @__PURE__ */ jsx60(FieldControl, { field: field2, value, onChange, id, recordId }),
|
|
17488
17497
|
problems.map((problem, index) => /* @__PURE__ */ jsx60(
|
|
17489
17498
|
RefusalNotice,
|
|
17490
17499
|
{
|
|
@@ -19176,6 +19185,9 @@ function useReverseGridColumns(tableId, rowIds) {
|
|
|
19176
19185
|
label: column.label,
|
|
19177
19186
|
accessorFn: (row) => held.answers?.[column.key]?.[row.id]?.total ?? 0,
|
|
19178
19187
|
sortable: false,
|
|
19188
|
+
// THE SAME HEADER AS EVERY OTHER COLUMN (WALK-FIXES-3 D13): its hover icon opens the menu,
|
|
19189
|
+
// which says why this column cannot sort — its links are kept on the other table.
|
|
19190
|
+
sortRefusal: `Kept on ${column.source_table_name}, so it cannot sort here.`,
|
|
19179
19191
|
filter: false,
|
|
19180
19192
|
copyValue: (row) => (held.answers?.[column.key]?.[row.id]?.links ?? []).map((l) => l.words).join(", "),
|
|
19181
19193
|
cell: (row) => row.id === SUMMARY_ROW_ID || row.id === ADD_ROW_ID ? null : /* @__PURE__ */ jsx64(ReverseCell, { held, column, rowId: row.id, tableId }),
|
|
@@ -19218,10 +19230,14 @@ function ReverseCell({ held, column, rowId, tableId }) {
|
|
|
19218
19230
|
const reading = useSyncExternalStore3(subscribe, readReading, readReading);
|
|
19219
19231
|
const chips = /* @__PURE__ */ jsx64(ReverseLinkChips, { column, answer, loading: reading, clamp: { tableId, recordId: rowId } });
|
|
19220
19232
|
if (column.read_only) return chips;
|
|
19221
|
-
return /* @__PURE__ */
|
|
19222
|
-
|
|
19223
|
-
|
|
19224
|
-
|
|
19233
|
+
return /* @__PURE__ */ jsx64(ReverseLinksEditCell, { tableId, recordId: rowId, column, chips });
|
|
19234
|
+
}
|
|
19235
|
+
var reverseCellOpeners = /* @__PURE__ */ new Map();
|
|
19236
|
+
function openReverseCell(rowId, columnId2) {
|
|
19237
|
+
const open = reverseCellOpeners.get(`${rowId}|${columnId2}`);
|
|
19238
|
+
if (!open) return false;
|
|
19239
|
+
open();
|
|
19240
|
+
return true;
|
|
19225
19241
|
}
|
|
19226
19242
|
function useReverseField(tableId, column) {
|
|
19227
19243
|
const client = useOptionalRecordsClient11();
|
|
@@ -19259,27 +19275,48 @@ function ReverseLinksEditor({ tableId, recordId, column, autoOpen, onClose }) {
|
|
|
19259
19275
|
if (done.ok) read.reload();
|
|
19260
19276
|
};
|
|
19261
19277
|
return /* @__PURE__ */ jsxs59("span", { className: "flex min-w-0 flex-col gap-1", "data-records-reverse-editor": column.key, children: [
|
|
19262
|
-
/* @__PURE__ */ jsx64(RelationPicker, { field: field2, value: current, onChange: (next) => void write(next), autoOpen, onClose }),
|
|
19278
|
+
/* @__PURE__ */ jsx64(RelationPicker, { field: field2, value: current, onChange: (next) => void write(next), autoOpen, onClose, excludeId: recordId }),
|
|
19263
19279
|
refused ? /* @__PURE__ */ jsx64(RefusalNotice, { error: refused }) : null
|
|
19264
19280
|
] });
|
|
19265
19281
|
}
|
|
19266
19282
|
var REVERSE_LINKS_EDIT_MAX = 50;
|
|
19267
|
-
function
|
|
19283
|
+
function ReverseLinksEditCell({ tableId, recordId, column, chips }) {
|
|
19268
19284
|
const [open, setOpen] = useState54(false);
|
|
19285
|
+
const key = `${recordId}|${reverseColumnId(column)}`;
|
|
19286
|
+
useEffect44(() => {
|
|
19287
|
+
reverseCellOpeners.set(key, () => setOpen(true));
|
|
19288
|
+
return () => {
|
|
19289
|
+
reverseCellOpeners.delete(key);
|
|
19290
|
+
};
|
|
19291
|
+
}, [key]);
|
|
19269
19292
|
return /* @__PURE__ */ jsxs59(Popover8, { open, onOpenChange: setOpen, children: [
|
|
19270
19293
|
/* @__PURE__ */ jsx64(PopoverTrigger8, { asChild: true, children: /* @__PURE__ */ jsx64(
|
|
19271
|
-
|
|
19294
|
+
"span",
|
|
19272
19295
|
{
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
"
|
|
19277
|
-
title: `Link ${column.source_table_name}`,
|
|
19296
|
+
role: "button",
|
|
19297
|
+
tabIndex: 0,
|
|
19298
|
+
"data-matrx-cell-control": "",
|
|
19299
|
+
"data-matrx-cell-fill": "",
|
|
19278
19300
|
"data-records-reverse-edit": column.key,
|
|
19279
|
-
|
|
19301
|
+
"aria-label": `Edit ${column.label}`,
|
|
19302
|
+
title: `${column.label} \u2014 click or press Enter to edit`,
|
|
19303
|
+
className: "flex w-full min-w-0 cursor-text items-center gap-1 rounded px-1 py-0.5 hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
19304
|
+
onClick: (event) => {
|
|
19305
|
+
if (event.target instanceof Element && event.target.closest("a[href]")) {
|
|
19306
|
+
event.preventDefault();
|
|
19307
|
+
return;
|
|
19308
|
+
}
|
|
19309
|
+
},
|
|
19310
|
+
onKeyDown: (event) => {
|
|
19311
|
+
if (event.key === "Enter" || event.key === "F2") {
|
|
19312
|
+
event.preventDefault();
|
|
19313
|
+
setOpen(true);
|
|
19314
|
+
}
|
|
19315
|
+
},
|
|
19316
|
+
children: /* @__PURE__ */ jsx64("span", { className: "min-w-0 flex-1", children: chips })
|
|
19280
19317
|
}
|
|
19281
19318
|
) }),
|
|
19282
|
-
/* @__PURE__ */ jsx64(PopoverContent8, { sizing: "content", align: "start", className: "w-80 p-2", children: open ? /* @__PURE__ */ jsx64(ReverseLinksEditor, { tableId, recordId, column }) : null })
|
|
19319
|
+
/* @__PURE__ */ jsx64(PopoverContent8, { sizing: "content", align: "start", className: "w-80 p-2", children: open ? /* @__PURE__ */ jsx64(ReverseLinksEditor, { tableId, recordId, column, autoOpen: true, onClose: () => setOpen(false) }) : null })
|
|
19283
19320
|
] });
|
|
19284
19321
|
}
|
|
19285
19322
|
var EMPTY_COLUMNS = [];
|
|
@@ -24929,9 +24966,10 @@ function GridBody({
|
|
|
24929
24966
|
(key) => holdHeaderMenu(headerHeld.current, menuLatest.current, key, controls.headerMenuFor(key)),
|
|
24930
24967
|
(key) => holdByContent(headerHeld.current, `filter:${key}`, filterFor(key))
|
|
24931
24968
|
);
|
|
24932
|
-
|
|
24969
|
+
const pinnedPlus = offersRowActions && mayManageActions;
|
|
24970
|
+
return merged && rights.structure && !readOnly && !pinnedPlus ? [...drawn, addColumnDef] : drawn;
|
|
24933
24971
|
},
|
|
24934
|
-
[bodyColumns, controls.headerMenuFor, controls.filterFor, merged, rights.structure, readOnly, addColumnDef]
|
|
24972
|
+
[bodyColumns, controls.headerMenuFor, controls.filterFor, merged, rights.structure, readOnly, addColumnDef, offersRowActions, mayManageActions]
|
|
24935
24973
|
);
|
|
24936
24974
|
const columnsHeld = useRef37(null);
|
|
24937
24975
|
const columns = columnsHeld.current !== null && sameColumns(columnsHeld.current, drawnColumns) ? columnsHeld.current : drawnColumns;
|
|
@@ -24940,7 +24978,7 @@ function GridBody({
|
|
|
24940
24978
|
() => offersRowActions ? [...columns, { id: "custom-actions", header: merged ? /* @__PURE__ */ jsxs69("span", { className: "inline-flex items-center gap-0.5", children: [
|
|
24941
24979
|
/* @__PURE__ */ jsx76("span", { children: "Actions" }),
|
|
24942
24980
|
actionsHeader
|
|
24943
|
-
] }) : "Actions", label: "Actions", reorderable: false, sortable: false, filter: false, customActions: rowActions }] : columns,
|
|
24981
|
+
] }) : "Actions", label: "Actions", reorderable: false, sortable: false, filter: false, customActions: rowActions, cell: drawNothing }] : columns,
|
|
24944
24982
|
[columns, offersRowActions, merged, actionsHeader, rowActions]
|
|
24945
24983
|
);
|
|
24946
24984
|
const [localColumns, setLocalColumns] = useState63(
|
|
@@ -25108,6 +25146,9 @@ function GridBody({
|
|
|
25108
25146
|
*/
|
|
25109
25147
|
onEditRequest: (address2, seed) => {
|
|
25110
25148
|
const now = sheetNow.current;
|
|
25149
|
+
if (address2.columnId.startsWith(REVERSE_COLUMN_PREFIX)) {
|
|
25150
|
+
return (seed === null || seed === "") && now.mayWriteRow(address2.rowId) && openReverseCell(address2.rowId, address2.columnId);
|
|
25151
|
+
}
|
|
25111
25152
|
const field2 = now.fields.find((f) => f.key === address2.columnId);
|
|
25112
25153
|
if (!field2 || !fieldIsEditable(field2) || !now.mayWriteRow(address2.rowId)) return false;
|
|
25113
25154
|
if (editorKindFor(field2) === "checkbox") {
|
|
@@ -35892,6 +35933,7 @@ function copyName(name, taken) {
|
|
|
35892
35933
|
// src/ViewBar.tsx
|
|
35893
35934
|
import { jsx as jsx117, jsxs as jsxs107 } from "react/jsx-runtime";
|
|
35894
35935
|
var SAVED_VIEWS_UNAVAILABLE = "Saved views are not available in this organization right now, so the layout you pick here is not being kept. Everything else on this table works as usual.";
|
|
35936
|
+
var VIEW_CHIP_BOX = "h-8 w-32 shrink-0";
|
|
35895
35937
|
function seedIsSatisfied(seed, views) {
|
|
35896
35938
|
if (views.some((v) => v.name === seed.name)) return true;
|
|
35897
35939
|
return seed.isDefault === true && views.some((v) => v.isDefault);
|
|
@@ -36049,7 +36091,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
|
|
|
36049
36091
|
);
|
|
36050
36092
|
}
|
|
36051
36093
|
if (error) return /* @__PURE__ */ jsx117(RefusalNotice, { error, className, actions: /* @__PURE__ */ jsx117(Button73, { size: "sm", variant: "ghost", onClick: () => void load(), children: "Try again" }) });
|
|
36052
|
-
if (views === null) return /* @__PURE__ */ jsx117(Skeleton15, { className: cn61("
|
|
36094
|
+
if (views === null) return /* @__PURE__ */ jsx117(Skeleton15, { className: cn61(VIEW_CHIP_BOX, className), "data-view-picker-reserved": "" });
|
|
36053
36095
|
const current = views.find((v) => v.id === active) ?? null;
|
|
36054
36096
|
return /* @__PURE__ */ jsxs107(Popover12, { open, onOpenChange: setOpen, children: [
|
|
36055
36097
|
/* @__PURE__ */ jsx117(PopoverTrigger12, { asChild: true, children: /* @__PURE__ */ jsxs107(
|
|
@@ -36057,7 +36099,8 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
|
|
|
36057
36099
|
{
|
|
36058
36100
|
size: "sm",
|
|
36059
36101
|
variant: "subtle",
|
|
36060
|
-
className: cn61("
|
|
36102
|
+
className: cn61(VIEW_CHIP_BOX, "justify-between gap-1 px-2 text-xs", className),
|
|
36103
|
+
title: current?.name ?? void 0,
|
|
36061
36104
|
"aria-label": `View: ${current?.name ?? "none yet"}. Change view`,
|
|
36062
36105
|
"data-view-picker": "",
|
|
36063
36106
|
children: [
|
|
@@ -49459,7 +49502,7 @@ function useEmbedHandshake(args) {
|
|
|
49459
49502
|
import { copyText as copyText12 } from "@ai-matrx/kit/clipboard";
|
|
49460
49503
|
import { useCallback as useCallback70, useEffect as useEffect117, useMemo as useMemo78, useRef as useRef63, useState as useState137 } from "react";
|
|
49461
49504
|
import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
|
|
49462
|
-
import { useFields as useFields37, useRecordsClient as useRecordsClient98, useSeededAnswer, useTable as useTable37 } from "@ai-matrx/records/react";
|
|
49505
|
+
import { tableShapeChanged as tableShapeChanged14, useFields as useFields37, useRecordsClient as useRecordsClient98, useSeededAnswer, useTable as useTable37, useTableArchive as useTableArchive2 } from "@ai-matrx/records/react";
|
|
49463
49506
|
import {
|
|
49464
49507
|
Badge as Badge26,
|
|
49465
49508
|
BottomSheet,
|
|
@@ -50573,6 +50616,37 @@ function TablePage({
|
|
|
50573
50616
|
const [shareAsked, setShareAsked] = useState137(0);
|
|
50574
50617
|
const { open: renameOpen, setOpen: setRenameOpen, ask: askRename, menuContentProps: renameMenuProps } = useRenameFromMenu();
|
|
50575
50618
|
const [archiveAsked, setArchiveAsked] = useState137(0);
|
|
50619
|
+
const pageArchive = useTableArchive2(tableId);
|
|
50620
|
+
const archiveRunning = useRef63(false);
|
|
50621
|
+
const archiveFromMenu = useCallback70(async () => {
|
|
50622
|
+
if (archiveRunning.current) return;
|
|
50623
|
+
archiveRunning.current = true;
|
|
50624
|
+
try {
|
|
50625
|
+
const look2 = await pageArchive.preview();
|
|
50626
|
+
const line = look2?.confirm_over;
|
|
50627
|
+
if (!look2 || typeof line !== "number" || look2.remaining > line) {
|
|
50628
|
+
setSurface((now) => ({ ...now, main: "records", rail: "settings" }));
|
|
50629
|
+
setArchiveAsked((n) => n + 1);
|
|
50630
|
+
return;
|
|
50631
|
+
}
|
|
50632
|
+
const finished = await pageArchive.start();
|
|
50633
|
+
if (finished?.done && finished.table_archived) {
|
|
50634
|
+
announceTableArchived({
|
|
50635
|
+
notify: recordsUi.notify,
|
|
50636
|
+
client,
|
|
50637
|
+
tableId,
|
|
50638
|
+
name: finished.table_name || table.data?.name || "the table",
|
|
50639
|
+
onRestored: () => tableShapeChanged14(tableId)
|
|
50640
|
+
});
|
|
50641
|
+
tableShapeChanged14(tableId);
|
|
50642
|
+
return;
|
|
50643
|
+
}
|
|
50644
|
+
setSurface((now) => ({ ...now, main: "records", rail: "settings" }));
|
|
50645
|
+
setArchiveAsked((n) => n + 1);
|
|
50646
|
+
} finally {
|
|
50647
|
+
archiveRunning.current = false;
|
|
50648
|
+
}
|
|
50649
|
+
}, [pageArchive, client, tableId, table.data, recordsUi.notify]);
|
|
50576
50650
|
const [moveAsked, setMoveAsked] = useState137(0);
|
|
50577
50651
|
const [duplicateOpen, setDuplicateOpen] = useState137(false);
|
|
50578
50652
|
const [referenceOpen, setReferenceOpen] = useState137(false);
|
|
@@ -50940,8 +51014,7 @@ function TablePage({
|
|
|
50940
51014
|
...layoutShowingLabel ? { layoutLabel: layoutShowingLabel } : {},
|
|
50941
51015
|
openBuiltOn: (destination) => go(BUILT_ON_PRESS[destination]),
|
|
50942
51016
|
archive: () => {
|
|
50943
|
-
|
|
50944
|
-
setArchiveAsked((n) => n + 1);
|
|
51017
|
+
void archiveFromMenu();
|
|
50945
51018
|
},
|
|
50946
51019
|
unavailableReasons: {
|
|
50947
51020
|
open: "Already open",
|