@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
package/dist/export.js ADDED
@@ -0,0 +1,114 @@
1
+ // Client-side export helpers.
2
+ //
3
+ // Pulls every record matching the current list query by paginating with a
4
+ // large pageSize, then serializes to CSV or JSON and triggers a browser
5
+ // download. Pure functions live here so they're trivially unit-testable;
6
+ // the dialog UI in pages/export-dialog.tsx wires them together.
7
+ /**
8
+ * Page through `client.list()` until exhausted, returning every record that
9
+ * matches the same filters/sorting as the current list view. `query.page`
10
+ * and `query.perPage` are overwritten — pass the user's filters/sorting only.
11
+ */
12
+ export async function fetchAllRecords(client, resourceId, query, opts = {}) {
13
+ // Backend caps `perPage` at 200 (see listQueryZ in @modern-admin/nest).
14
+ const batchSize = opts.batchSize ?? 200;
15
+ const baseQuery = { ...(query ?? {}), perPage: batchSize, page: 1 };
16
+ const all = [];
17
+ let total = 0;
18
+ for (let page = 1;; page++) {
19
+ if (opts.signal?.aborted)
20
+ throw new DOMException('Aborted', 'AbortError');
21
+ const res = await client.list(resourceId, { ...baseQuery, page });
22
+ total = res.meta.total;
23
+ all.push(...res.records);
24
+ opts.onProgress?.(all.length, total);
25
+ if (res.records.length < batchSize)
26
+ break;
27
+ if (all.length >= total)
28
+ break;
29
+ }
30
+ return all;
31
+ }
32
+ /** Escape a single CSV field per RFC 4180 (wrap in quotes when needed). */
33
+ export function csvEscape(value) {
34
+ if (value == null)
35
+ return '';
36
+ let str;
37
+ if (typeof value === 'string')
38
+ str = value;
39
+ else if (typeof value === 'number' || typeof value === 'boolean')
40
+ str = String(value);
41
+ else if (value instanceof Date)
42
+ str = value.toISOString();
43
+ else
44
+ str = JSON.stringify(value);
45
+ // Quote if it contains comma, quote, CR or LF.
46
+ if (/[",\r\n]/.test(str)) {
47
+ return `"${str.replace(/"/g, '""')}"`;
48
+ }
49
+ return str;
50
+ }
51
+ /** Build a CSV document for the given records. UTF-8 BOM for Excel friendliness. */
52
+ export function recordsToCsv(records, opts = {}) {
53
+ const columns = opts.properties
54
+ ? opts.properties.map((p) => ({ path: p.path, label: p.label }))
55
+ : columnsFromRecords(records);
56
+ const header = columns.map((c) => csvEscape(c.label)).join(',');
57
+ const lines = records.map((r) => columns.map((c) => csvEscape(r.params[c.path])).join(','));
58
+ const queryComment = opts.query
59
+ ? `# Query: ${JSON.stringify(opts.query)}\r\n`
60
+ : '';
61
+ return `\uFEFF${queryComment}${[header, ...lines].join('\r\n')}`;
62
+ }
63
+ /** Build a pretty-printed JSON document for the given records.
64
+ * When `opts.query` is set, a `// Query: ...` comment is prepended so the
65
+ * export is self-documenting (JSONC — understood by VS Code, TypeScript, etc.) */
66
+ export function recordsToJson(records, opts = {}) {
67
+ const paths = opts.properties?.map((p) => p.path);
68
+ const items = records.map((r) => {
69
+ if (!paths)
70
+ return { id: r.id, ...r.params };
71
+ const row = { id: r.id };
72
+ for (const p of paths)
73
+ row[p] = r.params[p];
74
+ return row;
75
+ });
76
+ const json = JSON.stringify(items, null, 2);
77
+ return opts.query ? `// Query: ${JSON.stringify(opts.query)}\n${json}` : json;
78
+ }
79
+ function columnsFromRecords(records) {
80
+ const seen = new Set();
81
+ const out = [];
82
+ for (const r of records) {
83
+ for (const k of Object.keys(r.params)) {
84
+ if (seen.has(k))
85
+ continue;
86
+ seen.add(k);
87
+ out.push({ path: k, label: k });
88
+ }
89
+ }
90
+ return out;
91
+ }
92
+ /** Trigger a browser download for the given text payload. */
93
+ export function downloadText(filename, mime, body) {
94
+ if (typeof window === 'undefined')
95
+ return;
96
+ const blob = new Blob([body], { type: `${mime};charset=utf-8` });
97
+ const url = URL.createObjectURL(blob);
98
+ const a = document.createElement('a');
99
+ a.href = url;
100
+ a.download = filename;
101
+ document.body.appendChild(a);
102
+ a.click();
103
+ a.remove();
104
+ // Revoke after a tick so Safari has time to start the download.
105
+ window.setTimeout(() => URL.revokeObjectURL(url), 1000);
106
+ }
107
+ /** Build a stable filename like `users-20260506-143015.csv`. */
108
+ export function exportFilename(resourceId, format, now = new Date()) {
109
+ const pad = (n) => String(n).padStart(2, '0');
110
+ const stamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}` +
111
+ `-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
112
+ return `${resourceId}-${stamp}.${format}`;
113
+ }
114
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ import type * as React from 'react';
2
+ import type { PropertyDisplayProps, PropertyEditorProps } from './types.js';
3
+ /**
4
+ * Extra navigation item rendered in the sidebar below the built-in entries
5
+ * (Home, Audit Log) and above the resource list.
6
+ */
7
+ export interface SidebarExtension {
8
+ /** Stable unique key (e.g. `'rbac'`). Duplicate keys are silently ignored. */
9
+ key: string;
10
+ /** Label rendered next to the icon in the sidebar. */
11
+ label: string;
12
+ /** Lucide-compatible icon component. */
13
+ icon: React.ComponentType<{
14
+ className?: string;
15
+ }>;
16
+ /**
17
+ * Extension route key — navigates to `/ext/<extensionKey>` within the
18
+ * admin shell (i.e., `{ name: 'extension', key: extensionKey }`).
19
+ * Must match the `key` of a corresponding `registerExtensionRoute` call
20
+ * so the router can render the right component.
21
+ */
22
+ extensionKey: string;
23
+ /**
24
+ * Optional capability gate. When set, the item is rendered only when
25
+ * `features[featureGate] === true` in the admin config (i.e. the backend
26
+ * has explicitly enabled the subsystem). Leave unset to always show.
27
+ */
28
+ featureGate?: string;
29
+ }
30
+ /**
31
+ * Extra section added to the Settings page navigation. The consumer's
32
+ * `component` is rendered as the main content area when the section is active.
33
+ */
34
+ export interface SettingsExtension {
35
+ /**
36
+ * Unique section key (appears in the URL as `/settings/<key>`). Must be
37
+ * URL-safe (no slashes, encodes cleanly). Duplicate keys are ignored.
38
+ */
39
+ key: string;
40
+ /**
41
+ * i18n translation key for the section label shown in the settings nav
42
+ * (e.g. `'rbac:settings.title'`). Falls back to `key` if the key is missing
43
+ * from the active locale.
44
+ */
45
+ labelKey: string;
46
+ /** Lucide-compatible icon component shown next to the label. */
47
+ icon: React.ComponentType<{
48
+ className?: string;
49
+ }>;
50
+ /**
51
+ * Component rendered as the main content when this section is active.
52
+ * It receives no props — read what you need via hooks or internal state.
53
+ */
54
+ component: React.ComponentType;
55
+ }
56
+ /**
57
+ * Custom property type renderer pair. When registered for `type`, the
58
+ * built-in `PropertyDisplay` and `PropertyEditor` switches fall through
59
+ * to this extension instead of rendering the default plain-text fallback.
60
+ */
61
+ export interface PropertyExtension {
62
+ /** Renders a read-only value cell (list / show view). */
63
+ display: React.ComponentType<PropertyDisplayProps>;
64
+ /** Renders an editable form field (edit / new view). */
65
+ editor: React.ComponentType<PropertyEditorProps>;
66
+ }
67
+ /**
68
+ * Full-page route rendered inside the authenticated admin shell at the
69
+ * reserved path `/ext/<key>`.
70
+ */
71
+ export interface RouteExtension {
72
+ /**
73
+ * URL-safe key (no slashes). The route becomes `/ext/<key>`. Must be
74
+ * unique — duplicate keys are silently ignored.
75
+ */
76
+ key: string;
77
+ /** Component rendered as the page content inside the shell layout. */
78
+ component: React.ComponentType;
79
+ }
80
+ /**
81
+ * Register a sidebar navigation item for an extension page.
82
+ * Call this during module initialisation, before `<AdminApp>` renders.
83
+ * Re-registering the same `key` is a no-op.
84
+ */
85
+ export declare function registerSidebarItem(ext: SidebarExtension): void;
86
+ /**
87
+ * Register a custom section in the Settings page.
88
+ * Call this during module initialisation, before `<AdminApp>` renders.
89
+ * Re-registering the same `key` is a no-op.
90
+ */
91
+ export declare function registerSettingsSection(ext: SettingsExtension): void;
92
+ /**
93
+ * Register a custom property type renderer (display + editor pair).
94
+ * When `property.type === type`, the built-in switch delegates to this
95
+ * extension instead of the plain-text fallback.
96
+ * Re-registering the same `type` overwrites the previous entry.
97
+ */
98
+ export declare function registerPropertyExtension(type: string, ext: PropertyExtension): void;
99
+ /**
100
+ * Register a full-page extension route at `/ext/<key>` inside the admin
101
+ * shell. A matching `SidebarExtension` with `extensionKey === key` provides
102
+ * the navigation entry.
103
+ * Re-registering the same `key` is a no-op.
104
+ */
105
+ export declare function registerExtensionRoute(ext: RouteExtension): void;
106
+ /** Returns all registered sidebar extensions in registration order. */
107
+ export declare function getSidebarExtensions(): SidebarExtension[];
108
+ /** Returns all registered settings sections in registration order. */
109
+ export declare function getSettingsSectionExtensions(): SettingsExtension[];
110
+ /**
111
+ * Returns the registered property extension for `type`, or `undefined` if
112
+ * no extension covers it (fall through to plain-text).
113
+ */
114
+ export declare function getPropertyExtension(type: string): PropertyExtension | undefined;
115
+ /** Returns the registered route extension for `key`, or `undefined`. */
116
+ export declare function getRouteExtension(key: string): RouteExtension | undefined;
117
+ /**
118
+ * Clears all registrations.
119
+ * @internal For unit tests only — do not call in production code.
120
+ */
121
+ export declare function _resetExtensionRegistry(): void;
122
+ //# sourceMappingURL=extension-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-registry.d.ts","sourceRoot":"","sources":["../src/extension-registry.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AACnC,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAI3E;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,GAAG,EAAE,MAAM,CAAA;IACX,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACjD;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAA;IACX;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACjD;;;OAGG;IACH,SAAS,EAAE,KAAK,CAAC,aAAa,CAAA;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAClD,wDAAwD;IACxD,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAA;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAA;IACX,sEAAsE;IACtE,SAAS,EAAE,KAAK,CAAC,aAAa,CAAA;CAC/B;AAoBD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAI/D;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAIpE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAEpF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAIhE;AAID,uEAAuE;AACvE,wBAAgB,oBAAoB,IAAI,gBAAgB,EAAE,CAEzD;AAED,sEAAsE;AACtE,wBAAgB,4BAA4B,IAAI,iBAAiB,EAAE,CAElE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEhF;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEzE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAK9C"}
@@ -0,0 +1,93 @@
1
+ // UI Extension Registry — lets Pro plugins add sidebar items, settings
2
+ // sections, custom property renderers, and full-page routes without
3
+ // modifying `packages/react` directly.
4
+ //
5
+ // Usage: call `register*` functions during module initialisation (before
6
+ // `<AdminApp>` renders). Every consumer of `@modern-admin/react` can import
7
+ // and call these helpers; the registry is a process-global singleton.
8
+ //
9
+ // Design notes:
10
+ // • Module-global (not React-context-based) so registration can happen in
11
+ // plain JS outside any component tree.
12
+ // • Idempotent: re-registering the same `key` is silently ignored so hot-
13
+ // reload doesn't produce duplicates.
14
+ // • Zero external runtime deps — only imports prop-type interfaces from
15
+ // `./types.ts` which is already bundled.
16
+ const registry = {
17
+ sidebarItems: [],
18
+ settingsSections: [],
19
+ propertyEditors: new Map(),
20
+ routes: [],
21
+ };
22
+ // ─── Registration API ─────────────────────────────────────────────────────────
23
+ /**
24
+ * Register a sidebar navigation item for an extension page.
25
+ * Call this during module initialisation, before `<AdminApp>` renders.
26
+ * Re-registering the same `key` is a no-op.
27
+ */
28
+ export function registerSidebarItem(ext) {
29
+ if (!registry.sidebarItems.find((e) => e.key === ext.key)) {
30
+ registry.sidebarItems.push(ext);
31
+ }
32
+ }
33
+ /**
34
+ * Register a custom section in the Settings page.
35
+ * Call this during module initialisation, before `<AdminApp>` renders.
36
+ * Re-registering the same `key` is a no-op.
37
+ */
38
+ export function registerSettingsSection(ext) {
39
+ if (!registry.settingsSections.find((e) => e.key === ext.key)) {
40
+ registry.settingsSections.push(ext);
41
+ }
42
+ }
43
+ /**
44
+ * Register a custom property type renderer (display + editor pair).
45
+ * When `property.type === type`, the built-in switch delegates to this
46
+ * extension instead of the plain-text fallback.
47
+ * Re-registering the same `type` overwrites the previous entry.
48
+ */
49
+ export function registerPropertyExtension(type, ext) {
50
+ registry.propertyEditors.set(type, ext);
51
+ }
52
+ /**
53
+ * Register a full-page extension route at `/ext/<key>` inside the admin
54
+ * shell. A matching `SidebarExtension` with `extensionKey === key` provides
55
+ * the navigation entry.
56
+ * Re-registering the same `key` is a no-op.
57
+ */
58
+ export function registerExtensionRoute(ext) {
59
+ if (!registry.routes.find((r) => r.key === ext.key)) {
60
+ registry.routes.push(ext);
61
+ }
62
+ }
63
+ // ─── Accessors (consumed by shell components at render time) ──────────────────
64
+ /** Returns all registered sidebar extensions in registration order. */
65
+ export function getSidebarExtensions() {
66
+ return registry.sidebarItems;
67
+ }
68
+ /** Returns all registered settings sections in registration order. */
69
+ export function getSettingsSectionExtensions() {
70
+ return registry.settingsSections;
71
+ }
72
+ /**
73
+ * Returns the registered property extension for `type`, or `undefined` if
74
+ * no extension covers it (fall through to plain-text).
75
+ */
76
+ export function getPropertyExtension(type) {
77
+ return registry.propertyEditors.get(type);
78
+ }
79
+ /** Returns the registered route extension for `key`, or `undefined`. */
80
+ export function getRouteExtension(key) {
81
+ return registry.routes.find((r) => r.key === key);
82
+ }
83
+ /**
84
+ * Clears all registrations.
85
+ * @internal For unit tests only — do not call in production code.
86
+ */
87
+ export function _resetExtensionRegistry() {
88
+ registry.sidebarItems = [];
89
+ registry.settingsSections = [];
90
+ registry.propertyEditors.clear();
91
+ registry.routes = [];
92
+ }
93
+ //# sourceMappingURL=extension-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-registry.js","sourceRoot":"","sources":["../src/extension-registry.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,oEAAoE;AACpE,uCAAuC;AACvC,EAAE;AACF,yEAAyE;AACzE,4EAA4E;AAC5E,sEAAsE;AACtE,EAAE;AACF,gBAAgB;AAChB,2EAA2E;AAC3E,0CAA0C;AAC1C,2EAA2E;AAC3E,wCAAwC;AACxC,yEAAyE;AACzE,4CAA4C;AA6F5C,MAAM,QAAQ,GAAiB;IAC7B,YAAY,EAAE,EAAE;IAChB,gBAAgB,EAAE,EAAE;IACpB,eAAe,EAAE,IAAI,GAAG,EAAE;IAC1B,MAAM,EAAE,EAAE;CACX,CAAA;AAED,iFAAiF;AAEjF;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAqB;IACvD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACjC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAsB;IAC5D,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9D,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACrC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAY,EAAE,GAAsB;IAC5E,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;AACzC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAmB;IACxD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACpD,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF,uEAAuE;AACvE,MAAM,UAAU,oBAAoB;IAClC,OAAO,QAAQ,CAAC,YAAY,CAAA;AAC9B,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,4BAA4B;IAC1C,OAAO,QAAQ,CAAC,gBAAgB,CAAA;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AAC3C,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAA;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,QAAQ,CAAC,YAAY,GAAG,EAAE,CAAA;IAC1B,QAAQ,CAAC,gBAAgB,GAAG,EAAE,CAAA;IAC9B,QAAQ,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;IAChC,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAA;AACtB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import * as React from 'react';
2
+ export declare function ThemeToggle(): React.ReactElement;
3
+ export declare function LanguageSwitcher(): React.ReactElement | null;
4
+ //# sourceMappingURL=header-controls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-controls.d.ts","sourceRoot":"","sources":["../src/header-controls.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA4C9B,wBAAgB,WAAW,IAAI,KAAK,CAAC,YAAY,CAyChD;AAED,wBAAgB,gBAAgB,IAAI,KAAK,CAAC,YAAY,GAAG,IAAI,CAiC5D"}
@@ -0,0 +1,70 @@
1
+ // Theme + language switchers for the admin header. Both render as
2
+ // dropdown menus using shadcn primitives and reflect persistent state
3
+ // (theme via @modern-admin/ui's lib/theme; locale via I18nProvider).
4
+ import * as React from 'react';
5
+ import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, ScrollArea, readThemeMode, setThemeMode, } from '@modern-admin/ui';
6
+ import { Check, Languages, Monitor, Moon, Sun } from 'lucide-react';
7
+ import { useI18n } from './i18n.js';
8
+ /** Single dropdown row with a leading icon, label, and trailing check when active. */
9
+ function MenuOption({ icon, label, active, onSelect, }) {
10
+ return (<DropdownMenuItem onSelect={(e) => {
11
+ e.preventDefault();
12
+ onSelect();
13
+ }} className="gap-3 px-3 py-2">
14
+ {icon && <span className="flex size-4 items-center justify-center text-muted-foreground">{icon}</span>}
15
+ <span className="flex-1 truncate">{label}</span>
16
+ {active && <Check className="size-4 text-primary"/>}
17
+ </DropdownMenuItem>);
18
+ }
19
+ export function ThemeToggle() {
20
+ const { t } = useI18n();
21
+ const [mode, setMode] = React.useState(() => readThemeMode());
22
+ const apply = (next) => {
23
+ setThemeMode(next);
24
+ setMode(next);
25
+ };
26
+ const Icon = mode === 'dark' ? Moon : mode === 'light' ? Sun : Monitor;
27
+ return (<DropdownMenu>
28
+ <DropdownMenuTrigger asChild>
29
+ <Button variant="ghost" size="icon" aria-label={t('common:toggleTheme')}>
30
+ <Icon className="size-4"/>
31
+ </Button>
32
+ </DropdownMenuTrigger>
33
+ <DropdownMenuContent align="end" sideOffset={8} className="w-44 p-1">
34
+ <DropdownMenuLabel className="px-3 py-2 text-xs uppercase tracking-wide text-muted-foreground">
35
+ {t('common:theme')}
36
+ </DropdownMenuLabel>
37
+ <DropdownMenuSeparator />
38
+ <MenuOption icon={<Sun className="size-4"/>} label={t('common:themeLight')} active={mode === 'light'} onSelect={() => apply('light')}/>
39
+ <MenuOption icon={<Moon className="size-4"/>} label={t('common:themeDark')} active={mode === 'dark'} onSelect={() => apply('dark')}/>
40
+ <MenuOption icon={<Monitor className="size-4"/>} label={t('common:themeSystem')} active={mode === 'system'} onSelect={() => apply('system')}/>
41
+ </DropdownMenuContent>
42
+ </DropdownMenu>);
43
+ }
44
+ export function LanguageSwitcher() {
45
+ const { locale, setLocale, availableLocales, t } = useI18n();
46
+ const locales = availableLocales();
47
+ // With a single registered locale there is nothing to switch between —
48
+ // hide the control entirely (consumers control the set via I18nProvider's
49
+ // `locales` prop, which the standalone shell wires from runtime config).
50
+ if (locales.length <= 1)
51
+ return null;
52
+ return (<DropdownMenu>
53
+ <DropdownMenuTrigger asChild>
54
+ <Button variant="ghost" size="sm" className="gap-2">
55
+ <Languages className="size-4"/>
56
+ <span className="text-xs uppercase">{locale}</span>
57
+ </Button>
58
+ </DropdownMenuTrigger>
59
+ <DropdownMenuContent align="end" sideOffset={8} className="w-52 p-1">
60
+ <DropdownMenuLabel className="px-3 py-2 text-xs uppercase tracking-wide text-muted-foreground">
61
+ {t('common:language')}
62
+ </DropdownMenuLabel>
63
+ <DropdownMenuSeparator />
64
+ <ScrollArea className="max-h-72">
65
+ {locales.map((l) => (<MenuOption key={l.code} label={l.name} active={l.code === locale} onSelect={() => setLocale(l.code)}/>))}
66
+ </ScrollArea>
67
+ </DropdownMenuContent>
68
+ </DropdownMenu>);
69
+ }
70
+ //# sourceMappingURL=header-controls.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-controls.jsx","sourceRoot":"","sources":["../src/header-controls.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { type InfiniteData, type UseInfiniteQueryResult, type UseMutationResult, type UseQueryResult } from '@tanstack/react-query';
2
+ import type { AdminConfig, AdminFeatures, CustomActionResponse, CurrentUser, ListQuery, ListResponse, RecordResponse, ResourceJSON } from './types.js';
3
+ import { type AuthUiProps, type AuditLogQuery, type AuditLogResponse, type GlobalSearchResponse, type HistoryListResponse, type HistoryRevisionResponse, type TimeSeriesQuery, type TimeSeriesResponse } from './client.js';
4
+ export declare const useAdminConfig: () => UseQueryResult<AdminConfig>;
5
+ export declare const useResource: (resourceId: string | undefined) => ResourceJSON | undefined;
6
+ /**
7
+ * Capability flags advertised by the backend via `/admin/api/config`.
8
+ * Use to gate optional UI surfaces (audit-log link, settings sections,
9
+ * revisions button, AI assistant widget) — every flag is `false` until
10
+ * the bootstrap config is loaded, so consumers can render unconditionally
11
+ * and the gating logic short-circuits during the initial paint.
12
+ */
13
+ export declare const useFeatures: () => AdminFeatures;
14
+ export declare const useResources: () => ResourceJSON[];
15
+ /**
16
+ * Fetch distinct values for a field, cached for 5 minutes.
17
+ * Used by the filter value picker to offer multi-select when cardinality is low.
18
+ * The `enabled` flag allows lazy loading only when the filter UI is open.
19
+ */
20
+ export declare const useDistinctValues: (resourceId: string, field: string, options?: {
21
+ search?: string;
22
+ limit?: number;
23
+ enabled?: boolean;
24
+ }) => UseQueryResult<{
25
+ values: string[];
26
+ hasMore: boolean;
27
+ }>;
28
+ export declare const useRecords: (resourceId: string, query?: ListQuery) => UseQueryResult<ListResponse>;
29
+ export declare const useRecord: (resourceId: string, recordId: string | undefined) => UseQueryResult<RecordResponse>;
30
+ export declare const useCreateRecord: (resourceId: string) => UseMutationResult<RecordResponse, Error, Record<string, unknown>>;
31
+ export declare const useUpdateRecord: (resourceId: string) => UseMutationResult<RecordResponse, Error, {
32
+ id: string;
33
+ payload: Record<string, unknown>;
34
+ }>;
35
+ export declare const useDeleteRecord: (resourceId: string) => UseMutationResult<void, Error, string>;
36
+ export declare const useBulkDeleteRecords: (resourceId: string) => UseMutationResult<unknown, Error, ReadonlyArray<string>>;
37
+ export interface CurrentUserResult {
38
+ user: CurrentUser | null;
39
+ isLoading: boolean;
40
+ isAuthenticated: boolean;
41
+ error: Error | null;
42
+ }
43
+ /** Resolve the current admin via /admin/api/auth/me. A 401 response surfaces
44
+ * as `user: null` (rather than an error) so callers can branch on it to
45
+ * render the login screen. */
46
+ export declare const useCurrentUser: () => CurrentUserResult;
47
+ /** Fetch public auth UI metadata (enabled social providers, email/password flag).
48
+ * Cached indefinitely — the provider list is static for a given deployment. */
49
+ export declare const useAuthUiProps: () => UseQueryResult<AuthUiProps>;
50
+ /** Initiate OAuth social login. Navigates the browser away to the provider;
51
+ * `isPending` is true while the redirect URL is being fetched. */
52
+ export declare const useSocialLogin: () => UseMutationResult<void, Error, string>;
53
+ export declare const useLogin: () => UseMutationResult<void, Error, {
54
+ email: string;
55
+ password: string;
56
+ }>;
57
+ export declare const useLogout: () => UseMutationResult<void, Error, void>;
58
+ export declare const useInvokeRecordAction: (resourceId: string) => UseMutationResult<CustomActionResponse, Error, {
59
+ recordId: string;
60
+ actionName: string;
61
+ }>;
62
+ export declare const useInvokeBulkAction: (resourceId: string) => UseMutationResult<CustomActionResponse, Error, {
63
+ actionName: string;
64
+ ids: string[];
65
+ }>;
66
+ export declare const useInvokeResourceAction: (resourceId: string) => UseMutationResult<CustomActionResponse, Error, {
67
+ actionName: string;
68
+ payload?: Record<string, unknown>;
69
+ }>;
70
+ /**
71
+ * Cross-resource search hook. Fires a single batched request that fans out
72
+ * to every registered resource's `search` action; results are grouped by
73
+ * resource. The empty-query case is handled by the caller (skip render);
74
+ * `enabled` allows lazy activation while the dialog is closed.
75
+ */
76
+ export declare const useGlobalSearch: (query: string, enabled?: boolean) => UseQueryResult<GlobalSearchResponse>;
77
+ export declare const useSearchRecords: (resourceId: string | undefined, query: string, enabled?: boolean) => UseQueryResult<ListResponse>;
78
+ /**
79
+ * Distinct (deduplicated, sorted) values pulled from a single field of a
80
+ * resource — the data source for the autocomplete `suggestionsResource +
81
+ * suggestionsField` binding on `KeyValueFieldSpec`. Loads up to `perPage`
82
+ * records and projects `field` client-side; for typical admin resources
83
+ * (hundreds–low thousands of rows) this is plenty cheap. For very large
84
+ * tables, reach for a dedicated `distinct` endpoint.
85
+ */
86
+ export declare const useFieldSuggestions: (resourceId: string | undefined, field: string | undefined, perPage?: number) => UseQueryResult<string[]>;
87
+ export declare const useTimeSeries: (query: TimeSeriesQuery | null) => UseQueryResult<TimeSeriesResponse>;
88
+ export declare const useRecordHistory: (resourceId: string, recordId: string | undefined, options?: {
89
+ limit?: number;
90
+ offset?: number;
91
+ }) => UseQueryResult<HistoryListResponse>;
92
+ export declare const useHistoryRevision: (resourceId: string, recordId: string | undefined, revisionId: string | undefined) => UseQueryResult<HistoryRevisionResponse>;
93
+ export declare const useRevertRevision: (resourceId: string, recordId: string) => UseMutationResult<RecordResponse, Error, {
94
+ revisionId: string;
95
+ reason?: string;
96
+ }>;
97
+ export declare const useAuditLog: (query?: AuditLogQuery) => UseQueryResult<AuditLogResponse>;
98
+ /**
99
+ * Cursor-based infinite scroll variant of `useAuditLog`.
100
+ * Each page passes the `at` timestamp of the last entry as the `before` cursor.
101
+ * `pageSize` entries are requested; if the response is full, there are more pages.
102
+ */
103
+ export declare const useInfiniteAuditLog: (filters: Omit<AuditLogQuery, "before" | "offset" | "limit">, pageSize: number) => UseInfiniteQueryResult<InfiniteData<AuditLogResponse>, Error>;
104
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}