@ai-matrx/records-ui 0.115.36 → 0.115.37

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.115.37
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/records-ui/v0.115.36..npm/records-ui/v0.115.37 -- apps/shared/records-ui`).
7
+ No source changes intended and no consumer action required.
8
+
3
9
  ## 0.115.36
4
10
 
5
11
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/index.cjs CHANGED
@@ -13867,7 +13867,7 @@ function SplitRecordDialog({ tableId, record, document: document2, open, onOpenC
13867
13867
  let madeName = recordNameIn(table.data ?? null, madeDoc, "New record");
13868
13868
  if (titleKey !== null && !titleHeld) {
13869
13869
  const named = `${record.name} (split)`;
13870
- const renamed = await client.recordUpdate({ record_id: created, patch: { [titleKey]: named } });
13870
+ const renamed = await (0, recordVersions_exports.updateRecordAt)(client, { record_id: created, patch: { [titleKey]: named }, version: await (0, recordVersions_exports.readVersionNow)(client, created) });
13871
13871
  if (renamed.ok) {
13872
13872
  madeName = named;
13873
13873
  onChanged?.();
@@ -19386,7 +19386,8 @@ function useGridDrillQuestion(args) {
19386
19386
  const source = (0, import_react112.useMemo)(() => ({ kind: "table", id: tableId }), [tableId]);
19387
19387
  const saved = (0, import_react112.useMemo)(() => questionFromGrouping(presentation.grouping), [presentation.grouping]);
19388
19388
  const url = (0, import_data_table14.useDrillUrlState)({ fallback: saved });
19389
- const requested = args.enabled && (url.question.by.length > (args.plainGroupingIsRows ? 1 : 0) || url.question.across !== null || url.question.where.length > 0 || // `!= null`: a question read by a design-system that does not know the window or the comparison
19389
+ const requested = args.enabled && // Up to three levels are ROWS under nested headers on the merged grid (Airtable's group levels).
19390
+ (url.question.by.length > (args.plainGroupingIsRows ? 3 : 0) || url.question.across !== null || url.question.where.length > 0 || // `!= null`: a question read by a design-system that does not know the window or the comparison
19390
19391
  // yet has them UNDEFINED, and `undefined !== null` asked for drill metadata on every plain grid.
19391
19392
  url.question.window != null || url.question.compare != null);
19392
19393
  const { def } = useDrillDefinition(requested ? source : null);
@@ -25059,10 +25060,17 @@ function GridBody({
25059
25060
  return viewSorts[0]?.field === seatedSort.id ? (0, import_first_page8.thenSortsOf)(viewSorts, list, seatedSort.id, unsortable) : [];
25060
25061
  }, [seatedSort, manual, fields.data, heldThen, viewSorts]);
25061
25062
  const thenKey = JSON.stringify(thenSorts);
25063
+ const groupThenKeys = rowGroupKey ? (presentation.grouping?.then ?? []).map((t) => t.field).join("|") : "";
25062
25064
  const pageSort = (0, import_react140.useMemo)(
25063
- () => storePaged ? (0, import_first_page6.groupedPageSort)(fields.data ?? [], rowGroupKey, (0, import_first_page8.pageSortsFor)(fields.data ?? [], seatedSort, thenSorts)) : [],
25065
+ () => {
25066
+ if (!storePaged) return [];
25067
+ const sorted = (0, import_first_page6.groupedPageSort)(fields.data ?? [], rowGroupKey, (0, import_first_page8.pageSortsFor)(fields.data ?? [], seatedSort, thenSorts));
25068
+ if (!rowGroupKey || groupThenKeys === "") return sorted;
25069
+ const inner2 = groupThenKeys.split("|").flatMap((key) => (0, import_first_page8.pageSortFor)(fields.data ?? [], { id: key, direction: "asc" }));
25070
+ return [...sorted.slice(0, 1), ...inner2, ...sorted.slice(1).filter((s) => !inner2.some((i) => i.field === s.field))];
25071
+ },
25064
25072
  // eslint-disable-next-line react-hooks/exhaustive-deps -- thenKey stands for thenSorts
25065
- [storePaged, fields.data, seatedSort, rowGroupKey, thenKey]
25073
+ [storePaged, fields.data, seatedSort, rowGroupKey, thenKey, groupThenKeys]
25066
25074
  );
25067
25075
  const fullSorts = (0, import_react140.useMemo)(
25068
25076
  () => seatedSort ? [{ field: seatedSort.id, direction: seatedSort.direction }, ...thenSorts] : [],
@@ -26265,12 +26273,15 @@ function GridBody({
26265
26273
  if (field2 === null && !onPresentationChange) return null;
26266
26274
  const rowsGrouped = merged;
26267
26275
  const aggregates = rowsGrouped ? void 0 : view && Object.keys(view.aggregates ?? {}).length > 0 ? view.aggregates : field2 ? { [field2]: { kind: "count" } } : void 0;
26268
- const facts = rowsGrouped ? groupFactsFor(groupFacts, fields.data ?? [], chosenSummaries) : void 0;
26276
+ const topFacts = rowsGrouped ? groupFactsFor(groupFacts, fields.data ?? [], chosenSummaries) : void 0;
26277
+ const facts = topFacts ? (group) => group.ancestors ? void 0 : topFacts(group) : void 0;
26278
+ const thenKeys = rowsGrouped ? (view?.then ?? []).map((t) => t.field) : [];
26269
26279
  return {
26270
26280
  columnId: field2,
26271
26281
  rowNoun: "record",
26282
+ ...thenKeys.length > 0 ? { thenColumnIds: thenKeys } : {},
26272
26283
  ...aggregates ? { aggregates } : {},
26273
- ...rowsGrouped ? { renderLabel: groupLabel2, order: "first-seen", emptyLabel: "No value" } : {},
26284
+ ...rowsGrouped ? { renderLabel: (group) => group.ancestors ? void 0 : groupLabel2(group), order: "first-seen", emptyLabel: "No value" } : {},
26274
26285
  ...facts ? { groupFacts: facts } : {},
26275
26286
  ...!rowsGrouped && view?.order ? { order: view.order } : {},
26276
26287
  ...view?.collapsed ? { collapsed: view.collapsed } : {},
@@ -26291,6 +26302,15 @@ function GridBody({
26291
26302
  }
26292
26303
  });
26293
26304
  },
26305
+ // NESTED GROUPS: the second and third level are the view's `grouping.then` (the store allows three levels).
26306
+ ...rowsGrouped ? {
26307
+ onThenColumnIdsChange: (ids) => {
26308
+ const current = presentation.grouping;
26309
+ if (!current) return;
26310
+ const { then: _was, collapsed: _shut, ...rest } = current;
26311
+ writeLook({ ...presentation, grouping: ids.length > 0 ? { ...rest, then: ids.slice(0, 2).map((field3) => ({ field: field3 })) } : rest });
26312
+ }
26313
+ } : {},
26294
26314
  onCollapsedChange: (collapsed) => {
26295
26315
  const current = presentation.grouping;
26296
26316
  if (!current) return;
@@ -39110,6 +39130,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
39110
39130
  return (initialViews.find((v) => v.id === activeViewId) ?? (0, import_views2.defaultViewOf)(initialViews) ?? initialViews[0]).id;
39111
39131
  });
39112
39132
  const readOnMount = (0, import_react230.useRef)(initialViews === void 0);
39133
+ const pendingPick = (0, import_react230.useRef)(null);
39113
39134
  const [naming, setNaming] = (0, import_react230.useState)(false);
39114
39135
  const [draftName, setDraftName] = (0, import_react230.useState)("");
39115
39136
  const [open, setOpen] = (0, import_react230.useState)(false);
@@ -39186,7 +39207,9 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
39186
39207
  }, [load]);
39187
39208
  (0, import_react230.useEffect)(() => {
39188
39209
  if (!views || views.length === 0) return;
39189
- const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? (0, import_views2.defaultViewOf)(views) ?? views[0];
39210
+ const wanted = pendingPick.current;
39211
+ pendingPick.current = null;
39212
+ const chosen = views.find((v) => v.id === (wanted ?? activeViewId ?? active)) ?? (0, import_views2.defaultViewOf)(views) ?? views[0];
39190
39213
  if (chosen.id !== active) setActive(chosen.id);
39191
39214
  onActiveView?.(chosen);
39192
39215
  }, [views, activeViewId]);
@@ -39201,6 +39224,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
39201
39224
  setNamingPersonal(false);
39202
39225
  setDraftName("");
39203
39226
  setActive(written.data);
39227
+ pendingPick.current = written.data;
39204
39228
  await load();
39205
39229
  }
39206
39230
  async function rename(view, name) {
@@ -39271,6 +39295,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
39271
39295
  return;
39272
39296
  }
39273
39297
  setActive(written.data);
39298
+ pendingPick.current = written.data;
39274
39299
  await load();
39275
39300
  }
39276
39301
  async function archive(view) {