@ai-matrx/records-ui 0.113.28 → 0.113.30

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,11 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.113.30
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/records-ui/v0.113.29..npm/records-ui/v0.113.30 -- apps/shared/records-ui`).
7
+ No source changes intended and no consumer action required.
8
+
3
9
  ## 0.113.28
4
10
 
5
11
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/index.cjs CHANGED
@@ -15420,6 +15420,7 @@ function ActionsHeaderControls({ onAddColumn }) {
15420
15420
  "aria-label": ADD_COLUMN_LABEL,
15421
15421
  title: ADD_COLUMN_LABEL,
15422
15422
  "data-records-actions-header-add": "",
15423
+ "data-records-add-column": "",
15423
15424
  onClick: (event) => {
15424
15425
  event.stopPropagation();
15425
15426
  onAddColumn();
@@ -19551,6 +19552,9 @@ function useReverseGridColumns(tableId, rowIds) {
19551
19552
  label: column.label,
19552
19553
  accessorFn: (row) => held.answers?.[column.key]?.[row.id]?.total ?? 0,
19553
19554
  sortable: false,
19555
+ // THE SAME HEADER AS EVERY OTHER COLUMN (WALK-FIXES-3 D13): its hover icon opens the menu,
19556
+ // which says why this column cannot sort — its links are kept on the other table.
19557
+ sortRefusal: `Kept on ${column.source_table_name}, so it cannot sort here.`,
19554
19558
  filter: false,
19555
19559
  copyValue: (row) => (held.answers?.[column.key]?.[row.id]?.links ?? []).map((l) => l.words).join(", "),
19556
19560
  cell: (row) => row.id === SUMMARY_ROW_ID || row.id === ADD_ROW_ID ? null : /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ReverseCell, { held, column, rowId: row.id, tableId }),
@@ -19593,10 +19597,14 @@ function ReverseCell({ held, column, rowId, tableId }) {
19593
19597
  const reading = (0, import_react106.useSyncExternalStore)(subscribe, readReading, readReading);
19594
19598
  const chips = /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ReverseLinkChips, { column, answer, loading: reading, clamp: { tableId, recordId: rowId } });
19595
19599
  if (column.read_only) return chips;
19596
- return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "flex min-w-0 items-start gap-1", children: [
19597
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "min-w-0 flex-1", children: chips }),
19598
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ReverseLinksEditPopover, { tableId, recordId: rowId, column })
19599
- ] });
19600
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ReverseLinksEditCell, { tableId, recordId: rowId, column, chips });
19601
+ }
19602
+ var reverseCellOpeners = /* @__PURE__ */ new Map();
19603
+ function openReverseCell(rowId, columnId2) {
19604
+ const open = reverseCellOpeners.get(`${rowId}|${columnId2}`);
19605
+ if (!open) return false;
19606
+ open();
19607
+ return true;
19600
19608
  }
19601
19609
  function useReverseField(tableId, column) {
19602
19610
  const client = (0, import_react107.useOptionalRecordsClient)();
@@ -19639,22 +19647,43 @@ function ReverseLinksEditor({ tableId, recordId, column, autoOpen, onClose }) {
19639
19647
  ] });
19640
19648
  }
19641
19649
  var REVERSE_LINKS_EDIT_MAX = 50;
19642
- function ReverseLinksEditPopover({ tableId, recordId, column }) {
19650
+ function ReverseLinksEditCell({ tableId, recordId, column, chips }) {
19643
19651
  const [open, setOpen] = (0, import_react106.useState)(false);
19652
+ const key = `${recordId}|${reverseColumnId(column)}`;
19653
+ (0, import_react106.useEffect)(() => {
19654
+ reverseCellOpeners.set(key, () => setOpen(true));
19655
+ return () => {
19656
+ reverseCellOpeners.delete(key);
19657
+ };
19658
+ }, [key]);
19644
19659
  return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_design_system57.Popover, { open, onOpenChange: setOpen, children: [
19645
19660
  /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_design_system57.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
19646
- import_design_system57.Button,
19661
+ "span",
19647
19662
  {
19648
- size: "sm",
19649
- variant: "ghost",
19650
- className: "h-5 w-5 shrink-0 p-0 text-muted-foreground",
19651
- "aria-label": `Link ${column.source_table_name}`,
19652
- title: `Link ${column.source_table_name}`,
19663
+ role: "button",
19664
+ tabIndex: 0,
19665
+ "data-matrx-cell-control": "",
19666
+ "data-matrx-cell-fill": "",
19653
19667
  "data-records-reverse-edit": column.key,
19654
- children: "+"
19668
+ "aria-label": `Edit ${column.label}`,
19669
+ title: `${column.label} \u2014 click or press Enter to edit`,
19670
+ 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",
19671
+ onClick: (event) => {
19672
+ if (event.target instanceof Element && event.target.closest("a[href]")) {
19673
+ event.preventDefault();
19674
+ return;
19675
+ }
19676
+ },
19677
+ onKeyDown: (event) => {
19678
+ if (event.key === "Enter" || event.key === "F2") {
19679
+ event.preventDefault();
19680
+ setOpen(true);
19681
+ }
19682
+ },
19683
+ children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "min-w-0 flex-1", children: chips })
19655
19684
  }
19656
19685
  ) }),
19657
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_design_system57.PopoverContent, { sizing: "content", align: "start", className: "w-80 p-2", children: open ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ReverseLinksEditor, { tableId, recordId, column }) : null })
19686
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_design_system57.PopoverContent, { sizing: "content", align: "start", className: "w-80 p-2", children: open ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ReverseLinksEditor, { tableId, recordId, column, autoOpen: true, onClose: () => setOpen(false) }) : null })
19658
19687
  ] });
19659
19688
  }
19660
19689
  var EMPTY_COLUMNS = [];
@@ -25270,9 +25299,10 @@ function GridBody({
25270
25299
  (key) => holdHeaderMenu(headerHeld.current, menuLatest.current, key, controls.headerMenuFor(key)),
25271
25300
  (key) => holdByContent(headerHeld.current, `filter:${key}`, filterFor(key))
25272
25301
  );
25273
- return merged && rights.structure && !readOnly ? [...drawn, addColumnDef] : drawn;
25302
+ const pinnedPlus = offersRowActions && mayManageActions;
25303
+ return merged && rights.structure && !readOnly && !pinnedPlus ? [...drawn, addColumnDef] : drawn;
25274
25304
  },
25275
- [bodyColumns, controls.headerMenuFor, controls.filterFor, merged, rights.structure, readOnly, addColumnDef]
25305
+ [bodyColumns, controls.headerMenuFor, controls.filterFor, merged, rights.structure, readOnly, addColumnDef, offersRowActions, mayManageActions]
25276
25306
  );
25277
25307
  const columnsHeld = (0, import_react127.useRef)(null);
25278
25308
  const columns = columnsHeld.current !== null && sameColumns(columnsHeld.current, drawnColumns) ? columnsHeld.current : drawnColumns;
@@ -25281,7 +25311,7 @@ function GridBody({
25281
25311
  () => offersRowActions ? [...columns, { id: "custom-actions", header: merged ? /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("span", { className: "inline-flex items-center gap-0.5", children: [
25282
25312
  /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { children: "Actions" }),
25283
25313
  actionsHeader
25284
- ] }) : "Actions", label: "Actions", reorderable: false, sortable: false, filter: false, customActions: rowActions }] : columns,
25314
+ ] }) : "Actions", label: "Actions", reorderable: false, sortable: false, filter: false, customActions: rowActions, cell: drawNothing }] : columns,
25285
25315
  [columns, offersRowActions, merged, actionsHeader, rowActions]
25286
25316
  );
25287
25317
  const [localColumns, setLocalColumns] = (0, import_react127.useState)(
@@ -25449,6 +25479,9 @@ function GridBody({
25449
25479
  */
25450
25480
  onEditRequest: (address2, seed) => {
25451
25481
  const now = sheetNow.current;
25482
+ if (address2.columnId.startsWith(REVERSE_COLUMN_PREFIX)) {
25483
+ return (seed === null || seed === "") && now.mayWriteRow(address2.rowId) && openReverseCell(address2.rowId, address2.columnId);
25484
+ }
25452
25485
  const field2 = now.fields.find((f) => f.key === address2.columnId);
25453
25486
  if (!field2 || !fieldIsEditable(field2) || !now.mayWriteRow(address2.rowId)) return false;
25454
25487
  if (editorKindFor(field2) === "checkbox") {
@@ -36123,6 +36156,7 @@ function copyName(name, taken) {
36123
36156
  // src/ViewBar.tsx
36124
36157
  var import_jsx_runtime117 = require("react/jsx-runtime");
36125
36158
  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.";
36159
+ var VIEW_CHIP_BOX = "h-8 w-32 shrink-0";
36126
36160
  function seedIsSatisfied(seed, views) {
36127
36161
  if (views.some((v) => v.name === seed.name)) return true;
36128
36162
  return seed.isDefault === true && views.some((v) => v.isDefault);
@@ -36280,7 +36314,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
36280
36314
  );
36281
36315
  }
36282
36316
  if (error) return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(RefusalNotice, { error, className, actions: /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_design_system100.Button, { size: "sm", variant: "ghost", onClick: () => void load(), children: "Try again" }) });
36283
- if (views === null) return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_design_system100.Skeleton, { className: (0, import_design_system100.cn)("h-8 w-28 shrink-0", className) });
36317
+ if (views === null) return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_design_system100.Skeleton, { className: (0, import_design_system100.cn)(VIEW_CHIP_BOX, className), "data-view-picker-reserved": "" });
36284
36318
  const current = views.find((v) => v.id === active) ?? null;
36285
36319
  return /* @__PURE__ */ (0, import_jsx_runtime117.jsxs)(import_design_system100.Popover, { open, onOpenChange: setOpen, children: [
36286
36320
  /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_design_system100.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime117.jsxs)(
@@ -36288,7 +36322,8 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
36288
36322
  {
36289
36323
  size: "sm",
36290
36324
  variant: "subtle",
36291
- className: (0, import_design_system100.cn)("h-8 max-w-[14rem] shrink-0 gap-1 px-2 text-xs", className),
36325
+ className: (0, import_design_system100.cn)(VIEW_CHIP_BOX, "justify-between gap-1 px-2 text-xs", className),
36326
+ title: current?.name ?? void 0,
36292
36327
  "aria-label": `View: ${current?.name ?? "none yet"}. Change view`,
36293
36328
  "data-view-picker": "",
36294
36329
  children: [
@@ -50679,6 +50714,37 @@ function TablePage({
50679
50714
  const [shareAsked, setShareAsked] = (0, import_react288.useState)(0);
50680
50715
  const { open: renameOpen, setOpen: setRenameOpen, ask: askRename, menuContentProps: renameMenuProps } = useRenameFromMenu();
50681
50716
  const [archiveAsked, setArchiveAsked] = (0, import_react288.useState)(0);
50717
+ const pageArchive = (0, import_react289.useTableArchive)(tableId);
50718
+ const archiveRunning = (0, import_react288.useRef)(false);
50719
+ const archiveFromMenu = (0, import_react288.useCallback)(async () => {
50720
+ if (archiveRunning.current) return;
50721
+ archiveRunning.current = true;
50722
+ try {
50723
+ const look2 = await pageArchive.preview();
50724
+ const line = look2?.confirm_over;
50725
+ if (!look2 || typeof line !== "number" || look2.remaining > line) {
50726
+ setSurface((now) => ({ ...now, main: "records", rail: "settings" }));
50727
+ setArchiveAsked((n) => n + 1);
50728
+ return;
50729
+ }
50730
+ const finished = await pageArchive.start();
50731
+ if (finished?.done && finished.table_archived) {
50732
+ announceTableArchived({
50733
+ notify: recordsUi.notify,
50734
+ client,
50735
+ tableId,
50736
+ name: finished.table_name || table.data?.name || "the table",
50737
+ onRestored: () => (0, import_react289.tableShapeChanged)(tableId)
50738
+ });
50739
+ (0, import_react289.tableShapeChanged)(tableId);
50740
+ return;
50741
+ }
50742
+ setSurface((now) => ({ ...now, main: "records", rail: "settings" }));
50743
+ setArchiveAsked((n) => n + 1);
50744
+ } finally {
50745
+ archiveRunning.current = false;
50746
+ }
50747
+ }, [pageArchive, client, tableId, table.data, recordsUi.notify]);
50682
50748
  const [moveAsked, setMoveAsked] = (0, import_react288.useState)(0);
50683
50749
  const [duplicateOpen, setDuplicateOpen] = (0, import_react288.useState)(false);
50684
50750
  const [referenceOpen, setReferenceOpen] = (0, import_react288.useState)(false);
@@ -51046,8 +51112,7 @@ function TablePage({
51046
51112
  ...layoutShowingLabel ? { layoutLabel: layoutShowingLabel } : {},
51047
51113
  openBuiltOn: (destination) => go(BUILT_ON_PRESS[destination]),
51048
51114
  archive: () => {
51049
- setSurface((now) => ({ ...now, main: "records", rail: "settings" }));
51050
- setArchiveAsked((n) => n + 1);
51115
+ void archiveFromMenu();
51051
51116
  },
51052
51117
  unavailableReasons: {
51053
51118
  open: "Already open",