@declarion/react 0.66.0 → 0.80.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.
Files changed (66) hide show
  1. package/README.md +1 -1
  2. package/dist-lib/api/auth.js +24 -14
  3. package/dist-lib/app.js +28 -23
  4. package/dist-lib/components/chrome/AssociationTabs.js +35 -38
  5. package/dist-lib/components/chrome/HighlightsStrip.js +2 -1
  6. package/dist-lib/components/chrome/RecordHeader.js +33 -38
  7. package/dist-lib/components/detail-layout/AssociatedBlock.js +10 -21
  8. package/dist-lib/components/detail-layout/ChildrenBlock.js +1 -8
  9. package/dist-lib/components/detail-layout/ChildrenCards.js +1 -8
  10. package/dist-lib/components/detail-layout/ChildrenList.js +1 -8
  11. package/dist-lib/components/detail-layout/ChildrenTable.js +1 -8
  12. package/dist-lib/components/detail-layout/ChildrenTimeline.js +1 -8
  13. package/dist-lib/components/detail-layout/DetailAuditStrip.js +33 -29
  14. package/dist-lib/components/detail-layout/DetailHighlights.js +7 -2
  15. package/dist-lib/components/detail-layout/FieldsBlock.js +12 -9
  16. package/dist-lib/components/detail-layout/LayoutRenderer.js +10 -10
  17. package/dist-lib/components/detail-layout/LayoutTabs.js +49 -48
  18. package/dist-lib/components/detail-layout/SectionBlock.js +20 -28
  19. package/dist-lib/components/detail-layout/visibility.js +28 -0
  20. package/dist-lib/components/fields/IntArrayField.js +37 -33
  21. package/dist-lib/components/fields/NumberField.js +28 -55
  22. package/dist-lib/components/fields/RichTextField.js +1 -1
  23. package/dist-lib/components/fields/TimestampField.js +50 -89
  24. package/dist-lib/components/fields/cells/factories/date.js +13 -14
  25. package/dist-lib/components/fields/cells/factories/money.js +1 -1
  26. package/dist-lib/components/fields/cells/factories/number.js +4 -4
  27. package/dist-lib/components/file-widgets/DocumentCard.js +1 -1
  28. package/dist-lib/components/file-widgets/Grid.js +153 -152
  29. package/dist-lib/components/file-widgets/ImageWidget.js +90 -91
  30. package/dist-lib/components/file-widgets/LabeledSlots.js +1 -0
  31. package/dist-lib/components/file-widgets/helpers.js +15 -19
  32. package/dist-lib/components/file-widgets/host.js +33 -32
  33. package/dist-lib/components/file-widgets/upload.js +10 -6
  34. package/dist-lib/components/layout/Layout.js +125 -123
  35. package/dist-lib/components/pages/NoScreensPage.impl.js +14 -0
  36. package/dist-lib/components/pages/NoScreensPage.js +12 -0
  37. package/dist-lib/components/pages/SmartDetailPage.impl.js +451 -451
  38. package/dist-lib/components/pages/auth/AuthShell.js +62 -61
  39. package/dist-lib/components/pages/auth/CodeInput.js +63 -0
  40. package/dist-lib/components/pages/auth/SignIn.js +12 -4
  41. package/dist-lib/components/pages/auth/SignUp.impl.js +80 -103
  42. package/dist-lib/components/pages/auth/SignUpCode.js +122 -0
  43. package/dist-lib/components/pages/auth/TwoFA.impl.js +9 -55
  44. package/dist-lib/components/pages/list/cardProjection.js +135 -122
  45. package/dist-lib/components/pages/list/columns.js +58 -43
  46. package/dist-lib/components/pages/profile/Profile.impl.js +87 -104
  47. package/dist-lib/components/pages/tenant-params/TenantParamsPage.impl.js +1 -1
  48. package/dist-lib/components/params/ParamsBlock.js +6 -17
  49. package/dist-lib/components/params/param-editors.js +14 -10
  50. package/dist-lib/components/primitives/Fields.js +314 -236
  51. package/dist-lib/components/shared/MarkdownRenderer.js +44 -43
  52. package/dist-lib/declarion-react.css +1 -1
  53. package/dist-lib/hooks/useActiveTabFollowsRoute.js +49 -0
  54. package/dist-lib/hooks/useAuth.js +44 -37
  55. package/dist-lib/hooks/useDocumentTitle.js +20 -0
  56. package/dist-lib/hooks/useFollowAgentOpen.js +1 -0
  57. package/dist-lib/hooks/useTabTitle.js +1 -1
  58. package/dist-lib/index.d.ts +21 -7
  59. package/dist-lib/lib/date-text.js +57 -0
  60. package/dist-lib/lib/number-text.js +9 -0
  61. package/dist-lib/lib/timestamp.js +29 -29
  62. package/dist-lib/stores/tabs.js +7 -5
  63. package/dist-lib/testing.d.ts +1 -1
  64. package/dist-lib/testing.js +1 -0
  65. package/dist-lib/{useResponsiveMode-DmrpMbZX.d.ts → useResponsiveMode-D3SKz5z4.d.ts} +20 -9
  66. package/package.json +11 -11
package/README.md CHANGED
@@ -44,7 +44,7 @@ subscribes via `useSyncExternalStore`, so replacing the registry (identity switc
44
44
  re-renders every icon. Bare names resolve from Lucide - no registry entry needed.
45
45
  Lucide's per-icon `dynamicIconImports` map is loaded only via `import()` and stays
46
46
  out of the eager bundle (the curated `Icons.tsx` set is tree-shaken named imports).
47
- See [`examples/embed-host`](https://github.com/disciplinedware/declarion/blob/main/typescript/examples/embed-host) for a working host.
47
+ See [`examples/embed-demo`](https://github.com/disciplinedware/declarion/blob/main/typescript/examples/embed-demo) for a working host.
48
48
 
49
49
  The curated built-in set is just a name→Lucide-component map with the SDK's
50
50
  `{ size, cls, style }` prop adapter; there is no hand-drawn SVG and no codegen.
@@ -17,51 +17,61 @@ async function i(n, r, i) {
17
17
  password: r,
18
18
  display_name: i
19
19
  });
20
- return t(a.expires_at), a;
20
+ return a.verification_required || t(a.expires_at), a;
21
+ }
22
+ async function a(n, r) {
23
+ let i = await e("auth.confirm_signup", {
24
+ email: n,
25
+ code: r
26
+ });
27
+ return t(i.expires_at), i;
28
+ }
29
+ async function o(t) {
30
+ return e("auth.resend_signup_code", { email: t });
21
31
  }
22
- async function a() {
32
+ async function s() {
23
33
  return e("auth.me");
24
34
  }
25
- async function o() {
35
+ async function c() {
26
36
  return e("auth.me", {}, { isSessionProbe: !0 });
27
37
  }
28
- async function s() {
38
+ async function l() {
29
39
  return (await e("auth.list_tenants")).tenants;
30
40
  }
31
- async function c(n) {
41
+ async function u(n) {
32
42
  let r = await e("auth.switch_tenant", { tenant_id: n });
33
43
  return t(r.expires_at), r;
34
44
  }
35
- async function l() {
45
+ async function d() {
36
46
  await e("auth.logout");
37
47
  }
38
- async function u(t) {
39
- return (await e("sso_provider.list", t ? { tenant_code: t } : {})).providers;
48
+ async function f(t) {
49
+ return (await e("auth.list_identity_providers", t ? { tenant_code: t } : {})).providers;
40
50
  }
41
- function d(e, t, n) {
51
+ function p(e, t, n) {
42
52
  let r = new URLSearchParams();
43
53
  t && r.set("tenant", t), n && r.set("redirect", n);
44
54
  let i = r.toString();
45
55
  return `/api/auth/sso/authorize/${encodeURIComponent(e)}${i ? `?${i}` : ""}`;
46
56
  }
47
- async function f(t, n, r) {
57
+ async function m(t, n, r) {
48
58
  let i = {
49
59
  target_user_id: t,
50
60
  reason: n
51
61
  };
52
62
  return r != null && (i.duration_minutes = r), e("impersonation.start", i);
53
63
  }
54
- async function p() {
64
+ async function h() {
55
65
  return e("impersonation.stop");
56
66
  }
57
- async function m(t) {
67
+ async function g(t) {
58
68
  await e("impersonation.revoke", { session_id: t });
59
69
  }
60
- async function h(t, n) {
70
+ async function _(t, n) {
61
71
  await e("auth.change_password", {
62
72
  current_password: t,
63
73
  new_password: n
64
74
  });
65
75
  }
66
76
  //#endregion
67
- export { h as changePassword, n as checkSetup, a as getMe, m as impersonationRevoke, f as impersonationStart, p as impersonationStop, u as listSSOProviders, s as listTenants, r as login, l as logout, o as probeSession, i as signup, d as ssoAuthorizeUrl, c as switchTenant };
77
+ export { _ as changePassword, n as checkSetup, a as confirmSignup, s as getMe, g as impersonationRevoke, m as impersonationStart, h as impersonationStop, f as listIdentityProviders, l as listTenants, r as login, d as logout, c as probeSession, o as resendSignupCode, i as signup, p as ssoAuthorizeUrl, u as switchTenant };
package/dist-lib/app.js CHANGED
@@ -21,16 +21,17 @@ import { Layout as b } from "./components/layout/Layout.js";
21
21
  import { BlankScreen as x } from "./components/shared/BlankScreen.js";
22
22
  import { schemaDefaultRoute as S } from "./lib/schema-routing.js";
23
23
  import { SignIn as C } from "./components/pages/auth/SignIn.js";
24
- import { SignUp as w } from "./components/pages/auth/SignUp.js";
25
- import { Forgot as te } from "./components/pages/auth/Forgot.js";
24
+ import { SignUp as te } from "./components/pages/auth/SignUp.js";
25
+ import { Forgot as w } from "./components/pages/auth/Forgot.js";
26
26
  import { Reset as T } from "./components/pages/auth/Reset.js";
27
27
  import { TwoFA as E } from "./components/pages/auth/TwoFA.js";
28
28
  import { SSOCallbackPage as D } from "./components/pages/SSOCallbackPage.js";
29
29
  import { NotFoundPage as O } from "./components/pages/NotFoundPage.js";
30
+ import { NoScreensPage as ne } from "./components/pages/NoScreensPage.js";
30
31
  import { Profile as k } from "./components/pages/profile/Profile.js";
31
32
  import { TenantParamsPage as A } from "./components/pages/tenant-params/TenantParamsPage.js";
32
- import { Preferences as ne } from "./components/pages/profile/Preferences.js";
33
- import { AdminCatalogPage as re } from "./components/pages/AdminCatalogPage.js";
33
+ import { Preferences as re } from "./components/pages/profile/Preferences.js";
34
+ import { AdminCatalogPage as ie } from "./components/pages/AdminCatalogPage.js";
34
35
  import { ErrorBoundary as j } from "./components/shared/ErrorBoundary.js";
35
36
  import { useVersionWatcher as M } from "./hooks/useVersionWatcher.js";
36
37
  import { ConnectionNotice as N } from "./components/shared/ConnectionNotice.js";
@@ -41,8 +42,8 @@ import { CONSUMER_BRAND_CSS_ID as R, applyBrandTokens as z, brandTokenCss as B }
41
42
  import { useEffect as V, useMemo as H } from "react";
42
43
  import { QueryClient as U, QueryClientProvider as W } from "@tanstack/react-query";
43
44
  import { Fragment as G, jsx as K, jsxs as q } from "react/jsx-runtime";
44
- import { BrowserRouter as J, Navigate as Y, Route as X, Routes as ie } from "react-router";
45
- import { Toaster as ae } from "sonner";
45
+ import { BrowserRouter as J, Navigate as Y, Route as X, Routes as ae } from "react-router";
46
+ import { Toaster as oe } from "sonner";
46
47
  I("Profile", k), I("TenantParameters", A);
47
48
  var Z = "declarion-managed-favicon", Q = new U({ defaultOptions: { queries: {
48
49
  staleTime: 3e5,
@@ -59,10 +60,10 @@ function $(e) {
59
60
  return null;
60
61
  }
61
62
  }
62
- function oe({ component: e, screenCode: t }) {
63
+ function se({ component: e, screenCode: t }) {
63
64
  return o(), /* @__PURE__ */ K(e, { screenCode: t });
64
65
  }
65
- function se() {
66
+ function ce() {
66
67
  let { data: e } = c();
67
68
  return {
68
69
  routes: H(() => {
@@ -98,7 +99,7 @@ function se() {
98
99
  path: o.route,
99
100
  element: /* @__PURE__ */ K(j, { children: /* @__PURE__ */ K(L, {
100
101
  code: n,
101
- children: /* @__PURE__ */ K(oe, {
102
+ children: /* @__PURE__ */ K(se, {
102
103
  component: e,
103
104
  screenCode: n
104
105
  })
@@ -110,8 +111,8 @@ function se() {
110
111
  defaultRoute: H(() => S(e), [e])
111
112
  };
112
113
  }
113
- function ce() {
114
- let e = s((e) => e.initialize), t = s((e) => e.isLoading), r = s((e) => e.isAuthenticated), { data: i, isError: a } = c(), o = ee(), { data: l, isLoading: m } = f(), { branding: h, isLoading: g } = p(), { routes: _, defaultRoute: v } = se(), y = n();
114
+ function le() {
115
+ let e = s((e) => e.initialize), t = s((e) => e.isLoading), r = s((e) => e.isAuthenticated), { data: i, isError: a } = c(), o = ee(), { data: l, isLoading: m } = f(), { branding: h, isLoading: g } = p(), { routes: _, defaultRoute: v } = ce(), y = n();
115
116
  V(() => {
116
117
  document.documentElement.lang = o;
117
118
  }, [o]);
@@ -164,7 +165,7 @@ function ce() {
164
165
  n.id = R, n.rel = "stylesheet", n.href = t, document.head.appendChild(n);
165
166
  }, [M]);
166
167
  let P = y.enabled && !r;
167
- return S || P || t || m && !l || g || !i && (r || !a) ? /* @__PURE__ */ K(x, {}) : /* @__PURE__ */ q(ie, { children: [
168
+ return S || P || t || m && !l || g || !i && (r || !a) ? /* @__PURE__ */ K(x, {}) : /* @__PURE__ */ q(ae, { children: [
168
169
  /* @__PURE__ */ K(X, {
169
170
  path: "/login",
170
171
  element: /* @__PURE__ */ K(C, {})
@@ -175,11 +176,11 @@ function ce() {
175
176
  }),
176
177
  /* @__PURE__ */ K(X, {
177
178
  path: "/signup",
178
- element: /* @__PURE__ */ K(w, {})
179
+ element: /* @__PURE__ */ K(te, {})
179
180
  }),
180
181
  /* @__PURE__ */ K(X, {
181
182
  path: "/forgot",
182
- element: /* @__PURE__ */ K(te, {})
183
+ element: /* @__PURE__ */ K(w, {})
183
184
  }),
184
185
  /* @__PURE__ */ K(X, {
185
186
  path: "/reset",
@@ -192,6 +193,10 @@ function ce() {
192
193
  /* @__PURE__ */ q(X, {
193
194
  element: /* @__PURE__ */ K(b, {}),
194
195
  children: [
196
+ i && !v && /* @__PURE__ */ K(X, {
197
+ index: !0,
198
+ element: /* @__PURE__ */ K(ne, {})
199
+ }),
195
200
  v && /* @__PURE__ */ q(G, { children: [/* @__PURE__ */ K(X, {
196
201
  index: !0,
197
202
  element: /* @__PURE__ */ K(Y, {
@@ -208,11 +213,11 @@ function ce() {
208
213
  _,
209
214
  /* @__PURE__ */ K(X, {
210
215
  path: "/preferences",
211
- element: /* @__PURE__ */ K(ne, {})
216
+ element: /* @__PURE__ */ K(re, {})
212
217
  }),
213
218
  /* @__PURE__ */ K(X, {
214
219
  path: "/admin/catalog",
215
- element: /* @__PURE__ */ K(re, {})
220
+ element: /* @__PURE__ */ K(ie, {})
216
221
  }),
217
222
  /* @__PURE__ */ K(X, {
218
223
  path: "*",
@@ -222,14 +227,14 @@ function ce() {
222
227
  })
223
228
  ] });
224
229
  }
225
- function le() {
230
+ function ue() {
226
231
  M();
227
232
  let e = m((e) => e.toastPosition);
228
233
  return /* @__PURE__ */ q(J, { children: [
229
234
  /* @__PURE__ */ K(h, {}),
230
235
  /* @__PURE__ */ K(N, {}),
231
- /* @__PURE__ */ K(ce, {}),
232
- /* @__PURE__ */ K(ae, {
236
+ /* @__PURE__ */ K(le, {}),
237
+ /* @__PURE__ */ K(oe, {
233
238
  position: e,
234
239
  toastOptions: { unstyled: !0 },
235
240
  expand: !0,
@@ -244,7 +249,7 @@ function le() {
244
249
  })
245
250
  ] });
246
251
  }
247
- function ue({ children: e }) {
252
+ function de({ children: e }) {
248
253
  let t = y(), n = v();
249
254
  return /* @__PURE__ */ K(l, {
250
255
  viewport: t,
@@ -252,11 +257,11 @@ function ue({ children: e }) {
252
257
  children: e
253
258
  });
254
259
  }
255
- function de() {
260
+ function fe() {
256
261
  return /* @__PURE__ */ K(j, { children: /* @__PURE__ */ K(W, {
257
262
  client: Q,
258
- children: /* @__PURE__ */ K(t, { children: /* @__PURE__ */ K(ue, { children: /* @__PURE__ */ K(le, {}) }) })
263
+ children: /* @__PURE__ */ K(t, { children: /* @__PURE__ */ K(de, { children: /* @__PURE__ */ K(ue, {}) }) })
259
264
  }) });
260
265
  }
261
266
  //#endregion
262
- export { de as App };
267
+ export { fe as App };
@@ -14,7 +14,7 @@ import { useQuery as g } from "@tanstack/react-query";
14
14
  import { jsx as _, jsxs as v } from "react/jsx-runtime";
15
15
  //#region src/components/chrome/AssociationTabs.tsx
16
16
  function y({ entityCode: e, recordId: t, associations: n, schema: o }) {
17
- let s = r(), c = m(() => Object.entries(n), [n]), [l, u] = h(0);
17
+ let s = r(), c = m(() => Object.entries(n).filter(([, e]) => !!o.entities[e.target]), [n, o.entities]), [l, u] = h(0);
18
18
  if (c.length === 0) return null;
19
19
  let [d, f] = c[l];
20
20
  return /* @__PURE__ */ _(i, {
@@ -66,72 +66,69 @@ function y({ entityCode: e, recordId: t, associations: n, schema: o }) {
66
66
  });
67
67
  }
68
68
  function b({ entityCode: i, recordId: a, assocKey: h, association: y, schema: b }) {
69
- let x = r(), S = r("errors"), C = c(), w = `${i}.${h}`, { data: T, isLoading: E } = g({
69
+ let x = r(), S = c(), C = `${i}.${h}`, { data: w, isLoading: T } = g({
70
70
  queryKey: [
71
71
  "association",
72
- w,
72
+ C,
73
73
  a
74
74
  ],
75
- queryFn: () => s(w, [a])
76
- }), D = T?.target_entity ?? y.target, O = b.entities[D], k = m(() => T?.ids ?? [], [T?.ids]), A = m(() => O?.fields.names().find((e) => O.fields.get(e)?.primary) ?? "id", [O]), j = m(() => k.slice(0, 50), [k]), { data: M, isLoading: N } = g({
75
+ queryFn: () => s(C, [a])
76
+ }), E = w?.target_entity ?? y.target, D = b.entities[E], O = m(() => w?.ids ?? [], [w?.ids]), k = m(() => D?.fields.names().find((e) => D.fields.get(e)?.primary) ?? "id", [D]), A = m(() => O.slice(0, 50), [O]), { data: j, isLoading: M } = g({
77
77
  queryKey: [
78
78
  "association-records",
79
- D,
80
- j
79
+ E,
80
+ A
81
81
  ],
82
- queryFn: () => o(D, {
82
+ queryFn: () => o(E, {
83
83
  per_page: 50,
84
84
  filters: [{
85
- field: A,
85
+ field: k,
86
86
  op: "in",
87
- value: j
87
+ value: A
88
88
  }]
89
89
  }),
90
- enabled: j.length > 0 && !!O
91
- }), P = M?.data ?? [], F = M?.$refs, I = m(() => O ? O.fields.names().filter((e) => {
92
- let t = O.fields.get(e);
90
+ enabled: A.length > 0 && !!D
91
+ }), N = j?.data ?? [], P = j?.$refs, F = m(() => D ? D.fields.names().filter((e) => {
92
+ let t = D.fields.get(e);
93
93
  return t && !t.primary && !t.auto && t.display?.is_listable !== !1;
94
- }).slice(0, 6) : [], [O]), L = () => {
95
- let e = l(b, D);
94
+ }).slice(0, 6) : [], [D]), I = () => {
95
+ let e = l(b, E);
96
96
  if (!e) return;
97
97
  let t = x(y.display?.name) || h, n = new URLSearchParams();
98
98
  n.set("filters", JSON.stringify([{
99
- field: A,
99
+ field: k,
100
100
  op: "in",
101
- value: k
102
- }])), C(e.route, {
101
+ value: O
102
+ }])), S(e.route, {
103
103
  title: t,
104
104
  icon: y.display?.icon || e.icon,
105
105
  search: n.toString()
106
106
  });
107
- }, R = {
107
+ }, L = {
108
108
  fontSize: 12.5,
109
109
  color: "var(--text-3)",
110
110
  padding: "14px 16px"
111
111
  };
112
- if (E || N) return /* @__PURE__ */ _("div", {
113
- style: R,
112
+ if (T || M) return /* @__PURE__ */ _("div", {
113
+ style: L,
114
114
  children: x("shell.loading", "Loading…")
115
115
  });
116
- if (!O) return /* @__PURE__ */ _("div", {
117
- style: R,
118
- children: S("record.related_entity_not_found", "The related record type is not declared in this deployment.")
119
- });
120
- if (k.length === 0) return /* @__PURE__ */ _("div", {
121
- style: R,
116
+ if (!D) return null;
117
+ if (O.length === 0) return /* @__PURE__ */ _("div", {
118
+ style: L,
122
119
  children: x("shell.association.empty", "No related records.")
123
120
  });
124
- let z = l(b, D);
121
+ let R = l(b, E);
125
122
  return /* @__PURE__ */ v("div", {
126
123
  style: { padding: "8px 0" },
127
124
  children: [
128
125
  /* @__PURE__ */ v("table", {
129
126
  style: p,
130
- children: [/* @__PURE__ */ _("thead", { children: /* @__PURE__ */ _("tr", { children: I.map((t) => /* @__PURE__ */ _("th", {
127
+ children: [/* @__PURE__ */ _("thead", { children: /* @__PURE__ */ _("tr", { children: F.map((t) => /* @__PURE__ */ _("th", {
131
128
  style: f,
132
- children: e(x, O.fields.get(t), t, b.entities)
133
- }, t)) }) }), /* @__PURE__ */ _("tbody", { children: P.map((e, t) => /* @__PURE__ */ _("tr", { children: I.map((t) => {
134
- let n = O.fields.get(t);
129
+ children: e(x, D.fields.get(t), t, b.entities)
130
+ }, t)) }) }), /* @__PURE__ */ _("tbody", { children: N.map((e, t) => /* @__PURE__ */ _("tr", { children: F.map((t) => {
131
+ let n = D.fields.get(t);
135
132
  return n ? /* @__PURE__ */ _("td", {
136
133
  style: d,
137
134
  children: u({
@@ -140,24 +137,24 @@ function b({ entityCode: i, recordId: a, assocKey: h, association: y, schema: b
140
137
  value: e[t],
141
138
  mode: "display",
142
139
  record: e,
143
- refs: F,
140
+ refs: P,
144
141
  t: x
145
142
  })
146
143
  }, t) : /* @__PURE__ */ _("td", {}, t);
147
144
  }) }, t)) })]
148
145
  }),
149
- z && T && T.count > P.length && /* @__PURE__ */ _("div", {
146
+ R && w && w.count > N.length && /* @__PURE__ */ _("div", {
150
147
  style: {
151
148
  padding: "10px 16px",
152
149
  textAlign: "center"
153
150
  },
154
151
  children: /* @__PURE__ */ _(n, {
155
152
  icon: /* @__PURE__ */ _(t.external, { size: 12 }),
156
- onClick: L,
157
- children: x("shell.association.view_all", "View all {count} records", { count: T.count })
153
+ onClick: I,
154
+ children: x("shell.association.view_all", "View all {count} records", { count: w.count })
158
155
  })
159
156
  }),
160
- z && P.length > 0 && T && T.count <= P.length && /* @__PURE__ */ _("div", {
157
+ R && N.length > 0 && w && w.count <= N.length && /* @__PURE__ */ _("div", {
161
158
  style: {
162
159
  padding: "10px 16px",
163
160
  textAlign: "center"
@@ -165,7 +162,7 @@ function b({ entityCode: i, recordId: a, assocKey: h, association: y, schema: b
165
162
  children: /* @__PURE__ */ _(n, {
166
163
  kind: "ghost",
167
164
  icon: /* @__PURE__ */ _(t.external, { size: 12 }),
168
- onClick: L,
165
+ onClick: I,
169
166
  children: x("shell.association.open_list", "Open in list view")
170
167
  })
171
168
  })
@@ -16,6 +16,7 @@ function r({ items: r }) {
16
16
  background: "var(--divider)",
17
17
  marginInline: 12
18
18
  } }), /* @__PURE__ */ n("span", {
19
+ "data-testid": `highlight-${r.code}`,
19
20
  style: {
20
21
  display: "inline-flex",
21
22
  alignItems: "center",
@@ -32,7 +33,7 @@ function r({ items: r }) {
32
33
  style: { color: "var(--text)" },
33
34
  children: r.value
34
35
  })]
35
- })] }, i))
36
+ })] }, r.code))
36
37
  });
37
38
  }
38
39
  //#endregion
@@ -3,14 +3,13 @@ import { IconBtn as t } from "../primitives/IconBtn.js";
3
3
  import { Pill as n } from "../primitives/Pill.js";
4
4
  import { InfoTooltip as r } from "../primitives/Tooltip.js";
5
5
  import { useText as i } from "../../hooks/useText.js";
6
- import { RecordIdBadge as a } from "../primitives/RecordIdBadge.js";
7
- import { headerActionZoneStyle as o } from "./headerActionZone.js";
8
- import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
6
+ import { headerActionZoneStyle as a } from "./headerActionZone.js";
7
+ import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
9
8
  //#region src/components/chrome/RecordHeader.tsx
10
- var u = 160;
11
- function d({ icon: d, title: f, recordId: p, description: m, highlights: h, mode: g, dirty: _ = !1, showBack: v = !1, onBack: y, right: b, identityControls: x, showTitle: S = !0 }) {
12
- let C = i();
13
- return /* @__PURE__ */ l("div", {
9
+ var l = 160;
10
+ function u({ icon: u, title: d, description: f, highlights: p, mode: m, dirty: h = !1, showBack: g = !1, onBack: _, right: v, identityControls: y, showTitle: b = !0 }) {
11
+ let x = i();
12
+ return /* @__PURE__ */ c("div", {
14
13
  style: {
15
14
  display: "flex",
16
15
  alignItems: "flex-start",
@@ -19,24 +18,24 @@ function d({ icon: d, title: f, recordId: p, description: m, highlights: h, mode
19
18
  minWidth: 0
20
19
  },
21
20
  children: [
22
- S && v && /* @__PURE__ */ c("div", {
21
+ b && g && /* @__PURE__ */ s("div", {
23
22
  style: {
24
23
  paddingTop: 4,
25
24
  flexShrink: 0
26
25
  },
27
- children: /* @__PURE__ */ c(t, {
26
+ children: /* @__PURE__ */ s(t, {
28
27
  size: 26,
29
- icon: /* @__PURE__ */ c(e.back, { size: 14 }),
30
- title: C("shell.back", "Back"),
31
- onClick: y
28
+ icon: /* @__PURE__ */ s(e.back, { size: 14 }),
29
+ title: x("shell.back", "Back"),
30
+ onClick: _
32
31
  })
33
32
  }),
34
- S && d && /* @__PURE__ */ c("div", {
33
+ b && u && /* @__PURE__ */ s("div", {
35
34
  style: {
36
35
  flexShrink: 0,
37
36
  paddingTop: 2
38
37
  },
39
- children: /* @__PURE__ */ c("span", {
38
+ children: /* @__PURE__ */ s("span", {
40
39
  style: {
41
40
  width: 32,
42
41
  height: 32,
@@ -47,11 +46,11 @@ function d({ icon: d, title: f, recordId: p, description: m, highlights: h, mode
47
46
  alignItems: "center",
48
47
  justifyContent: "center"
49
48
  },
50
- children: d
49
+ children: u
51
50
  })
52
51
  }),
53
- S && /* @__PURE__ */ l(s, { children: [
54
- /* @__PURE__ */ c("h1", {
52
+ b && /* @__PURE__ */ c(o, { children: [
53
+ /* @__PURE__ */ s("h1", {
55
54
  style: {
56
55
  margin: 0,
57
56
  fontSize: "var(--page-title-size, var(--page-title-size-detail))",
@@ -59,25 +58,21 @@ function d({ icon: d, title: f, recordId: p, description: m, highlights: h, mode
59
58
  letterSpacing: 0,
60
59
  lineHeight: "var(--page-title-line-height, var(--page-title-line-height-detail))",
61
60
  color: "var(--text)",
62
- minWidth: u,
63
- overflow: "hidden",
64
- textOverflow: "ellipsis",
65
- whiteSpace: "nowrap",
61
+ minWidth: l,
66
62
  overflowWrap: "anywhere",
67
63
  maxWidth: "100%",
68
64
  flexGrow: 0,
69
65
  flexShrink: 1,
70
66
  flexBasis: "auto"
71
67
  },
72
- children: f
68
+ children: d
73
69
  }),
74
- p && p !== f && /* @__PURE__ */ c(a, { value: p }),
75
- m && /* @__PURE__ */ c(r, {
76
- label: m,
70
+ f && /* @__PURE__ */ s(r, {
71
+ label: f,
77
72
  "data-testid": "detail-description-info"
78
73
  }),
79
- x,
80
- g === "edit" && _ && /* @__PURE__ */ l("span", {
74
+ y,
75
+ m === "edit" && h && /* @__PURE__ */ c("span", {
81
76
  style: {
82
77
  display: "inline-flex",
83
78
  alignItems: "center",
@@ -85,35 +80,35 @@ function d({ icon: d, title: f, recordId: p, description: m, highlights: h, mode
85
80
  fontSize: 11,
86
81
  color: "var(--warn)"
87
82
  },
88
- children: [/* @__PURE__ */ c("span", { style: {
83
+ children: [/* @__PURE__ */ s("span", { style: {
89
84
  width: 6,
90
85
  height: 6,
91
86
  borderRadius: 999,
92
87
  background: "var(--warn)"
93
- } }), C("shell.record.unsaved", "Unsaved")]
88
+ } }), x("shell.record.unsaved", "Unsaved")]
94
89
  }),
95
- g === "create" && /* @__PURE__ */ c(n, {
90
+ m === "create" && /* @__PURE__ */ s(n, {
96
91
  tone: "violet",
97
92
  size: "xs",
98
93
  dot: !0,
99
- children: C("shell.record.new", "New record")
94
+ children: x("shell.record.new", "New record")
100
95
  })
101
96
  ] }),
102
- b && /* @__PURE__ */ c("div", {
97
+ v && /* @__PURE__ */ s("div", {
103
98
  role: "toolbar",
104
- "aria-label": C("shell.record.page_actions", "Page actions"),
105
- style: o,
106
- children: b
99
+ "aria-label": x("shell.record.page_actions", "Page actions"),
100
+ style: a,
101
+ children: v
107
102
  }),
108
- h && g === "display" && /* @__PURE__ */ c("div", {
103
+ p && m === "display" && /* @__PURE__ */ s("div", {
109
104
  style: {
110
105
  flexBasis: "100%",
111
106
  minWidth: 0
112
107
  },
113
- children: h
108
+ children: p
114
109
  })
115
110
  ]
116
111
  });
117
112
  }
118
113
  //#endregion
119
- export { d as RecordHeader };
114
+ export { u as RecordHeader };
@@ -19,8 +19,8 @@ import { renderField as O } from "../fields/index.js";
19
19
  import { dispatchAction as k } from "../../lib/action-dispatch.js";
20
20
  import { ResponsiveActionBar as A } from "../actions/ResponsiveActionBar.js";
21
21
  import { dataTableCellStyle as j, dataTableHeadCellStyle as M, dataTableStyle as N } from "../primitives/dataTableStyles.js";
22
- import { useAssociatedData as P } from "../../hooks/useAssociatedData.js";
23
- import { ActionButton as F } from "../actions/ActionButton.js";
22
+ import { ActionButton as P } from "../actions/ActionButton.js";
23
+ import { useAssociatedData as F } from "../../hooks/useAssociatedData.js";
24
24
  import { RowActionsKebab as I } from "../actions/RowActionsKebab.js";
25
25
  import { AssociatedToolbar as L } from "./AssociatedToolbar.js";
26
26
  import { useCallback as R, useEffect as ee, useId as z, useMemo as B, useRef as V, useState as H } from "react";
@@ -113,18 +113,7 @@ function q({ node: e, ctx: t }) {
113
113
  let n = u("errors"), r = e.associated;
114
114
  if (!r || t.isNew) return null;
115
115
  let i = t.schema.entities[r];
116
- if (!i) return /* @__PURE__ */ G("div", {
117
- style: {
118
- fontSize: 12.5,
119
- color: "var(--text-3)",
120
- padding: "8px 0"
121
- },
122
- children: [
123
- n("record.related_entity_not_found", "The related record type is not declared in this deployment."),
124
- " ",
125
- /* @__PURE__ */ W("code", { children: r })
126
- ]
127
- });
116
+ if (!i) return null;
128
117
  let a = e.foreign_key ?? re(t.schema.entities, t.entityCode, r);
129
118
  return a ? /* @__PURE__ */ W(J, {
130
119
  node: e,
@@ -185,7 +174,7 @@ function J({ node: e, ctx: t, assocCode: r, assocEntity: i, fkField: a }) {
185
174
  r,
186
175
  o,
187
176
  j
188
- ]), N = U(), P = R(() => {
177
+ ]), N = U(), F = R(() => {
189
178
  N.invalidateQueries({ predicate: (e) => {
190
179
  let t = e.queryKey;
191
180
  return t[0] === "entity-children" && t[3] === r;
@@ -197,7 +186,7 @@ function J({ node: e, ctx: t, assocCode: r, assocEntity: i, fkField: a }) {
197
186
  title: o(t.display?.name) || e,
198
187
  execute: async (e) => {
199
188
  let t = await y(n, h(e, void 0));
200
- return P(), t;
189
+ return F(), t;
201
190
  }
202
191
  });
203
192
  }, [
@@ -205,7 +194,7 @@ function J({ node: e, ctx: t, assocCode: r, assocEntity: i, fkField: a }) {
205
194
  l,
206
195
  O,
207
196
  r,
208
- P
197
+ F
209
198
  ]), [L, ee] = H(0), z = /* @__PURE__ */ G("div", {
210
199
  style: {
211
200
  display: "flex",
@@ -222,13 +211,13 @@ function J({ node: e, ctx: t, assocCode: r, assocEntity: i, fkField: a }) {
222
211
  onRun: I,
223
212
  widgetContext: M,
224
213
  ariaLabel: o("record.associated.toolbar_actions", "{name} toolbar actions", { name: v })
225
- }) : x.map(({ code: e, action: t }) => /* @__PURE__ */ W(F, {
214
+ }) : x.map(({ code: e, action: t }) => /* @__PURE__ */ W(P, {
226
215
  actionCode: e,
227
216
  action: t,
228
217
  entityCode: r,
229
218
  variant: "ghost",
230
219
  size: "sm",
231
- onSuccess: P
220
+ onSuccess: F
232
221
  }, e)), _ && /* @__PURE__ */ W(c, {
233
222
  kind: "ghost",
234
223
  size: "xs",
@@ -329,7 +318,7 @@ function se({ entityCode: e, entity: t, parentEntity: n, parentId: r, foreignKey
329
318
  [e]: t
330
319
  };
331
320
  });
332
- }, []), E = B(() => Object.keys(S).length > 0 ? S : void 0, [S]), { data: D, isLoading: O, isError: k, hasNextPage: A, fetchNextPage: j, isFetchingNextPage: M } = P(n, r, e, i, m, void 0, b || void 0, E), { rows: N, refs: F } = B(() => {
321
+ }, []), E = B(() => Object.keys(S).length > 0 ? S : void 0, [S]), { data: D, isLoading: O, isError: k, hasNextPage: A, fetchNextPage: j, isFetchingNextPage: M } = F(n, r, e, i, m, void 0, b || void 0, E), { rows: N, refs: P } = B(() => {
333
322
  if (!D?.pages) return {
334
323
  rows: [],
335
324
  refs: void 0
@@ -373,7 +362,7 @@ function se({ entityCode: e, entity: t, parentEntity: n, parentId: r, foreignKey
373
362
  interaction: s,
374
363
  ctx: l,
375
364
  rows: N,
376
- refs: F,
365
+ refs: P,
377
366
  isLoading: O,
378
367
  isError: k,
379
368
  invalidateQuery: I,
@@ -30,14 +30,7 @@ function b({ node: g, ctx: b }) {
30
30
  ]
31
31
  });
32
32
  let D = b.schema.entities[E.entity];
33
- if (!D) return /* @__PURE__ */ v("div", {
34
- className: "text-sm text-muted-foreground py-2",
35
- children: [
36
- S("record.related_entity_not_found", "The related record type is not declared in this deployment."),
37
- " ",
38
- /* @__PURE__ */ _("code", { children: E.entity })
39
- ]
40
- });
33
+ if (!D) return null;
41
34
  let O = l(E, D, g), k = s(g, b, x), A = o(g, b), j = (e) => O.mode === "timeline" || b.withinCard ? e : /* @__PURE__ */ _(n, {
42
35
  title: k,
43
36
  icon: A ? /* @__PURE__ */ _(i, {