@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.
- package/dist/action-guard.d.ts +13 -0
- package/dist/action-guard.d.ts.map +1 -0
- package/dist/action-guard.js +15 -0
- package/dist/action-guard.js.map +1 -0
- package/dist/action-menu.d.ts +17 -0
- package/dist/action-menu.d.ts.map +1 -0
- package/dist/action-menu.jsx +80 -0
- package/dist/action-menu.jsx.map +1 -0
- package/dist/admin-app.d.ts +23 -0
- package/dist/admin-app.d.ts.map +1 -0
- package/dist/admin-app.jsx +407 -0
- package/dist/admin-app.jsx.map +1 -0
- package/dist/admin-router.d.ts +29 -0
- package/dist/admin-router.d.ts.map +1 -0
- package/dist/admin-router.jsx +215 -0
- package/dist/admin-router.jsx.map +1 -0
- package/dist/breadcrumbs.d.ts +17 -0
- package/dist/breadcrumbs.d.ts.map +1 -0
- package/dist/breadcrumbs.jsx +40 -0
- package/dist/breadcrumbs.jsx.map +1 -0
- package/dist/client.d.ts +526 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +582 -0
- package/dist/client.js.map +1 -0
- package/dist/component-loader.d.ts +10 -0
- package/dist/component-loader.d.ts.map +1 -0
- package/dist/component-loader.js +23 -0
- package/dist/component-loader.js.map +1 -0
- package/dist/components/ai-assistant-widget.d.ts +3 -0
- package/dist/components/ai-assistant-widget.d.ts.map +1 -0
- package/dist/components/ai-assistant-widget.jsx +390 -0
- package/dist/components/ai-assistant-widget.jsx.map +1 -0
- package/dist/components/ai-fill-dialog.d.ts +9 -0
- package/dist/components/ai-fill-dialog.d.ts.map +1 -0
- package/dist/components/ai-fill-dialog.jsx +105 -0
- package/dist/components/ai-fill-dialog.jsx.map +1 -0
- package/dist/components/chart-builder-dialog.d.ts +10 -0
- package/dist/components/chart-builder-dialog.d.ts.map +1 -0
- package/dist/components/chart-builder-dialog.jsx +433 -0
- package/dist/components/chart-builder-dialog.jsx.map +1 -0
- package/dist/components/chart-widget.d.ts +12 -0
- package/dist/components/chart-widget.d.ts.map +1 -0
- package/dist/components/chart-widget.jsx +365 -0
- package/dist/components/chart-widget.jsx.map +1 -0
- package/dist/components/global-search-dialog.d.ts +7 -0
- package/dist/components/global-search-dialog.d.ts.map +1 -0
- package/dist/components/global-search-dialog.jsx +187 -0
- package/dist/components/global-search-dialog.jsx.map +1 -0
- package/dist/components/group-settings-dialog.d.ts +13 -0
- package/dist/components/group-settings-dialog.d.ts.map +1 -0
- package/dist/components/group-settings-dialog.jsx +53 -0
- package/dist/components/group-settings-dialog.jsx.map +1 -0
- package/dist/components/move-chart-dialog.d.ts +18 -0
- package/dist/components/move-chart-dialog.d.ts.map +1 -0
- package/dist/components/move-chart-dialog.jsx +68 -0
- package/dist/components/move-chart-dialog.jsx.map +1 -0
- package/dist/components/reference-multi-table-dialog.d.ts +12 -0
- package/dist/components/reference-multi-table-dialog.d.ts.map +1 -0
- package/dist/components/reference-multi-table-dialog.jsx +126 -0
- package/dist/components/reference-multi-table-dialog.jsx.map +1 -0
- package/dist/components/related-records-tabs.d.ts +8 -0
- package/dist/components/related-records-tabs.d.ts.map +1 -0
- package/dist/components/related-records-tabs.jsx +75 -0
- package/dist/components/related-records-tabs.jsx.map +1 -0
- package/dist/components/revisions-button.d.ts +7 -0
- package/dist/components/revisions-button.d.ts.map +1 -0
- package/dist/components/revisions-button.jsx +152 -0
- package/dist/components/revisions-button.jsx.map +1 -0
- package/dist/components/wizard-form.d.ts +43 -0
- package/dist/components/wizard-form.d.ts.map +1 -0
- package/dist/components/wizard-form.jsx +136 -0
- package/dist/components/wizard-form.jsx.map +1 -0
- package/dist/dashboard/time-series.d.ts +20 -0
- package/dist/dashboard/time-series.d.ts.map +1 -0
- package/dist/dashboard/time-series.js +108 -0
- package/dist/dashboard/time-series.js.map +1 -0
- package/dist/dialogs.d.ts +35 -0
- package/dist/dialogs.d.ts.map +1 -0
- package/dist/dialogs.jsx +152 -0
- package/dist/dialogs.jsx.map +1 -0
- package/dist/export.d.ts +39 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +114 -0
- package/dist/export.js.map +1 -0
- package/dist/extension-registry.d.ts +122 -0
- package/dist/extension-registry.d.ts.map +1 -0
- package/dist/extension-registry.js +93 -0
- package/dist/extension-registry.js.map +1 -0
- package/dist/header-controls.d.ts +4 -0
- package/dist/header-controls.d.ts.map +1 -0
- package/dist/header-controls.jsx +70 -0
- package/dist/header-controls.jsx.map +1 -0
- package/dist/hooks.d.ts +104 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +374 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hotkey-help.d.ts +3 -0
- package/dist/hotkey-help.d.ts.map +1 -0
- package/dist/hotkey-help.jsx +32 -0
- package/dist/hotkey-help.jsx.map +1 -0
- package/dist/hotkey-registry.d.ts +18 -0
- package/dist/hotkey-registry.d.ts.map +1 -0
- package/dist/hotkey-registry.jsx +34 -0
- package/dist/hotkey-registry.jsx.map +1 -0
- package/dist/i18n.d.ts +74 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.jsx +127 -0
- package/dist/i18n.jsx.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/notify.d.ts +41 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.jsx +58 -0
- package/dist/notify.jsx.map +1 -0
- package/dist/pages/ai-assistant-settings-section.d.ts +3 -0
- package/dist/pages/ai-assistant-settings-section.d.ts.map +1 -0
- package/dist/pages/ai-assistant-settings-section.jsx +126 -0
- package/dist/pages/ai-assistant-settings-section.jsx.map +1 -0
- package/dist/pages/audit-log-page.d.ts +3 -0
- package/dist/pages/audit-log-page.d.ts.map +1 -0
- package/dist/pages/audit-log-page.jsx +354 -0
- package/dist/pages/audit-log-page.jsx.map +1 -0
- package/dist/pages/edit-page.d.ts +7 -0
- package/dist/pages/edit-page.d.ts.map +1 -0
- package/dist/pages/edit-page.jsx +614 -0
- package/dist/pages/edit-page.jsx.map +1 -0
- package/dist/pages/export-dialog.d.ts +11 -0
- package/dist/pages/export-dialog.d.ts.map +1 -0
- package/dist/pages/export-dialog.jsx +102 -0
- package/dist/pages/export-dialog.jsx.map +1 -0
- package/dist/pages/home-page.d.ts +3 -0
- package/dist/pages/home-page.d.ts.map +1 -0
- package/dist/pages/home-page.jsx +211 -0
- package/dist/pages/home-page.jsx.map +1 -0
- package/dist/pages/list-page.d.ts +42 -0
- package/dist/pages/list-page.d.ts.map +1 -0
- package/dist/pages/list-page.jsx +1596 -0
- package/dist/pages/list-page.jsx.map +1 -0
- package/dist/pages/login-page.d.ts +11 -0
- package/dist/pages/login-page.d.ts.map +1 -0
- package/dist/pages/login-page.jsx +157 -0
- package/dist/pages/login-page.jsx.map +1 -0
- package/dist/pages/settings-page.d.ts +5 -0
- package/dist/pages/settings-page.d.ts.map +1 -0
- package/dist/pages/settings-page.jsx +787 -0
- package/dist/pages/settings-page.jsx.map +1 -0
- package/dist/pages/settings-shared.d.ts +51 -0
- package/dist/pages/settings-shared.d.ts.map +1 -0
- package/dist/pages/settings-shared.jsx +66 -0
- package/dist/pages/settings-shared.jsx.map +1 -0
- package/dist/pages/show-page.d.ts +7 -0
- package/dist/pages/show-page.d.ts.map +1 -0
- package/dist/pages/show-page.jsx +147 -0
- package/dist/pages/show-page.jsx.map +1 -0
- package/dist/pages/wizard-create-page.d.ts +14 -0
- package/dist/pages/wizard-create-page.d.ts.map +1 -0
- package/dist/pages/wizard-create-page.jsx +106 -0
- package/dist/pages/wizard-create-page.jsx.map +1 -0
- package/dist/property-renderer.d.ts +8 -0
- package/dist/property-renderer.d.ts.map +1 -0
- package/dist/property-renderer.jsx +690 -0
- package/dist/property-renderer.jsx.map +1 -0
- package/dist/provider.d.ts +20 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.jsx +32 -0
- package/dist/provider.jsx.map +1 -0
- package/dist/realtime.d.ts +22 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +38 -0
- package/dist/realtime.js.map +1 -0
- package/dist/reference.d.ts +52 -0
- package/dist/reference.d.ts.map +1 -0
- package/dist/reference.jsx +224 -0
- package/dist/reference.jsx.map +1 -0
- package/dist/relations.d.ts +11 -0
- package/dist/relations.d.ts.map +1 -0
- package/dist/relations.js +36 -0
- package/dist/relations.js.map +1 -0
- package/dist/router.d.ts +82 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.jsx +187 -0
- package/dist/router.jsx.map +1 -0
- package/dist/show-when.d.ts +7 -0
- package/dist/show-when.d.ts.map +1 -0
- package/dist/show-when.js +77 -0
- package/dist/show-when.js.map +1 -0
- package/dist/types.d.ts +194 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +18 -0
- package/dist/types.js.map +1 -0
- package/dist/use-dashboard-charts.d.ts +93 -0
- package/dist/use-dashboard-charts.d.ts.map +1 -0
- package/dist/use-dashboard-charts.js +263 -0
- package/dist/use-dashboard-charts.js.map +1 -0
- package/dist/use-hotkey.d.ts +17 -0
- package/dist/use-hotkey.d.ts.map +1 -0
- package/dist/use-hotkey.js +103 -0
- package/dist/use-hotkey.js.map +1 -0
- package/dist/user-directory.d.ts +18 -0
- package/dist/user-directory.d.ts.map +1 -0
- package/dist/user-directory.js +51 -0
- package/dist/user-directory.js.map +1 -0
- package/dist/validation.d.ts +22 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +338 -0
- package/dist/validation.js.map +1 -0
- package/package.json +59 -0
- package/src/action-guard.ts +20 -0
- package/src/action-menu.tsx +161 -0
- package/src/admin-app.tsx +630 -0
- package/src/admin-router.tsx +273 -0
- package/src/breadcrumbs.tsx +75 -0
- package/src/client.ts +1093 -0
- package/src/component-loader.ts +33 -0
- package/src/components/ai-assistant-widget.tsx +565 -0
- package/src/components/ai-fill-dialog.tsx +143 -0
- package/src/components/chart-builder-dialog.tsx +618 -0
- package/src/components/chart-widget.tsx +654 -0
- package/src/components/global-search-dialog.tsx +272 -0
- package/src/components/group-settings-dialog.tsx +93 -0
- package/src/components/move-chart-dialog.tsx +130 -0
- package/src/components/reference-multi-table-dialog.tsx +196 -0
- package/src/components/related-records-tabs.tsx +130 -0
- package/src/components/revisions-button.tsx +237 -0
- package/src/components/wizard-form.tsx +302 -0
- package/src/dashboard/time-series.ts +125 -0
- package/src/dialogs.tsx +265 -0
- package/src/export.ts +140 -0
- package/src/extension-registry.ts +195 -0
- package/src/header-controls.tsx +125 -0
- package/src/hooks.ts +509 -0
- package/src/hotkey-help.tsx +56 -0
- package/src/hotkey-registry.tsx +60 -0
- package/src/i18n.tsx +267 -0
- package/src/index.ts +192 -0
- package/src/notify.tsx +94 -0
- package/src/pages/ai-assistant-settings-section.tsx +167 -0
- package/src/pages/audit-log-page.tsx +580 -0
- package/src/pages/edit-page.tsx +743 -0
- package/src/pages/export-dialog.tsx +154 -0
- package/src/pages/home-page.tsx +318 -0
- package/src/pages/list-page.tsx +2645 -0
- package/src/pages/login-page.tsx +242 -0
- package/src/pages/settings-page.tsx +1143 -0
- package/src/pages/settings-shared.tsx +134 -0
- package/src/pages/show-page.tsx +223 -0
- package/src/pages/wizard-create-page.tsx +164 -0
- package/src/property-renderer.tsx +1143 -0
- package/src/provider.tsx +70 -0
- package/src/realtime.ts +55 -0
- package/src/reference.tsx +386 -0
- package/src/relations.ts +55 -0
- package/src/router.tsx +211 -0
- package/src/show-when.ts +76 -0
- package/src/types.ts +198 -0
- package/src/use-dashboard-charts.ts +362 -0
- package/src/use-hotkey.ts +128 -0
- package/src/user-directory.ts +56 -0
- package/src/validation.ts +361 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// AiFillDialog — dropzone + "Recognize" button that sends a single image to
|
|
2
|
+
// the resource's `aiFill` action and forwards the extracted values to the
|
|
3
|
+
// caller. The dialog is purely presentational regarding form state; the
|
|
4
|
+
// edit page handles merging the returned values into the live form.
|
|
5
|
+
|
|
6
|
+
import * as React from 'react'
|
|
7
|
+
import { Sparkles, Loader2 } from 'lucide-react'
|
|
8
|
+
import {
|
|
9
|
+
Button,
|
|
10
|
+
Dialog,
|
|
11
|
+
DialogContent,
|
|
12
|
+
DialogDescription,
|
|
13
|
+
DialogFooter,
|
|
14
|
+
DialogHeader,
|
|
15
|
+
DialogTitle,
|
|
16
|
+
FileInput,
|
|
17
|
+
} from '@modern-admin/ui'
|
|
18
|
+
import { useAdminClient } from '../provider.js'
|
|
19
|
+
import { useI18n } from '../i18n.js'
|
|
20
|
+
import { useNotify } from '../notify.js'
|
|
21
|
+
import { parseApiError } from '../client.js'
|
|
22
|
+
|
|
23
|
+
export interface AiFillDialogProps {
|
|
24
|
+
resourceId: string
|
|
25
|
+
onClose(): void
|
|
26
|
+
/** Called with the extracted values map. Caller merges into form state. */
|
|
27
|
+
onFilled(values: Record<string, unknown>): void
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function AiFillDialog({
|
|
31
|
+
resourceId,
|
|
32
|
+
onClose,
|
|
33
|
+
onFilled,
|
|
34
|
+
}: AiFillDialogProps): React.ReactElement {
|
|
35
|
+
const { t } = useI18n()
|
|
36
|
+
const client = useAdminClient()
|
|
37
|
+
const notify = useNotify()
|
|
38
|
+
const [file, setFile] = React.useState<File | null>(null)
|
|
39
|
+
const [busy, setBusy] = React.useState(false)
|
|
40
|
+
const abortRef = React.useRef<AbortController | null>(null)
|
|
41
|
+
|
|
42
|
+
// Use useEffect for createObjectURL to ensure cleanup is always paired with
|
|
43
|
+
// creation and happens at the right time (avoiding the side-effect-in-useMemo
|
|
44
|
+
// anti-pattern).
|
|
45
|
+
const [previewUrl, setPreviewUrl] = React.useState<string | null>(null)
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
if (!file) {
|
|
48
|
+
setPreviewUrl(null)
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
const url = URL.createObjectURL(file)
|
|
52
|
+
setPreviewUrl(url)
|
|
53
|
+
return () => URL.revokeObjectURL(url)
|
|
54
|
+
}, [file])
|
|
55
|
+
|
|
56
|
+
// Abort any in-flight request when the dialog unmounts.
|
|
57
|
+
React.useEffect(() => {
|
|
58
|
+
return () => {
|
|
59
|
+
abortRef.current?.abort('dialog unmounted')
|
|
60
|
+
}
|
|
61
|
+
}, [])
|
|
62
|
+
|
|
63
|
+
const handleFill = async (): Promise<void> => {
|
|
64
|
+
if (!file || busy) return
|
|
65
|
+
|
|
66
|
+
const ac = new AbortController()
|
|
67
|
+
abortRef.current = ac
|
|
68
|
+
setBusy(true)
|
|
69
|
+
try {
|
|
70
|
+
const { values } = await client.aiFillFromImage(resourceId, file, { signal: ac.signal })
|
|
71
|
+
const count = Object.keys(values).length
|
|
72
|
+
if (count === 0) {
|
|
73
|
+
notify.error({ key: 'aiFill:noValues' })
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
onFilled(values)
|
|
77
|
+
// The undo toast is surfaced by the edit-page (applyAiFillValues); the
|
|
78
|
+
// dialog only needs to close cleanly after handing off the values.
|
|
79
|
+
onClose()
|
|
80
|
+
} catch (err) {
|
|
81
|
+
if (ac.signal.aborted) return // user-initiated close — silently ignore
|
|
82
|
+
const { message } = parseApiError(err)
|
|
83
|
+
notify.error(
|
|
84
|
+
{ key: 'aiFill:errorGeneric', params: { message } },
|
|
85
|
+
{ description: message },
|
|
86
|
+
)
|
|
87
|
+
} finally {
|
|
88
|
+
setBusy(false)
|
|
89
|
+
abortRef.current = null
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const handleClose = (): void => {
|
|
94
|
+
if (busy) {
|
|
95
|
+
abortRef.current?.abort('dialog closed')
|
|
96
|
+
}
|
|
97
|
+
onClose()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<Dialog open onOpenChange={(open) => { if (!open) handleClose() }}>
|
|
102
|
+
<DialogContent className="w-full max-w-md">
|
|
103
|
+
<DialogHeader>
|
|
104
|
+
<DialogTitle className="flex items-center gap-2">
|
|
105
|
+
<Sparkles className="size-4" />
|
|
106
|
+
{t('aiFill:dialogTitle')}
|
|
107
|
+
</DialogTitle>
|
|
108
|
+
<DialogDescription>{t('aiFill:dialogDescription')}</DialogDescription>
|
|
109
|
+
</DialogHeader>
|
|
110
|
+
|
|
111
|
+
<FileInput
|
|
112
|
+
accept="image/*"
|
|
113
|
+
value={file ? file.name : null}
|
|
114
|
+
displayName={file?.name ?? null}
|
|
115
|
+
previewUrl={previewUrl}
|
|
116
|
+
uploading={busy}
|
|
117
|
+
uploadingName={file?.name}
|
|
118
|
+
disabled={busy}
|
|
119
|
+
onFileSelect={(f) => setFile(f)}
|
|
120
|
+
onRemove={() => setFile(null)}
|
|
121
|
+
labels={{
|
|
122
|
+
chooseFile: t('common:chooseFile'),
|
|
123
|
+
dragAndDrop: t('common:dragAndDrop'),
|
|
124
|
+
chooseAFile: t('common:chooseAFile'),
|
|
125
|
+
uploading: t('aiFill:processing'),
|
|
126
|
+
uploadingFile: t('aiFill:processing'),
|
|
127
|
+
removeFile: t('common:removeFile'),
|
|
128
|
+
}}
|
|
129
|
+
/>
|
|
130
|
+
|
|
131
|
+
<DialogFooter>
|
|
132
|
+
<Button variant="outline" onClick={handleClose}>
|
|
133
|
+
{t('common:cancel')}
|
|
134
|
+
</Button>
|
|
135
|
+
<Button onClick={() => void handleFill()} disabled={!file || busy}>
|
|
136
|
+
{busy ? <Loader2 className="size-4 animate-spin" /> : <Sparkles className="size-4" />}
|
|
137
|
+
{t('aiFill:fillButton')}
|
|
138
|
+
</Button>
|
|
139
|
+
</DialogFooter>
|
|
140
|
+
</DialogContent>
|
|
141
|
+
</Dialog>
|
|
142
|
+
)
|
|
143
|
+
}
|