@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.
- package/lib/cjs/constants/new-block-template/index.tsx +13 -4
- package/lib/cjs/middlewares/init-block-studio-router.js +194 -0
- package/lib/cjs/plugins/_theme.js +536 -3
- package/lib/cjs/plugins/vite-plugin-block-studio.js +2 -2
- package/lib/cjs/tsconfig.tsbuildinfo +1 -1
- package/lib/cjs/types/properties.js +2 -0
- package/lib/cjs/utils/block-props-utils.js +151 -0
- package/lib/cjs/utils/generate-wrapper-code.js +127 -345
- package/lib/cjs/utils/ts-morph-utils.js +255 -0
- package/lib/cjs/utils/zod-utils.js +314 -0
- package/lib/esm/constants/new-block-template/index.tsx +13 -4
- package/lib/esm/middlewares/init-block-studio-router.js +161 -0
- package/lib/esm/plugins/_theme.js +501 -3
- package/lib/esm/plugins/vite-plugin-block-studio.js +2 -2
- package/lib/esm/tsconfig.tsbuildinfo +1 -1
- package/lib/esm/types/properties.js +1 -0
- package/lib/esm/utils/block-props-utils.js +114 -0
- package/lib/esm/utils/generate-wrapper-code.js +123 -345
- package/lib/esm/utils/ts-morph-utils.js +217 -0
- package/lib/esm/utils/zod-utils.js +269 -0
- package/lib/types/constants/new-block-template/index.d.ts +13 -6
- package/lib/types/plugins/_theme.d.ts +5 -1
- package/lib/types/tsconfig.tsbuildinfo +1 -1
- package/lib/types/types/properties.d.ts +17 -0
- package/lib/types/utils/block-props-utils.d.ts +103 -0
- package/lib/types/utils/generate-wrapper-code.d.ts +24 -0
- package/lib/types/utils/ts-morph-utils.d.ts +24 -0
- package/lib/types/utils/zod-utils.d.ts +67 -0
- package/package.json +20 -4
|
@@ -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
|
-
|
|
6
|
-
|
|
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
|
-
|
|
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',
|