@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,167 @@
1
+ import * as React from 'react'
2
+ import { useMutation, useQuery } from '@tanstack/react-query'
3
+ import { Badge, Button, Input, Label, Switch, Textarea } from '@modern-admin/ui'
4
+ import { Bot, KeyRound, Save } from 'lucide-react'
5
+ import { useAdminClient } from '../provider.js'
6
+ import { useNotify } from '../notify.js'
7
+ import { useI18n } from '../i18n.js'
8
+ import type { AiAssistantSettings } from '../client.js'
9
+ import { SettingsCard } from './settings-shared.js'
10
+
11
+ export function AiAssistantSettingsSection(): React.ReactElement {
12
+ const client = useAdminClient()
13
+ const notify = useNotify()
14
+ const { t } = useI18n()
15
+ const settings = useQuery({
16
+ queryKey: ['modern-admin', 'ai-assistant', 'settings'],
17
+ queryFn: () => client.getAiAssistantSettings(),
18
+ })
19
+ const [form, setForm] = React.useState({
20
+ enabled: true,
21
+ model: 'google/gemini-3.1-flash-lite-preview',
22
+ apiKey: '',
23
+ systemPrompt: '',
24
+ })
25
+
26
+ React.useEffect(() => {
27
+ if (!settings.data) return
28
+ setForm({
29
+ enabled: settings.data.enabled,
30
+ model: settings.data.model,
31
+ apiKey: '',
32
+ systemPrompt: settings.data.systemPrompt,
33
+ })
34
+ }, [settings.data])
35
+
36
+ const save = useMutation({
37
+ mutationFn: async (): Promise<AiAssistantSettings> =>
38
+ client.updateAiAssistantSettings({
39
+ enabled: form.enabled,
40
+ model: form.model,
41
+ ...(form.apiKey.trim() ? { apiKey: form.apiKey.trim() } : {}),
42
+ systemPrompt: form.systemPrompt,
43
+ }),
44
+ onSuccess: () => {
45
+ settings.refetch()
46
+ setForm((prev) => ({ ...prev, apiKey: '' }))
47
+ notify.success({ message: t('aiAssistant:settings.saved') })
48
+ },
49
+ onError: (err) => {
50
+ notify.error({ message: err instanceof Error ? err.message : String(err) })
51
+ },
52
+ })
53
+
54
+ if (settings.isLoading) {
55
+ return <div className="py-8 text-sm text-muted-foreground">{t('common:loading')}</div>
56
+ }
57
+
58
+ if (settings.error) {
59
+ return (
60
+ <div className="rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive">
61
+ {settings.error instanceof Error ? settings.error.message : String(settings.error)}
62
+ </div>
63
+ )
64
+ }
65
+
66
+ const data = settings.data
67
+ if (!data) {
68
+ return <div className="py-8 text-sm text-muted-foreground">{t('aiAssistant:settings.empty')}</div>
69
+ }
70
+
71
+ return (
72
+ <div className="flex flex-col gap-4">
73
+ <SettingsCard
74
+ icon={Bot}
75
+ title={t('aiAssistant:settings.title')}
76
+ description={t('aiAssistant:settings.description')}
77
+ bodyClassName="space-y-4"
78
+ >
79
+ <div className="flex flex-wrap items-center gap-2">
80
+ <Badge variant={data.enabled ? 'secondary' : 'outline'}>
81
+ {data.enabled ? t('aiAssistant:settings.enabled') : t('aiAssistant:settings.disabled')}
82
+ </Badge>
83
+ <Badge variant={data.configured ? 'secondary' : 'outline'}>
84
+ {data.configured ? t('aiAssistant:settings.configured') : t('aiAssistant:settings.apiKeyRequired')}
85
+ </Badge>
86
+ <Badge variant="outline">{t('aiAssistant:settings.readOnly')}</Badge>
87
+ <Badge variant="outline">{t('aiAssistant:settings.provider', { provider: data.provider })}</Badge>
88
+ </div>
89
+
90
+ <div className="grid gap-4 sm:grid-cols-2">
91
+ <div className="flex items-center justify-between rounded-lg border border-border p-3">
92
+ <div className="space-y-1">
93
+ <Label htmlFor="ai-assistant-enabled">{t('aiAssistant:settings.enableLabel')}</Label>
94
+ <p className="text-xs text-muted-foreground">
95
+ {t('aiAssistant:settings.enableHint')}
96
+ </p>
97
+ </div>
98
+ <Switch
99
+ id="ai-assistant-enabled"
100
+ checked={form.enabled}
101
+ disabled={!data.canManage || save.isPending}
102
+ onCheckedChange={(enabled) => setForm((prev) => ({ ...prev, enabled }))}
103
+ />
104
+ </div>
105
+
106
+ <div className="space-y-1.5">
107
+ <Label htmlFor="ai-assistant-model">{t('aiAssistant:settings.modelLabel')}</Label>
108
+ <Input
109
+ id="ai-assistant-model"
110
+ value={form.model}
111
+ disabled={!data.canManage || save.isPending}
112
+ onChange={(e) => setForm((prev) => ({ ...prev, model: e.target.value }))}
113
+ placeholder="google/gemini-3.1-flash-lite-preview"
114
+ />
115
+ </div>
116
+ </div>
117
+
118
+ <div className="space-y-1.5">
119
+ <Label htmlFor="ai-assistant-api-key" className="flex items-center gap-2">
120
+ <KeyRound className="size-4"/>
121
+ {t('aiAssistant:settings.apiKeyLabel')}
122
+ </Label>
123
+ <Input
124
+ id="ai-assistant-api-key"
125
+ type="password"
126
+ value={form.apiKey}
127
+ disabled={!data.canManage || save.isPending}
128
+ onChange={(e) => setForm((prev) => ({ ...prev, apiKey: e.target.value }))}
129
+ placeholder={data.maskedApiKey ?? 'sk-or-v1-...'}
130
+ />
131
+ <p className="text-xs text-muted-foreground">
132
+ {t('aiAssistant:settings.apiKeyHint')}
133
+ </p>
134
+ </div>
135
+
136
+ <div className="space-y-1.5">
137
+ <Label htmlFor="ai-assistant-system-prompt">{t('aiAssistant:settings.systemPromptLabel')}</Label>
138
+ <Textarea
139
+ id="ai-assistant-system-prompt"
140
+ value={form.systemPrompt}
141
+ disabled={!data.canManage || save.isPending}
142
+ onChange={(e) => setForm((prev) => ({ ...prev, systemPrompt: e.target.value }))}
143
+ rows={8}
144
+ placeholder={t('aiAssistant:settings.systemPromptPlaceholder')}
145
+ />
146
+ </div>
147
+
148
+ <div className="flex items-center justify-between gap-3 rounded-lg border border-border p-3 text-sm">
149
+ <div>
150
+ <div className="font-medium">{t('aiAssistant:settings.accessTitle')}</div>
151
+ <div className="text-muted-foreground">
152
+ {t('aiAssistant:settings.accessDescription')}
153
+ </div>
154
+ </div>
155
+ <Badge variant="outline">{t('aiAssistant:settings.futureToolsReady')}</Badge>
156
+ </div>
157
+
158
+ <div className="flex justify-end">
159
+ <Button onClick={() => save.mutate()} disabled={!data.canManage || save.isPending || !form.model.trim()}>
160
+ <Save className="size-4"/>
161
+ {save.isPending ? t('aiAssistant:settings.saving') : t('aiAssistant:settings.save')}
162
+ </Button>
163
+ </div>
164
+ </SettingsCard>
165
+ </div>
166
+ )
167
+ }