@ai-matrx/records-ui 0.101.33 → 0.101.34

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.101.34
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/records-ui/v0.101.33..npm/records-ui/v0.101.34 -- apps/shared/records-ui`).
7
+ No source changes intended and no consumer action required.
8
+
3
9
  ## 0.101.33
4
10
 
5
11
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/index.cjs CHANGED
@@ -5699,6 +5699,7 @@ var EMBEDDED_TABLE_CLASS = [
5699
5699
  "[&_thead_th:last-child]:border-r-0"
5700
5700
  ].join(" ");
5701
5701
  var EMBEDDED_PLAIN_FOOTER_CLASS = "[&_tfoot]:bg-transparent [&_tfoot]:border-t-0";
5702
+ var EMBEDDED_PAGE_SIZE = 50;
5702
5703
 
5703
5704
  // src/enumLabels.ts
5704
5705
  function exhaustiveValuesOf() {
@@ -21381,7 +21382,9 @@ function GridBody({
21381
21382
  onAskWhoChanged,
21382
21383
  embedded = false,
21383
21384
  newRowLabel,
21384
- sortOverride
21385
+ sortOverride,
21386
+ searchOverride,
21387
+ onSearchChange
21385
21388
  }) {
21386
21389
  const toolbarSlot = useTableToolbarSlot();
21387
21390
  const tableCard = (0, import_data_table10.useMatrxTableCard)();
@@ -21458,6 +21461,14 @@ function GridBody({
21458
21461
  page: 1
21459
21462
  }));
21460
21463
  }, [overrideKey]);
21464
+ const overrideSearchSeen = (0, import_react113.useRef)(void 0);
21465
+ (0, import_react113.useEffect)(() => {
21466
+ if (searchOverride === void 0) return;
21467
+ const wanted = searchOverride ?? "";
21468
+ if (overrideSearchSeen.current === wanted) return;
21469
+ overrideSearchSeen.current = wanted;
21470
+ setQuery((held) => held.search === wanted ? held : { ...held, search: wanted, page: 1 });
21471
+ }, [searchOverride]);
21461
21472
  const reportQuery = address?.report;
21462
21473
  (0, import_react113.useEffect)(() => {
21463
21474
  if (!reportQuery) return;
@@ -21541,7 +21552,32 @@ function GridBody({
21541
21552
  filter: readFilter ?? null,
21542
21553
  version: records.data
21543
21554
  });
21544
- const pageRows = (0, import_react113.useMemo)(() => manual && !storePaged ? hand.rows ?? [] : storeRows, [manual, storePaged, hand.rows, storeRows]);
21555
+ const embeddedMore = embedded && storePaged;
21556
+ const [appendedRows, setAppendedRows] = (0, import_react113.useState)([]);
21557
+ const [appending, setAppending] = (0, import_react113.useState)(false);
21558
+ const askKey2 = JSON.stringify([tableId, searchTerm, pageSort, readFilter ?? null, viewId]);
21559
+ (0, import_react113.useEffect)(() => setAppendedRows([]), [askKey2]);
21560
+ const pageRows = (0, import_react113.useMemo)(() => {
21561
+ if (manual && !storePaged) return hand.rows ?? [];
21562
+ if (!embeddedMore || appendedRows.length === 0) return storeRows;
21563
+ const seen = new Set(storeRows.map((row) => row.id));
21564
+ return [...storeRows, ...appendedRows.filter((row) => !seen.has(row.id))];
21565
+ }, [manual, storePaged, hand.rows, storeRows, embeddedMore, appendedRows]);
21566
+ const showMoreRows = (0, import_react113.useCallback)(async () => {
21567
+ if (appending || !embeddedMore) return;
21568
+ setAppending(true);
21569
+ const asked3 = await client.listPage({
21570
+ table_id: tableId,
21571
+ ...readFilter ? { filter: readFilter } : {},
21572
+ search: searchTerm.trim() === "" ? null : searchTerm.trim(),
21573
+ sort: pageSort,
21574
+ view_id: manual && pageSort.length === 0 ? viewId : null,
21575
+ limit: EMBEDDED_PAGE_SIZE,
21576
+ offset: pageRows.length
21577
+ });
21578
+ setAppending(false);
21579
+ if (asked3.ok) setAppendedRows((held) => [...held, ...asked3.data.rows]);
21580
+ }, [appending, embeddedMore, client, tableId, readFilter, searchTerm, pageSort, manual, viewId, pageRows.length]);
21545
21581
  const added = useAddedRows({
21546
21582
  tableId,
21547
21583
  enabled: merged,
@@ -22721,6 +22757,21 @@ function GridBody({
22721
22757
  const tableToolbar = (0, import_react113.useMemo)(
22722
22758
  () => ({
22723
22759
  search: !embedded,
22760
+ // EMBEDDED: Notion's magnifier — the design system's own search group, a button that
22761
+ // opens into a field. It is the same `query.search` the store's read asks.
22762
+ ...embedded ? {
22763
+ customSearch: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
22764
+ import_design_system58.TapTargetSearchGroup,
22765
+ {
22766
+ placeholder: "Search",
22767
+ value: searchOverride ?? query.search,
22768
+ onValueChange: (term) => {
22769
+ setQuery((held) => ({ ...held, search: term, page: 1 }));
22770
+ onSearchChange?.(term);
22771
+ }
22772
+ }
22773
+ )
22774
+ } : {},
22724
22775
  // The host (Spaces) has its own Properties menu: an embedded table draws no Columns button.
22725
22776
  ...embedded ? { columns: false } : {},
22726
22777
  searchPlaceholder: "Search records",
@@ -22921,7 +22972,9 @@ function GridBody({
22921
22972
  sheetExtras,
22922
22973
  tableId,
22923
22974
  noun,
22924
- embedded
22975
+ embedded,
22976
+ searchOverride,
22977
+ onSearchChange
22925
22978
  ]
22926
22979
  );
22927
22980
  const labelOfField = (0, import_react113.useCallback)(
@@ -23127,7 +23180,7 @@ function GridBody({
23127
23180
  pageSize,
23128
23181
  query: tableQuery,
23129
23182
  ...valueFacets ? { facets: valueFacets, filterUi: VALUE_FILTER_UI } : {},
23130
- ...classicInCard ? { hidePagination: true } : {},
23183
+ ...classicInCard || embeddedMore ? { hidePagination: true } : {},
23131
23184
  ...embedded ? { appearance: "embedded" } : {},
23132
23185
  tableClassName: (0, import_design_system58.cn)(
23133
23186
  !look.wrap && "[&_tbody_td]:max-w-[28rem] [&_tbody_td]:overflow-hidden [&_tbody_td]:text-ellipsis [&_tbody_td]:whitespace-nowrap! [&_tbody_td_*]:whitespace-nowrap!",
@@ -23232,7 +23285,15 @@ function GridBody({
23232
23285
  onShowMore: () => setCardExtraRows((extra) => extra + pageSize)
23233
23286
  }
23234
23287
  ) : null
23235
- ) : storePaged || embedded ? null : /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
23288
+ ) : embeddedMore ? typeof records.data?.total === "number" && records.data.total > pageRows.length ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
23289
+ import_data_table10.MatrxTableCardShowMore,
23290
+ {
23291
+ shown: pageRows.length,
23292
+ total: records.data.total,
23293
+ busy: appending,
23294
+ onShowMore: () => void showMoreRows()
23295
+ }
23296
+ ) : null : storePaged || embedded ? null : /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
23236
23297
  Pager,
23237
23298
  {
23238
23299
  page,
@@ -23391,6 +23452,8 @@ function useEntitySource(token, options = {}) {
23391
23452
  const client = (0, import_react116.useRecordsClient)();
23392
23453
  const limit = options.limit ?? 50;
23393
23454
  const [tick, setTick] = (0, import_react115.useState)(0);
23455
+ const held = (0, import_react115.useRef)(0);
23456
+ const [loadingMore, setLoadingMore] = (0, import_react115.useState)(false);
23394
23457
  const [state, setState] = (0, import_react115.useState)({
23395
23458
  label: null,
23396
23459
  columns: [],
@@ -23403,7 +23466,7 @@ function useEntitySource(token, options = {}) {
23403
23466
  (0, import_react115.useEffect)(() => {
23404
23467
  let cancelled = false;
23405
23468
  const source = { kind: "entity", token };
23406
- void Promise.all([client.drillDescribe({ source }), client.drillRows({ source, limit })]).then(
23469
+ void Promise.all([client.drillDescribe({ source }), client.drillRows({ source, limit: Math.max(limit, held.current) })]).then(
23407
23470
  ([def, page]) => {
23408
23471
  if (cancelled) return;
23409
23472
  if (!def.ok) return setState((s) => ({ ...s, loading: false, error: refusalSentence(def.error) || "This table could not be read." }));
@@ -23411,6 +23474,7 @@ function useEntitySource(token, options = {}) {
23411
23474
  const api = def.data.api;
23412
23475
  const shown4 = new Set(page.data.columns instanceof Array ? page.data.columns.filter((c) => typeof c === "string") : []);
23413
23476
  const columns = (api?.columns ?? []).filter((c) => c.api_name !== "id" && (shown4.size === 0 || shown4.has(c.api_name) || shown4.has(c.lookup?.via ?? "")));
23477
+ held.current = (page.data.rows ?? []).length;
23414
23478
  setState({
23415
23479
  label: api?.label ?? def.data.label ?? token,
23416
23480
  columns,
@@ -23454,7 +23518,22 @@ function useEntitySource(token, options = {}) {
23454
23518
  },
23455
23519
  [client, token]
23456
23520
  );
23457
- return { ...state, write, create, reload };
23521
+ const loadMore = (0, import_react115.useCallback)(async () => {
23522
+ if (loadingMore) return;
23523
+ setLoadingMore(true);
23524
+ const source = { kind: "entity", token };
23525
+ const next = await client.drillRows({ source, limit, offset: held.current });
23526
+ setLoadingMore(false);
23527
+ if (!next.ok) return;
23528
+ const more = next.data.rows ?? [];
23529
+ held.current += more.length;
23530
+ setState((s) => {
23531
+ const seen = new Set(s.rows.map((r) => r.id));
23532
+ return { ...s, rows: [...s.rows, ...more.filter((r) => !seen.has(r.id))] };
23533
+ });
23534
+ }, [client, token, limit, loadingMore]);
23535
+ const hasMore = !state.loading && state.total > state.rows.length;
23536
+ return { ...state, write, create, reload, loadMore, hasMore, loadingMore };
23458
23537
  }
23459
23538
  function entityValueText(column, v) {
23460
23539
  if (v === null || v === void 0 || v === "") return "";
@@ -23484,7 +23563,7 @@ function entityTableColumns(columns) {
23484
23563
  ...c.type === "choice" && c.choices ? { filter: "select", filterOptions: c.choices.map((w) => ({ value: w, label: w })) } : {}
23485
23564
  }));
23486
23565
  }
23487
- function EntityGrid({ entity, pageSize, drill }) {
23566
+ function EntityGrid({ entity, pageSize, drill, embedded }) {
23488
23567
  const columns = (0, import_react115.useMemo)(() => entityTableColumns(entity.columns), [entity.columns]);
23489
23568
  return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
23490
23569
  import_data_table11.MatrxDataTable,
@@ -23494,7 +23573,8 @@ function EntityGrid({ entity, pageSize, drill }) {
23494
23573
  getRowId: (row) => String(row.id),
23495
23574
  isLoading: entity.loading,
23496
23575
  ...pageSize ? { pageSize } : {},
23497
- ...drill ? { drill } : {}
23576
+ ...drill ? { drill } : {},
23577
+ ...embedded ? { appearance: "embedded", hidePagination: true } : {}
23498
23578
  }
23499
23579
  );
23500
23580
  }
@@ -31547,10 +31627,12 @@ function ViewSwitcher({
31547
31627
  footer,
31548
31628
  embedded,
31549
31629
  sortOverride,
31630
+ searchOverride,
31631
+ onSearchChange,
31550
31632
  newRowLabel,
31551
31633
  className
31552
31634
  }) {
31553
- const pageSize = pageSizeAsked ?? (embedded ? 50 : 200);
31635
+ const pageSize = pageSizeAsked ?? (embedded ? EMBEDDED_PAGE_SIZE : 200);
31554
31636
  const toolbarSlot = useTableToolbarSlot();
31555
31637
  const [layout, setLayout] = (0, import_react178.useState)(view.layout);
31556
31638
  const hostLayouts = useRecordsUi().layouts ?? [];
@@ -31612,6 +31694,8 @@ function ViewSwitcher({
31612
31694
  ...footer ? { footer } : {},
31613
31695
  ...embedded ? { embedded } : {},
31614
31696
  ...sortOverride !== void 0 ? { sortOverride } : {},
31697
+ ...searchOverride !== void 0 ? { searchOverride } : {},
31698
+ ...onSearchChange ? { onSearchChange } : {},
31615
31699
  ...newRowLabel ? { newRowLabel } : {},
31616
31700
  ...filter ? { filter } : {},
31617
31701
  ...onClearFilter ? { onClearFilter } : {},
@@ -46134,6 +46218,8 @@ function TablePage({
46134
46218
  tableId,
46135
46219
  presentation: pagePresentation2 = "page",
46136
46220
  newRowLabel,
46221
+ searchOverride,
46222
+ onSearchChange,
46137
46223
  pageSize: pageSizeAsked,
46138
46224
  seedViews,
46139
46225
  onLeave,
@@ -46227,7 +46313,7 @@ function TablePage({
46227
46313
  const face = tableOpening(view, hostLayouts.map((h) => h.id));
46228
46314
  const designated = face.kind === "designated";
46229
46315
  const embedded = pagePresentation2 === "embedded";
46230
- const pageSize = pageSizeAsked ?? (embedded ? 50 : 100);
46316
+ const pageSize = pageSizeAsked ?? (embedded ? EMBEDDED_PAGE_SIZE : 100);
46231
46317
  const chooserInline = !embedded && !designated && !phone && toolbarFold2 < 2;
46232
46318
  const chooserCompact = !embedded && !designated && !phone && toolbarFold2 >= 2;
46233
46319
  const controlsInSheet = phone && !designated;
@@ -47018,6 +47104,8 @@ function TablePage({
47018
47104
  chooser: false,
47019
47105
  ...embedded ? { embedded } : {},
47020
47106
  ...newRowLabel ? { newRowLabel } : {},
47107
+ ...searchOverride !== void 0 ? { searchOverride } : {},
47108
+ ...onSearchChange ? { onSearchChange } : {},
47021
47109
  footer,
47022
47110
  openExport: () => setRail("export"),
47023
47111
  view: {
@@ -47180,6 +47268,7 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
47180
47268
  }
47181
47269
 
47182
47270
  // src/entityViews.tsx
47271
+ var import_data_table22 = require("@ai-matrx/design-system/data-table");
47183
47272
  var import_react267 = require("react");
47184
47273
  var import_design_system138 = require("@ai-matrx/design-system");
47185
47274
  var import_react268 = require("@ai-matrx/records/react");
@@ -47323,7 +47412,7 @@ function EntityChartBlock({ source, kind, by, measure, title, where, organizatio
47323
47412
  function EntityTablePage({
47324
47413
  source,
47325
47414
  presentation = "page",
47326
- pageSize = 100,
47415
+ pageSize = presentation === "embedded" ? EMBEDDED_PAGE_SIZE : 100,
47327
47416
  layout: opened = "grid",
47328
47417
  onLayoutChange,
47329
47418
  groupBy,
@@ -47407,7 +47496,18 @@ function EntityTablePage({
47407
47496
  ] })
47408
47497
  ] }) : null,
47409
47498
  addRefused ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(import_design_system138.ErrorBox, { className: "rounded border border-destructive/40 px-1.5 py-1 text-xs text-destructive", message: addRefused, operation: "Add a row", origin: "records-ui/entityViews" }) : null,
47410
- entity.error ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)("p", { className: "px-1 py-3 text-xs text-muted-foreground", children: `This table could not be read: ${entity.error}` }) : layout === "board" && boardable ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(EntityBoard, { entity, groupBy, onOpenRecord }) : /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(EntityGrid, { entity, pageSize, ...drill ? { drill } : {} })
47499
+ entity.error ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)("p", { className: "px-1 py-3 text-xs text-muted-foreground", children: `This table could not be read: ${entity.error}` }) : layout === "board" && boardable ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(EntityBoard, { entity, groupBy, onOpenRecord }) : /* @__PURE__ */ (0, import_jsx_runtime153.jsxs)(import_jsx_runtime153.Fragment, { children: [
47500
+ /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(EntityGrid, { entity, pageSize, embedded: presentation === "embedded", ...drill ? { drill } : {} }),
47501
+ presentation === "embedded" && entity.hasMore ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(
47502
+ import_data_table22.MatrxTableCardShowMore,
47503
+ {
47504
+ shown: entity.rows.length,
47505
+ total: entity.total,
47506
+ busy: entity.loadingMore,
47507
+ onShowMore: () => void entity.loadMore()
47508
+ }
47509
+ ) : null
47510
+ ] })
47411
47511
  ] });
47412
47512
  }
47413
47513