@ai-matrx/records-ui 0.42.0 → 0.44.0

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
@@ -2330,6 +2330,19 @@ interface TablePageProps {
2330
2330
  * it always has.
2331
2331
  */
2332
2332
  activeDashboardId?: Uuid$1 | null | undefined;
2333
+ /**
2334
+ * THE RECORD A LINK NAMED, OPENED ON ARRIVAL.
2335
+ *
2336
+ * 🚨 THE DEAD LINK THIS CLOSES (lane SCREENS-2, 2026-09-20). `ActionInbox` has always
2337
+ * handed its host `onOpenRecord(recordId, tableId)`, and the app has always routed that to
2338
+ * `/data-v2/<table>?record=<record>` — and NOTHING read the parameter. Pressing Open on a
2339
+ * checklist step, an assignment or an agent's proposal landed you on the table with the
2340
+ * record still shut, which is the inbox not finishing the sentence it started. Measured in
2341
+ * the real app on a dental practice's onboarding steps.
2342
+ *
2343
+ * Absent, nothing changes: the page opens exactly as it did.
2344
+ */
2345
+ activeRecordId?: Uuid$1 | null | undefined;
2333
2346
  className?: string | undefined;
2334
2347
  }
2335
2348
  /**
@@ -2371,7 +2384,7 @@ declare const DEFAULT_VIEW_NAME = "All records";
2371
2384
  * it: the bar above saves a view, and from then on the layout is remembered.
2372
2385
  */
2373
2386
  declare const VIEW_NOT_SAVED_YET: string;
2374
- declare function TablePage({ tableId, pageSize, seedViews, onLeave, leaveLabel, activeDashboardId, className, }: TablePageProps): react.JSX.Element;
2387
+ declare function TablePage({ tableId, pageSize, seedViews, onLeave, leaveLabel, activeDashboardId, activeRecordId, className, }: TablePageProps): react.JSX.Element;
2375
2388
 
2376
2389
  /** One Field a person asked for, in the words a person uses (FLD-1 / FLD-11). */
2377
2390
  interface NewFieldSpec {
package/dist/index.d.ts CHANGED
@@ -2330,6 +2330,19 @@ interface TablePageProps {
2330
2330
  * it always has.
2331
2331
  */
2332
2332
  activeDashboardId?: Uuid$1 | null | undefined;
2333
+ /**
2334
+ * THE RECORD A LINK NAMED, OPENED ON ARRIVAL.
2335
+ *
2336
+ * 🚨 THE DEAD LINK THIS CLOSES (lane SCREENS-2, 2026-09-20). `ActionInbox` has always
2337
+ * handed its host `onOpenRecord(recordId, tableId)`, and the app has always routed that to
2338
+ * `/data-v2/<table>?record=<record>` — and NOTHING read the parameter. Pressing Open on a
2339
+ * checklist step, an assignment or an agent's proposal landed you on the table with the
2340
+ * record still shut, which is the inbox not finishing the sentence it started. Measured in
2341
+ * the real app on a dental practice's onboarding steps.
2342
+ *
2343
+ * Absent, nothing changes: the page opens exactly as it did.
2344
+ */
2345
+ activeRecordId?: Uuid$1 | null | undefined;
2333
2346
  className?: string | undefined;
2334
2347
  }
2335
2348
  /**
@@ -2371,7 +2384,7 @@ declare const DEFAULT_VIEW_NAME = "All records";
2371
2384
  * it: the bar above saves a view, and from then on the layout is remembered.
2372
2385
  */
2373
2386
  declare const VIEW_NOT_SAVED_YET: string;
2374
- declare function TablePage({ tableId, pageSize, seedViews, onLeave, leaveLabel, activeDashboardId, className, }: TablePageProps): react.JSX.Element;
2387
+ declare function TablePage({ tableId, pageSize, seedViews, onLeave, leaveLabel, activeDashboardId, activeRecordId, className, }: TablePageProps): react.JSX.Element;
2375
2388
 
2376
2389
  /** One Field a person asked for, in the words a person uses (FLD-1 / FLD-11). */
2377
2390
  interface NewFieldSpec {
package/dist/index.js CHANGED
@@ -4898,6 +4898,27 @@ import {
4898
4898
  } from "@ai-matrx/records/react";
4899
4899
  import { Button as Button15, Skeleton as Skeleton5, cn as cn17 } from "@ai-matrx/design-system";
4900
4900
  import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
4901
+ var UNPLACED = "\0unplaced";
4902
+ function stageOfCard(row, stageKey, stages) {
4903
+ const document2 = row.document ?? {};
4904
+ const choices = document2["_choices"];
4905
+ if (choices && typeof choices === "object") {
4906
+ const chosen = choices[stageKey];
4907
+ if (chosen && typeof chosen === "object") {
4908
+ const key = chosen["key"];
4909
+ if (typeof key === "string" && key !== "") {
4910
+ return stages.some((s) => s.key === key) ? key : null;
4911
+ }
4912
+ }
4913
+ }
4914
+ const raw = document2[stageKey];
4915
+ if (raw === null || raw === void 0 || raw === "") return null;
4916
+ const said = String(raw).trim();
4917
+ const byKey = stages.find((s) => s.key === said);
4918
+ if (byKey) return byKey.key;
4919
+ const byLabel = stages.find((s) => s.label.toLowerCase() === said.toLowerCase());
4920
+ return byLabel ? byLabel.key : null;
4921
+ }
4901
4922
  function PipelineBoard({
4902
4923
  tableId,
4903
4924
  rows,
@@ -4947,12 +4968,12 @@ function PipelineBoard({
4947
4968
  const map = /* @__PURE__ */ new Map();
4948
4969
  if (!stageKey) return map;
4949
4970
  for (const row of rows) {
4950
- const raw = (row.document ?? {})[stageKey];
4951
- const key = raw === null || raw === void 0 || raw === "" ? "" : String(raw);
4952
- map.set(key, [...map.get(key) ?? [], row]);
4971
+ const key = stageOfCard(row, stageKey, definition?.stages ?? []);
4972
+ map.set(key ?? UNPLACED, [...map.get(key ?? UNPLACED) ?? [], row]);
4953
4973
  }
4954
4974
  return map;
4955
- }, [rows, stageKey]);
4975
+ }, [rows, stageKey, definition?.stages]);
4976
+ const unplaced = cardsByStage.get(UNPLACED) ?? [];
4956
4977
  const all = fields.data ?? [];
4957
4978
  const titleField = useMemo14(
4958
4979
  () => all.find((f) => f.key !== stageKey) ?? all[0],
@@ -5099,7 +5120,14 @@ function PipelineBoard({
5099
5120
  },
5100
5121
  stage.key
5101
5122
  );
5102
- }) })
5123
+ }) }),
5124
+ unplaced.length > 0 ? /* @__PURE__ */ jsxs17("p", { className: "text-xs text-muted-foreground", "data-testid": "pipeline-unplaced", children: [
5125
+ unplaced.length === 1 ? "One record is" : `${unplaced.length} records are`,
5126
+ " not in any of these columns \u2014 ",
5127
+ unplaced.slice(0, 3).map((r) => rowName(r, titleField?.key ?? null, "Untitled")).join(", "),
5128
+ unplaced.length > 3 ? ` and ${unplaced.length - 3} more` : "",
5129
+ ". Their stage is not one this pipeline offers, so nothing here can draw them; open one from the grid to move it."
5130
+ ] }) : null
5103
5131
  ] });
5104
5132
  }
5105
5133
  function formatTotal(total) {
@@ -11776,7 +11804,7 @@ function TablesHome({ onOpenTable, className }) {
11776
11804
  }
11777
11805
 
11778
11806
  // src/TablePage.tsx
11779
- import { useCallback as useCallback32, useState as useState45 } from "react";
11807
+ import { useCallback as useCallback32, useEffect as useEffect36, useState as useState45 } from "react";
11780
11808
  import { useRecordsClient as useRecordsClient37, useTable as useTable20 } from "@ai-matrx/records/react";
11781
11809
  import { Button as Button40, Separator as Separator8, Skeleton as Skeleton30, cn as cn45 } from "@ai-matrx/design-system";
11782
11810
  import { Fragment as Fragment21, jsx as jsx49, jsxs as jsxs45 } from "react/jsx-runtime";
@@ -11786,6 +11814,9 @@ var VIEW_NOT_SAVED_YET = "This table has no saved view yet, so the layout you pi
11786
11814
  function defaultView(tableId) {
11787
11815
  return { name: DEFAULT_VIEW_NAME, subject: tableId, layout: "grid", isDefault: true };
11788
11816
  }
11817
+ function openingRail(activeRecordId) {
11818
+ return activeRecordId ? { rail: "record", record: activeRecordId } : { rail: "none", record: null };
11819
+ }
11789
11820
  function TablePage({
11790
11821
  tableId,
11791
11822
  pageSize = 100,
@@ -11793,6 +11824,7 @@ function TablePage({
11793
11824
  onLeave,
11794
11825
  leaveLabel = "Back to your tables",
11795
11826
  activeDashboardId,
11827
+ activeRecordId,
11796
11828
  className
11797
11829
  }) {
11798
11830
  const client = useRecordsClient37();
@@ -11800,12 +11832,18 @@ function TablePage({
11800
11832
  const rights = useTableRights(table.data);
11801
11833
  const organizationId = useRecordsClient37().config.organizationId;
11802
11834
  const [view, setView] = useState45(null);
11803
- const [rail, setRail] = useState45("none");
11835
+ const opening = openingRail(activeRecordId);
11836
+ const [rail, setRail] = useState45(opening.rail);
11804
11837
  const [asking, setAsking] = useState45(null);
11805
11838
  const [main, setMain] = useState45(activeDashboardId ? "dashboards" : "records");
11806
- const [openRecord, setOpenRecord] = useState45(null);
11839
+ const [openRecord, setOpenRecord] = useState45(opening.record);
11807
11840
  const viewVersion = useRecordVersion(view?.id ?? null);
11808
11841
  const show = (next) => setRail((current) => current === next ? "none" : next);
11842
+ useEffect36(() => {
11843
+ if (!activeRecordId) return;
11844
+ setOpenRecord(activeRecordId);
11845
+ setRail("record");
11846
+ }, [activeRecordId]);
11809
11847
  const patchView = useCallback32(
11810
11848
  async (patch) => {
11811
11849
  const current = view;