@blocklet/pages-kit-block-studio 0.4.64 → 0.4.66

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.
@@ -1,7 +1,540 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
2
38
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = Theme;
4
39
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- function Theme() {
6
- return (0, jsx_runtime_1.jsx)("div", { children: "Theme" });
40
+ /* eslint-disable */
41
+ // @ts-nocheck
42
+ const Session_1 = require("@arcblock/did-connect/lib/Session");
43
+ const context_1 = require("@arcblock/ux/lib/Locale/context");
44
+ const Toast_1 = __importStar(require("@arcblock/ux/lib/Toast"));
45
+ const js_sdk_1 = require("@blocklet/js-sdk");
46
+ // @ts-ignore
47
+ const theme_1 = require("@blocklet/pages-kit-inner-components/theme");
48
+ // @ts-ignore
49
+ const components_1 = require("@blocklet/pages-kit-runtime/components");
50
+ // @ts-ignore
51
+ const locales_1 = require("@blocklet/pages-kit-runtime/locales");
52
+ const components_2 = require("@blocklet/pages-kit/components");
53
+ // @ts-ignore
54
+ const studio_ui_1 = require("@blocklet/studio-ui");
55
+ const ui_react_1 = require("@blocklet/ui-react");
56
+ const Add_1 = __importDefault(require("@mui/icons-material/Add"));
57
+ const material_1 = require("@mui/material");
58
+ const ahooks_1 = require("ahooks");
59
+ const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
60
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
61
+ const react_1 = require("react");
62
+ const react_dnd_1 = require("react-dnd");
63
+ const react_dnd_html5_backend_1 = require("react-dnd-html5-backend");
64
+ const react_router_dom_1 = require("react-router-dom");
65
+ const ufo_1 = require("ufo");
66
+ // eslint-disable-next-line import/no-extraneous-dependencies
67
+ const client_1 = require("vite-plugin-react-pages/client");
68
+ // @ts-ignore
69
+ const basename = window.blocklet?.prefix || '/';
70
+ const PAGES_KIT_BLOCK_STUDIO_BLOCKLET_DID = 'z2qa7rr3eUyVnWp2PCxEVARuUfLFh6cE5V2xV';
71
+ const api = (0, js_sdk_1.createAxios)({
72
+ timeout: 200000,
73
+ }, {
74
+ componentDid: PAGES_KIT_BLOCK_STUDIO_BLOCKLET_DID,
75
+ });
76
+ const { SessionProvider, SessionContext, SessionConsumer, withSession } = (0, Session_1.createAuthServiceSessionContext)();
77
+ const LEFT_DRAWER_WIDTH = 200;
78
+ const RIGHT_DRAWER_WIDTH = 300;
79
+ const ComparisonPreviewDialog = ({ open, title, leftTitle, leftContent, rightTitle, rightContent, description = '确认后将更新配置。', loading, onConfirm, onClose, }) => {
80
+ const handleConfirm = async () => {
81
+ try {
82
+ await onConfirm();
83
+ }
84
+ catch (error) {
85
+ console.error('执行操作失败:', error);
86
+ Toast_1.default.error('执行操作失败');
87
+ }
88
+ };
89
+ return ((0, jsx_runtime_1.jsxs)(material_1.Dialog, { open: open, onClose: onClose, maxWidth: "md", fullWidth: true, children: [(0, jsx_runtime_1.jsx)(material_1.DialogTitle, { children: title }), (0, jsx_runtime_1.jsx)(material_1.DialogContent, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', flexDirection: 'row', mb: 2 }, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { flex: 1, mr: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", sx: { mb: 1 }, children: leftTitle }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, fullWidth: true, rows: 10, InputProps: {
90
+ readOnly: true,
91
+ }, value: leftContent, sx: {
92
+ '& .MuiOutlinedInput-root': {
93
+ fontFamily: 'monospace',
94
+ fontSize: '0.875rem',
95
+ },
96
+ } })] }), (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { flex: 1, ml: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", sx: { mb: 1 }, children: rightTitle }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, fullWidth: true, rows: 10, InputProps: {
97
+ readOnly: true,
98
+ }, value: rightContent, sx: {
99
+ '& .MuiOutlinedInput-root': {
100
+ fontFamily: 'monospace',
101
+ fontSize: '0.875rem',
102
+ },
103
+ } })] })] }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", sx: { mt: 2, color: 'text.secondary' }, children: description })] }) }), (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', justifyContent: 'flex-end', p: 2 }, children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", onClick: onClose, sx: { mr: 1 }, children: "\u53D6\u6D88" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: handleConfirm, disabled: loading, children: loading ? (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 24 }) : '确认更新' })] })] }));
104
+ };
105
+ function Layout({ loadState, loadedData }) {
106
+ const state = (0, ahooks_1.useReactive)({
107
+ injectBlocks: [],
108
+ selectingParam: null,
109
+ componentSelectOpen: false,
110
+ createResourceOpen: false,
111
+ createBlockOpen: false,
112
+ metadata: {
113
+ id: '',
114
+ createdAt: '',
115
+ updatedAt: '',
116
+ },
117
+ data: {},
118
+ allBlocks: {},
119
+ searchValue: '',
120
+ newBlockParams: {
121
+ name: '',
122
+ description: '',
123
+ },
124
+ previewDialog: {
125
+ open: false,
126
+ title: '',
127
+ leftTitle: '',
128
+ leftContent: '',
129
+ rightTitle: '',
130
+ rightContent: '',
131
+ description: '',
132
+ loading: false,
133
+ onConfirm: async () => { },
134
+ },
135
+ });
136
+ const { locale } = (0, context_1.useLocaleContext)();
137
+ const location = (0, react_router_dom_1.useLocation)();
138
+ const navigate = (0, react_router_dom_1.useNavigate)();
139
+ const staticData = (0, client_1.useStaticData)();
140
+ const { routes, firstRoute, currentPage } = (0, react_1.useMemo)(() => {
141
+ const routes = Object.keys(staticData).sort((a, b) => a.localeCompare(b));
142
+ return {
143
+ routes,
144
+ firstRoute: routes.find((route) => route !== '404' && route !== '*'),
145
+ currentPage: {
146
+ ...staticData[location.pathname]?.main,
147
+ pageId: location.pathname,
148
+ },
149
+ };
150
+ }, [staticData, location.pathname]);
151
+ const getStaticData = (0, react_1.useCallback)(() => {
152
+ return staticData[location.pathname]?.main || {};
153
+ }, [staticData, location.pathname]);
154
+ const getBlockMetadata = async (metadataPath) => {
155
+ if (!metadataPath)
156
+ return {};
157
+ const response = await api.get(`/api/blocks?path=${encodeURIComponent(metadataPath)}`);
158
+ return response.data || {};
159
+ };
160
+ const getAllBlocks = async () => {
161
+ const response = await api.get('/api/blocks/all');
162
+ return response.data || [];
163
+ };
164
+ const debouncedUpdateMetadata = (0, ahooks_1.useDebounceFn)(async (metadata) => {
165
+ const { metadataPath } = getStaticData() || {};
166
+ if (metadataPath) {
167
+ try {
168
+ const metdadataWithoutRenderer = (0, cloneDeep_1.default)(metadata);
169
+ delete metdadataWithoutRenderer.renderer;
170
+ await api.post('/api/blocks', {
171
+ path: metadataPath,
172
+ content: metdadataWithoutRenderer,
173
+ });
174
+ }
175
+ catch (error) {
176
+ console.error('Failed to write metadata:', error);
177
+ }
178
+ }
179
+ }, { wait: 500 });
180
+ (0, react_1.useEffect)(() => {
181
+ debouncedUpdateMetadata.run(state.metadata);
182
+ }, [state.metadata, debouncedUpdateMetadata]);
183
+ (0, react_1.useEffect)(() => {
184
+ if (currentPage && state.injectBlocks.length === 0) {
185
+ state.injectBlocks.push({
186
+ ...currentPage,
187
+ level: 0,
188
+ });
189
+ }
190
+ }, [currentPage]);
191
+ // Add new effect to fetch metadata when page changes
192
+ (0, react_1.useEffect)(() => {
193
+ const fetchMetadata = async () => {
194
+ const { metadataPath, code } = getStaticData() || {};
195
+ if (metadataPath) {
196
+ try {
197
+ const metadata = await getBlockMetadata(metadataPath);
198
+ state.metadata = {
199
+ ...metadata,
200
+ renderer: {
201
+ script: code,
202
+ type: 'react-component',
203
+ },
204
+ };
205
+ }
206
+ catch (error) {
207
+ console.error('Failed to fetch metadata:', error);
208
+ }
209
+ }
210
+ };
211
+ const fetchAllBlocks = async () => {
212
+ const allBlocks = await getAllBlocks();
213
+ state.allBlocks = allBlocks;
214
+ };
215
+ fetchMetadata();
216
+ fetchAllBlocks();
217
+ }, [location.pathname]); // 当路由变化时重新获取
218
+ const mergedAllBlocks = (0, react_1.useMemo)(() => {
219
+ // Add all staticData code and importPath mappings
220
+ if (import.meta.env.DEV) {
221
+ const win = window;
222
+ win.__BLOCK_STUDIO__ = win.__BLOCK_STUDIO__ || {};
223
+ win.__BLOCK_STUDIO__.codeImportPathMap = win.__BLOCK_STUDIO__.codeImportPathMap || {};
224
+ Object.entries(staticData).forEach(([_, pageData]) => {
225
+ const { code, importPath } = pageData?.main || {};
226
+ if (code && importPath) {
227
+ win.__BLOCK_STUDIO__.codeImportPathMap[code] = (0, ufo_1.joinURL)(window.blocklet?.prefix, importPath);
228
+ }
229
+ });
230
+ win.__BLOCK_STUDIO__.getCodeImportPath = (code) => {
231
+ return win.__BLOCK_STUDIO__?.codeImportPathMap?.[code];
232
+ };
233
+ }
234
+ return {
235
+ ...state.allBlocks,
236
+ [state.metadata.id]: {
237
+ ...state.allBlocks[state.metadata.id],
238
+ data: state.metadata,
239
+ },
240
+ };
241
+ }, [state.allBlocks, state.metadata, staticData]);
242
+ const onCloseCreateBlock = () => {
243
+ state.createBlockOpen = false;
244
+ state.newBlockParams = {
245
+ name: '',
246
+ description: '',
247
+ };
248
+ };
249
+ const getRenderContent = (0, react_1.useCallback)(() => {
250
+ if (loadState.type === '404') {
251
+ return null;
252
+ }
253
+ if (['load-error', 'loading'].includes(loadState.type)) {
254
+ return ((0, jsx_runtime_1.jsx)(material_1.Box, { width: "100%", height: "100%", display: "flex", justifyContent: "center", alignItems: "center", children: loadState.type === 'load-error' ? ((0, jsx_runtime_1.jsx)(material_1.Alert, { severity: "error", variant: "filled", children: "Failed to load component code" })) : ((0, jsx_runtime_1.jsx)(material_1.CircularProgress, {})) }));
255
+ }
256
+ // const pageData = loadedData[loadState.routePath];
257
+ // const Component = pageData.main.default;
258
+ // return <Component {...state.data} />;
259
+ return [
260
+ (0, jsx_runtime_1.jsx)(components_2.CustomComponentRenderer, { locale: locale, componentId: state.metadata.id, dev: { mode: 'draft', components: mergedAllBlocks, defaultLocale: 'en' }, props: state.data }, "custom"),
261
+ // <Component key="original" {...state.data} />,
262
+ ];
263
+ }, [loadedData, loadState, locale, state.injectBlocks, state.metadata, mergedAllBlocks]);
264
+ // add auto redirect to first route
265
+ if (loadState.type === '404' &&
266
+ !routes.includes(location.pathname) &&
267
+ !location.search.includes('no-redirect=true')) {
268
+ return (0, jsx_runtime_1.jsx)(react_router_dom_1.Navigate, { to: `${firstRoute ?? '/'}`, replace: true });
269
+ }
270
+ return ((0, jsx_runtime_1.jsx)(material_1.StyledEngineProvider, { injectFirst: true, children: (0, jsx_runtime_1.jsx)(material_1.ThemeProvider, { theme: theme_1.theme, children: (0, jsx_runtime_1.jsx)(SessionProvider, { serviceHost: basename, protectedRoutes: [`${basename}/*`], children: (0, jsx_runtime_1.jsx)(react_dnd_1.DndProvider, { backend: react_dnd_html5_backend_1.HTML5Backend, children: (0, jsx_runtime_1.jsxs)(StyledDashboard, { HeaderProps: {
271
+ // @ts-ignore
272
+ homeLink: (0, ufo_1.joinURL)(basename),
273
+ addons: (addons) => {
274
+ return [
275
+ (0, jsx_runtime_1.jsx)(material_1.Button, { onClick: () => (state.createResourceOpen = true), children: "Create Resource" }, "logout"),
276
+ ...addons,
277
+ ];
278
+ },
279
+ }, MenusDrawerProps: { sx: { [`.${material_1.backdropClasses.root}`]: { top: 64 } } }, children: [(0, jsx_runtime_1.jsxs)(material_1.Drawer, { variant: "permanent", sx: {
280
+ width: LEFT_DRAWER_WIDTH,
281
+ flexShrink: 0,
282
+ zIndex: 1000,
283
+ '& .MuiDrawer-paper': {
284
+ width: LEFT_DRAWER_WIDTH,
285
+ boxSizing: 'border-box',
286
+ position: 'relative',
287
+ height: '100%',
288
+ },
289
+ }, children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, { gap: 1, direction: "row", alignItems: "center", sx: { py: 2, pr: 1, pl: 0.5 }, children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { placeholder: "Search Blocks...", sx: { minWidth: 120 }, onChange: (e) => {
290
+ state.searchValue = e.target.value;
291
+ } }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", sx: { minWidth: 'auto' }, onClick: () => {
292
+ state.createBlockOpen = true;
293
+ }, children: (0, jsx_runtime_1.jsx)(Add_1.default, { fontSize: "small" }) })] }), (0, jsx_runtime_1.jsx)(material_1.List, { sx: { pr: 1, overflowY: 'auto' }, children: routes
294
+ .map((route) => {
295
+ const routeName = route;
296
+ const staticDataInRoute = staticData[route]?.main;
297
+ if (state.searchValue && !routeName?.toLowerCase().includes(state.searchValue?.toLowerCase())) {
298
+ return null;
299
+ }
300
+ return ((0, jsx_runtime_1.jsx)(material_1.ListItem, { disablePadding: true, children: (0, jsx_runtime_1.jsx)(material_1.ListItemButton, { selected: currentPage.pageId === route, onClick: () => {
301
+ navigate(route);
302
+ }, sx: {
303
+ borderRadius: 1,
304
+ mb: 1,
305
+ width: '100%',
306
+ textOverflow: 'ellipsis',
307
+ whiteSpace: 'nowrap',
308
+ overflowX: 'hidden',
309
+ transition: 'all 0.3s ease',
310
+ '&.Mui-selected': {
311
+ backgroundColor: 'primary.main',
312
+ color: 'white',
313
+ '&:hover': {
314
+ backgroundColor: 'primary.main',
315
+ },
316
+ },
317
+ fontSize: '14px',
318
+ }, children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: staticDataInRoute.blockName || routeName, children: (0, jsx_runtime_1.jsx)("div", { style: {
319
+ width: '100%',
320
+ overflow: 'hidden',
321
+ textOverflow: 'ellipsis',
322
+ }, children: staticDataInRoute.blockName || routeName }) }) }) }, route));
323
+ })
324
+ .filter(Boolean) })] }), (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { flex: 1, overflowX: 'hidden', overflowY: getStaticData()?.isHtml ? 'hidden' : 'auto' }, children: (0, jsx_runtime_1.jsx)(material_1.ThemeProvider, { theme: theme_1.pagesTheme, children: (0, jsx_runtime_1.jsx)(react_1.Suspense, { children: getRenderContent() }) }) }), (0, jsx_runtime_1.jsx)(material_1.Drawer, { variant: "permanent", anchor: "right", sx: {
325
+ width: RIGHT_DRAWER_WIDTH,
326
+ flexShrink: 0,
327
+ zIndex: 1000,
328
+ '& .MuiDrawer-paper': {
329
+ width: RIGHT_DRAWER_WIDTH,
330
+ boxSizing: 'border-box',
331
+ position: 'relative',
332
+ height: '100%',
333
+ },
334
+ }, children: (0, jsx_runtime_1.jsxs)(material_1.List, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { width: '100%' }, children: (0, jsx_runtime_1.jsx)(components_1.BasicInfo, { config: state.metadata }) }) }), (0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { width: '100%' }, children: [(0, jsx_runtime_1.jsx)(components_1.PropertiesConfig, { config: state.metadata, currentLocale: locale, defaultLocale: "en", allComponents: mergedAllBlocks, onUpdateConfig: (updater) => {
335
+ updater(state.metadata);
336
+ }, useI18nEditor: false }), (0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "column", spacing: 1, sx: { mt: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", size: "small", color: "primary", onClick: async () => {
337
+ try {
338
+ const { dataPath } = getStaticData() || {};
339
+ if (!dataPath) {
340
+ Toast_1.default.error('无法找到组件路径');
341
+ return;
342
+ }
343
+ Toast_1.default.info('正在分析组件接口...');
344
+ const response = await api.post('/api/blocks/interface-to-properties', {
345
+ componentPath: dataPath,
346
+ });
347
+ if (response.data.success) {
348
+ const { currentProperties, newProperties } = response.data;
349
+ state.previewDialog = {
350
+ open: true,
351
+ title: 'Interface → Properties 预览',
352
+ leftTitle: '当前 Properties',
353
+ leftContent: JSON.stringify(currentProperties, null, 2),
354
+ rightTitle: '新 Properties',
355
+ rightContent: JSON.stringify(newProperties, null, 2),
356
+ description: '确认后将更新metadata文件。这将保留现有配置值,但可能更改属性结构。',
357
+ loading: false,
358
+ onConfirm: async () => {
359
+ state.previewDialog.loading = true;
360
+ try {
361
+ const updateResponse = await api.post('/api/blocks/interface-to-properties', {
362
+ componentPath: dataPath,
363
+ write: true,
364
+ });
365
+ if (updateResponse.data.success) {
366
+ Toast_1.default.success('Metadata生成成功!');
367
+ // 更新当前的metadata状态
368
+ state.metadata = {
369
+ ...updateResponse.data.metadata,
370
+ renderer: state.metadata.renderer,
371
+ };
372
+ state.previewDialog.open = false;
373
+ }
374
+ else {
375
+ throw new Error(updateResponse.data.error || '生成失败');
376
+ }
377
+ }
378
+ finally {
379
+ state.previewDialog.loading = false;
380
+ }
381
+ },
382
+ };
383
+ }
384
+ else {
385
+ Toast_1.default.error(response.data.error || '预览失败');
386
+ }
387
+ }
388
+ catch (error) {
389
+ console.error('生成预览失败:', error);
390
+ Toast_1.default.error('生成预览失败');
391
+ }
392
+ }, children: "Interface \u2192 Properties" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", color: "primary", onClick: async () => {
393
+ try {
394
+ const { dataPath } = getStaticData() || {};
395
+ if (!dataPath) {
396
+ Toast_1.default.error('无法找到组件路径');
397
+ return;
398
+ }
399
+ Toast_1.default.info('正在生成TypeScript接口预览...');
400
+ const response = await api.post('/api/blocks/properties-to-interface', {
401
+ componentPath: dataPath,
402
+ });
403
+ if (response.data.success) {
404
+ const { currentInterface, newInterface } = response.data;
405
+ state.previewDialog = {
406
+ open: true,
407
+ title: 'Properties → Interface 预览',
408
+ leftTitle: '当前接口',
409
+ leftContent: currentInterface,
410
+ rightTitle: '新接口',
411
+ rightContent: newInterface,
412
+ description: '确认后将更新TypeScript接口。这将覆盖当前的接口定义。',
413
+ loading: false,
414
+ onConfirm: async () => {
415
+ state.previewDialog.loading = true;
416
+ try {
417
+ const updateResponse = await api.post('/api/blocks/properties-to-interface', {
418
+ componentPath: dataPath,
419
+ write: true,
420
+ });
421
+ if (updateResponse.data.success) {
422
+ Toast_1.default.success('TypeScript接口生成成功!');
423
+ state.previewDialog.open = false;
424
+ }
425
+ else {
426
+ throw new Error(updateResponse.data.error || '生成失败');
427
+ }
428
+ }
429
+ finally {
430
+ state.previewDialog.loading = false;
431
+ }
432
+ },
433
+ };
434
+ }
435
+ else {
436
+ Toast_1.default.error(response.data.error || '预览失败');
437
+ }
438
+ }
439
+ catch (error) {
440
+ console.error('生成接口预览失败:', error);
441
+ Toast_1.default.error('生成接口预览失败');
442
+ }
443
+ }, children: "Properties \u2192 Interface" })] })] }) }), state.metadata.id && ((0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { width: '100%' }, children: (0, jsx_runtime_1.jsx)(components_1.ParametersConfig, { config: state.metadata, allComponents: mergedAllBlocks, defaultLocale: "en", locale: locale,
444
+ // 不需要 propertiesValue
445
+ // propertiesValue={{}}
446
+ onChange: ({ key, value }) => {
447
+ state.data = {
448
+ ...state.data,
449
+ [key]: value.value,
450
+ };
451
+ }, props: {
452
+ ...state.data,
453
+ } }) }) }))] }) }), (0, jsx_runtime_1.jsx)(CreateResource, { open: state.createResourceOpen, onClose: () => {
454
+ state.createResourceOpen = false;
455
+ } }), (0, jsx_runtime_1.jsxs)(material_1.Dialog, { open: state.createBlockOpen, onClose: onCloseCreateBlock, children: [(0, jsx_runtime_1.jsx)(material_1.DialogTitle, { children: "Create New Block" }), (0, jsx_runtime_1.jsx)(material_1.DialogContent, { children: (0, jsx_runtime_1.jsxs)(material_1.Stack, { spacing: 2, sx: { pt: 1, minWidth: 300 }, children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { autoFocus: true, required: true, label: "Name", fullWidth: true, value: state.newBlockParams.name, onChange: (e) => {
456
+ state.newBlockParams.name = e.target.value.replace(/[^a-zA-Z0-9-]/g, '');
457
+ } }), (0, jsx_runtime_1.jsx)(material_1.TextField, { label: "Description", fullWidth: true, multiline: true, rows: 3, value: state.newBlockParams.description, onChange: (e) => {
458
+ state.newBlockParams.description = e.target.value;
459
+ } }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", fullWidth: true, onClick: async () => {
460
+ if (!state.newBlockParams.name) {
461
+ Toast_1.default.warning('Block name is required');
462
+ return;
463
+ }
464
+ if (routes.some((route) => {
465
+ const staticDataInRoute = staticData[route]?.main;
466
+ return (staticDataInRoute?.blockName?.toLowerCase() === state.newBlockParams.name.toLowerCase());
467
+ })) {
468
+ Toast_1.default.warning('Block name already exists, please change it');
469
+ return;
470
+ }
471
+ try {
472
+ await api.post('/api/blocks/create', state.newBlockParams);
473
+ navigate(`/${state.newBlockParams.name}?no-redirect=true`);
474
+ // wait for the file to be created
475
+ setTimeout(() => {
476
+ window.location.reload();
477
+ }, 100);
478
+ onCloseCreateBlock();
479
+ }
480
+ catch (error) {
481
+ console.error('Failed to create block:', error);
482
+ Toast_1.default.error('Failed to create block');
483
+ }
484
+ }, children: "Create" })] }) })] }), (0, jsx_runtime_1.jsx)(ComparisonPreviewDialog, { open: state.previewDialog.open, title: state.previewDialog.title, leftTitle: state.previewDialog.leftTitle, leftContent: state.previewDialog.leftContent, rightTitle: state.previewDialog.rightTitle, rightContent: state.previewDialog.rightContent, description: state.previewDialog.description, loading: state.previewDialog.loading, onConfirm: state.previewDialog.onConfirm, onClose: () => {
485
+ state.previewDialog.open = false;
486
+ } })] }) }) }) }) }));
487
+ }
488
+ const StyledDashboard = (0, material_1.styled)(studio_ui_1.Dashboard) `
489
+ .dashboard-content {
490
+ display: flex;
491
+ flex-direction: row;
492
+ gap: ${({ theme }) => theme.spacing(1)};
493
+ padding: 0 ${({ theme }) => theme.spacing(1)};
494
+ width: 100vw;
495
+ height: calc(100vh - 64px - 1px);
496
+ }
497
+
498
+ .header-container {
499
+ padding-left: ${({ theme }) => theme.spacing(3)};
500
+ padding-right: ${({ theme }) => theme.spacing(3)};
501
+
502
+ ${({ theme }) => theme.breakpoints.down('md')} {
503
+ padding-left: ${({ theme }) => theme.spacing(2)};
504
+ padding-right: ${({ theme }) => theme.spacing(2)};
505
+
506
+ .header-addons {
507
+ button {
508
+ svg,
509
+ .${material_1.circularProgressClasses.root} {
510
+ font-size: 1.25rem !important;
511
+ width: 1.25rem !important;
512
+ height: 1.25rem !important;
513
+ }
514
+ }
515
+ }
516
+ }
517
+
518
+ .locales {
519
+ border-radius: ${({ theme }) => theme.shape.borderRadius}px;
520
+ box-shadow: ${({ theme }) => theme.shadows[1]};
521
+ margin-top: ${({ theme }) => theme.spacing(1.5)}px;
522
+ }
523
+ }
524
+ `;
525
+ function LayoutWrapper({ loadState, loadedData, ...rest }) {
526
+ return ((0, jsx_runtime_1.jsx)(Toast_1.ToastProvider, { children: (0, jsx_runtime_1.jsx)(context_1.LocaleProvider, { translations: locales_1.translations, fallbackLocale: "en", children: (0, jsx_runtime_1.jsx)(Layout, { loadState: loadState, loadedData: loadedData }) }) }));
527
+ }
528
+ exports.default = LayoutWrapper;
529
+ function CreateResource({ open, onClose }) {
530
+ if (!open) {
531
+ return null;
532
+ }
533
+ const tenantScope = 'pages-kit-block-studio';
534
+ return ((0, jsx_runtime_1.jsx)(react_1.Suspense, { children: (0, jsx_runtime_1.jsx)(ui_react_1.BlockletStudio, { mode: "dialog", tenantScope: tenantScope, title: "Pages Kit Blocks", description: "", note: "", introduction: "", logo: "", componentDid: PAGES_KIT_BLOCK_STUDIO_BLOCKLET_DID,
535
+ // 透传到 get blocklet resource 的参数
536
+ resourcesParams: {}, dependentComponentsMode: "readonly", open: true, setOpen: () => onClose(), onConnected: () => { }, onUploaded: () => { }, onReleased: () => { },
537
+ // onOpened={() => onOpened?.()}
538
+ // 默认选中的资源
539
+ resources: {} }) }));
7
540
  }
@@ -53,8 +53,8 @@ const vite_plugin_node_polyfills_1 = require("vite-plugin-node-polyfills");
53
53
  const vite_plugin_react_pages_1 = __importStar(require("vite-plugin-react-pages"));
54
54
  const helper_1 = require("../utils/helper");
55
55
  const vite_plugin_html_transform_1 = require("./vite-plugin-html-transform");
56
- const BUILTIN_MODULES_VAR = '__PAGES_KIT_BUILTIN_MODULES__';
57
- helper_1.logger.log('BUILTIN_MODULES_VAR', BUILTIN_MODULES_VAR);
56
+ // const BUILTIN_MODULES_VAR = '__PAGES_KIT_BUILTIN_MODULES__';
57
+ // logger.log('BUILTIN_MODULES_VAR', BUILTIN_MODULES_VAR);
58
58
  const defaultBlockExternals = {
59
59
  // 核心 React 相关
60
60
  react: '@blocklet/pages-kit/builtin/react',