@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,365 @@
1
+ // Dashboard tile rendering one ChartDef. Phase 10 brings:
2
+ // • Per-widget toolbar (step / range / width / SQL toggle) — changes persist
3
+ // via `onUpdate` so a tweak survives reload without re-opening the builder.
4
+ // • Time-series chart (date X-axis, value Y-axis) with multi-series via
5
+ // secondary `groupBy`. Zero-fill happens UI-side regardless of adapter.
6
+ // • KPI mode = `step: 'all'` — sums the single bucket and shows period-over-
7
+ // period delta.
8
+ // • Graceful degradation when the adapter cannot do time-series aggregation
9
+ // (e.g. non-relational DB) — shows a friendly message instead of erroring.
10
+ import * as React from 'react';
11
+ import { MoreHorizontal, Pencil, Trash2, RefreshCw, Maximize2, Minimize2, Code, Copy, Check, FolderSymlink, } from 'lucide-react';
12
+ import { Card, CardContent, CardHeader, CardTitle, TimeSeriesChart, KpiCard, DatePicker, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Skeleton, } from '@modern-admin/ui';
13
+ import { ReferenceCombobox } from '../reference.js';
14
+ import { useTimeSeries, useResource } from '../hooks.js';
15
+ import { useI18n } from '../i18n.js';
16
+ import { resolveRange } from '../use-dashboard-charts.js';
17
+ import { fillTimeSeries, makeLabelFormatter, makeTickFormatter, } from '../dashboard/time-series.js';
18
+ const PRESETS = ['7d', '30d', '90d', '1y', 'all', 'custom'];
19
+ const STEPS = ['day', 'week', 'month', 'year'];
20
+ export function ChartWidget({ config, onEdit, onDelete, onMove, onUpdate, }) {
21
+ const { t, locale } = useI18n();
22
+ const isKpi = config.visualisation === 'kpi';
23
+ // KPI charts force `step: 'all'`; the schema enforces this at save time.
24
+ // For very wide presets, automatically coarsen granularity so the point
25
+ // count stays manageable — 3650 daily buckets for 'all' would render an
26
+ // unreadable axis and cause significant memory pressure in Recharts.
27
+ const renderStep = isKpi ? 'all'
28
+ : config.timeRange.preset === 'all' && (config.step === 'day' || config.step === 'week') ? 'month'
29
+ : config.timeRange.preset === '1y' && config.step === 'day' ? 'week'
30
+ : config.step;
31
+ // Resolve the time-range preset to concrete from/to per render so cards
32
+ // automatically reflect "now" as days roll over without re-saving.
33
+ const range = React.useMemo(() => resolveRange(config.timeRange), [config.timeRange]);
34
+ // If the saved ChartDef pre-dates the groupByLabelResource feature (i.e.,
35
+ // groupBy is set but groupByLabelResource is not), derive it from the
36
+ // resource's property metadata so labels resolve without requiring a re-save.
37
+ const resourceConfig = useResource(config.resource);
38
+ const effectiveLabelResource = React.useMemo(() => {
39
+ if (config.groupByLabelResource)
40
+ return config.groupByLabelResource;
41
+ if (!config.groupBy || !resourceConfig)
42
+ return undefined;
43
+ const props = resourceConfig.properties;
44
+ const prop = props.find((p) => p.path === config.groupBy);
45
+ if (!prop)
46
+ return undefined;
47
+ if (prop.reference)
48
+ return prop.reference;
49
+ // FK heuristic: strip Id / _id suffix and look for a sibling reference prop.
50
+ const base = prop.path.endsWith('_id')
51
+ ? prop.path.slice(0, -3)
52
+ : prop.path.endsWith('Id')
53
+ ? prop.path.slice(0, -2)
54
+ : '';
55
+ if (base) {
56
+ const sibling = props.find((p) => p.path === base && p.reference);
57
+ if (sibling?.reference)
58
+ return sibling.reference;
59
+ }
60
+ return undefined;
61
+ }, [config.groupBy, config.groupByLabelResource, resourceConfig]);
62
+ const query = React.useMemo(() => ({
63
+ resource: config.resource,
64
+ dateField: config.dateField,
65
+ step: renderStep,
66
+ metric: config.metric,
67
+ from: range.from,
68
+ to: range.to,
69
+ ...(config.field ? { field: config.field } : {}),
70
+ ...(!isKpi && config.groupBy ? { groupBy: config.groupBy } : {}),
71
+ ...(!isKpi && config.groupBy ? { topN: config.topN } : {}),
72
+ ...(!isKpi && config.groupBy && effectiveLabelResource
73
+ ? { groupByLabelResource: effectiveLabelResource }
74
+ : {}),
75
+ ...(Object.keys(config.filters).length ? { filters: config.filters } : {}),
76
+ ...(isKpi ? { comparePrevious: true } : {}),
77
+ }), [config, range, isKpi, renderStep, effectiveLabelResource]);
78
+ const { data, isLoading, isError, refetch, isFetching } = useTimeSeries(query);
79
+ const [showSql, setShowSql] = React.useState(false);
80
+ const [sqlCopied, setSqlCopied] = React.useState(false);
81
+ // Draft from/to — only committed when the user clicks Apply.
82
+ // Seeded from `config.timeRange` when preset changes to 'custom'.
83
+ const [draftFrom, setDraftFrom] = React.useState(range.from);
84
+ const [draftTo, setDraftTo] = React.useState(range.to);
85
+ // Draft state for quick filters exposed above the chart. The user tweaks
86
+ // values inline and clicks Apply to refetch — mirroring the custom-range
87
+ // pattern so widgets don't refetch on every keystroke.
88
+ const quickFilterPaths = config.quickFilters ?? [];
89
+ const [draftFilters, setDraftFilters] = React.useState(() => seedDraftFilters(quickFilterPaths, config.filters));
90
+ // Re-seed whenever the saved chart definition changes externally.
91
+ const quickFiltersKey = quickFilterPaths.join('|');
92
+ const savedFiltersKey = React.useMemo(() => Object.entries(config.filters)
93
+ .map(([k, v]) => `${k}=${v}`)
94
+ .sort()
95
+ .join('|'), [config.filters]);
96
+ React.useEffect(() => {
97
+ setDraftFilters(seedDraftFilters(quickFilterPaths, config.filters));
98
+ // eslint-disable-next-line react-hooks/exhaustive-deps
99
+ }, [quickFiltersKey, savedFiltersKey]);
100
+ const applyQuickFilters = () => {
101
+ const next = { ...config.filters };
102
+ for (const p of quickFilterPaths) {
103
+ const v = draftFilters[p] ?? '';
104
+ if (v === '')
105
+ delete next[p];
106
+ else
107
+ next[p] = v;
108
+ }
109
+ update({ filters: next });
110
+ };
111
+ const draftDirty = quickFilterPaths.some((p) => (draftFilters[p] ?? '') !== (config.filters[p] ?? ''));
112
+ // Mutators — persisted by the parent via `onUpdate(updatedDef)`.
113
+ const update = (patch) => {
114
+ onUpdate({ ...config, ...patch, updatedAt: new Date().toISOString() });
115
+ };
116
+ const onPresetChange = (preset) => {
117
+ if (preset === 'custom') {
118
+ // Seed draft with the currently resolved window — user can then narrow
119
+ // it and click Apply without triggering an immediate refetch.
120
+ setDraftFrom(range.from);
121
+ setDraftTo(range.to);
122
+ update({
123
+ timeRange: { preset: 'custom', from: range.from, to: range.to },
124
+ });
125
+ }
126
+ else {
127
+ update({ timeRange: { preset } });
128
+ }
129
+ };
130
+ const applyCustomRange = () => {
131
+ if (draftFrom && draftTo) {
132
+ update({
133
+ timeRange: { preset: 'custom', from: draftFrom, to: draftTo },
134
+ });
135
+ }
136
+ };
137
+ const onStepChange = (step) => {
138
+ if (step === 'all')
139
+ return; // KPI is selected via the builder, not the toolbar
140
+ update({ step });
141
+ };
142
+ const onWidthToggle = () => {
143
+ update({ width: (config.width === 'full' ? 'half' : 'full') });
144
+ };
145
+ // ── Render ────────────────────────────────────────────────────────────
146
+ const heightClass = isKpi ? 'h-32' : 'h-[320px]';
147
+ const resolvedLabels = data?.resolvedLabels;
148
+ const seriesLabel = React.useCallback((key) => {
149
+ if (key === '__total__')
150
+ return t('dashboard:seriesTotal');
151
+ if (key === '__other__')
152
+ return t('dashboard:seriesOther');
153
+ if (key === '__null__')
154
+ return t('dashboard:seriesNull');
155
+ return resolvedLabels?.[key] ?? key;
156
+ }, [resolvedLabels, t]);
157
+ const chartSeries = React.useMemo(() => prepareSeries(data?.series ?? [], range, renderStep, seriesLabel),
158
+ // eslint-disable-next-line react-hooks/exhaustive-deps
159
+ [data?.series, range.from, range.to, renderStep, seriesLabel]);
160
+ // Adapter cannot do time-series — friendly message, no toolbar churn.
161
+ const unsupported = data && data.supported === false;
162
+ return (<Card className="flex flex-col">
163
+ <CardHeader className="flex flex-row items-center justify-between gap-2 p-3 pb-2 space-y-0 sm:p-6 sm:pb-2">
164
+ <CardTitle className="text-sm font-medium truncate pr-2">
165
+ {config.title || t('chart:untitled')}
166
+ </CardTitle>
167
+ <div className="flex items-center gap-1 shrink-0">
168
+ <Button variant="ghost" size="icon" className="size-7" onClick={onWidthToggle} aria-label={config.width === 'full'
169
+ ? t('dashboard:widget.shrink')
170
+ : t('dashboard:widget.expand')}>
171
+ {config.width === 'full' ? (<Minimize2 className="size-3.5"/>) : (<Maximize2 className="size-3.5"/>)}
172
+ </Button>
173
+ {data?.sql && (<Button variant={showSql ? 'secondary' : 'ghost'} size="icon" className="size-7" onClick={() => setShowSql((v) => !v)} aria-label={t('dashboard:widget.toggleSql')}>
174
+ <Code className="size-3.5"/>
175
+ </Button>)}
176
+ <Button variant="ghost" size="icon" className="size-7" onClick={() => refetch()} disabled={isFetching} aria-label={t('common:refresh')}>
177
+ <RefreshCw className={`size-3.5 ${isFetching ? 'animate-spin' : ''}`}/>
178
+ </Button>
179
+ <DropdownMenu>
180
+ <DropdownMenuTrigger asChild>
181
+ <Button variant="ghost" size="icon" className="size-7" aria-label={t('common:openMenu')}>
182
+ <MoreHorizontal className="size-3.5"/>
183
+ </Button>
184
+ </DropdownMenuTrigger>
185
+ <DropdownMenuContent align="end">
186
+ <DropdownMenuItem onClick={onEdit}>
187
+ <Pencil className="size-4 mr-2"/>
188
+ {t('chart:editChart')}
189
+ </DropdownMenuItem>
190
+ {onMove && (<DropdownMenuItem onClick={onMove}>
191
+ <FolderSymlink className="size-4 mr-2"/>
192
+ {t('chart:moveToGroup')}
193
+ </DropdownMenuItem>)}
194
+ <DropdownMenuSeparator />
195
+ <DropdownMenuItem onClick={onDelete} className="text-destructive focus:text-destructive">
196
+ <Trash2 className="size-4 mr-2"/>
197
+ {t('chart:deleteChart')}
198
+ </DropdownMenuItem>
199
+ </DropdownMenuContent>
200
+ </DropdownMenu>
201
+ </div>
202
+ </CardHeader>
203
+
204
+ <CardContent className="flex-1 p-3 pt-0 space-y-3 sm:p-6 sm:pt-0">
205
+ {/* Quick filters — compact inline row, label as placeholder, Apply on the right. */}
206
+ {!unsupported && quickFilterPaths.length > 0 && resourceConfig && (<div className="flex flex-wrap items-center gap-2">
207
+ {quickFilterPaths.map((path) => {
208
+ const prop = resourceConfig.properties.find((p) => p.path === path);
209
+ if (!prop)
210
+ return null;
211
+ return (<QuickFilterInput key={path} property={prop} placeholder={prop.label} value={draftFilters[path] ?? ''} onChange={(v) => setDraftFilters((prev) => ({ ...prev, [path]: v }))}/>);
212
+ })}
213
+ <Button size="sm" className="h-8 px-3 text-xs shrink-0" onClick={applyQuickFilters} disabled={!draftDirty}>
214
+ <Check className="size-3.5 mr-1"/>
215
+ {t('common:apply')}
216
+ </Button>
217
+ </div>)}
218
+
219
+ {/* Toolbar — step + range + window display. Hidden for unsupported
220
+ adapters because changing knobs would have no effect. */}
221
+ {!unsupported && (<div className="flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
222
+ {!isKpi && (<Select value={config.step === 'all' ? 'day' : config.step} onValueChange={(v) => onStepChange(v)}>
223
+ <SelectTrigger className="h-8 px-2 text-xs w-auto" aria-label={t('chart:step')}>
224
+ <SelectValue />
225
+ </SelectTrigger>
226
+ <SelectContent>
227
+ {STEPS.map((s) => (<SelectItem key={s} value={s}>
228
+ {t(`chart:step${cap(s)}`)}
229
+ </SelectItem>))}
230
+ </SelectContent>
231
+ </Select>)}
232
+ <Select value={config.timeRange.preset} onValueChange={(v) => onPresetChange(v)}>
233
+ <SelectTrigger className="h-8 px-2 text-xs w-auto" aria-label={t('dashboard:builder.range')}>
234
+ <SelectValue />
235
+ </SelectTrigger>
236
+ <SelectContent>
237
+ {PRESETS.map((p) => (<SelectItem key={p} value={p}>
238
+ {t(`dashboard:range.${p}`)}
239
+ </SelectItem>))}
240
+ </SelectContent>
241
+ </Select>
242
+ {config.timeRange.preset === 'custom' ? (<>
243
+ <DatePicker value={draftFrom} onChange={setDraftFrom} ariaLabel={t('common:from')} openCalendarLabel={t('common:openCalendar')} className="w-[130px]" inputClassName="h-8 text-xs"/>
244
+ <span className="text-muted-foreground">—</span>
245
+ <DatePicker value={draftTo} onChange={setDraftTo} ariaLabel={t('common:to')} openCalendarLabel={t('common:openCalendar')} className="w-[130px]" inputClassName="h-8 text-xs"/>
246
+ <Button size="sm" className="h-8 px-3 shrink-0" onClick={applyCustomRange} disabled={!draftFrom || !draftTo} aria-label={t('common:apply')}>
247
+ <Check className="size-3.5 mr-1"/>
248
+ {t('common:apply')}
249
+ </Button>
250
+ </>) : (<span className="ml-auto tabular-nums">
251
+ {range.from} — {range.to}
252
+ </span>)}
253
+ </div>)}
254
+
255
+ {/* Body */}
256
+ {isLoading ? (<Skeleton className={`${heightClass} w-full rounded-md`}/>) : isError ? (<div className={`flex items-center justify-center text-sm text-muted-foreground ${heightClass}`}>
257
+ {t('chart:loadError')}
258
+ </div>) : unsupported ? (<div className={`flex items-center justify-center text-center text-sm text-muted-foreground px-4 ${heightClass}`}>
259
+ {t('dashboard:widget.unsupported')}
260
+ </div>) : isKpi ? (<KpiBody data={data} labels={kpiLabels(t)}/>) : (<TimeSeriesChart series={chartSeries} height={320} visualisation={config.visualisation === 'kpi' ? undefined : config.visualisation} tickFormatter={makeTickFormatter(renderStep, locale)} labelFormatter={makeLabelFormatter(renderStep, locale)} labels={{
261
+ noData: t('chart:noData'),
262
+ showAll: t('dashboard:widget.showAll'),
263
+ hideAll: t('dashboard:widget.hideAll'),
264
+ }}/>)}
265
+
266
+ {/* Captured SQL — only when the user toggled and server returned it. */}
267
+ {data?.sql && showSql && (<div className="relative">
268
+ <Button variant="ghost" size="icon" className="absolute top-1 right-1 size-6" onClick={() => {
269
+ void navigator.clipboard.writeText(data.sql ?? '');
270
+ setSqlCopied(true);
271
+ setTimeout(() => setSqlCopied(false), 2000);
272
+ }} aria-label={sqlCopied ? t('common:copied') : t('common:copy')}>
273
+ {sqlCopied
274
+ ? <Check className="size-3 text-green-500"/>
275
+ : <Copy className="size-3"/>}
276
+ </Button>
277
+ <pre className="text-[11px] leading-snug bg-muted/50 border border-border rounded-md p-2 pr-8 overflow-x-auto whitespace-pre">
278
+ {data.sql}
279
+ </pre>
280
+ </div>)}
281
+ </CardContent>
282
+ </Card>);
283
+ }
284
+ // ── Helpers ──────────────────────────────────────────────────────────────
285
+ const cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
286
+ const QF_NONE = '__none__';
287
+ function seedDraftFilters(paths, filters) {
288
+ const out = {};
289
+ for (const p of paths)
290
+ out[p] = filters[p] ?? '';
291
+ return out;
292
+ }
293
+ /** Compact inline filter input — label is passed as placeholder so no
294
+ * extra row is needed. Matches the `h-7 text-xs` sizing of toolbar controls. */
295
+ function QuickFilterInput({ property, placeholder, value, onChange, }) {
296
+ const ph = placeholder ?? property.label;
297
+ if (property.reference) {
298
+ return (<div className="w-36">
299
+ <ReferenceCombobox referenceResourceId={property.reference} value={value || null} onChange={(next) => onChange(next == null ? '' : String(next))} placeholder={ph} className="h-8 text-xs"/>
300
+ </div>);
301
+ }
302
+ if (property.availableValues && property.availableValues.length > 0) {
303
+ return (<Select value={value || QF_NONE} onValueChange={(v) => onChange(v === QF_NONE ? '' : v)}>
304
+ <SelectTrigger className="h-8 px-2 text-xs w-36">
305
+ <SelectValue placeholder={ph}/>
306
+ </SelectTrigger>
307
+ <SelectContent>
308
+ <SelectItem value={QF_NONE}>{ph}</SelectItem>
309
+ {property.availableValues.map((opt) => (<SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>))}
310
+ </SelectContent>
311
+ </Select>);
312
+ }
313
+ if (property.type === 'boolean') {
314
+ return (<Select value={value || QF_NONE} onValueChange={(v) => onChange(v === QF_NONE ? '' : v)}>
315
+ <SelectTrigger className="h-8 px-2 text-xs w-36">
316
+ <SelectValue placeholder={ph}/>
317
+ </SelectTrigger>
318
+ <SelectContent>
319
+ <SelectItem value={QF_NONE}>{ph}</SelectItem>
320
+ <SelectItem value="true">true</SelectItem>
321
+ <SelectItem value="false">false</SelectItem>
322
+ </SelectContent>
323
+ </Select>);
324
+ }
325
+ const isNumeric = property.type === 'number' || property.type === 'float' || property.type === 'currency';
326
+ return (<Input type={isNumeric ? 'number' : 'text'} className="h-8 px-2 text-xs w-36" value={value} placeholder={ph} onChange={(e) => onChange(e.target.value)}/>);
327
+ }
328
+ /**
329
+ * Zero-fill every series across the resolved date range and re-tag each
330
+ * with its display label (so legend shows "Total" / "Other" / actual
331
+ * groupBy values rather than the wire-format internal keys).
332
+ */
333
+ function prepareSeries(series, range, step, labelFor) {
334
+ const filled = fillTimeSeries(series.map((s) => ({ key: s.key, points: s.points })), range.from, range.to, step);
335
+ return filled.map((s) => ({
336
+ key: s.key,
337
+ label: labelFor(s.key),
338
+ points: [...s.points],
339
+ }));
340
+ }
341
+ /** KPI mode summarises the single-bucket response to one scalar. */
342
+ function KpiBody({ data, labels }) {
343
+ const value = sumAll(data?.series);
344
+ const prev = sumAll(data?.previous);
345
+ return <KpiCard value={value} previousValue={prev} labels={labels}/>;
346
+ }
347
+ function sumAll(series) {
348
+ if (!series || series.length === 0)
349
+ return null;
350
+ let total = 0;
351
+ for (const s of series)
352
+ for (const p of s.points)
353
+ total += p.value;
354
+ return total;
355
+ }
356
+ function kpiLabels(t) {
357
+ return {
358
+ noData: t('chart:noData'),
359
+ deltaUp: t('dashboard:widget.deltaUp'),
360
+ deltaDown: t('dashboard:widget.deltaDown'),
361
+ deltaFlat: t('dashboard:widget.deltaFlat'),
362
+ previousPeriod: t('dashboard:widget.previousPeriod'),
363
+ };
364
+ }
365
+ //# sourceMappingURL=chart-widget.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-widget.jsx","sourceRoot":"","sources":["../../src/components/chart-widget.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ export interface GlobalSearchDialogProps {
3
+ open: boolean;
4
+ onOpenChange(open: boolean): void;
5
+ }
6
+ export declare function GlobalSearchDialog({ open, onOpenChange, }: GlobalSearchDialogProps): React.ReactElement;
7
+ //# sourceMappingURL=global-search-dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-search-dialog.d.ts","sourceRoot":"","sources":["../../src/components/global-search-dialog.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAqB9B,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,OAAO,CAAA;IAEb,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;CAClC;AAwDD,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,YAAY,GACb,EAAE,uBAAuB,GAAG,KAAK,CAAC,YAAY,CAkL9C"}
@@ -0,0 +1,187 @@
1
+ // Cross-resource command palette. Backed by `useGlobalSearch`, which fans
2
+ // the query out to every registered resource's `search` action server-side.
3
+ // Results are grouped by resource; selecting an entry navigates to the
4
+ // record's show page and closes the palette.
5
+ //
6
+ // Designed as a controlled component — the parent (typically the header)
7
+ // holds the `open` state so it can pair the trigger button with the
8
+ // `mod+k` hotkey.
9
+ import * as React from 'react';
10
+ import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, DialogDescription, DialogTitle, } from '@modern-admin/ui';
11
+ import { ArrowRight, Clock, Loader2, X } from 'lucide-react';
12
+ import { useGlobalSearch } from '../hooks.js';
13
+ import { useI18n } from '../i18n.js';
14
+ import { useNavigate } from '../router.js';
15
+ const DEBOUNCE_MS = 300;
16
+ const RECENT_STORAGE_KEY = 'modern-admin:global-search:recent:v1';
17
+ const RECENT_MAX = 6;
18
+ const readRecent = () => {
19
+ if (typeof window === 'undefined')
20
+ return [];
21
+ try {
22
+ const raw = window.localStorage.getItem(RECENT_STORAGE_KEY);
23
+ if (!raw)
24
+ return [];
25
+ const parsed = JSON.parse(raw);
26
+ if (!Array.isArray(parsed))
27
+ return [];
28
+ return parsed.filter((v) => typeof v === 'string').slice(0, RECENT_MAX);
29
+ }
30
+ catch {
31
+ return [];
32
+ }
33
+ };
34
+ const writeRecent = (entries) => {
35
+ if (typeof window === 'undefined')
36
+ return;
37
+ try {
38
+ window.localStorage.setItem(RECENT_STORAGE_KEY, JSON.stringify(entries.slice(0, RECENT_MAX)));
39
+ }
40
+ catch {
41
+ /* quota exceeded — recent list is best-effort */
42
+ }
43
+ };
44
+ /**
45
+ * Highlight every case-insensitive occurrence of `needle` in `text` with
46
+ * `<mark>`. Returns an array of React nodes ready to render inside any
47
+ * inline container. Empty `needle` falls back to the raw string.
48
+ */
49
+ const highlightMatch = (text, needle) => {
50
+ if (!needle)
51
+ return text;
52
+ const lower = text.toLowerCase();
53
+ const target = needle.toLowerCase();
54
+ const nodes = [];
55
+ let cursor = 0;
56
+ let key = 0;
57
+ while (cursor < text.length) {
58
+ const idx = lower.indexOf(target, cursor);
59
+ if (idx === -1) {
60
+ nodes.push(text.slice(cursor));
61
+ break;
62
+ }
63
+ if (idx > cursor)
64
+ nodes.push(text.slice(cursor, idx));
65
+ nodes.push(<mark key={key++} className="rounded-sm bg-primary/20 px-0.5 text-foreground">
66
+ {text.slice(idx, idx + target.length)}
67
+ </mark>);
68
+ cursor = idx + target.length;
69
+ }
70
+ return nodes;
71
+ };
72
+ export function GlobalSearchDialog({ open, onOpenChange, }) {
73
+ const { t } = useI18n();
74
+ const navigate = useNavigate();
75
+ const [query, setQuery] = React.useState('');
76
+ const [debounced, setDebounced] = React.useState('');
77
+ const [recent, setRecent] = React.useState(() => readRecent());
78
+ // Reset query each time the dialog opens so it starts empty, and rehydrate
79
+ // the recent list (other tabs may have appended entries while we were idle).
80
+ React.useEffect(() => {
81
+ if (open) {
82
+ setQuery('');
83
+ setDebounced('');
84
+ setRecent(readRecent());
85
+ }
86
+ }, [open]);
87
+ React.useEffect(() => {
88
+ const timer = window.setTimeout(() => setDebounced(query.trim()), DEBOUNCE_MS);
89
+ return () => window.clearTimeout(timer);
90
+ }, [query]);
91
+ const { data, isFetching } = useGlobalSearch(debounced, open);
92
+ // Capture the most recent successful query so it's available for the
93
+ // "recent" list. We only persist on user-driven navigation (not every
94
+ // keystroke) to keep the list signal-to-noise high.
95
+ const persistRecent = React.useCallback((value) => {
96
+ if (!value)
97
+ return;
98
+ setRecent((prev) => {
99
+ const next = [value, ...prev.filter((q) => q !== value)].slice(0, RECENT_MAX);
100
+ writeRecent(next);
101
+ return next;
102
+ });
103
+ }, []);
104
+ const groups = data?.groups ?? [];
105
+ const hasQuery = debounced.length > 0;
106
+ const showEmpty = hasQuery && !isFetching && groups.length === 0;
107
+ const handleSelect = React.useCallback((resourceId, recordId) => {
108
+ persistRecent(debounced);
109
+ onOpenChange(false);
110
+ navigate({ name: 'show', resourceId, recordId });
111
+ }, [debounced, navigate, onOpenChange, persistRecent]);
112
+ const handleShowAll = React.useCallback((resourceId) => {
113
+ persistRecent(debounced);
114
+ onOpenChange(false);
115
+ navigate({ name: 'list', resourceId });
116
+ }, [debounced, navigate, onOpenChange, persistRecent]);
117
+ const handlePickRecent = React.useCallback((value) => {
118
+ setQuery(value);
119
+ setDebounced(value);
120
+ }, []);
121
+ const handleClearRecent = React.useCallback(() => {
122
+ setRecent([]);
123
+ writeRecent([]);
124
+ }, []);
125
+ return (<CommandDialog open={open} onOpenChange={onOpenChange}>
126
+ {/* Visually-hidden title + description keep Radix Dialog accessibility
127
+ warnings quiet and provide a label for screen readers. */}
128
+ <DialogTitle className="sr-only">{t('globalSearch:title')}</DialogTitle>
129
+ <DialogDescription className="sr-only">
130
+ {t('globalSearch:description')}
131
+ </DialogDescription>
132
+ <CommandInput placeholder={t('globalSearch:placeholder')} value={query} onValueChange={setQuery}/>
133
+ {/* cmdk dedupes by item value — prefix each value with `resourceId:recordId`
134
+ so identical record ids across resources keep distinct entries.
135
+ shouldFilter is left on (default) so cmdk re-orders by relevance against
136
+ the typed query — server already narrowed the set down. */}
137
+ <CommandList>
138
+ {!hasQuery && recent.length === 0 && (<div className="py-6 text-center text-sm text-muted-foreground">
139
+ {t('globalSearch:hint')}
140
+ </div>)}
141
+ {!hasQuery && recent.length > 0 && (<CommandGroup heading={<span className="flex items-center justify-between gap-2">
142
+ <span>{t('globalSearch:recent')}</span>
143
+ <button type="button" className="text-xs text-muted-foreground hover:text-foreground" onClick={handleClearRecent}>
144
+ <X className="mr-1 inline size-3" aria-hidden="true"/>
145
+ {t('globalSearch:clearRecent')}
146
+ </button>
147
+ </span>}>
148
+ {recent.map((entry) => (<CommandItem key={`recent:${entry}`} value={`recent:${entry}`} onSelect={() => handlePickRecent(entry)}>
149
+ <Clock className="mr-2 size-4 text-muted-foreground" aria-hidden="true"/>
150
+ <span className="flex-1 truncate">{entry}</span>
151
+ </CommandItem>))}
152
+ </CommandGroup>)}
153
+ {showEmpty && <CommandEmpty>{t('globalSearch:noResults')}</CommandEmpty>}
154
+ {hasQuery && isFetching && groups.length === 0 && (<div className="flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground" role="status" aria-live="polite">
155
+ <Loader2 className="size-4 animate-spin" aria-hidden="true"/>
156
+ <span>{t('common:loading')}</span>
157
+ </div>)}
158
+ {groups.map((group, idx) => (<React.Fragment key={group.resourceId}>
159
+ {idx > 0 && <CommandSeparator />}
160
+ <CommandGroup heading={group.resourceName}>
161
+ {group.records.map((hit) => (<CommandItem key={`${hit.resourceId}:${hit.recordId}`} value={`${hit.resourceId}:${hit.recordId} ${hit.title} ${hit.snippet ?? ''}`} onSelect={() => handleSelect(hit.resourceId, hit.recordId)} className="flex-col items-start gap-0.5">
162
+ <div className="flex w-full items-baseline gap-2">
163
+ <span className="flex-1 truncate font-medium">
164
+ {highlightMatch(hit.title, debounced)}
165
+ </span>
166
+ {hit.matchedField && (<span className="shrink-0 text-xs text-muted-foreground">
167
+ {t('globalSearch:matchedIn').replace('{field}', hit.matchedField)}
168
+ </span>)}
169
+ </div>
170
+ {hit.snippet && (<div className="line-clamp-1 text-xs text-muted-foreground">
171
+ {highlightMatch(hit.snippet, debounced)}
172
+ </div>)}
173
+ </CommandItem>))}
174
+ {/* `forceMount` keeps this row visible regardless of the current
175
+ query — cmdk's default fuzzy filter would otherwise drop it
176
+ because the value `${id}:show-all` rarely contains the typed
177
+ needle. */}
178
+ <CommandItem key={`${group.resourceId}:show-all`} value={`${group.resourceId}:show-all`} forceMount onSelect={() => handleShowAll(group.resourceId)} className="text-xs text-muted-foreground">
179
+ <ArrowRight className="mr-2 size-3.5" aria-hidden="true"/>
180
+ {t('globalSearch:showAllIn').replace('{resource}', group.resourceName)}
181
+ </CommandItem>
182
+ </CommandGroup>
183
+ </React.Fragment>))}
184
+ </CommandList>
185
+ </CommandDialog>);
186
+ }
187
+ //# sourceMappingURL=global-search-dialog.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-search-dialog.jsx","sourceRoot":"","sources":["../../src/components/global-search-dialog.tsx"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,uEAAuE;AACvE,6CAA6C;AAC7C,EAAE;AACF,yEAAyE;AACzE,oEAAoE;AACpE,kBAAkB;AAElB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,GACZ,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,WAAW,GAAG,GAAG,CAAA;AACvB,MAAM,kBAAkB,GAAG,sCAAsC,CAAA;AACjE,MAAM,UAAU,GAAG,CAAC,CAAA;AAQpB,MAAM,UAAU,GAAG,GAAa,EAAE;IAChC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,CAAA;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;QAC3D,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAA;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAA;QACzC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,CAAA;QACrC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,OAAiB,EAAQ,EAAE;IAC9C,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAM;IACzC,IAAI,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IAC/F,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;IACnD,CAAC;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,MAAc,EAAmB,EAAE;IACvE,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACxB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;IAChC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAA;IACnC,MAAM,KAAK,GAAsB,EAAE,CAAA;IACnC,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACzC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;YAC9B,MAAK;QACP,CAAC;QACD,IAAI,GAAG,GAAG,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;QACrD,KAAK,CAAC,IAAI,CACR,CAAC,IAAI,CACH,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CACX,SAAS,CAAC,iDAAiD,CAE3D;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CACvC;MAAA,EAAE,IAAI,CAAC,CACR,CAAA;QACD,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,CAAA;IAC9B,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,UAAU,kBAAkB,CAAC,EACjC,IAAI,EACJ,YAAY,GACY;IACxB,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,CAAA;IACvB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC5C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IACpD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAW,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,CAAA;IAExE,2EAA2E;IAC3E,6EAA6E;IAC7E,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,IAAI,EAAE,CAAC;YACT,QAAQ,CAAC,EAAE,CAAC,CAAA;YACZ,YAAY,CAAC,EAAE,CAAC,CAAA;YAChB,SAAS,CAAC,UAAU,EAAE,CAAC,CAAA;QACzB,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,WAAW,CAAC,CAAA;QAC9E,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;IACzC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IAE7D,qEAAqE;IACrE,sEAAsE;IACtE,oDAAoD;IACpD,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,KAAa,EAAQ,EAAE;QAC9D,IAAI,CAAC,KAAK;YAAE,OAAM;QAClB,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YACjB,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;YAC7E,WAAW,CAAC,IAAI,CAAC,CAAA;YACjB,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,EAAE,CAAA;IACjC,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAA;IACrC,MAAM,SAAS,GAAG,QAAQ,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAA;IAEhE,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CACpC,CAAC,UAAkB,EAAE,QAAgB,EAAQ,EAAE;QAC7C,aAAa,CAAC,SAAS,CAAC,CAAA;QACxB,YAAY,CAAC,KAAK,CAAC,CAAA;QACnB,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAA;IAClD,CAAC,EACD,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,CAAC,CACnD,CAAA;IAED,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,CACrC,CAAC,UAAkB,EAAQ,EAAE;QAC3B,aAAa,CAAC,SAAS,CAAC,CAAA;QACxB,YAAY,CAAC,KAAK,CAAC,CAAA;QACnB,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAA;IACxC,CAAC,EACD,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,CAAC,CACnD,CAAA;IAED,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,KAAa,EAAQ,EAAE;QACjE,QAAQ,CAAC,KAAK,CAAC,CAAA;QACf,YAAY,CAAC,KAAK,CAAC,CAAA;IACrB,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,iBAAiB,GAAG,KAAK,CAAC,WAAW,CAAC,GAAS,EAAE;QACrD,SAAS,CAAC,EAAE,CAAC,CAAA;QACb,WAAW,CAAC,EAAE,CAAC,CAAA;IACjB,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CACL,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CACpD;MAAA,CAAC;qEAC4D,CAC7D;MAAA,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,EAAE,WAAW,CACvE;MAAA,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,CACpC;QAAA,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAChC;MAAA,EAAE,iBAAiB,CACnB;MAAA,CAAC,YAAY,CACX,WAAW,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAC3C,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,aAAa,CAAC,CAAC,QAAQ,CAAC,EAE1B;MAAA,CAAC;;;sEAG6D,CAC9D;MAAA,CAAC,WAAW,CACV;QAAA,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CACnC,CAAC,GAAG,CAAC,SAAS,CAAC,gDAAgD,CAC7D;YAAA,CAAC,CAAC,CAAC,mBAAmB,CAAC,CACzB;UAAA,EAAE,GAAG,CAAC,CACP,CACD;QAAA,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CACjC,CAAC,YAAY,CACX,OAAO,CAAC,CACN,CAAC,IAAI,CAAC,SAAS,CAAC,yCAAyC,CACvD;gBAAA,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,EAAE,IAAI,CACtC;gBAAA,CAAC,MAAM,CACL,IAAI,CAAC,QAAQ,CACb,SAAS,CAAC,qDAAqD,CAC/D,OAAO,CAAC,CAAC,iBAAiB,CAAC,CAE3B;kBAAA,CAAC,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,WAAW,CAAC,MAAM,EACpD;kBAAA,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAChC;gBAAA,EAAE,MAAM,CACV;cAAA,EAAE,IAAI,CACR,CAAC,CAED;YAAA,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACrB,CAAC,WAAW,CACV,GAAG,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC,CACvB,KAAK,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC,CACzB,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAExC;gBAAA,CAAC,KAAK,CAAC,SAAS,CAAC,mCAAmC,CAAC,WAAW,CAAC,MAAM,EACvE;gBAAA,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CACjD;cAAA,EAAE,WAAW,CAAC,CACf,CAAC,CACJ;UAAA,EAAE,YAAY,CAAC,CAChB,CACD;QAAA,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,EAAE,YAAY,CAAC,CACxE;QAAA,CAAC,QAAQ,IAAI,UAAU,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAChD,CAAC,GAAG,CACF,SAAS,CAAC,2EAA2E,CACrF,IAAI,CAAC,QAAQ,CACb,SAAS,CAAC,QAAQ,CAElB;YAAA,CAAC,OAAO,CAAC,SAAS,CAAC,qBAAqB,CAAC,WAAW,CAAC,MAAM,EAC3D;YAAA,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,EAAE,IAAI,CACnC;UAAA,EAAE,GAAG,CAAC,CACP,CACD;QAAA,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAC1B,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CACpC;YAAA,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAA,EAAE,CAC/B;YAAA,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CACxC;cAAA,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAC1B,CAAC,WAAW,CACV,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,CACzC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAC7E,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAC3D,SAAS,CAAC,8BAA8B,CAExC;kBAAA,CAAC,GAAG,CAAC,SAAS,CAAC,kCAAkC,CAC/C;oBAAA,CAAC,IAAI,CAAC,SAAS,CAAC,6BAA6B,CAC3C;sBAAA,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CACvC;oBAAA,EAAE,IAAI,CACN;oBAAA,CAAC,GAAG,CAAC,YAAY,IAAI,CACnB,CAAC,IAAI,CAAC,SAAS,CAAC,wCAAwC,CACtD;wBAAA,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,YAAY,CAAC,CACnE;sBAAA,EAAE,IAAI,CAAC,CACR,CACH;kBAAA,EAAE,GAAG,CACL;kBAAA,CAAC,GAAG,CAAC,OAAO,IAAI,CACd,CAAC,GAAG,CAAC,SAAS,CAAC,4CAA4C,CACzD;sBAAA,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CACzC;oBAAA,EAAE,GAAG,CAAC,CACP,CACH;gBAAA,EAAE,WAAW,CAAC,CACf,CAAC,CACF;cAAA,CAAC;;;0BAGa,CACd;cAAA,CAAC,WAAW,CACV,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,UAAU,WAAW,CAAC,CACpC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,UAAU,WAAW,CAAC,CACtC,UAAU,CACV,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAChD,SAAS,CAAC,+BAA+B,CAEzC;gBAAA,CAAC,UAAU,CAAC,SAAS,CAAC,eAAe,CAAC,WAAW,CAAC,MAAM,EACxD;gBAAA,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,CACxE;cAAA,EAAE,WAAW,CACf;YAAA,EAAE,YAAY,CAChB;UAAA,EAAE,KAAK,CAAC,QAAQ,CAAC,CAClB,CAAC,CACJ;MAAA,EAAE,WAAW,CACf;IAAA,EAAE,aAAa,CAAC,CACjB,CAAA;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import type { ChartGroup } from '@modern-admin/core';
3
+ export interface GroupSettingsDialogProps {
4
+ /** When set, the dialog is in edit mode and pre-populates from this group. */
5
+ initial?: ChartGroup;
6
+ onSave(input: {
7
+ name: string;
8
+ order: number;
9
+ }): void;
10
+ onClose(): void;
11
+ }
12
+ export declare function GroupSettingsDialog({ initial, onSave, onClose, }: GroupSettingsDialogProps): React.ReactElement;
13
+ //# sourceMappingURL=group-settings-dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-settings-dialog.d.ts","sourceRoot":"","sources":["../../src/components/group-settings-dialog.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAY9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGpD,MAAM,WAAW,wBAAwB;IACvC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,MAAM,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACpD,OAAO,IAAI,IAAI,CAAA;CAChB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACP,MAAM,EACN,OAAO,GACR,EAAE,wBAAwB,GAAG,KAAK,CAAC,YAAY,CA8D/C"}