@ai-matrx/detail 0.1.1 → 0.1.3

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,26 @@
1
1
  # Changelog — @ai-matrx/detail
2
2
 
3
+ ## 0.1.3
4
+ ### Unreleased
5
+
6
+ - **Added — the not-found state carries the host's error actions.** A record that cannot be read
7
+ (moved, deleted, or not shared with the person) now renders design-system's `ErrorActions` slot
8
+ beside its sentence, with `origin: "detail/DetailBody"`, the sentence as `message`, an
9
+ `operation` of "Open this <label>", and the record as `records: [{ type, id }]`. A host that
10
+ mounts `ErrorActionsProvider` (matrx-frontend: its Alchemy copy-for-AI menu) gets its actions
11
+ there; with no provider nothing extra renders. This is the last difference between this package
12
+ and matrx-frontend's in-repo copy (frontend audit 2026-09-29, detail-002), so the frontend can
13
+ adopt the package and delete the copy. Proof:
14
+ `src/react/__tests__/the-absent-record-carries-the-hosts-error-actions.test.tsx`.
15
+ - **Consumer action:** none — additive. A host with `ErrorActionsProvider` mounted sees its
16
+ actions appear on the not-found state.
17
+
18
+ ## 0.1.2
19
+
20
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
21
+ `git diff npm/detail/v0.1.1..npm/detail/v0.1.2 -- apps/shared/detail`).
22
+ No source changes intended and no consumer action required.
23
+
3
24
  ## 0.1.1
4
25
 
5
26
  Automatic changed-only republish (docs/metadata drift since the last tag — see
@@ -115,3 +136,5 @@ What changed on the way in, and why:
115
136
  remedy names the item registry.
116
137
  6. Any health producer that decides a reconnect would not help must answer
117
138
  `onReconnect: null` (not omit the key) — omitting it now means "defer to the host".
139
+
140
+
package/dist/react.cjs CHANGED
@@ -1014,20 +1014,26 @@ function DetailPresentationPane({ core }) {
1014
1014
  }, [open, save, registerSave]);
1015
1015
  if (!save) return null;
1016
1016
  if (!open) {
1017
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1018
- "button",
1019
- {
1020
- type: "button",
1021
- onClick: () => setOpen(true),
1022
- className: "flex w-full items-center gap-1.5 rounded-md px-1 py-1 text-left text-[11px] text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1023
- "data-detail-presentation-pane": "collapsed",
1024
- children: [
1025
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Settings2Icon, { className: "h-3 w-3 shrink-0" }),
1026
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: setting.error ? `Your "open details as" setting could not be read (${setting.error}) \u2014 details are opening as ${WORD[core.presentation]}.` : `Details open as ${WORD[effective]}.` }),
1027
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "underline underline-offset-2", children: "Change" })
1028
- ]
1029
- }
1030
- );
1017
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "w-full", children: [
1018
+ setting.error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "px-1 pt-1 text-[11px] text-muted-foreground", children: [
1019
+ `Your "open details as" setting could not be read (${setting.error}) \u2014 details are opening as ${WORD[core.presentation]}.`,
1020
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.ErrorActions, { origin: "detail/DetailPresentationPane", operation: "Read the open-details-as setting", error: setting.error })
1021
+ ] }) : null,
1022
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1023
+ "button",
1024
+ {
1025
+ type: "button",
1026
+ onClick: () => setOpen(true),
1027
+ className: "flex w-full items-center gap-1.5 rounded-md px-1 py-1 text-left text-[11px] text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1028
+ "data-detail-presentation-pane": "collapsed",
1029
+ children: [
1030
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Settings2Icon, { className: "h-3 w-3 shrink-0" }),
1031
+ setting.error ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: `Details open as ${WORD[effective]}.` }),
1032
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "underline underline-offset-2", children: "Change" })
1033
+ ]
1034
+ }
1035
+ )
1036
+ ] });
1031
1037
  }
1032
1038
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1033
1039
  "section",
@@ -1109,11 +1115,15 @@ function DetailPresentationPane({ core }) {
1109
1115
  }
1110
1116
  )
1111
1117
  ] }),
1112
- state.status === "refused" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-xs text-destructive", "data-detail-presentation-refusal": true, children: state.reason }) : null,
1118
+ state.status === "refused" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "text-xs text-destructive", "data-detail-presentation-refusal": true, children: [
1119
+ state.reason,
1120
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.ErrorActions, { origin: "detail/DetailPresentationPane", operation: "Change how details open", message: state.reason })
1121
+ ] }) : null,
1113
1122
  setting.error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
1114
1123
  "The saved setting could not be read here (",
1115
1124
  setting.error,
1116
- "), so this shows what this detail is actually doing."
1125
+ "), so this shows what this detail is actually doing.",
1126
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.ErrorActions, { origin: "detail/DetailPresentationPane", operation: "Read the open-details-as setting", error: setting.error })
1117
1127
  ] }) : null
1118
1128
  ]
1119
1129
  }
@@ -1273,10 +1283,25 @@ function FieldsSection({ core }) {
1273
1283
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LoadingFields, { core, label });
1274
1284
  }
1275
1285
  if (core.status === "not-found") {
1276
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Notice, { tone: "warn", children: `This ${label} couldn't be found \u2014 it may have been moved, deleted, or isn't shared with you.` });
1286
+ const sentence = `This ${label} couldn't be found \u2014 it may have been moved, deleted, or isn't shared with you.`;
1287
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Notice, { tone: "warn", children: [
1288
+ sentence,
1289
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1290
+ import_design_system3.ErrorActions,
1291
+ {
1292
+ origin: "detail/DetailBody",
1293
+ operation: `Open this ${label}`,
1294
+ message: sentence,
1295
+ records: [{ type: core.ref.type, id: core.ref.id }]
1296
+ }
1297
+ )
1298
+ ] });
1277
1299
  }
1278
1300
  if (core.status === "error") {
1279
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Notice, { tone: "error", children: `Couldn't load the details for this ${label}. ${core.errorMessage ?? ""}`.trim() });
1301
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Notice, { tone: "error", children: [
1302
+ `Couldn't load the details for this ${label}. ${core.errorMessage ?? ""}`.trim(),
1303
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.ErrorActions, { origin: "detail/DetailBody", operation: `Load this ${label}`, error: core.errorMessage })
1304
+ ] });
1280
1305
  }
1281
1306
  if (core.status === "none") {
1282
1307
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Notice, { tone: "muted", children: `Nothing more about this ${label} is stored here, so there is nothing else to show. ` + whatTheControlsDo(core) });
@@ -1391,7 +1416,10 @@ function HistorySection({ core }) {
1391
1416
  state.status === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "space-y-1.5", "aria-busy": "true", "aria-label": "Loading history", children: [
1392
1417
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Skeleton, { className: "h-3.5 w-2/3" }),
1393
1418
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Skeleton, { className: "h-3.5 w-1/2" })
1394
- ] }) : state.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-xs text-muted-foreground", children: state.message.toLowerCase().includes("access denied") ? "History is only shown to people who can view this record." : `History could not be read: ${state.message}` }) : state.entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-xs text-muted-foreground", children: "No recorded changes yet." }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ol", { className: "space-y-1", children: state.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1419
+ ] }) : state.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
1420
+ state.message.toLowerCase().includes("access denied") ? "History is only shown to people who can view this record." : `History could not be read: ${state.message}`,
1421
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.ErrorActions, { origin: "detail/DetailBody", operation: "Read the history", error: state.message })
1422
+ ] }) : state.entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-xs text-muted-foreground", children: "No recorded changes yet." }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ol", { className: "space-y-1", children: state.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1395
1423
  "li",
1396
1424
  {
1397
1425
  className: "flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs",