@ai-matrx/records-ui 0.113.28 → 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/dist/index.d.cts CHANGED
@@ -4468,10 +4468,6 @@ interface ViewBarProps {
4468
4468
  * still works and a longer sentence would suggest otherwise.
4469
4469
  */
4470
4470
  declare const SAVED_VIEWS_UNAVAILABLE: string;
4471
- /**
4472
- * WHETHER A SEED IS ALREADY THERE. A view by the seed's name always satisfies it; a DEFAULT seed
4473
- * is also satisfied by any view the table already marks as its default, whatever it is called.
4474
- */
4475
4471
  declare function seedIsSatisfied(seed: SavedViewSpec, views: readonly SavedView[]): boolean;
4476
4472
  declare function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews, initialViews, className }: ViewBarProps): react.JSX.Element;
4477
4473
 
package/dist/index.d.ts CHANGED
@@ -4468,10 +4468,6 @@ interface ViewBarProps {
4468
4468
  * still works and a longer sentence would suggest otherwise.
4469
4469
  */
4470
4470
  declare const SAVED_VIEWS_UNAVAILABLE: string;
4471
- /**
4472
- * WHETHER A SEED IS ALREADY THERE. A view by the seed's name always satisfies it; a DEFAULT seed
4473
- * is also satisfied by any view the table already marks as its default, whatever it is called.
4474
- */
4475
4471
  declare function seedIsSatisfied(seed: SavedViewSpec, views: readonly SavedView[]): boolean;
4476
4472
  declare function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews, initialViews, className }: ViewBarProps): react.JSX.Element;
4477
4473
 
package/dist/index.js CHANGED
@@ -14966,6 +14966,7 @@ function ActionsHeaderControls({ onAddColumn }) {
14966
14966
  "aria-label": ADD_COLUMN_LABEL,
14967
14967
  title: ADD_COLUMN_LABEL,
14968
14968
  "data-records-actions-header-add": "",
14969
+ "data-records-add-column": "",
14969
14970
  onClick: (event) => {
14970
14971
  event.stopPropagation();
14971
14972
  onAddColumn();
@@ -19184,6 +19185,9 @@ function useReverseGridColumns(tableId, rowIds) {
19184
19185
  label: column.label,
19185
19186
  accessorFn: (row) => held.answers?.[column.key]?.[row.id]?.total ?? 0,
19186
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.`,
19187
19191
  filter: false,
19188
19192
  copyValue: (row) => (held.answers?.[column.key]?.[row.id]?.links ?? []).map((l) => l.words).join(", "),
19189
19193
  cell: (row) => row.id === SUMMARY_ROW_ID || row.id === ADD_ROW_ID ? null : /* @__PURE__ */ jsx64(ReverseCell, { held, column, rowId: row.id, tableId }),
@@ -19226,10 +19230,14 @@ function ReverseCell({ held, column, rowId, tableId }) {
19226
19230
  const reading = useSyncExternalStore3(subscribe, readReading, readReading);
19227
19231
  const chips = /* @__PURE__ */ jsx64(ReverseLinkChips, { column, answer, loading: reading, clamp: { tableId, recordId: rowId } });
19228
19232
  if (column.read_only) return chips;
19229
- return /* @__PURE__ */ jsxs59("span", { className: "flex min-w-0 items-start gap-1", children: [
19230
- /* @__PURE__ */ jsx64("span", { className: "min-w-0 flex-1", children: chips }),
19231
- /* @__PURE__ */ jsx64(ReverseLinksEditPopover, { tableId, recordId: rowId, column })
19232
- ] });
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;
19233
19241
  }
19234
19242
  function useReverseField(tableId, column) {
19235
19243
  const client = useOptionalRecordsClient11();
@@ -19272,22 +19280,43 @@ function ReverseLinksEditor({ tableId, recordId, column, autoOpen, onClose }) {
19272
19280
  ] });
19273
19281
  }
19274
19282
  var REVERSE_LINKS_EDIT_MAX = 50;
19275
- function ReverseLinksEditPopover({ tableId, recordId, column }) {
19283
+ function ReverseLinksEditCell({ tableId, recordId, column, chips }) {
19276
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]);
19277
19292
  return /* @__PURE__ */ jsxs59(Popover8, { open, onOpenChange: setOpen, children: [
19278
19293
  /* @__PURE__ */ jsx64(PopoverTrigger8, { asChild: true, children: /* @__PURE__ */ jsx64(
19279
- Button37,
19294
+ "span",
19280
19295
  {
19281
- size: "sm",
19282
- variant: "ghost",
19283
- className: "h-5 w-5 shrink-0 p-0 text-muted-foreground",
19284
- "aria-label": `Link ${column.source_table_name}`,
19285
- title: `Link ${column.source_table_name}`,
19296
+ role: "button",
19297
+ tabIndex: 0,
19298
+ "data-matrx-cell-control": "",
19299
+ "data-matrx-cell-fill": "",
19286
19300
  "data-records-reverse-edit": column.key,
19287
- children: "+"
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 })
19288
19317
  }
19289
19318
  ) }),
19290
- /* @__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 })
19291
19320
  ] });
19292
19321
  }
19293
19322
  var EMPTY_COLUMNS = [];
@@ -24937,9 +24966,10 @@ function GridBody({
24937
24966
  (key) => holdHeaderMenu(headerHeld.current, menuLatest.current, key, controls.headerMenuFor(key)),
24938
24967
  (key) => holdByContent(headerHeld.current, `filter:${key}`, filterFor(key))
24939
24968
  );
24940
- return merged && rights.structure && !readOnly ? [...drawn, addColumnDef] : drawn;
24969
+ const pinnedPlus = offersRowActions && mayManageActions;
24970
+ return merged && rights.structure && !readOnly && !pinnedPlus ? [...drawn, addColumnDef] : drawn;
24941
24971
  },
24942
- [bodyColumns, controls.headerMenuFor, controls.filterFor, merged, rights.structure, readOnly, addColumnDef]
24972
+ [bodyColumns, controls.headerMenuFor, controls.filterFor, merged, rights.structure, readOnly, addColumnDef, offersRowActions, mayManageActions]
24943
24973
  );
24944
24974
  const columnsHeld = useRef37(null);
24945
24975
  const columns = columnsHeld.current !== null && sameColumns(columnsHeld.current, drawnColumns) ? columnsHeld.current : drawnColumns;
@@ -24948,7 +24978,7 @@ function GridBody({
24948
24978
  () => offersRowActions ? [...columns, { id: "custom-actions", header: merged ? /* @__PURE__ */ jsxs69("span", { className: "inline-flex items-center gap-0.5", children: [
24949
24979
  /* @__PURE__ */ jsx76("span", { children: "Actions" }),
24950
24980
  actionsHeader
24951
- ] }) : "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,
24952
24982
  [columns, offersRowActions, merged, actionsHeader, rowActions]
24953
24983
  );
24954
24984
  const [localColumns, setLocalColumns] = useState63(
@@ -25116,6 +25146,9 @@ function GridBody({
25116
25146
  */
25117
25147
  onEditRequest: (address2, seed) => {
25118
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
+ }
25119
25152
  const field2 = now.fields.find((f) => f.key === address2.columnId);
25120
25153
  if (!field2 || !fieldIsEditable(field2) || !now.mayWriteRow(address2.rowId)) return false;
25121
25154
  if (editorKindFor(field2) === "checkbox") {
@@ -35900,6 +35933,7 @@ function copyName(name, taken) {
35900
35933
  // src/ViewBar.tsx
35901
35934
  import { jsx as jsx117, jsxs as jsxs107 } from "react/jsx-runtime";
35902
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";
35903
35937
  function seedIsSatisfied(seed, views) {
35904
35938
  if (views.some((v) => v.name === seed.name)) return true;
35905
35939
  return seed.isDefault === true && views.some((v) => v.isDefault);
@@ -36057,7 +36091,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
36057
36091
  );
36058
36092
  }
36059
36093
  if (error) return /* @__PURE__ */ jsx117(RefusalNotice, { error, className, actions: /* @__PURE__ */ jsx117(Button73, { size: "sm", variant: "ghost", onClick: () => void load(), children: "Try again" }) });
36060
- if (views === null) return /* @__PURE__ */ jsx117(Skeleton15, { className: cn61("h-8 w-28 shrink-0", className) });
36094
+ if (views === null) return /* @__PURE__ */ jsx117(Skeleton15, { className: cn61(VIEW_CHIP_BOX, className), "data-view-picker-reserved": "" });
36061
36095
  const current = views.find((v) => v.id === active) ?? null;
36062
36096
  return /* @__PURE__ */ jsxs107(Popover12, { open, onOpenChange: setOpen, children: [
36063
36097
  /* @__PURE__ */ jsx117(PopoverTrigger12, { asChild: true, children: /* @__PURE__ */ jsxs107(
@@ -36065,7 +36099,8 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
36065
36099
  {
36066
36100
  size: "sm",
36067
36101
  variant: "subtle",
36068
- className: cn61("h-8 max-w-[14rem] shrink-0 gap-1 px-2 text-xs", className),
36102
+ className: cn61(VIEW_CHIP_BOX, "justify-between gap-1 px-2 text-xs", className),
36103
+ title: current?.name ?? void 0,
36069
36104
  "aria-label": `View: ${current?.name ?? "none yet"}. Change view`,
36070
36105
  "data-view-picker": "",
36071
36106
  children: [
@@ -49467,7 +49502,7 @@ function useEmbedHandshake(args) {
49467
49502
  import { copyText as copyText12 } from "@ai-matrx/kit/clipboard";
49468
49503
  import { useCallback as useCallback70, useEffect as useEffect117, useMemo as useMemo78, useRef as useRef63, useState as useState137 } from "react";
49469
49504
  import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
49470
- 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";
49471
49506
  import {
49472
49507
  Badge as Badge26,
49473
49508
  BottomSheet,
@@ -50581,6 +50616,37 @@ function TablePage({
50581
50616
  const [shareAsked, setShareAsked] = useState137(0);
50582
50617
  const { open: renameOpen, setOpen: setRenameOpen, ask: askRename, menuContentProps: renameMenuProps } = useRenameFromMenu();
50583
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]);
50584
50650
  const [moveAsked, setMoveAsked] = useState137(0);
50585
50651
  const [duplicateOpen, setDuplicateOpen] = useState137(false);
50586
50652
  const [referenceOpen, setReferenceOpen] = useState137(false);
@@ -50948,8 +51014,7 @@ function TablePage({
50948
51014
  ...layoutShowingLabel ? { layoutLabel: layoutShowingLabel } : {},
50949
51015
  openBuiltOn: (destination) => go(BUILT_ON_PRESS[destination]),
50950
51016
  archive: () => {
50951
- setSurface((now) => ({ ...now, main: "records", rail: "settings" }));
50952
- setArchiveAsked((n) => n + 1);
51017
+ void archiveFromMenu();
50953
51018
  },
50954
51019
  unavailableReasons: {
50955
51020
  open: "Already open",