@gadmin2n/schematics 0.0.136 → 0.0.137
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.server +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/compose-ctl.sh +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/canvas.prisma +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +14 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/User.ts +4 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/docker-compose.md +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/docker-compose.yml +13 -92
- package/dist/lib/application/files/gadmin2-game-angle-demo/readme.md +105 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/ensure-database.js +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +5 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma.config.ts +9 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/notify-dev-servers.js +9 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/wait-for-nest-ready.js +5 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +43 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +9 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +24 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas-export.dto.ts +27 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas-export.service.spec.ts +430 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas-export.service.ts +203 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.controller.ts +36 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.module.ts +2 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.spec.ts +54 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.ts +245 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.service.spec.ts +366 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.service.ts +110 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +19 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +15 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +79 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +41 -19
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/start-prod.sh +5 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +37 -573
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/ecosystem.dev.config.cjs +12 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +3 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +39 -26
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/i18n.ts +3 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +3 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +3 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx +23 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +66 -10
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +16 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +21 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasApi.ts +30 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/ExportModal.tsx +84 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/ImportModal.tsx +166 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/hooks/useCanvasHistory.ts +52 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.tsx +6 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +6 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +17 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +18 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +225 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/utilities/lazy-with-reload.ts +31 -0
- package/package.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-dsl-validate.spec.ts +0 -220
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-dsl-validate.ts +0 -132
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/TODO.md +0 -152
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/config/development-sql.yaml +0 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/docker-compose.yml +0 -25
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/package.json +0 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.dockerignore +0 -12
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.env +0 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/Dockerfile +0 -79
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/GRACEFUL-DEPLOYMENT.md +0 -270
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/SANDBOX.md +0 -122
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package-lock.json +0 -4285
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package.json +0 -28
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/code-execute.ts +0 -51
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-execute.ts +0 -85
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-query.ts +0 -35
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/http-request.ts +0 -54
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts +0 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/reporting.ts +0 -85
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/send-notification.ts +0 -47
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/config.ts +0 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/condition.ts +0 -101
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/context.ts +0 -58
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/graph.ts +0 -184
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/helpers.ts +0 -133
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/node-types.ts +0 -96
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/types.ts +0 -77
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/validate.ts +0 -109
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/index.ts +0 -101
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/outbox-poller.ts +0 -382
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/activities/code-execute.test.ts +0 -44
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/activities/http-request.test.ts +0 -87
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/cron-trigger-workflow.test.ts +0 -20
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/helpers.test.ts +0 -225
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/node-type-consistency.test.ts +0 -101
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/validate.test.ts +0 -205
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/workflows/dsl-workflow.ts +0 -499
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/tsconfig.json +0 -19
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/vitest.config.ts +0 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/yarn.lock +0 -1905
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// pm2 dev 场景专用配置:直接跑 vite CLI,不套 npm 壳。
|
|
2
2
|
// 由 branch.service.ts 通过 pm2 CLI 传入 PM2_NAME / VITE_PORT / VITE_BRANCH_OWNER 等环境变量。
|
|
3
|
-
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const dotenv = require('dotenv');
|
|
5
|
+
|
|
6
|
+
const baseEnv = dotenv.config({ path: path.join(__dirname, '.env') }).parsed || {};
|
|
7
|
+
const localEnv = dotenv.config({ path: path.join(__dirname, '.env.local') }).parsed || {};
|
|
8
|
+
|
|
4
9
|
module.exports = {
|
|
5
10
|
apps: [
|
|
6
11
|
{
|
|
@@ -13,9 +18,15 @@ module.exports = {
|
|
|
13
18
|
// NODE_OPTIONS 保留原 package.json 里的 4GB 上限设置。
|
|
14
19
|
node_args: '--max-old-space-size=4096',
|
|
15
20
|
env: {
|
|
21
|
+
...baseEnv,
|
|
22
|
+
...localEnv,
|
|
23
|
+
// branch.service.ts 注入的变量优先,覆盖 .env* 里的默认值
|
|
16
24
|
...(process.env.VITE_BRANCH_OWNER
|
|
17
25
|
? { VITE_BRANCH_OWNER: process.env.VITE_BRANCH_OWNER }
|
|
18
26
|
: {}),
|
|
27
|
+
...(process.env.VITE_PORT
|
|
28
|
+
? { VITE_PORT: process.env.VITE_PORT }
|
|
29
|
+
: {}),
|
|
19
30
|
},
|
|
20
31
|
},
|
|
21
32
|
],
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx
CHANGED
|
@@ -14,6 +14,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
14
14
|
import type { MenuProps } from 'antd';
|
|
15
15
|
import { agentAttrs } from 'components/agentPanel/agentAttributes';
|
|
16
16
|
import { HEADER_HEIGHT, Z_INDEX } from 'constants/layout';
|
|
17
|
+
import { SUPPORTED_LANGUAGES } from '../../i18n';
|
|
17
18
|
|
|
18
19
|
type IUser = {
|
|
19
20
|
id: number;
|
|
@@ -37,7 +38,7 @@ export const Header: React.FC = () => {
|
|
|
37
38
|
const langMenu = useMemo<MenuProps>(
|
|
38
39
|
() => ({
|
|
39
40
|
selectedKeys: currentLocale ? [currentLocale] : [],
|
|
40
|
-
items: [...
|
|
41
|
+
items: [...SUPPORTED_LANGUAGES].sort().map((lang: string) => ({
|
|
41
42
|
key: lang,
|
|
42
43
|
icon: (
|
|
43
44
|
<span style={{ marginRight: 8, display: 'inline-flex' }}>
|
|
@@ -48,7 +49,7 @@ export const Header: React.FC = () => {
|
|
|
48
49
|
})),
|
|
49
50
|
onClick: ({ key: lang }) => changeLanguage(lang),
|
|
50
51
|
}),
|
|
51
|
-
[
|
|
52
|
+
[currentLocale, changeLanguage],
|
|
52
53
|
);
|
|
53
54
|
|
|
54
55
|
const currentLanguageLabel = currentLocale === 'en' ? 'English' : '中文';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { Suspense } from 'react';
|
|
2
|
+
import { lazyWithReload } from 'utilities/lazy-with-reload';
|
|
2
3
|
import { Outlet, Route } from 'react-router-dom';
|
|
3
4
|
import { Spin } from 'antd';
|
|
4
5
|
import generatedResources from 'generated/resources';
|
|
@@ -184,7 +185,7 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
184
185
|
// 菜单指引 — sortOrder 1020, code: admin.permission.readme
|
|
185
186
|
permission_readme: {
|
|
186
187
|
path: 'readme',
|
|
187
|
-
component:
|
|
188
|
+
component: lazyWithReload(() =>
|
|
188
189
|
import('routes/permissionReadme').then((m) => ({
|
|
189
190
|
default: m.PermissionReadmePage,
|
|
190
191
|
})),
|
|
@@ -193,14 +194,14 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
193
194
|
// 用户管理 — sortOrder 1030, code: admin.permission.user
|
|
194
195
|
user: {
|
|
195
196
|
path: 'user',
|
|
196
|
-
component:
|
|
197
|
+
component: lazyWithReload(() =>
|
|
197
198
|
import('routes/user').then((m) => ({ default: m.UserListPage })),
|
|
198
199
|
),
|
|
199
200
|
},
|
|
200
201
|
// 角色管理 — sortOrder 1040, code: admin.permission.role
|
|
201
202
|
role: {
|
|
202
203
|
path: 'role-list',
|
|
203
|
-
component:
|
|
204
|
+
component: lazyWithReload(() =>
|
|
204
205
|
import('routes/role').then((m) => ({
|
|
205
206
|
default: m.RoleManagementListPage,
|
|
206
207
|
})),
|
|
@@ -209,7 +210,7 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
209
210
|
// 页面管理 — sortOrder 1050, code: admin.permission.page
|
|
210
211
|
page: {
|
|
211
212
|
path: 'page-list',
|
|
212
|
-
component:
|
|
213
|
+
component: lazyWithReload(() =>
|
|
213
214
|
import('routes/page/list').then((m) => ({
|
|
214
215
|
default: m.PageManagementListPage,
|
|
215
216
|
})),
|
|
@@ -218,7 +219,7 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
218
219
|
// 资源管理 — sortOrder 1060, code: admin.permission.resource
|
|
219
220
|
resource: {
|
|
220
221
|
path: 'resource-list',
|
|
221
|
-
component:
|
|
222
|
+
component: lazyWithReload(() =>
|
|
222
223
|
import('routes/resource').then((m) => ({
|
|
223
224
|
default: m.ResourceManagementListPage,
|
|
224
225
|
})),
|
|
@@ -237,7 +238,7 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
237
238
|
list: {
|
|
238
239
|
path: '',
|
|
239
240
|
index: true,
|
|
240
|
-
component:
|
|
241
|
+
component: lazyWithReload(() =>
|
|
241
242
|
import('routes/canvas').then((m) => ({
|
|
242
243
|
default: m.CanvasListPage,
|
|
243
244
|
})),
|
|
@@ -245,7 +246,7 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
245
246
|
},
|
|
246
247
|
edit: {
|
|
247
248
|
path: 'edit/:id',
|
|
248
|
-
component:
|
|
249
|
+
component: lazyWithReload(() =>
|
|
249
250
|
import('routes/canvas').then((m) => ({
|
|
250
251
|
default: m.CanvasEditPage,
|
|
251
252
|
})),
|
|
@@ -256,7 +257,7 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
256
257
|
// Canvas published pages (dynamic, DB-driven)
|
|
257
258
|
'canvas-page': {
|
|
258
259
|
path: 'p/:slug',
|
|
259
|
-
component:
|
|
260
|
+
component: lazyWithReload(() => import('routes/canvas-page')),
|
|
260
261
|
},
|
|
261
262
|
/*game: {
|
|
262
263
|
path: 'game-list',
|
|
@@ -264,25 +265,25 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
264
265
|
list: {
|
|
265
266
|
path: '',
|
|
266
267
|
index: true,
|
|
267
|
-
component:
|
|
268
|
+
component: lazyWithReload(() =>
|
|
268
269
|
import('routes/game').then((m) => ({ default: m.GameList })),
|
|
269
270
|
),
|
|
270
271
|
},
|
|
271
272
|
show: {
|
|
272
273
|
path: 'show/:id',
|
|
273
|
-
component:
|
|
274
|
+
component: lazyWithReload(() =>
|
|
274
275
|
import('routes/game').then((m) => ({ default: m.GameShow })),
|
|
275
276
|
),
|
|
276
277
|
},
|
|
277
278
|
edit: {
|
|
278
279
|
path: 'edit/:id',
|
|
279
|
-
component:
|
|
280
|
+
component: lazyWithReload(() =>
|
|
280
281
|
import('routes/game').then((m) => ({ default: m.GameEdit })),
|
|
281
282
|
),
|
|
282
283
|
},
|
|
283
284
|
create: {
|
|
284
285
|
path: 'create',
|
|
285
|
-
component:
|
|
286
|
+
component: lazyWithReload(() =>
|
|
286
287
|
import('routes/game').then((m) => ({ default: m.GameCreate })),
|
|
287
288
|
),
|
|
288
289
|
},
|
|
@@ -295,11 +296,11 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
295
296
|
list: {
|
|
296
297
|
path: '',
|
|
297
298
|
index: true,
|
|
298
|
-
component:
|
|
299
|
+
component: lazyWithReload(() => import('routes/agenda')),
|
|
299
300
|
},
|
|
300
301
|
show: {
|
|
301
302
|
path: 'show/:jobName',
|
|
302
|
-
component:
|
|
303
|
+
component: lazyWithReload(() => import('routes/agenda/show')),
|
|
303
304
|
},
|
|
304
305
|
},
|
|
305
306
|
},
|
|
@@ -310,56 +311,68 @@ export const routeRegistry: Record<string, RouteEntry> = {
|
|
|
310
311
|
workflow_list: {
|
|
311
312
|
path: '',
|
|
312
313
|
index: true,
|
|
313
|
-
component:
|
|
314
|
+
component: lazyWithReload(() => import('routes/workflow')),
|
|
314
315
|
},
|
|
315
316
|
editor_new: {
|
|
316
317
|
path: 'create',
|
|
317
|
-
component:
|
|
318
|
+
component: lazyWithReload(() => import('routes/workflow/editor')),
|
|
318
319
|
},
|
|
319
320
|
instances: {
|
|
320
321
|
path: 'instances/show/:workflowId',
|
|
321
|
-
component:
|
|
322
|
+
component: lazyWithReload(
|
|
323
|
+
() => import('routes/workflow/instances'),
|
|
324
|
+
),
|
|
322
325
|
},
|
|
323
326
|
instanceDetail: {
|
|
324
327
|
path: 'instance/show/:instanceId',
|
|
325
|
-
component:
|
|
328
|
+
component: lazyWithReload(
|
|
329
|
+
() => import('routes/workflow/instance-detail'),
|
|
330
|
+
),
|
|
326
331
|
},
|
|
327
332
|
editor: {
|
|
328
333
|
path: 'edit/:id',
|
|
329
|
-
component:
|
|
334
|
+
component: lazyWithReload(() => import('routes/workflow/editor')),
|
|
330
335
|
},
|
|
331
336
|
show: {
|
|
332
337
|
path: 'show/:id',
|
|
333
|
-
component:
|
|
338
|
+
component: lazyWithReload(() => import('routes/workflow/show')),
|
|
334
339
|
},
|
|
335
340
|
workflow_node_instance: {
|
|
336
341
|
path: 'node-instances',
|
|
337
|
-
component:
|
|
342
|
+
component: lazyWithReload(
|
|
343
|
+
() => import('routes/workflow/node-instances'),
|
|
344
|
+
),
|
|
338
345
|
},
|
|
339
346
|
nodeInstanceCreate: {
|
|
340
347
|
path: 'node-instances/create',
|
|
341
|
-
component:
|
|
348
|
+
component: lazyWithReload(
|
|
342
349
|
() => import('routes/workflow/node-instances/create'),
|
|
343
350
|
),
|
|
344
351
|
},
|
|
345
352
|
nodeInstanceEdit: {
|
|
346
353
|
path: 'node-instances/edit/:id',
|
|
347
|
-
component:
|
|
354
|
+
component: lazyWithReload(
|
|
348
355
|
() => import('routes/workflow/node-instances/edit'),
|
|
349
356
|
),
|
|
350
357
|
},
|
|
351
358
|
nodeInstanceShow: {
|
|
352
359
|
path: 'node-instances/show/:id',
|
|
353
|
-
component:
|
|
360
|
+
component: lazyWithReload(
|
|
354
361
|
() => import('routes/workflow/node-instances/show'),
|
|
355
362
|
),
|
|
356
363
|
},
|
|
364
|
+
workflow_temporal_tenant: {
|
|
365
|
+
path: 'temporal-tenant',
|
|
366
|
+
component: lazyWithReload(
|
|
367
|
+
() => import('routes/workflow/temporal-tenant'),
|
|
368
|
+
),
|
|
369
|
+
},
|
|
357
370
|
},
|
|
358
371
|
},
|
|
359
372
|
// 操作日志 — sortOrder 1070, code: admin.audit
|
|
360
373
|
audits: {
|
|
361
374
|
path: 'audit-log-list',
|
|
362
|
-
component:
|
|
375
|
+
component: lazyWithReload(() =>
|
|
363
376
|
import('routes/audit').then((m) => ({ default: m.AuditLogPage })),
|
|
364
377
|
),
|
|
365
378
|
},
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import i18n from 'i18next';
|
|
2
|
+
|
|
3
|
+
export const SUPPORTED_LANGUAGES = ['en', 'zh_CN'] as const;
|
|
2
4
|
import { initReactI18next } from 'react-i18next';
|
|
3
5
|
import detector from 'i18next-browser-languagedetector';
|
|
4
6
|
import en from './locales/en/common.json';
|
|
@@ -8,7 +10,7 @@ i18n
|
|
|
8
10
|
.use(detector)
|
|
9
11
|
.use(initReactI18next)
|
|
10
12
|
.init({
|
|
11
|
-
supportedLngs: [
|
|
13
|
+
supportedLngs: [...SUPPORTED_LANGUAGES],
|
|
12
14
|
resources: {
|
|
13
15
|
en: { common: en },
|
|
14
16
|
zh_CN: { common: zh_CN },
|
|
@@ -147,6 +147,7 @@
|
|
|
147
147
|
"componentLib": "Components",
|
|
148
148
|
"backToList": "Back to list",
|
|
149
149
|
"undo": "Undo",
|
|
150
|
+
"redo": "Redo",
|
|
150
151
|
"save": "Save",
|
|
151
152
|
"saveDirty": "Save •",
|
|
152
153
|
"preview": "Preview",
|
|
@@ -295,6 +296,8 @@
|
|
|
295
296
|
"myCanvases": "My Canvas",
|
|
296
297
|
"othersCanvases": "Others' Canvas",
|
|
297
298
|
"create": "New Canvas",
|
|
299
|
+
"import": "Import",
|
|
300
|
+
"export": "Export",
|
|
298
301
|
"published": "Published",
|
|
299
302
|
"unpublished": "Unpublished",
|
|
300
303
|
"rename": "Rename",
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json
CHANGED
|
@@ -149,6 +149,7 @@
|
|
|
149
149
|
"componentLib": "组件库",
|
|
150
150
|
"backToList": "返回列表",
|
|
151
151
|
"undo": "撤销",
|
|
152
|
+
"redo": "重做",
|
|
152
153
|
"save": "保存",
|
|
153
154
|
"saveDirty": "保存 •",
|
|
154
155
|
"preview": "预览",
|
|
@@ -297,6 +298,8 @@
|
|
|
297
298
|
"myCanvases": "我的 Canvas",
|
|
298
299
|
"othersCanvases": "其他人的 Canvas",
|
|
299
300
|
"create": "新建 Canvas",
|
|
301
|
+
"import": "导入",
|
|
302
|
+
"export": "导出",
|
|
300
303
|
"published": "已发布",
|
|
301
304
|
"unpublished": "未发布",
|
|
302
305
|
"rename": "重命名",
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx
CHANGED
|
@@ -114,12 +114,28 @@ const CanvasEditPage: React.FC = () => {
|
|
|
114
114
|
[history],
|
|
115
115
|
);
|
|
116
116
|
|
|
117
|
-
// ── Undo:
|
|
118
|
-
// through handleItemsChange/
|
|
119
|
-
// those push to history, which
|
|
120
|
-
//
|
|
117
|
+
// ── Undo/Redo: move a snapshot between the two stacks and write it
|
|
118
|
+
// back directly, WITHOUT going through handleItemsChange/
|
|
119
|
+
// handleLayoutChange/handleBothChange — those push to history, which
|
|
120
|
+
// would corrupt the undo/redo chain (consecutive undos would toggle
|
|
121
|
+
// instead of walking further back, and redo would get cleared by its
|
|
122
|
+
// own undo). ──
|
|
121
123
|
const handleUndo = useCallback(() => {
|
|
122
|
-
const snapshot = history.
|
|
124
|
+
const snapshot = history.undo({
|
|
125
|
+
items: liveRef.current.canvasItems,
|
|
126
|
+
layout: liveRef.current.canvasLayout,
|
|
127
|
+
});
|
|
128
|
+
if (!snapshot) return;
|
|
129
|
+
setCanvasItems(snapshot.items);
|
|
130
|
+
setCanvasLayout(snapshot.layout);
|
|
131
|
+
setIsDirty(true);
|
|
132
|
+
}, [history]);
|
|
133
|
+
|
|
134
|
+
const handleRedo = useCallback(() => {
|
|
135
|
+
const snapshot = history.redo({
|
|
136
|
+
items: liveRef.current.canvasItems,
|
|
137
|
+
layout: liveRef.current.canvasLayout,
|
|
138
|
+
});
|
|
123
139
|
if (!snapshot) return;
|
|
124
140
|
setCanvasItems(snapshot.items);
|
|
125
141
|
setCanvasLayout(snapshot.layout);
|
|
@@ -208,6 +224,8 @@ const CanvasEditPage: React.FC = () => {
|
|
|
208
224
|
isPublished={!!canvas.publishedPageCode}
|
|
209
225
|
canUndo={history.canUndo}
|
|
210
226
|
onUndo={handleUndo}
|
|
227
|
+
canRedo={history.canRedo}
|
|
228
|
+
onRedo={handleRedo}
|
|
211
229
|
onItemsChange={handleItemsChange}
|
|
212
230
|
onLayoutChange={handleLayoutChange}
|
|
213
231
|
onBothChange={handleBothChange}
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx
CHANGED
|
@@ -9,8 +9,15 @@ import {
|
|
|
9
9
|
Modal,
|
|
10
10
|
Input,
|
|
11
11
|
Typography,
|
|
12
|
+
Space,
|
|
12
13
|
} from 'antd';
|
|
13
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
PlusOutlined,
|
|
16
|
+
DeleteOutlined,
|
|
17
|
+
EditOutlined,
|
|
18
|
+
ExportOutlined,
|
|
19
|
+
ImportOutlined,
|
|
20
|
+
} from '@ant-design/icons';
|
|
14
21
|
import {
|
|
15
22
|
fetchCanvases,
|
|
16
23
|
createCanvas,
|
|
@@ -21,6 +28,8 @@ import {
|
|
|
21
28
|
} from './canvasApi';
|
|
22
29
|
import type { SavedCanvas } from './types';
|
|
23
30
|
import IsolatedLivePreview from './IsolatedLivePreview';
|
|
31
|
+
import { ExportModal } from './components/ExportModal';
|
|
32
|
+
import { ImportModal } from './components/ImportModal';
|
|
24
33
|
import { useTranslation } from 'react-i18next';
|
|
25
34
|
import { useUserPageAccess } from 'hooks/useUserPageAccess';
|
|
26
35
|
import { customRequest } from 'helpers/http';
|
|
@@ -196,6 +205,11 @@ const CanvasListPage: React.FC = () => {
|
|
|
196
205
|
}
|
|
197
206
|
}, [renameModal, renameValue]);
|
|
198
207
|
|
|
208
|
+
// ── 导出/导入 ──
|
|
209
|
+
const [exportModalOpen, setExportModalOpen] = useState(false);
|
|
210
|
+
const [exportCanvasId, setExportCanvasId] = useState<string | null>(null);
|
|
211
|
+
const [importModalOpen, setImportModalOpen] = useState(false);
|
|
212
|
+
|
|
199
213
|
// ── 删除确认 ──
|
|
200
214
|
const [deleteConfirm, setDeleteConfirm] = useState<SavedCanvas | null>(null);
|
|
201
215
|
|
|
@@ -233,15 +247,25 @@ const CanvasListPage: React.FC = () => {
|
|
|
233
247
|
<Typography.Title level={4} style={{ margin: 0 }}>
|
|
234
248
|
{t('canvas.list.title')}
|
|
235
249
|
</Typography.Title>
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
250
|
+
<Space>
|
|
251
|
+
{isAgentAllowed && (
|
|
252
|
+
<Button
|
|
253
|
+
icon={<ImportOutlined />}
|
|
254
|
+
onClick={() => setImportModalOpen(true)}
|
|
255
|
+
>
|
|
256
|
+
{t('canvas.list.import')}
|
|
257
|
+
</Button>
|
|
258
|
+
)}
|
|
259
|
+
{isAgentAllowed && (
|
|
260
|
+
<Button
|
|
261
|
+
type="primary"
|
|
262
|
+
icon={<PlusOutlined />}
|
|
263
|
+
onClick={handleCreate}
|
|
264
|
+
>
|
|
265
|
+
{t('canvas.list.create')}
|
|
266
|
+
</Button>
|
|
267
|
+
)}
|
|
268
|
+
</Space>
|
|
245
269
|
</div>
|
|
246
270
|
</Card>
|
|
247
271
|
|
|
@@ -362,6 +386,19 @@ const CanvasListPage: React.FC = () => {
|
|
|
362
386
|
<div style={{ display: 'flex', gap: 4 }}>
|
|
363
387
|
{isAgentAllowed && (
|
|
364
388
|
<>
|
|
389
|
+
<Button
|
|
390
|
+
type="text"
|
|
391
|
+
size="small"
|
|
392
|
+
icon={<ExportOutlined />}
|
|
393
|
+
onClick={(e) => {
|
|
394
|
+
e.stopPropagation();
|
|
395
|
+
setExportCanvasId(canvas.id);
|
|
396
|
+
setExportModalOpen(true);
|
|
397
|
+
}}
|
|
398
|
+
style={{ fontSize: 12, color: '#666' }}
|
|
399
|
+
>
|
|
400
|
+
{t('canvas.list.export')}
|
|
401
|
+
</Button>
|
|
365
402
|
<Button
|
|
366
403
|
type="text"
|
|
367
404
|
size="small"
|
|
@@ -602,6 +639,25 @@ const CanvasListPage: React.FC = () => {
|
|
|
602
639
|
: t('canvas.list.deleteConfirm')}
|
|
603
640
|
</p>
|
|
604
641
|
</Modal>
|
|
642
|
+
|
|
643
|
+
<ExportModal
|
|
644
|
+
open={exportModalOpen}
|
|
645
|
+
canvasId={exportCanvasId}
|
|
646
|
+
onClose={() => {
|
|
647
|
+
setExportModalOpen(false);
|
|
648
|
+
setExportCanvasId(null);
|
|
649
|
+
}}
|
|
650
|
+
/>
|
|
651
|
+
|
|
652
|
+
<ImportModal
|
|
653
|
+
open={importModalOpen}
|
|
654
|
+
onClose={() => setImportModalOpen(false)}
|
|
655
|
+
onSuccess={() => {
|
|
656
|
+
fetchCanvases()
|
|
657
|
+
.then(setCanvases)
|
|
658
|
+
.catch(() => message.error(t('canvas.list.loadFailed')));
|
|
659
|
+
}}
|
|
660
|
+
/>
|
|
605
661
|
</div>
|
|
606
662
|
);
|
|
607
663
|
};
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx
CHANGED
|
@@ -117,6 +117,8 @@ interface CanvasPageProps {
|
|
|
117
117
|
isPublished: boolean;
|
|
118
118
|
canUndo: boolean;
|
|
119
119
|
onUndo: () => void;
|
|
120
|
+
canRedo: boolean;
|
|
121
|
+
onRedo: () => void;
|
|
120
122
|
onItemsChange: (
|
|
121
123
|
items: CanvasItemType[],
|
|
122
124
|
opts?: { coalesce?: boolean },
|
|
@@ -143,6 +145,8 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
143
145
|
isPublished,
|
|
144
146
|
canUndo,
|
|
145
147
|
onUndo,
|
|
148
|
+
canRedo,
|
|
149
|
+
onRedo,
|
|
146
150
|
onItemsChange,
|
|
147
151
|
onLayoutChange,
|
|
148
152
|
onBothChange,
|
|
@@ -428,13 +432,12 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
428
432
|
};
|
|
429
433
|
}, []);
|
|
430
434
|
|
|
431
|
-
// ── 全局 Ctrl/Cmd+Z
|
|
432
|
-
//
|
|
435
|
+
// ── 全局 Ctrl/Cmd+Z 撤销 / Ctrl/Cmd+Shift+Z 重做快捷键 — 焦点在代码编辑器
|
|
436
|
+
// 或普通输入框内时,交给它们自己处理本地撤销/重做,不拦截 ──
|
|
433
437
|
useEffect(() => {
|
|
434
438
|
const handler = (e: KeyboardEvent) => {
|
|
435
|
-
const
|
|
436
|
-
|
|
437
|
-
if (!isUndoCombo) return;
|
|
439
|
+
const isZCombo = (e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'z';
|
|
440
|
+
if (!isZCombo) return;
|
|
438
441
|
const active = document.activeElement as HTMLElement | null;
|
|
439
442
|
if (active) {
|
|
440
443
|
if (active.closest('.monaco-editor')) return;
|
|
@@ -447,11 +450,15 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
447
450
|
}
|
|
448
451
|
}
|
|
449
452
|
e.preventDefault();
|
|
450
|
-
|
|
453
|
+
if (e.shiftKey) {
|
|
454
|
+
onRedo();
|
|
455
|
+
} else {
|
|
456
|
+
onUndo();
|
|
457
|
+
}
|
|
451
458
|
};
|
|
452
459
|
window.addEventListener('keydown', handler);
|
|
453
460
|
return () => window.removeEventListener('keydown', handler);
|
|
454
|
-
}, [onUndo]);
|
|
461
|
+
}, [onUndo, onRedo]);
|
|
455
462
|
|
|
456
463
|
// ── MultiChart 工具栏切换图表类型时,同步更新代码中的 defaultVariant ──
|
|
457
464
|
useEffect(() => {
|
|
@@ -658,6 +665,8 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
658
665
|
isPublished={isPublished}
|
|
659
666
|
canUndo={canUndo}
|
|
660
667
|
onUndo={onUndo}
|
|
668
|
+
canRedo={canRedo}
|
|
669
|
+
onRedo={onRedo}
|
|
661
670
|
onSave={onSave}
|
|
662
671
|
onBack={onBack}
|
|
663
672
|
onPublish={onPublish}
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
EyeOutlined,
|
|
9
9
|
RobotOutlined,
|
|
10
10
|
UndoOutlined,
|
|
11
|
+
RedoOutlined,
|
|
11
12
|
} from '@ant-design/icons';
|
|
12
13
|
import { useTranslation } from 'react-i18next';
|
|
13
14
|
|
|
@@ -17,6 +18,8 @@ interface CanvasToolbarProps {
|
|
|
17
18
|
isPublished: boolean;
|
|
18
19
|
canUndo: boolean;
|
|
19
20
|
onUndo: () => void;
|
|
21
|
+
canRedo: boolean;
|
|
22
|
+
onRedo: () => void;
|
|
20
23
|
onSave: () => void;
|
|
21
24
|
onBack: () => void;
|
|
22
25
|
onPublish: () => void;
|
|
@@ -31,6 +34,8 @@ const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
|
31
34
|
isPublished,
|
|
32
35
|
canUndo,
|
|
33
36
|
onUndo,
|
|
37
|
+
canRedo,
|
|
38
|
+
onRedo,
|
|
34
39
|
onSave,
|
|
35
40
|
onBack,
|
|
36
41
|
onPublish,
|
|
@@ -117,6 +122,22 @@ const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
|
117
122
|
}}
|
|
118
123
|
/>
|
|
119
124
|
</Tooltip>
|
|
125
|
+
<Tooltip title={t('canvas.redo')}>
|
|
126
|
+
<Button
|
|
127
|
+
size="small"
|
|
128
|
+
icon={<RedoOutlined />}
|
|
129
|
+
onClick={onRedo}
|
|
130
|
+
disabled={!canRedo}
|
|
131
|
+
style={{
|
|
132
|
+
borderRadius: 8,
|
|
133
|
+
border: '1px solid #e0e0e0',
|
|
134
|
+
background: 'transparent',
|
|
135
|
+
color: canRedo ? '#555' : '#ccc',
|
|
136
|
+
fontWeight: 500,
|
|
137
|
+
transition: 'all 200ms ease',
|
|
138
|
+
}}
|
|
139
|
+
/>
|
|
140
|
+
</Tooltip>
|
|
120
141
|
{isAgentAllowed && (
|
|
121
142
|
<Button
|
|
122
143
|
size="small"
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasApi.ts
CHANGED
|
@@ -110,3 +110,33 @@ export async function fetchAllCanvases(): Promise<SavedCanvasWithOwner[]> {
|
|
|
110
110
|
);
|
|
111
111
|
return records.map(toSavedCanvasWithOwner);
|
|
112
112
|
}
|
|
113
|
+
|
|
114
|
+
// ── 导出/导入 ────────────────────────────────────────────────────────────
|
|
115
|
+
|
|
116
|
+
export async function generateExportToken(
|
|
117
|
+
id: string,
|
|
118
|
+
): Promise<{ url: string }> {
|
|
119
|
+
return customRequest<{ url: string }>(`canvas/${id}/export-token`, 'POST');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export async function importPreview(
|
|
123
|
+
payload: any,
|
|
124
|
+
): Promise<{ current: any; incoming: any }> {
|
|
125
|
+
return customRequest<{ current: any; incoming: any }>(
|
|
126
|
+
'canvas/import-preview',
|
|
127
|
+
'POST',
|
|
128
|
+
{ payload },
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function importConfirm(payload: any): Promise<{
|
|
133
|
+
success: boolean;
|
|
134
|
+
canvasId: string;
|
|
135
|
+
canvasName: string;
|
|
136
|
+
}> {
|
|
137
|
+
return customRequest<{
|
|
138
|
+
success: boolean;
|
|
139
|
+
canvasId: string;
|
|
140
|
+
canvasName: string;
|
|
141
|
+
}>('canvas/import-confirm', 'POST', { payload });
|
|
142
|
+
}
|