@modern-admin/react 0.1.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 (261) hide show
  1. package/dist/action-guard.d.ts +13 -0
  2. package/dist/action-guard.d.ts.map +1 -0
  3. package/dist/action-guard.js +15 -0
  4. package/dist/action-guard.js.map +1 -0
  5. package/dist/action-menu.d.ts +17 -0
  6. package/dist/action-menu.d.ts.map +1 -0
  7. package/dist/action-menu.jsx +80 -0
  8. package/dist/action-menu.jsx.map +1 -0
  9. package/dist/admin-app.d.ts +23 -0
  10. package/dist/admin-app.d.ts.map +1 -0
  11. package/dist/admin-app.jsx +407 -0
  12. package/dist/admin-app.jsx.map +1 -0
  13. package/dist/admin-router.d.ts +29 -0
  14. package/dist/admin-router.d.ts.map +1 -0
  15. package/dist/admin-router.jsx +215 -0
  16. package/dist/admin-router.jsx.map +1 -0
  17. package/dist/breadcrumbs.d.ts +17 -0
  18. package/dist/breadcrumbs.d.ts.map +1 -0
  19. package/dist/breadcrumbs.jsx +40 -0
  20. package/dist/breadcrumbs.jsx.map +1 -0
  21. package/dist/client.d.ts +526 -0
  22. package/dist/client.d.ts.map +1 -0
  23. package/dist/client.js +582 -0
  24. package/dist/client.js.map +1 -0
  25. package/dist/component-loader.d.ts +10 -0
  26. package/dist/component-loader.d.ts.map +1 -0
  27. package/dist/component-loader.js +23 -0
  28. package/dist/component-loader.js.map +1 -0
  29. package/dist/components/ai-assistant-widget.d.ts +3 -0
  30. package/dist/components/ai-assistant-widget.d.ts.map +1 -0
  31. package/dist/components/ai-assistant-widget.jsx +390 -0
  32. package/dist/components/ai-assistant-widget.jsx.map +1 -0
  33. package/dist/components/ai-fill-dialog.d.ts +9 -0
  34. package/dist/components/ai-fill-dialog.d.ts.map +1 -0
  35. package/dist/components/ai-fill-dialog.jsx +105 -0
  36. package/dist/components/ai-fill-dialog.jsx.map +1 -0
  37. package/dist/components/chart-builder-dialog.d.ts +10 -0
  38. package/dist/components/chart-builder-dialog.d.ts.map +1 -0
  39. package/dist/components/chart-builder-dialog.jsx +433 -0
  40. package/dist/components/chart-builder-dialog.jsx.map +1 -0
  41. package/dist/components/chart-widget.d.ts +12 -0
  42. package/dist/components/chart-widget.d.ts.map +1 -0
  43. package/dist/components/chart-widget.jsx +365 -0
  44. package/dist/components/chart-widget.jsx.map +1 -0
  45. package/dist/components/global-search-dialog.d.ts +7 -0
  46. package/dist/components/global-search-dialog.d.ts.map +1 -0
  47. package/dist/components/global-search-dialog.jsx +187 -0
  48. package/dist/components/global-search-dialog.jsx.map +1 -0
  49. package/dist/components/group-settings-dialog.d.ts +13 -0
  50. package/dist/components/group-settings-dialog.d.ts.map +1 -0
  51. package/dist/components/group-settings-dialog.jsx +53 -0
  52. package/dist/components/group-settings-dialog.jsx.map +1 -0
  53. package/dist/components/move-chart-dialog.d.ts +18 -0
  54. package/dist/components/move-chart-dialog.d.ts.map +1 -0
  55. package/dist/components/move-chart-dialog.jsx +68 -0
  56. package/dist/components/move-chart-dialog.jsx.map +1 -0
  57. package/dist/components/reference-multi-table-dialog.d.ts +12 -0
  58. package/dist/components/reference-multi-table-dialog.d.ts.map +1 -0
  59. package/dist/components/reference-multi-table-dialog.jsx +126 -0
  60. package/dist/components/reference-multi-table-dialog.jsx.map +1 -0
  61. package/dist/components/related-records-tabs.d.ts +8 -0
  62. package/dist/components/related-records-tabs.d.ts.map +1 -0
  63. package/dist/components/related-records-tabs.jsx +75 -0
  64. package/dist/components/related-records-tabs.jsx.map +1 -0
  65. package/dist/components/revisions-button.d.ts +7 -0
  66. package/dist/components/revisions-button.d.ts.map +1 -0
  67. package/dist/components/revisions-button.jsx +152 -0
  68. package/dist/components/revisions-button.jsx.map +1 -0
  69. package/dist/components/wizard-form.d.ts +43 -0
  70. package/dist/components/wizard-form.d.ts.map +1 -0
  71. package/dist/components/wizard-form.jsx +136 -0
  72. package/dist/components/wizard-form.jsx.map +1 -0
  73. package/dist/dashboard/time-series.d.ts +20 -0
  74. package/dist/dashboard/time-series.d.ts.map +1 -0
  75. package/dist/dashboard/time-series.js +108 -0
  76. package/dist/dashboard/time-series.js.map +1 -0
  77. package/dist/dialogs.d.ts +35 -0
  78. package/dist/dialogs.d.ts.map +1 -0
  79. package/dist/dialogs.jsx +152 -0
  80. package/dist/dialogs.jsx.map +1 -0
  81. package/dist/export.d.ts +39 -0
  82. package/dist/export.d.ts.map +1 -0
  83. package/dist/export.js +114 -0
  84. package/dist/export.js.map +1 -0
  85. package/dist/extension-registry.d.ts +122 -0
  86. package/dist/extension-registry.d.ts.map +1 -0
  87. package/dist/extension-registry.js +93 -0
  88. package/dist/extension-registry.js.map +1 -0
  89. package/dist/header-controls.d.ts +4 -0
  90. package/dist/header-controls.d.ts.map +1 -0
  91. package/dist/header-controls.jsx +70 -0
  92. package/dist/header-controls.jsx.map +1 -0
  93. package/dist/hooks.d.ts +104 -0
  94. package/dist/hooks.d.ts.map +1 -0
  95. package/dist/hooks.js +374 -0
  96. package/dist/hooks.js.map +1 -0
  97. package/dist/hotkey-help.d.ts +3 -0
  98. package/dist/hotkey-help.d.ts.map +1 -0
  99. package/dist/hotkey-help.jsx +32 -0
  100. package/dist/hotkey-help.jsx.map +1 -0
  101. package/dist/hotkey-registry.d.ts +18 -0
  102. package/dist/hotkey-registry.d.ts.map +1 -0
  103. package/dist/hotkey-registry.jsx +34 -0
  104. package/dist/hotkey-registry.jsx.map +1 -0
  105. package/dist/i18n.d.ts +74 -0
  106. package/dist/i18n.d.ts.map +1 -0
  107. package/dist/i18n.jsx +127 -0
  108. package/dist/i18n.jsx.map +1 -0
  109. package/dist/index.d.ts +35 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +36 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/notify.d.ts +41 -0
  114. package/dist/notify.d.ts.map +1 -0
  115. package/dist/notify.jsx +58 -0
  116. package/dist/notify.jsx.map +1 -0
  117. package/dist/pages/ai-assistant-settings-section.d.ts +3 -0
  118. package/dist/pages/ai-assistant-settings-section.d.ts.map +1 -0
  119. package/dist/pages/ai-assistant-settings-section.jsx +126 -0
  120. package/dist/pages/ai-assistant-settings-section.jsx.map +1 -0
  121. package/dist/pages/audit-log-page.d.ts +3 -0
  122. package/dist/pages/audit-log-page.d.ts.map +1 -0
  123. package/dist/pages/audit-log-page.jsx +354 -0
  124. package/dist/pages/audit-log-page.jsx.map +1 -0
  125. package/dist/pages/edit-page.d.ts +7 -0
  126. package/dist/pages/edit-page.d.ts.map +1 -0
  127. package/dist/pages/edit-page.jsx +614 -0
  128. package/dist/pages/edit-page.jsx.map +1 -0
  129. package/dist/pages/export-dialog.d.ts +11 -0
  130. package/dist/pages/export-dialog.d.ts.map +1 -0
  131. package/dist/pages/export-dialog.jsx +102 -0
  132. package/dist/pages/export-dialog.jsx.map +1 -0
  133. package/dist/pages/home-page.d.ts +3 -0
  134. package/dist/pages/home-page.d.ts.map +1 -0
  135. package/dist/pages/home-page.jsx +211 -0
  136. package/dist/pages/home-page.jsx.map +1 -0
  137. package/dist/pages/list-page.d.ts +42 -0
  138. package/dist/pages/list-page.d.ts.map +1 -0
  139. package/dist/pages/list-page.jsx +1596 -0
  140. package/dist/pages/list-page.jsx.map +1 -0
  141. package/dist/pages/login-page.d.ts +11 -0
  142. package/dist/pages/login-page.d.ts.map +1 -0
  143. package/dist/pages/login-page.jsx +157 -0
  144. package/dist/pages/login-page.jsx.map +1 -0
  145. package/dist/pages/settings-page.d.ts +5 -0
  146. package/dist/pages/settings-page.d.ts.map +1 -0
  147. package/dist/pages/settings-page.jsx +787 -0
  148. package/dist/pages/settings-page.jsx.map +1 -0
  149. package/dist/pages/settings-shared.d.ts +51 -0
  150. package/dist/pages/settings-shared.d.ts.map +1 -0
  151. package/dist/pages/settings-shared.jsx +66 -0
  152. package/dist/pages/settings-shared.jsx.map +1 -0
  153. package/dist/pages/show-page.d.ts +7 -0
  154. package/dist/pages/show-page.d.ts.map +1 -0
  155. package/dist/pages/show-page.jsx +147 -0
  156. package/dist/pages/show-page.jsx.map +1 -0
  157. package/dist/pages/wizard-create-page.d.ts +14 -0
  158. package/dist/pages/wizard-create-page.d.ts.map +1 -0
  159. package/dist/pages/wizard-create-page.jsx +106 -0
  160. package/dist/pages/wizard-create-page.jsx.map +1 -0
  161. package/dist/property-renderer.d.ts +8 -0
  162. package/dist/property-renderer.d.ts.map +1 -0
  163. package/dist/property-renderer.jsx +690 -0
  164. package/dist/property-renderer.jsx.map +1 -0
  165. package/dist/provider.d.ts +20 -0
  166. package/dist/provider.d.ts.map +1 -0
  167. package/dist/provider.jsx +32 -0
  168. package/dist/provider.jsx.map +1 -0
  169. package/dist/realtime.d.ts +22 -0
  170. package/dist/realtime.d.ts.map +1 -0
  171. package/dist/realtime.js +38 -0
  172. package/dist/realtime.js.map +1 -0
  173. package/dist/reference.d.ts +52 -0
  174. package/dist/reference.d.ts.map +1 -0
  175. package/dist/reference.jsx +224 -0
  176. package/dist/reference.jsx.map +1 -0
  177. package/dist/relations.d.ts +11 -0
  178. package/dist/relations.d.ts.map +1 -0
  179. package/dist/relations.js +36 -0
  180. package/dist/relations.js.map +1 -0
  181. package/dist/router.d.ts +82 -0
  182. package/dist/router.d.ts.map +1 -0
  183. package/dist/router.jsx +187 -0
  184. package/dist/router.jsx.map +1 -0
  185. package/dist/show-when.d.ts +7 -0
  186. package/dist/show-when.d.ts.map +1 -0
  187. package/dist/show-when.js +77 -0
  188. package/dist/show-when.js.map +1 -0
  189. package/dist/types.d.ts +194 -0
  190. package/dist/types.d.ts.map +1 -0
  191. package/dist/types.js +18 -0
  192. package/dist/types.js.map +1 -0
  193. package/dist/use-dashboard-charts.d.ts +93 -0
  194. package/dist/use-dashboard-charts.d.ts.map +1 -0
  195. package/dist/use-dashboard-charts.js +263 -0
  196. package/dist/use-dashboard-charts.js.map +1 -0
  197. package/dist/use-hotkey.d.ts +17 -0
  198. package/dist/use-hotkey.d.ts.map +1 -0
  199. package/dist/use-hotkey.js +103 -0
  200. package/dist/use-hotkey.js.map +1 -0
  201. package/dist/user-directory.d.ts +18 -0
  202. package/dist/user-directory.d.ts.map +1 -0
  203. package/dist/user-directory.js +51 -0
  204. package/dist/user-directory.js.map +1 -0
  205. package/dist/validation.d.ts +22 -0
  206. package/dist/validation.d.ts.map +1 -0
  207. package/dist/validation.js +338 -0
  208. package/dist/validation.js.map +1 -0
  209. package/package.json +59 -0
  210. package/src/action-guard.ts +20 -0
  211. package/src/action-menu.tsx +161 -0
  212. package/src/admin-app.tsx +630 -0
  213. package/src/admin-router.tsx +273 -0
  214. package/src/breadcrumbs.tsx +75 -0
  215. package/src/client.ts +1093 -0
  216. package/src/component-loader.ts +33 -0
  217. package/src/components/ai-assistant-widget.tsx +565 -0
  218. package/src/components/ai-fill-dialog.tsx +143 -0
  219. package/src/components/chart-builder-dialog.tsx +618 -0
  220. package/src/components/chart-widget.tsx +654 -0
  221. package/src/components/global-search-dialog.tsx +272 -0
  222. package/src/components/group-settings-dialog.tsx +93 -0
  223. package/src/components/move-chart-dialog.tsx +130 -0
  224. package/src/components/reference-multi-table-dialog.tsx +196 -0
  225. package/src/components/related-records-tabs.tsx +130 -0
  226. package/src/components/revisions-button.tsx +237 -0
  227. package/src/components/wizard-form.tsx +302 -0
  228. package/src/dashboard/time-series.ts +125 -0
  229. package/src/dialogs.tsx +265 -0
  230. package/src/export.ts +140 -0
  231. package/src/extension-registry.ts +195 -0
  232. package/src/header-controls.tsx +125 -0
  233. package/src/hooks.ts +509 -0
  234. package/src/hotkey-help.tsx +56 -0
  235. package/src/hotkey-registry.tsx +60 -0
  236. package/src/i18n.tsx +267 -0
  237. package/src/index.ts +192 -0
  238. package/src/notify.tsx +94 -0
  239. package/src/pages/ai-assistant-settings-section.tsx +167 -0
  240. package/src/pages/audit-log-page.tsx +580 -0
  241. package/src/pages/edit-page.tsx +743 -0
  242. package/src/pages/export-dialog.tsx +154 -0
  243. package/src/pages/home-page.tsx +318 -0
  244. package/src/pages/list-page.tsx +2645 -0
  245. package/src/pages/login-page.tsx +242 -0
  246. package/src/pages/settings-page.tsx +1143 -0
  247. package/src/pages/settings-shared.tsx +134 -0
  248. package/src/pages/show-page.tsx +223 -0
  249. package/src/pages/wizard-create-page.tsx +164 -0
  250. package/src/property-renderer.tsx +1143 -0
  251. package/src/provider.tsx +70 -0
  252. package/src/realtime.ts +55 -0
  253. package/src/reference.tsx +386 -0
  254. package/src/relations.ts +55 -0
  255. package/src/router.tsx +211 -0
  256. package/src/show-when.ts +76 -0
  257. package/src/types.ts +198 -0
  258. package/src/use-dashboard-charts.ts +362 -0
  259. package/src/use-hotkey.ts +128 -0
  260. package/src/user-directory.ts +56 -0
  261. package/src/validation.ts +361 -0
@@ -0,0 +1,82 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * Provides the SPA mount basepath (e.g. `/admin`) to all navigation
4
+ * primitives (`Link`, `useNavigate`, `useRoute`). Set by
5
+ * `AdminRouterProvider` from `window.__MODERN_ADMIN__.basePath`. Defaults
6
+ * to `''` (root mount).
7
+ */
8
+ export declare const BasepathContext: React.Context<string>;
9
+ /** Returns the normalised basepath (never has a trailing slash; `''` at root). */
10
+ export declare const useBasepath: () => string;
11
+ /** URL-persisted state for the resource list page. */
12
+ export interface ListQueryState {
13
+ page?: number;
14
+ perPage?: number;
15
+ sortBy?: string;
16
+ direction?: 'asc' | 'desc';
17
+ /** Per-column filter values keyed by property path. */
18
+ filters?: Record<string, string>;
19
+ }
20
+ export type Route = {
21
+ name: 'home';
22
+ } | {
23
+ name: 'audit-log';
24
+ } | {
25
+ name: 'list';
26
+ resourceId: string;
27
+ query?: ListQueryState;
28
+ } | {
29
+ name: 'show';
30
+ resourceId: string;
31
+ recordId: string;
32
+ } | {
33
+ name: 'edit';
34
+ resourceId: string;
35
+ recordId: string;
36
+ } | {
37
+ name: 'new';
38
+ resourceId: string;
39
+ }
40
+ /** Settings hub. Sub-section selected via `section` (e.g. 'api-keys'). */
41
+ | {
42
+ name: 'settings';
43
+ section?: string;
44
+ }
45
+ /**
46
+ * Extension page registered by a Pro plugin via `registerExtensionRoute`.
47
+ * Renders at `/ext/<key>` inside the authenticated admin shell.
48
+ */
49
+ | {
50
+ name: 'extension';
51
+ key: string;
52
+ };
53
+ /** Map a TSR location (pathname + raw searchStr) to the canonical `Route`
54
+ * union the rest of the codebase consumes. Pure — used both at render
55
+ * time (via `useRoute`) and outside the React tree if ever needed. */
56
+ export declare const parseLocation: (pathname: string, searchStr: string) => Route;
57
+ /** Build a path URL for the given route. Pure — kept for tests and for
58
+ * `<Link>` href generation. */
59
+ export declare const buildHref: (route: Route) => string;
60
+ /** Current canonical route, derived from the live TSR state.
61
+ * When the router has a basepath, TSR strips it from `location.pathname`
62
+ * before exposing it in state — so `parseLocation` sees only the
63
+ * basepath-relative portion. */
64
+ export declare const useRoute: () => Route;
65
+ /** Imperative navigator. Same signature as the legacy custom router so
66
+ * call-sites don't change. Goes through TSR history → re-routing flows
67
+ * through TSR's lifecycle. */
68
+ export declare const useNavigate: () => ((route: Route) => void);
69
+ /** Open an in-app route in a new browser tab, honouring the admin's
70
+ * `basepath`. `buildHref` returns a basepath-relative path, so we prepend
71
+ * the basepath the same way `Link`/`useNavigate` do — otherwise the new tab
72
+ * loads a URL outside the admin mount (e.g. `/resources/...` instead of
73
+ * `/admin/resources/...`). */
74
+ export declare const useOpenInNewTab: () => ((route: Route) => void);
75
+ export interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
76
+ to: Route;
77
+ }
78
+ /** Anchor with path href + client-side navigation on plain left-click.
79
+ * Modifier clicks (cmd/ctrl/shift/alt, middle button) fall through to
80
+ * default browser behaviour so "open in new tab" keeps working. */
81
+ export declare const Link: ({ to, onClick, ...rest }: LinkProps) => React.ReactElement;
82
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B;;;;;GAKG;AACH,eAAO,MAAM,eAAe,uBAAkC,CAAA;AAE9D,kFAAkF;AAClF,eAAO,MAAM,WAAW,QAAO,MAA2C,CAAA;AAE1E,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IAC1B,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC;AAED,MAAM,MAAM,KAAK,GACb;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,cAAc,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AACrC,0EAA0E;GACxE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;AACxC;;;GAGG;GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AA6CtC;;uEAEuE;AACvE,eAAO,MAAM,aAAa,GAAI,UAAU,MAAM,EAAE,WAAW,MAAM,KAAG,KAsBnE,CAAA;AAED;gCACgC;AAChC,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,KAAG,MAmBxC,CAAA;AAED;;;iCAGiC;AACjC,eAAO,MAAM,QAAQ,QAAO,KAGxB,CAAA;AAEJ;;+BAE+B;AAC/B,eAAO,MAAM,WAAW,QAAO,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CASrD,CAAA;AAED;;;;+BAI+B;AAC/B,eAAO,MAAM,eAAe,QAAO,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAMzD,CAAA;AAED,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IAC9E,EAAE,EAAE,KAAK,CAAA;CACV;AAED;;oEAEoE;AACpE,eAAO,MAAM,IAAI,GAAI,0BAA0B,SAAS,KAAG,KAAK,CAAC,YAiBhE,CAAA"}
@@ -0,0 +1,187 @@
1
+ // Routing engine compat layer over @tanstack/react-router with `createBrowserHistory()`.
2
+ //
3
+ // Why browser history? Clean, standard path-based URLs (`/resources/:id?page=2`).
4
+ // Works with server-side analytics and deep links. Requires an SPA fallback rule
5
+ // on the server (`try_files ... index.html` in nginx, `historyApiFallback` in
6
+ // Vite preview). This is the one-line standard config for any modern static host
7
+ // (Vercel, Netlify, nginx). No SSR is used — admin pages are auth-walled.
8
+ //
9
+ // Why TSR? Future-proof primitives — devtools, search-param schemas, per-route
10
+ // loaders, code-splitting — without paying for SSR/Nitro (TanStack Start).
11
+ //
12
+ // Public API (Route discriminated union, `Link`, `useRoute`, `useNavigate`,
13
+ // `buildHref`) is kept stable. `Route` is the canonical surface; the underlying
14
+ // TSR state is mapped to it via `parseLocation`. Search params are kept
15
+ // opaque to TSR (`parseSearch`/`stringifySearch` are no-ops in `admin-router`):
16
+ // `ListQueryState` (with `filters[<key>]=<v>` keys) is parsed manually from
17
+ // the raw `searchStr` so the URL format doesn't depend on TSR's JSON-search encoding.
18
+ import * as React from 'react';
19
+ import { useRouter, useRouterState } from '@tanstack/react-router';
20
+ /**
21
+ * Provides the SPA mount basepath (e.g. `/admin`) to all navigation
22
+ * primitives (`Link`, `useNavigate`, `useRoute`). Set by
23
+ * `AdminRouterProvider` from `window.__MODERN_ADMIN__.basePath`. Defaults
24
+ * to `''` (root mount).
25
+ */
26
+ export const BasepathContext = React.createContext('');
27
+ /** Returns the normalised basepath (never has a trailing slash; `''` at root). */
28
+ export const useBasepath = () => React.useContext(BasepathContext);
29
+ const parseListQuery = (search) => {
30
+ if (!search)
31
+ return undefined;
32
+ const params = new URLSearchParams(search.startsWith('?') ? search.slice(1) : search);
33
+ const out = {};
34
+ const page = params.get('page');
35
+ if (page) {
36
+ const n = Number(page);
37
+ if (Number.isFinite(n) && n >= 1)
38
+ out.page = n;
39
+ }
40
+ const perPage = params.get('perPage');
41
+ if (perPage) {
42
+ const n = Number(perPage);
43
+ if (Number.isFinite(n) && n >= 1)
44
+ out.perPage = n;
45
+ }
46
+ const sortBy = params.get('sortBy');
47
+ if (sortBy)
48
+ out.sortBy = sortBy;
49
+ const direction = params.get('direction');
50
+ if (direction === 'asc' || direction === 'desc')
51
+ out.direction = direction;
52
+ const filters = {};
53
+ params.forEach((value, key) => {
54
+ const m = key.match(/^filters\[(.+)\]$/);
55
+ if (m && m[1] != null && value !== '')
56
+ filters[m[1]] = value;
57
+ });
58
+ if (Object.keys(filters).length > 0)
59
+ out.filters = filters;
60
+ return Object.keys(out).length > 0 ? out : undefined;
61
+ };
62
+ const buildListQuery = (q) => {
63
+ if (!q)
64
+ return '';
65
+ const params = new URLSearchParams();
66
+ if (q.page != null && q.page !== 1)
67
+ params.set('page', String(q.page));
68
+ if (q.perPage != null && q.perPage !== 20)
69
+ params.set('perPage', String(q.perPage));
70
+ if (q.sortBy)
71
+ params.set('sortBy', q.sortBy);
72
+ if (q.direction)
73
+ params.set('direction', q.direction);
74
+ if (q.filters) {
75
+ for (const [k, v] of Object.entries(q.filters)) {
76
+ if (v != null && v !== '')
77
+ params.set(`filters[${k}]`, v);
78
+ }
79
+ }
80
+ const s = params.toString();
81
+ return s ? `?${s}` : '';
82
+ };
83
+ /** Map a TSR location (pathname + raw searchStr) to the canonical `Route`
84
+ * union the rest of the codebase consumes. Pure — used both at render
85
+ * time (via `useRoute`) and outside the React tree if ever needed. */
86
+ export const parseLocation = (pathname, searchStr) => {
87
+ const parts = pathname.split('/').filter(Boolean);
88
+ if (parts.length === 0)
89
+ return { name: 'home' };
90
+ if (parts[0] === 'audit-log')
91
+ return { name: 'audit-log' };
92
+ if (parts[0] === 'settings') {
93
+ const section = parts[1] ? decodeURIComponent(parts[1]) : undefined;
94
+ return section ? { name: 'settings', section } : { name: 'settings' };
95
+ }
96
+ if (parts[0] === 'ext' && parts[1]) {
97
+ return { name: 'extension', key: decodeURIComponent(parts[1]) };
98
+ }
99
+ if (parts[0] === 'resources' && parts[1]) {
100
+ const resourceId = decodeURIComponent(parts[1]);
101
+ if (parts[2] === 'new')
102
+ return { name: 'new', resourceId };
103
+ if (parts[2] && parts[3] === 'edit') {
104
+ return { name: 'edit', resourceId, recordId: decodeURIComponent(parts[2]) };
105
+ }
106
+ if (parts[2])
107
+ return { name: 'show', resourceId, recordId: decodeURIComponent(parts[2]) };
108
+ const query = parseListQuery(searchStr);
109
+ return query ? { name: 'list', resourceId, query } : { name: 'list', resourceId };
110
+ }
111
+ return { name: 'home' };
112
+ };
113
+ /** Build a path URL for the given route. Pure — kept for tests and for
114
+ * `<Link>` href generation. */
115
+ export const buildHref = (route) => {
116
+ switch (route.name) {
117
+ case 'home':
118
+ return '/';
119
+ case 'audit-log':
120
+ return '/audit-log';
121
+ case 'list':
122
+ return `/resources/${encodeURIComponent(route.resourceId)}${buildListQuery(route.query)}`;
123
+ case 'show':
124
+ return `/resources/${encodeURIComponent(route.resourceId)}/${encodeURIComponent(route.recordId)}`;
125
+ case 'edit':
126
+ return `/resources/${encodeURIComponent(route.resourceId)}/${encodeURIComponent(route.recordId)}/edit`;
127
+ case 'new':
128
+ return `/resources/${encodeURIComponent(route.resourceId)}/new`;
129
+ case 'settings':
130
+ return route.section ? `/settings/${encodeURIComponent(route.section)}` : '/settings';
131
+ case 'extension':
132
+ return `/ext/${encodeURIComponent(route.key)}`;
133
+ }
134
+ };
135
+ /** Current canonical route, derived from the live TSR state.
136
+ * When the router has a basepath, TSR strips it from `location.pathname`
137
+ * before exposing it in state — so `parseLocation` sees only the
138
+ * basepath-relative portion. */
139
+ export const useRoute = () => useRouterState({
140
+ select: (s) => parseLocation(s.location.pathname, s.location.searchStr ?? ''),
141
+ });
142
+ /** Imperative navigator. Same signature as the legacy custom router so
143
+ * call-sites don't change. Goes through TSR history → re-routing flows
144
+ * through TSR's lifecycle. */
145
+ export const useNavigate = () => {
146
+ const router = useRouter();
147
+ const basepath = useBasepath();
148
+ return React.useCallback((next) => {
149
+ router.history.push(basepath + buildHref(next));
150
+ }, [router, basepath]);
151
+ };
152
+ /** Open an in-app route in a new browser tab, honouring the admin's
153
+ * `basepath`. `buildHref` returns a basepath-relative path, so we prepend
154
+ * the basepath the same way `Link`/`useNavigate` do — otherwise the new tab
155
+ * loads a URL outside the admin mount (e.g. `/resources/...` instead of
156
+ * `/admin/resources/...`). */
157
+ export const useOpenInNewTab = () => {
158
+ const basepath = useBasepath();
159
+ return React.useCallback((route) => {
160
+ if (typeof window === 'undefined')
161
+ return;
162
+ window.open(basepath + buildHref(route), '_blank', 'noopener,noreferrer');
163
+ }, [basepath]);
164
+ };
165
+ /** Anchor with path href + client-side navigation on plain left-click.
166
+ * Modifier clicks (cmd/ctrl/shift/alt, middle button) fall through to
167
+ * default browser behaviour so "open in new tab" keeps working. */
168
+ export const Link = ({ to, onClick, ...rest }) => {
169
+ const router = useRouter();
170
+ const basepath = useBasepath();
171
+ const href = basepath + buildHref(to);
172
+ const handleClick = React.useCallback((event) => {
173
+ onClick?.(event);
174
+ if (event.defaultPrevented)
175
+ return;
176
+ if (event.button !== 0)
177
+ return;
178
+ if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
179
+ return;
180
+ if (rest.target && rest.target !== '_self')
181
+ return;
182
+ event.preventDefault();
183
+ router.history.push(href);
184
+ }, [onClick, router, href, rest.target]);
185
+ return <a href={href} onClick={handleClick} {...rest}/>;
186
+ };
187
+ //# sourceMappingURL=router.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.jsx","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ShowWhenSpec } from './types.js';
2
+ /**
3
+ * Evaluate a `ShowWhenSpec` against the live form values.
4
+ * Returns `true` (visible) when no rule is configured.
5
+ */
6
+ export declare function evaluateShowWhen(rule: ShowWhenSpec | undefined, values: Record<string, unknown>): boolean;
7
+ //# sourceMappingURL=show-when.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show-when.d.ts","sourceRoot":"","sources":["../src/show-when.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAiB9C;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAkCT"}
@@ -0,0 +1,77 @@
1
+ // Pure helper that evaluates a `ShowWhenSpec` against a snapshot of form
2
+ // values. Lives outside React/RHF on purpose so both the edit page renderer
3
+ // and the validation builder can share the exact same semantics.
4
+ //
5
+ // Operator semantics:
6
+ // - `equals` — control value === provided value
7
+ // - `notEquals` — control value !== provided value
8
+ // - `in` — control value matches any item in array
9
+ // - `notIn` — control value matches none of the items
10
+ // - `isEmpty:true` — control value is null / undefined / ''
11
+ // - `isEmpty:false` — control value is NOT null / undefined / ''
12
+ // - `defaultWhenEmpty` — fallback: shows the field when control is empty,
13
+ // regardless of the other operators
14
+ //
15
+ // Operators combine with OR — the field shows when **any** of them passes.
16
+ // When no operator is configured, the rule trivially passes (visible).
17
+ const isBlank = (v) => v === undefined || v === null || (typeof v === 'string' && v.trim() === '');
18
+ /** Loose equality that handles primitives + dates + arrays of primitives. */
19
+ const sameValue = (a, b) => {
20
+ if (a === b)
21
+ return true;
22
+ if (a == null || b == null)
23
+ return false;
24
+ if (a instanceof Date && b instanceof Date)
25
+ return a.getTime() === b.getTime();
26
+ // Coerce numbers vs string-numbers (HTML inputs ship strings).
27
+ if (typeof a === 'number' && typeof b === 'string')
28
+ return String(a) === b;
29
+ if (typeof a === 'string' && typeof b === 'number')
30
+ return a === String(b);
31
+ if (typeof a === 'boolean' && typeof b === 'string')
32
+ return String(a) === b;
33
+ return false;
34
+ };
35
+ /**
36
+ * Evaluate a `ShowWhenSpec` against the live form values.
37
+ * Returns `true` (visible) when no rule is configured.
38
+ */
39
+ export function evaluateShowWhen(rule, values) {
40
+ if (!rule)
41
+ return true;
42
+ const control = values[rule.field];
43
+ const empty = isBlank(control);
44
+ // Default branch: when control is empty AND defaultWhenEmpty is set, show.
45
+ if (rule.defaultWhenEmpty && empty)
46
+ return true;
47
+ let anyOperator = false;
48
+ if ('equals' in rule && rule.equals !== undefined) {
49
+ anyOperator = true;
50
+ if (sameValue(control, rule.equals))
51
+ return true;
52
+ }
53
+ if ('notEquals' in rule && rule.notEquals !== undefined) {
54
+ anyOperator = true;
55
+ if (!sameValue(control, rule.notEquals))
56
+ return true;
57
+ }
58
+ if (rule.in && rule.in.length > 0) {
59
+ anyOperator = true;
60
+ if (rule.in.some((v) => sameValue(control, v)))
61
+ return true;
62
+ }
63
+ if (rule.notIn && rule.notIn.length > 0) {
64
+ anyOperator = true;
65
+ if (!rule.notIn.some((v) => sameValue(control, v)))
66
+ return true;
67
+ }
68
+ if (rule.isEmpty !== undefined) {
69
+ anyOperator = true;
70
+ if (rule.isEmpty === empty)
71
+ return true;
72
+ }
73
+ // Rule with operators that all failed → hidden.
74
+ // Rule with no operators (only `field` declared) → visible.
75
+ return !anyOperator;
76
+ }
77
+ //# sourceMappingURL=show-when.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show-when.js","sourceRoot":"","sources":["../src/show-when.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ export type View = 'list' | 'show' | 'edit' | 'filter';
2
+ /**
3
+ * Mirror of `core` `ShowWhen` — declarative rule that conditionally hides a
4
+ * field on the edit form based on the current value of another form field.
5
+ * Operators combine with OR semantics; `defaultWhenEmpty` triggers when the
6
+ * control field is null / undefined / ''.
7
+ */
8
+ export interface ShowWhenSpec {
9
+ field: string;
10
+ equals?: unknown;
11
+ notEquals?: unknown;
12
+ in?: unknown[];
13
+ notIn?: unknown[];
14
+ isEmpty?: boolean;
15
+ defaultWhenEmpty?: boolean;
16
+ }
17
+ /**
18
+ * Mirror of `core` `KeyValueField` — declares one row in the key-value
19
+ * editor used as a friendly alternative to the raw JSON editor.
20
+ */
21
+ export interface KeyValueFieldSpec {
22
+ key: string;
23
+ label?: string;
24
+ type?: 'string' | 'number' | 'boolean' | 'textarea' | 'select' | 'autocomplete';
25
+ description?: string;
26
+ placeholder?: string;
27
+ isRequired?: boolean;
28
+ availableValues?: ReadonlyArray<string | {
29
+ value: string;
30
+ label: string;
31
+ }>;
32
+ /** For `type: 'autocomplete'`: pull dynamic suggestions from another resource. */
33
+ suggestionsResource?: string;
34
+ /** Path of the field on `suggestionsResource` to project. */
35
+ suggestionsField?: string;
36
+ }
37
+ export interface PropertyJSON {
38
+ path: string;
39
+ label: string;
40
+ type: string;
41
+ isId: boolean;
42
+ isSortable: boolean;
43
+ isRequired: boolean;
44
+ isDisabled: boolean;
45
+ isArray: boolean;
46
+ reference: string | null;
47
+ availableValues: Array<{
48
+ value: string;
49
+ label: string;
50
+ }> | null;
51
+ components: {
52
+ list?: string;
53
+ edit?: string;
54
+ show?: string;
55
+ filter?: string;
56
+ } | Record<string, string>;
57
+ visibility: Record<View, boolean>;
58
+ position: number;
59
+ description?: string;
60
+ showWhen?: ShowWhenSpec;
61
+ keyValueFields?: KeyValueFieldSpec[];
62
+ custom: Record<string, unknown>;
63
+ }
64
+ export interface ActionGroup {
65
+ name: string;
66
+ icon?: string;
67
+ }
68
+ export interface ActionDescriptor {
69
+ name: string;
70
+ actionType: 'resource' | 'record' | 'bulk';
71
+ resourceId: string;
72
+ nesting?: ActionGroup[];
73
+ guard?: string;
74
+ component?: string | null;
75
+ custom?: Record<string, unknown>;
76
+ }
77
+ export interface RelatedResource {
78
+ resourceId: string;
79
+ foreignKey: string;
80
+ label?: string;
81
+ }
82
+ export interface ResourceJSON {
83
+ id: string;
84
+ name: string;
85
+ navigation: {
86
+ name?: string;
87
+ icon?: string;
88
+ group?: string;
89
+ } | null;
90
+ relatedResources?: RelatedResource[];
91
+ properties: PropertyJSON[];
92
+ actions: ActionDescriptor[];
93
+ }
94
+ export interface CurrentUser {
95
+ id: string;
96
+ email?: string;
97
+ name?: string;
98
+ role?: string;
99
+ avatarUrl?: string;
100
+ [claim: string]: unknown;
101
+ }
102
+ /**
103
+ * Mirror of `core` `AdminFeatures`. Each flag is `true` iff the
104
+ * corresponding backend subsystem is wired and ready. The SPA uses these
105
+ * to hide UI surfaces (audit-log link, settings sections, revisions
106
+ * button, AI assistant widget) for features the host hasn't enabled.
107
+ */
108
+ export interface AdminFeatures {
109
+ auditLog: boolean;
110
+ history: boolean;
111
+ webhooks: boolean;
112
+ apiKeys: boolean;
113
+ aiAssistant: boolean;
114
+ }
115
+ /** Defensive resolver for older API servers that don't yet surface
116
+ * `features` in their `/admin/api/config` payload — every flag falls back
117
+ * to `false`, so optional surfaces stay hidden until the backend opts in. */
118
+ export declare const resolveFeatures: (raw?: Partial<AdminFeatures>) => AdminFeatures;
119
+ export interface AdminConfig {
120
+ rootPath: string;
121
+ branding?: {
122
+ companyName?: string;
123
+ logo?: string;
124
+ theme?: string;
125
+ };
126
+ auth: Record<string, unknown>;
127
+ resources: ResourceJSON[];
128
+ features?: Partial<AdminFeatures>;
129
+ }
130
+ export interface RecordJSON {
131
+ id: string;
132
+ title: string;
133
+ params: Record<string, unknown>;
134
+ populated: Record<string, unknown>;
135
+ errors: Record<string, unknown>;
136
+ baseError: unknown | null;
137
+ }
138
+ export interface ListResponse {
139
+ records: RecordJSON[];
140
+ meta: {
141
+ total: number;
142
+ page: number;
143
+ perPage: number;
144
+ sortBy?: string;
145
+ direction?: 'asc' | 'desc';
146
+ };
147
+ }
148
+ export interface RecordResponse {
149
+ record: RecordJSON;
150
+ }
151
+ /** Generic response from a custom action invocation (record / bulk / resource). */
152
+ export interface CustomActionResponse {
153
+ record?: RecordJSON;
154
+ records?: RecordJSON[];
155
+ notice?: {
156
+ message: string;
157
+ type: 'success' | 'info' | 'error' | 'warning';
158
+ };
159
+ redirectUrl?: string;
160
+ [key: string]: unknown;
161
+ }
162
+ export interface ListQuery {
163
+ page?: number;
164
+ perPage?: number;
165
+ sortBy?: string;
166
+ direction?: 'asc' | 'desc';
167
+ filters?: Record<string, string>;
168
+ }
169
+ /**
170
+ * Props contract for a property **display** component. Shared between the
171
+ * built-in `PropertyDisplay` and any custom property extension registered
172
+ * via `registerPropertyExtension`.
173
+ */
174
+ export interface PropertyDisplayProps {
175
+ property: PropertyJSON;
176
+ value: unknown;
177
+ view?: 'list' | 'show';
178
+ /** The record's `populated` map (pre-fetched reference titles). */
179
+ populated?: Record<string, unknown>;
180
+ }
181
+ /**
182
+ * Props contract for a property **editor** component. Shared between the
183
+ * built-in `PropertyEditor` and any custom property extension registered
184
+ * via `registerPropertyExtension`.
185
+ */
186
+ export interface PropertyEditorProps {
187
+ property: PropertyJSON;
188
+ value: unknown;
189
+ onChange(next: unknown): void;
190
+ disabled?: boolean;
191
+ /** Required for `type: 'file'` properties to route uploads correctly. */
192
+ resourceId?: string;
193
+ }
194
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,18 @@
1
+ // Wire-shape mirror of `ResourceDecorator#toJSON()` and friends. We re-declare
2
+ // rather than re-import so the React bundle doesn't drag in the full core
3
+ // (which references Node-only deps in a few corners).
4
+ const ALL_FEATURES_OFF = {
5
+ auditLog: false,
6
+ history: false,
7
+ webhooks: false,
8
+ apiKeys: false,
9
+ aiAssistant: false,
10
+ };
11
+ /** Defensive resolver for older API servers that don't yet surface
12
+ * `features` in their `/admin/api/config` payload — every flag falls back
13
+ * to `false`, so optional surfaces stay hidden until the backend opts in. */
14
+ export const resolveFeatures = (raw) => ({
15
+ ...ALL_FEATURES_OFF,
16
+ ...(raw ?? {}),
17
+ });
18
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,0EAA0E;AAC1E,sDAAsD;AA+GtD,MAAM,gBAAgB,GAAkB;IACtC,QAAQ,EAAE,KAAK;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,KAAK;IACf,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,KAAK;CACnB,CAAA;AAED;;8EAE8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAA4B,EAAiB,EAAE,CAAC,CAAC;IAC/E,GAAG,gBAAgB;IACnB,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;CACf,CAAC,CAAA"}