hazo_admin 0.1.1 → 0.3.1
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/CHANGE_LOG.md +17 -0
- package/README.md +72 -4
- package/SETUP_CHECKLIST.md +9 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +109 -5
- package/dist/components/admin_app.d.ts.map +1 -1
- package/dist/components/admin_app.js +26 -0
- package/dist/components/admin_kinds.d.ts +15 -0
- package/dist/components/admin_kinds.d.ts.map +1 -0
- package/dist/components/admin_kinds.js +120 -0
- package/dist/components/admin_layout.d.ts.map +1 -1
- package/dist/components/admin_layout.js +18 -20
- package/dist/components/admin_nav.d.ts +17 -2
- package/dist/components/admin_nav.d.ts.map +1 -1
- package/dist/components/admin_nav.js +111 -1
- package/dist/components/api_keys_panel.d.ts +5 -0
- package/dist/components/api_keys_panel.d.ts.map +1 -0
- package/dist/components/api_keys_panel.js +21 -0
- package/dist/components/audit_panel.d.ts +5 -0
- package/dist/components/audit_panel.d.ts.map +1 -0
- package/dist/components/audit_panel.js +19 -0
- package/dist/components/blog_panel.d.ts +5 -0
- package/dist/components/blog_panel.d.ts.map +1 -0
- package/dist/components/blog_panel.js +23 -0
- package/dist/components/env_migration_panel.d.ts.map +1 -1
- package/dist/components/env_migration_panel.js +6 -8
- package/dist/components/feedback_panel.d.ts +5 -0
- package/dist/components/feedback_panel.d.ts.map +1 -0
- package/dist/components/feedback_panel.js +24 -0
- package/dist/components/files_panel.d.ts +5 -0
- package/dist/components/files_panel.d.ts.map +1 -0
- package/dist/components/files_panel.js +22 -0
- package/dist/components/masking_panel.d.ts +5 -0
- package/dist/components/masking_panel.d.ts.map +1 -0
- package/dist/components/masking_panel.js +65 -0
- package/dist/components/settings_panel.d.ts +5 -0
- package/dist/components/settings_panel.d.ts.map +1 -0
- package/dist/components/settings_panel.js +19 -0
- package/dist/index.client.d.ts +8 -0
- package/dist/index.client.d.ts.map +1 -1
- package/dist/index.client.js +8 -0
- package/dist/index.ui.d.ts +2 -0
- package/dist/index.ui.d.ts.map +1 -1
- package/dist/index.ui.js +1 -0
- package/dist/preset/page_factory.d.ts.map +1 -1
- package/dist/preset/page_factory.js +9 -13
- package/package.json +18 -8
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { getDefaultPermission } from './admin_kinds.js';
|
|
1
2
|
export function defaultPermissionForKind(kind) {
|
|
2
|
-
return kind
|
|
3
|
+
return getDefaultPermission(kind) ?? 'admin_system';
|
|
3
4
|
}
|
|
4
5
|
export function resolveNav(manifest, permissions) {
|
|
5
6
|
const items = [];
|
|
@@ -15,6 +16,8 @@ export function resolveNav(manifest, permissions) {
|
|
|
15
16
|
basePath: section.basePath ?? '/api/hazo_auth',
|
|
16
17
|
icon: section.icon,
|
|
17
18
|
permission,
|
|
19
|
+
group: section.group,
|
|
20
|
+
order: section.order,
|
|
18
21
|
});
|
|
19
22
|
}
|
|
20
23
|
else if (section.kind === 'jobs') {
|
|
@@ -25,6 +28,8 @@ export function resolveNav(manifest, permissions) {
|
|
|
25
28
|
basePath: section.basePath ?? '/api/admin/jobs',
|
|
26
29
|
icon: section.icon,
|
|
27
30
|
permission,
|
|
31
|
+
group: section.group,
|
|
32
|
+
order: section.order,
|
|
28
33
|
});
|
|
29
34
|
}
|
|
30
35
|
else if (section.kind === 'logs') {
|
|
@@ -35,6 +40,8 @@ export function resolveNav(manifest, permissions) {
|
|
|
35
40
|
basePath: section.basePath ?? '/api/admin/logs',
|
|
36
41
|
icon: section.icon,
|
|
37
42
|
permission,
|
|
43
|
+
group: section.group,
|
|
44
|
+
order: section.order,
|
|
38
45
|
});
|
|
39
46
|
}
|
|
40
47
|
else if (section.kind === 'env_migration') {
|
|
@@ -45,6 +52,8 @@ export function resolveNav(manifest, permissions) {
|
|
|
45
52
|
basePath: section.basePath ?? '/api/admin',
|
|
46
53
|
icon: section.icon,
|
|
47
54
|
permission,
|
|
55
|
+
group: section.group,
|
|
56
|
+
order: section.order,
|
|
48
57
|
});
|
|
49
58
|
}
|
|
50
59
|
else if (section.kind === 'health') {
|
|
@@ -55,6 +64,105 @@ export function resolveNav(manifest, permissions) {
|
|
|
55
64
|
basePath: section.basePath ?? '/api/admin',
|
|
56
65
|
icon: section.icon,
|
|
57
66
|
permission,
|
|
67
|
+
group: section.group,
|
|
68
|
+
order: section.order,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
else if (section.kind === 'masking') {
|
|
72
|
+
items.push({
|
|
73
|
+
kind: 'masking',
|
|
74
|
+
label: section.label ?? 'Masking Rules',
|
|
75
|
+
path: '/admin/masking',
|
|
76
|
+
basePath: section.basePath ?? '/api/admin',
|
|
77
|
+
icon: section.icon,
|
|
78
|
+
permission,
|
|
79
|
+
group: section.group,
|
|
80
|
+
order: section.order,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else if (section.kind === 'audit') {
|
|
84
|
+
items.push({
|
|
85
|
+
kind: 'audit',
|
|
86
|
+
label: section.label ?? 'Audit Log',
|
|
87
|
+
path: '/admin/audit',
|
|
88
|
+
basePath: section.basePath ?? '/api/admin',
|
|
89
|
+
icon: section.icon,
|
|
90
|
+
permission,
|
|
91
|
+
group: section.group,
|
|
92
|
+
order: section.order,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
else if (section.kind === 'settings') {
|
|
96
|
+
items.push({
|
|
97
|
+
kind: 'settings',
|
|
98
|
+
label: section.label ?? 'Settings',
|
|
99
|
+
path: '/admin/settings',
|
|
100
|
+
basePath: section.basePath ?? '/api/admin',
|
|
101
|
+
icon: section.icon,
|
|
102
|
+
permission,
|
|
103
|
+
group: section.group,
|
|
104
|
+
order: section.order,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else if (section.kind === 'api_keys') {
|
|
108
|
+
items.push({
|
|
109
|
+
kind: 'api_keys',
|
|
110
|
+
label: section.label ?? 'API Keys',
|
|
111
|
+
path: '/admin/api-keys',
|
|
112
|
+
basePath: section.basePath ?? '/api/admin',
|
|
113
|
+
icon: section.icon,
|
|
114
|
+
permission,
|
|
115
|
+
group: section.group,
|
|
116
|
+
order: section.order,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
else if (section.kind === 'blog') {
|
|
120
|
+
items.push({
|
|
121
|
+
kind: 'blog',
|
|
122
|
+
label: section.label ?? 'Blog',
|
|
123
|
+
path: '/admin/blog',
|
|
124
|
+
basePath: section.basePath ?? '/api/admin',
|
|
125
|
+
icon: section.icon,
|
|
126
|
+
permission,
|
|
127
|
+
group: section.group,
|
|
128
|
+
order: section.order,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
else if (section.kind === 'files') {
|
|
132
|
+
items.push({
|
|
133
|
+
kind: 'files',
|
|
134
|
+
label: section.label ?? 'Files',
|
|
135
|
+
path: '/admin/files',
|
|
136
|
+
basePath: section.basePath ?? '/api/admin',
|
|
137
|
+
icon: section.icon,
|
|
138
|
+
permission,
|
|
139
|
+
group: section.group,
|
|
140
|
+
order: section.order,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else if (section.kind === 'feedback') {
|
|
144
|
+
items.push({
|
|
145
|
+
kind: 'feedback',
|
|
146
|
+
label: section.label ?? 'Feedback',
|
|
147
|
+
path: '/admin/feedback',
|
|
148
|
+
basePath: section.basePath ?? '/api/admin',
|
|
149
|
+
icon: section.icon,
|
|
150
|
+
permission,
|
|
151
|
+
group: section.group,
|
|
152
|
+
order: section.order,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
else if (section.kind === 'metrics') {
|
|
156
|
+
items.push({
|
|
157
|
+
kind: 'metrics',
|
|
158
|
+
label: section.label ?? 'Metrics',
|
|
159
|
+
path: '/admin/analytics',
|
|
160
|
+
basePath: section.basePath ?? '/api/admin/metrics',
|
|
161
|
+
icon: section.icon,
|
|
162
|
+
permission,
|
|
163
|
+
component: section.component,
|
|
164
|
+
group: section.group,
|
|
165
|
+
order: section.order,
|
|
58
166
|
});
|
|
59
167
|
}
|
|
60
168
|
else if (section.kind === 'custom') {
|
|
@@ -66,6 +174,8 @@ export function resolveNav(manifest, permissions) {
|
|
|
66
174
|
icon: section.icon,
|
|
67
175
|
permission,
|
|
68
176
|
component: section.component,
|
|
177
|
+
group: section.group,
|
|
178
|
+
order: section.order,
|
|
69
179
|
});
|
|
70
180
|
}
|
|
71
181
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api_keys_panel.d.ts","sourceRoot":"","sources":["../../src/components/api_keys_panel.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,SAAwB,EAAE,EAAE,iBAAiB,+BAqCrF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
export function ApiKeysPanel({ basePath: _basePath = '/api/admin' }) {
|
|
5
|
+
const [notInstalled, setNotInstalled] = useState(false);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
// Probe the CLIENT entry — the default `hazo_api` entry pulls server-only
|
|
9
|
+
// code that breaks this 'use client' component's browser bundle.
|
|
10
|
+
import('hazo_api/client').catch(() => null).then((pkg) => {
|
|
11
|
+
setNotInstalled(pkg === null);
|
|
12
|
+
setLoading(false);
|
|
13
|
+
});
|
|
14
|
+
}, []);
|
|
15
|
+
if (loading)
|
|
16
|
+
return _jsx("div", { className: "p-6 text-sm text-gray-400", children: "Loading\u2026" });
|
|
17
|
+
if (notInstalled) {
|
|
18
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "API Keys" }), _jsxs("p", { className: "text-sm text-gray-500", children: [_jsx("code", { className: "text-xs bg-gray-100 px-1 rounded", children: "hazo_api" }), " is not installed. To enable API key management, install it and configure it in your application."] })] }));
|
|
19
|
+
}
|
|
20
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "API Keys" }), _jsxs("p", { className: "text-sm text-gray-500", children: ["API Keys \u2014 manage application API keys", ' ', _jsxs("span", { className: "text-xs text-gray-400", children: ["(powered by ", _jsx("code", { className: "bg-gray-100 px-1 rounded", children: "hazo_api" }), ")"] })] }), _jsx("div", { className: "mt-4 text-sm text-gray-400 border rounded p-4 bg-gray-50", children: "Panel coming soon." })] }));
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit_panel.d.ts","sourceRoot":"","sources":["../../src/components/audit_panel.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,SAAwB,EAAE,EAAE,eAAe,+BAmCjF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
export function AuditPanel({ basePath: _basePath = '/api/admin' }) {
|
|
5
|
+
const [notInstalled, setNotInstalled] = useState(false);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
import('hazo_audit').catch(() => null).then((pkg) => {
|
|
9
|
+
setNotInstalled(pkg === null);
|
|
10
|
+
setLoading(false);
|
|
11
|
+
});
|
|
12
|
+
}, []);
|
|
13
|
+
if (loading)
|
|
14
|
+
return _jsx("div", { className: "p-6 text-sm text-gray-400", children: "Loading\u2026" });
|
|
15
|
+
if (notInstalled) {
|
|
16
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Audit Log" }), _jsxs("p", { className: "text-sm text-gray-500", children: [_jsx("code", { className: "text-xs bg-gray-100 px-1 rounded", children: "hazo_audit" }), " is not installed. To enable audit logging, install it and configure it in your application."] })] }));
|
|
17
|
+
}
|
|
18
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Audit Log" }), _jsxs("p", { className: "text-sm text-gray-500", children: ["Audit log \u2014 view field-level audit events", ' ', _jsxs("span", { className: "text-xs text-gray-400", children: ["(powered by ", _jsx("code", { className: "bg-gray-100 px-1 rounded", children: "hazo_audit" }), ")"] })] }), _jsx("div", { className: "mt-4 text-sm text-gray-400 border rounded p-4 bg-gray-50", children: "Panel coming soon." })] }));
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blog_panel.d.ts","sourceRoot":"","sources":["../../src/components/blog_panel.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAwB,EAAE,EAAE,cAAc,+BAuC/E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
export function BlogPanel({ basePath: _basePath = '/api/admin' }) {
|
|
5
|
+
const [notInstalled, setNotInstalled] = useState(false);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
// Probe the CLIENT entry, not the default `hazo_blog` entry. The default is
|
|
9
|
+
// server-only; importing it from this 'use client' component would drag
|
|
10
|
+
// server-only code into the browser bundle and crash the route with
|
|
11
|
+
// "react-dom/server is not supported in React Server Components".
|
|
12
|
+
import('hazo_blog/client').catch(() => null).then((pkg) => {
|
|
13
|
+
setNotInstalled(pkg === null);
|
|
14
|
+
setLoading(false);
|
|
15
|
+
});
|
|
16
|
+
}, []);
|
|
17
|
+
if (loading)
|
|
18
|
+
return _jsx("div", { className: "p-6 text-sm text-gray-400", children: "Loading\u2026" });
|
|
19
|
+
if (notInstalled) {
|
|
20
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Blog" }), _jsxs("p", { className: "text-sm text-gray-500", children: [_jsx("code", { className: "text-xs bg-gray-100 px-1 rounded", children: "hazo_blog" }), " is not installed. To enable blog management, install it and configure it in your application."] })] }));
|
|
21
|
+
}
|
|
22
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Blog" }), _jsxs("p", { className: "text-sm text-gray-500", children: ["Blog \u2014 manage posts, categories, and tags", ' ', _jsxs("span", { className: "text-xs text-gray-400", children: ["(powered by ", _jsx("code", { className: "bg-gray-100 px-1 rounded", children: "hazo_blog" }), ")"] })] }), _jsx("div", { className: "mt-4 text-sm text-gray-400 border rounded p-4 bg-gray-50", children: "Panel coming soon." })] }));
|
|
23
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env_migration_panel.d.ts","sourceRoot":"","sources":["../../src/components/env_migration_panel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"env_migration_panel.d.ts","sourceRoot":"","sources":["../../src/components/env_migration_panel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAkDD,wBAAgB,iBAAiB,CAAC,EAAE,QAAuB,EAAE,EAAE,sBAAsB,qBA+dpF"}
|
|
@@ -15,7 +15,6 @@ function normalizeResult(result) {
|
|
|
15
15
|
}
|
|
16
16
|
return result;
|
|
17
17
|
}
|
|
18
|
-
const PROD_ROLES = ['prod', 'production'];
|
|
19
18
|
export function EnvMigrationPanel({ basePath = '/api/admin' }) {
|
|
20
19
|
// Env list
|
|
21
20
|
const [envs, setEnvs] = useState([]);
|
|
@@ -52,9 +51,9 @@ export function EnvMigrationPanel({ basePath = '/api/admin' }) {
|
|
|
52
51
|
if (Array.isArray(data)) {
|
|
53
52
|
setEnvs(data);
|
|
54
53
|
if (data.length > 0)
|
|
55
|
-
setFrom(data[0]);
|
|
54
|
+
setFrom(data[0].name);
|
|
56
55
|
if (data.length > 1)
|
|
57
|
-
setTo(data[1]);
|
|
56
|
+
setTo(data[1].name);
|
|
58
57
|
}
|
|
59
58
|
else {
|
|
60
59
|
setEnvsError('Failed to parse env list');
|
|
@@ -122,8 +121,7 @@ export function EnvMigrationPanel({ basePath = '/api/admin' }) {
|
|
|
122
121
|
setJob(null);
|
|
123
122
|
setRestoreMsg(null);
|
|
124
123
|
setDetailsOpen(true);
|
|
125
|
-
|
|
126
|
-
if (isProd && prodConfirm !== to)
|
|
124
|
+
if (isProdTarget && prodConfirm !== to)
|
|
127
125
|
return;
|
|
128
126
|
const payload = {
|
|
129
127
|
from,
|
|
@@ -135,7 +133,7 @@ export function EnvMigrationPanel({ basePath = '/api/admin' }) {
|
|
|
135
133
|
tables,
|
|
136
134
|
dryRun,
|
|
137
135
|
};
|
|
138
|
-
if (
|
|
136
|
+
if (isProdTarget) {
|
|
139
137
|
payload.allowProdTarget = true;
|
|
140
138
|
payload.confirmToken = prodConfirm;
|
|
141
139
|
}
|
|
@@ -181,10 +179,10 @@ export function EnvMigrationPanel({ basePath = '/api/admin' }) {
|
|
|
181
179
|
setRestoreMsg(`Restore failed: ${err instanceof Error ? err.message : 'Network error'}`);
|
|
182
180
|
}
|
|
183
181
|
}
|
|
184
|
-
const isProdTarget =
|
|
182
|
+
const isProdTarget = envs.find(e => e.name === to)?.role === 'production';
|
|
185
183
|
const prodConfirmValid = !isProdTarget || prodConfirm === to;
|
|
186
184
|
const canRun = !running && prodConfirmValid && !!from && !!to && from !== to;
|
|
187
|
-
return (_jsxs("div", { className: "p-6 max-w-2xl space-y-6", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800", children: "Env Migration" }), envsError && (_jsx("div", { className: "text-sm text-red-500", children: envsError })), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [_jsxs("div", { className: "flex gap-4", children: [_jsxs("div", { className: "flex-1", children: [_jsx("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "From" }), _jsx("select", { value: from, onChange: e => setFrom(e.target.value), className: "w-full border border-gray-300 rounded px-2 py-1.5 text-sm", disabled: running, children: envs.map(env => (
|
|
185
|
+
return (_jsxs("div", { className: "p-6 max-w-2xl space-y-6", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800", children: "Env Migration" }), envsError && (_jsx("div", { className: "text-sm text-red-500", children: envsError })), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [_jsxs("div", { className: "flex gap-4", children: [_jsxs("div", { className: "flex-1", children: [_jsx("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "From" }), _jsx("select", { value: from, onChange: e => setFrom(e.target.value), className: "w-full border border-gray-300 rounded px-2 py-1.5 text-sm", disabled: running, children: envs.map(env => (_jsxs("option", { value: env.name, children: [env.name, " ", env.role !== 'production' ? `(${env.role})` : '(PRODUCTION)'] }, env.name))) })] }), _jsxs("div", { className: "flex-1", children: [_jsx("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "To" }), _jsx("select", { value: to, onChange: e => { setTo(e.target.value); setProdConfirm(''); }, className: "w-full border border-gray-300 rounded px-2 py-1.5 text-sm", disabled: running, children: envs.map(env => (_jsxs("option", { value: env.name, children: [env.name, " ", env.role !== 'production' ? `(${env.role})` : '(PRODUCTION)'] }, env.name))) })] })] }), _jsxs("div", { className: "flex gap-6", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm text-gray-700", children: [_jsx("input", { type: "checkbox", checked: includeDb, onChange: e => setIncludeDb(e.target.checked), disabled: running }), "Include DB"] }), _jsxs("label", { className: "flex items-center gap-2 text-sm text-gray-700", children: [_jsx("input", { type: "checkbox", checked: includeFiles, onChange: e => setIncludeFiles(e.target.checked), disabled: running }), "Include Files"] }), _jsxs("label", { className: "flex items-center gap-2 text-sm text-gray-700", children: [_jsx("input", { type: "checkbox", checked: dryRun, onChange: e => setDryRun(e.target.checked), disabled: running }), "Dry run"] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Transport" }), _jsxs("select", { value: transport, onChange: e => setTransport(e.target.value), className: "border border-gray-300 rounded px-2 py-1.5 text-sm", disabled: running, children: [_jsx("option", { value: "auto", children: "auto" }), _jsx("option", { value: "local", children: "local" }), _jsx("option", { value: "api", children: "api" }), _jsx("option", { value: "ssh", disabled: true, children: "ssh (coming soon)" })] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Scrub (PII masking)" }), _jsxs("select", { value: scrub, onChange: e => setScrub(e.target.value), className: "border border-gray-300 rounded px-2 py-1.5 text-sm", disabled: running, children: [_jsx("option", { value: "none", children: "none" }), _jsx("option", { value: "auto", children: "auto" })] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Tables (glob, * = all)" }), _jsx("input", { type: "text", value: tables, onChange: e => setTables(e.target.value), className: "w-full border border-gray-300 rounded px-2 py-1.5 text-sm", disabled: running })] }), isProdTarget && (_jsxs("div", { className: "border border-red-300 rounded p-3 space-y-2 bg-red-50", children: [_jsx("div", { className: "text-sm font-medium text-red-700", children: "Warning: you are targeting a production environment." }), _jsxs("label", { className: "block text-xs font-medium text-red-600 mb-1", children: ["Type ", _jsx("code", { className: "font-mono bg-red-100 px-1 rounded", children: to }), " to confirm"] }), _jsx("input", { type: "text", value: prodConfirm, onChange: e => setProdConfirm(e.target.value), placeholder: to, className: "w-full border border-red-300 rounded px-2 py-1.5 text-sm", disabled: running })] })), _jsx("div", { children: _jsx("button", { type: "submit", disabled: !canRun, className: "px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed", children: running ? 'Running…' : dryRun ? 'Run dry run' : 'Run migration' }) })] }), running && progress && (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "text-xs text-gray-500 uppercase tracking-wide font-medium", children: "Progress" }), _jsxs("div", { className: "text-sm text-gray-700", children: [progress.phase, ": ", progress.message] }), _jsx("div", { className: "w-full bg-gray-200 rounded h-2", children: _jsx("div", { className: "bg-blue-500 h-2 rounded transition-all", style: { width: `${Math.max(0, Math.min(100, progress.percent))}%` } }) }), _jsxs("div", { className: "text-xs text-gray-500", children: [progress.percent, "%"] })] })), submitError && (_jsx("div", { className: "text-sm text-red-600 border border-red-200 rounded p-3 bg-red-50", children: submitError })), job?.status === 'completed' && (() => {
|
|
188
186
|
const result = normalizeResult(job.result);
|
|
189
187
|
const db = result?.db;
|
|
190
188
|
const files = result?.files;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback_panel.d.ts","sourceRoot":"","sources":["../../src/components/feedback_panel.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAwB,EAAE,EAAE,kBAAkB,+BAwCvF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
export function FeedbackPanel({ basePath: _basePath = '/api/admin' }) {
|
|
5
|
+
const [notInstalled, setNotInstalled] = useState(false);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
// Probe the CLIENT entry, not the default `hazo_feedback` entry. The default
|
|
9
|
+
// is server-only (`import 'server-only'` + the server factory → hazo_auth's
|
|
10
|
+
// next/headers chain); importing it from this 'use client' component drags
|
|
11
|
+
// server-only code into the browser bundle and crashes the whole route with
|
|
12
|
+
// "react-dom/server is not supported in React Server Components".
|
|
13
|
+
import('hazo_feedback/client').catch(() => null).then((pkg) => {
|
|
14
|
+
setNotInstalled(pkg === null);
|
|
15
|
+
setLoading(false);
|
|
16
|
+
});
|
|
17
|
+
}, []);
|
|
18
|
+
if (loading)
|
|
19
|
+
return _jsx("div", { className: "p-6 text-sm text-gray-400", children: "Loading\u2026" });
|
|
20
|
+
if (notInstalled) {
|
|
21
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Feedback" }), _jsxs("p", { className: "text-sm text-gray-500", children: [_jsx("code", { className: "text-xs bg-gray-100 px-1 rounded", children: "hazo_feedback" }), " is not installed. To enable feedback review, install it and configure it in your application."] })] }));
|
|
22
|
+
}
|
|
23
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Feedback" }), _jsxs("p", { className: "text-sm text-gray-500", children: ["Feedback \u2014 review in-app feedback submissions", ' ', _jsxs("span", { className: "text-xs text-gray-400", children: ["(powered by ", _jsx("code", { className: "bg-gray-100 px-1 rounded", children: "hazo_feedback" }), ")"] })] }), _jsx("div", { className: "mt-4 text-sm text-gray-400 border rounded p-4 bg-gray-50", children: "Panel coming soon." })] }));
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files_panel.d.ts","sourceRoot":"","sources":["../../src/components/files_panel.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,SAAwB,EAAE,EAAE,eAAe,+BAsCjF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
export function FilesPanel({ basePath: _basePath = '/api/admin' }) {
|
|
5
|
+
const [notInstalled, setNotInstalled] = useState(false);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
// Probe the client-safe UI entry — the default `hazo_files` entry pulls
|
|
9
|
+
// googleapis / google-auth-library (Node-only) into this 'use client'
|
|
10
|
+
// component's browser bundle, which crashes the route.
|
|
11
|
+
import('hazo_files/ui').catch(() => null).then((pkg) => {
|
|
12
|
+
setNotInstalled(pkg === null);
|
|
13
|
+
setLoading(false);
|
|
14
|
+
});
|
|
15
|
+
}, []);
|
|
16
|
+
if (loading)
|
|
17
|
+
return _jsx("div", { className: "p-6 text-sm text-gray-400", children: "Loading\u2026" });
|
|
18
|
+
if (notInstalled) {
|
|
19
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Files" }), _jsxs("p", { className: "text-sm text-gray-500", children: [_jsx("code", { className: "text-xs bg-gray-100 px-1 rounded", children: "hazo_files" }), " is not installed. To enable file management, install it and configure it in your application."] })] }));
|
|
20
|
+
}
|
|
21
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Files" }), _jsxs("p", { className: "text-sm text-gray-500", children: ["Files \u2014 browse and manage uploaded files", ' ', _jsxs("span", { className: "text-xs text-gray-400", children: ["(powered by ", _jsx("code", { className: "bg-gray-100 px-1 rounded", children: "hazo_files" }), ")"] })] }), _jsx("div", { className: "mt-4 text-sm text-gray-400 border rounded p-4 bg-gray-50", children: "Panel coming soon." })] }));
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masking_panel.d.ts","sourceRoot":"","sources":["../../src/components/masking_panel.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AASD,wBAAgB,iBAAiB,CAAC,EAAE,QAAuB,EAAE,EAAE,sBAAsB,sCA+GpF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
export function MaskingRulesPanel({ basePath = '/api/admin' }) {
|
|
5
|
+
const [rules, setRules] = useState(null);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const [loading, setLoading] = useState(true);
|
|
8
|
+
const [seeding, setSeeding] = useState(false);
|
|
9
|
+
const [seedMessage, setSeedMessage] = useState(null);
|
|
10
|
+
const [seedError, setSeedError] = useState(false);
|
|
11
|
+
function fetchRules() {
|
|
12
|
+
setLoading(true);
|
|
13
|
+
setError(null);
|
|
14
|
+
fetch(`${basePath}/mask/rules`, { credentials: 'include' })
|
|
15
|
+
.then(async (r) => {
|
|
16
|
+
if (r.status === 503) {
|
|
17
|
+
const body = await r.json().catch(() => ({}));
|
|
18
|
+
throw new Error(body?.error?.reason ?? 'hazo_env not installed');
|
|
19
|
+
}
|
|
20
|
+
if (!r.ok)
|
|
21
|
+
throw new Error(`Failed to load masking rules (${r.status})`);
|
|
22
|
+
return r.json();
|
|
23
|
+
})
|
|
24
|
+
.then(setRules)
|
|
25
|
+
.catch((e) => setError(e instanceof Error ? e.message : 'Failed to load masking rules'))
|
|
26
|
+
.finally(() => setLoading(false));
|
|
27
|
+
}
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
fetchRules();
|
|
30
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
31
|
+
}, [basePath]);
|
|
32
|
+
async function handleSeedFromIni() {
|
|
33
|
+
setSeeding(true);
|
|
34
|
+
setSeedMessage(null);
|
|
35
|
+
try {
|
|
36
|
+
const r = await fetch(`${basePath}/mask/seed-from-ini`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
credentials: 'include',
|
|
39
|
+
});
|
|
40
|
+
if (!r.ok) {
|
|
41
|
+
const body = await r.json().catch(() => ({}));
|
|
42
|
+
throw new Error(body?.error?.reason ?? `Seed failed (${r.status})`);
|
|
43
|
+
}
|
|
44
|
+
setSeedMessage('Rules seeded successfully.');
|
|
45
|
+
setSeedError(false);
|
|
46
|
+
fetchRules();
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
setSeedMessage(e instanceof Error ? e.message : 'Seed failed');
|
|
50
|
+
setSeedError(true);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
setSeeding(false);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (loading)
|
|
57
|
+
return _jsx("div", { className: "p-6 text-sm text-gray-400", children: "Loading masking rules\u2026" });
|
|
58
|
+
if (error)
|
|
59
|
+
return _jsx("div", { className: "p-6 text-sm text-gray-500", children: error });
|
|
60
|
+
if (!rules)
|
|
61
|
+
return null;
|
|
62
|
+
return (_jsxs("div", { className: "p-6 max-w-3xl", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800", children: "Masking Rules" }), _jsx("button", { onClick: handleSeedFromIni, disabled: seeding, className: "px-3 py-1.5 text-sm font-medium rounded border border-gray-300 bg-white hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed", children: seeding ? 'Seeding…' : 'Seed from INI' })] }), seedMessage && (_jsx("div", { className: `mb-4 text-sm border rounded p-2 ${seedError
|
|
63
|
+
? 'bg-destructive/10 text-destructive'
|
|
64
|
+
: 'bg-green-50 text-green-800'}`, children: seedMessage })), rules.length === 0 ? (_jsxs("div", { className: "text-sm text-gray-500", children: ["No masking rules configured. Use \"Seed from INI\" to load rules from", ' ', _jsx("code", { className: "text-xs bg-gray-100 px-1 rounded", children: "hazo_env_masking.ini" }), "."] })) : (_jsx("div", { className: "border rounded overflow-hidden", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "bg-gray-50 border-b", children: [_jsx("th", { className: "text-left px-4 py-2 font-medium text-gray-700", children: "Table" }), _jsx("th", { className: "text-left px-4 py-2 font-medium text-gray-700", children: "Column" }), _jsx("th", { className: "text-left px-4 py-2 font-medium text-gray-700", children: "Transform" })] }) }), _jsx("tbody", { children: rules.map((rule, i) => (_jsxs("tr", { className: "border-b last:border-0", children: [_jsx("td", { className: "px-4 py-2 font-mono text-xs text-gray-800", children: rule.table }), _jsx("td", { className: "px-4 py-2 font-mono text-xs text-gray-800", children: rule.column }), _jsx("td", { className: "px-4 py-2 text-gray-600", children: rule.transform })] }, i))) })] }) }))] }));
|
|
65
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings_panel.d.ts","sourceRoot":"","sources":["../../src/components/settings_panel.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAwB,EAAE,EAAE,kBAAkB,+BAmCvF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
export function SettingsPanel({ basePath: _basePath = '/api/admin' }) {
|
|
5
|
+
const [notInstalled, setNotInstalled] = useState(false);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
import('hazo_config').catch(() => null).then((pkg) => {
|
|
9
|
+
setNotInstalled(pkg === null);
|
|
10
|
+
setLoading(false);
|
|
11
|
+
});
|
|
12
|
+
}, []);
|
|
13
|
+
if (loading)
|
|
14
|
+
return _jsx("div", { className: "p-6 text-sm text-gray-400", children: "Loading\u2026" });
|
|
15
|
+
if (notInstalled) {
|
|
16
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Settings" }), _jsxs("p", { className: "text-sm text-gray-500", children: [_jsx("code", { className: "text-xs bg-gray-100 px-1 rounded", children: "hazo_config" }), " is not installed. To enable settings management, install it and configure it in your application."] })] }));
|
|
17
|
+
}
|
|
18
|
+
return (_jsxs("div", { className: "p-6 max-w-xl", children: [_jsx("h2", { className: "text-base font-semibold text-gray-800 mb-2", children: "Settings" }), _jsxs("p", { className: "text-sm text-gray-500", children: ["Settings \u2014 manage configuration keys per environment", ' ', _jsxs("span", { className: "text-xs text-gray-400", children: ["(powered by ", _jsx("code", { className: "bg-gray-100 px-1 rounded", children: "hazo_config" }), ")"] })] }), _jsx("div", { className: "mt-4 text-sm text-gray-400 border rounded p-4 bg-gray-50", children: "Panel coming soon." })] }));
|
|
19
|
+
}
|
package/dist/index.client.d.ts
CHANGED
|
@@ -2,6 +2,14 @@ export declare const HAZO_ADMIN_PERMISSIONS: {
|
|
|
2
2
|
readonly ADMIN_SYSTEM: "admin_system";
|
|
3
3
|
readonly ENV_MIGRATE: "env.migrate";
|
|
4
4
|
readonly ENV_MASK_MANAGE: "env.mask.manage";
|
|
5
|
+
readonly AUDIT_READ: "audit.read";
|
|
6
|
+
readonly SETTINGS_MANAGE: "admin.settings.manage";
|
|
7
|
+
readonly APIKEYS_MANAGE: "admin.apikeys.manage";
|
|
8
|
+
readonly BLOG_MANAGE: "admin.blog.manage";
|
|
9
|
+
readonly FILES_MANAGE: "admin.files.manage";
|
|
10
|
+
readonly FEEDBACK_REVIEW: "admin.feedback.review";
|
|
11
|
+
readonly METRICS_VIEW: "metrics.view";
|
|
12
|
+
readonly METRICS_MANAGE: "metrics.manage";
|
|
5
13
|
};
|
|
6
14
|
export type HazoAdminPermissionKey = keyof typeof HAZO_ADMIN_PERMISSIONS;
|
|
7
15
|
export type HazoAdminPermission = (typeof HAZO_ADMIN_PERMISSIONS)[HazoAdminPermissionKey];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB
|
|
1
|
+
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB;;;;;;;;;;;;CAYzB,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,MAAM,OAAO,sBAAsB,CAAC;AACzE,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,sBAAsB,CAAC,CAAC"}
|
package/dist/index.client.js
CHANGED
|
@@ -2,4 +2,12 @@ export const HAZO_ADMIN_PERMISSIONS = {
|
|
|
2
2
|
ADMIN_SYSTEM: 'admin_system',
|
|
3
3
|
ENV_MIGRATE: 'env.migrate',
|
|
4
4
|
ENV_MASK_MANAGE: 'env.mask.manage',
|
|
5
|
+
AUDIT_READ: 'audit.read',
|
|
6
|
+
SETTINGS_MANAGE: 'admin.settings.manage',
|
|
7
|
+
APIKEYS_MANAGE: 'admin.apikeys.manage',
|
|
8
|
+
BLOG_MANAGE: 'admin.blog.manage',
|
|
9
|
+
FILES_MANAGE: 'admin.files.manage',
|
|
10
|
+
FEEDBACK_REVIEW: 'admin.feedback.review',
|
|
11
|
+
METRICS_VIEW: 'metrics.view',
|
|
12
|
+
METRICS_MANAGE: 'metrics.manage',
|
|
5
13
|
};
|
package/dist/index.ui.d.ts
CHANGED
|
@@ -14,4 +14,6 @@ export { HealthPanel } from './components/health_panel.js';
|
|
|
14
14
|
export type { HealthPanelProps } from './components/health_panel.js';
|
|
15
15
|
export type { AdminManifest, AdminNavSection, AdminNavItem } from './components/admin_nav.js';
|
|
16
16
|
export { resolveNav } from './components/admin_nav.js';
|
|
17
|
+
export type { AdminKindDef } from './components/admin_kinds.js';
|
|
18
|
+
export { ADMIN_KINDS, getKindDef, getDefaultPermission, getDefaultIcon } from './components/admin_kinds.js';
|
|
17
19
|
//# sourceMappingURL=index.ui.d.ts.map
|
package/dist/index.ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.ui.d.ts","sourceRoot":"","sources":["../src/index.ui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,YAAY,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.ui.d.ts","sourceRoot":"","sources":["../src/index.ui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,YAAY,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/index.ui.js
CHANGED
|
@@ -7,3 +7,4 @@ export { LogsPanel } from './components/logs_panel.js';
|
|
|
7
7
|
export { EnvMigrationPanel } from './components/env_migration_panel.js';
|
|
8
8
|
export { HealthPanel } from './components/health_panel.js';
|
|
9
9
|
export { resolveNav } from './components/admin_nav.js';
|
|
10
|
+
export { ADMIN_KINDS, getKindDef, getDefaultPermission, getDefaultIcon } from './components/admin_kinds.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page_factory.d.ts","sourceRoot":"","sources":["../../src/preset/page_factory.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"page_factory.d.ts","sourceRoot":"","sources":["../../src/preset/page_factory.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGhE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAK/D,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,GAAG;IACpF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;CAC3C,CAAC;AAoBF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,qBAAqB,IACxD,YAAY;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,0CAgDhF"}
|