@gadmin2n/schematics 0.0.87 → 0.0.89
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/.dockerignore +16 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.codegen +40 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.server +76 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.web +53 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/Jenkinsfile +219 -33
- package/dist/lib/application/files/gadmin2-game-angle-demo/compose-ctl.sh +250 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +4 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/dev/postgres/init.sql +12 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/docker-compose.md +170 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/docker-compose.yml +254 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +8 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/lib/page-helpers.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/prismaModels.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/agenda.seed.ts +39 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/audit.seed.ts +40 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/bootstrap.ts +56 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/canvas.seed.ts +39 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/{scripts/sync-data-mngt-pages.ts → seed/data-mngt.seed.ts} +36 -20
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/game.seed.ts +44 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +30 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permission.seed.ts +130 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-event-trigger.ts +60 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +11 -25
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +108 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/main.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.service.spec.ts +41 -57
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.service.spec.ts +309 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.service.spec.ts +315 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.service.spec.ts +312 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.service.spec.ts +317 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.service.spec.ts +309 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.service.spec.ts +299 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.service.spec.ts +307 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.service.spec.ts +309 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.spec.ts +205 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.ts +116 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.spec.ts +158 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +110 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/webhook-signature.util.spec.ts +79 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/webhook-signature.util.ts +54 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +34 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +457 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +241 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +34 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +24 -30
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.spec.ts +34 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +36 -36
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.spec.ts +34 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.spec.ts +48 -24
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +312 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/TODO.md +152 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.dockerignore +12 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/Dockerfile +79 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/GRACEFUL-DEPLOYMENT.md +270 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/reporting.ts +23 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/index.ts +70 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/outbox-poller.ts +246 -90
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/cron-trigger-workflow.test.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/workflows/dsl-workflow.ts +96 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/nginx.conf +74 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/ElementInspector.tsx +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/promptGenerator.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/form.tsx +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +3 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +3 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts +4 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx +9 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +156 -139
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +14 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/PublishModal.tsx +4 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasApi.ts +18 -27
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasDefaults.ts +32 -11
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/demos.ts +48 -61
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas-page/index.tsx +3 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.tsx +16 -16
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +28 -35
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +34 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/antd.css +6 -0
- package/package.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile +0 -63
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/sync-resources.ts +0 -100
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +0 -302
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.controller.spec.ts +0 -20
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/sql/create-event-trigger.sql +0 -87
- /package/dist/lib/application/files/gadmin2-game-angle-demo/{GRACEFUL-DEPLOYMENT.md → server/GRACEFUL-DEPLOYMENT.md} +0 -0
|
@@ -157,8 +157,8 @@
|
|
|
157
157
|
"editCode": "Edit Code",
|
|
158
158
|
"duplicate": "Duplicate",
|
|
159
159
|
"delete": "Delete",
|
|
160
|
-
"custom": "
|
|
161
|
-
"customAction": "
|
|
160
|
+
"custom": "Customize...",
|
|
161
|
+
"customAction": "Customize...",
|
|
162
162
|
"customPlaceholder": "Describe what you want to do with this component",
|
|
163
163
|
"components": {
|
|
164
164
|
"NumCard": "Metric Card",
|
|
@@ -184,7 +184,7 @@
|
|
|
184
184
|
"inline-right": "Inline Right"
|
|
185
185
|
},
|
|
186
186
|
"dataSource": {
|
|
187
|
-
"label": "
|
|
187
|
+
"label": "Change data source...",
|
|
188
188
|
"placeholder": "Describe the data, e.g.: revenue comparison over last 30 days"
|
|
189
189
|
},
|
|
190
190
|
"dataSourceModal": {
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json
CHANGED
|
@@ -159,8 +159,8 @@
|
|
|
159
159
|
"editCode": "编辑代码",
|
|
160
160
|
"duplicate": "复制",
|
|
161
161
|
"delete": "删除",
|
|
162
|
-
"custom": "
|
|
163
|
-
"customAction": "
|
|
162
|
+
"custom": "自定义...",
|
|
163
|
+
"customAction": "自定义...",
|
|
164
164
|
"customPlaceholder": "描述你想对这个组件做的修改",
|
|
165
165
|
"components": {
|
|
166
166
|
"NumCard": "数字卡片",
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
"inline-right": "行内右对齐"
|
|
187
187
|
},
|
|
188
188
|
"dataSource": {
|
|
189
|
-
"label": "
|
|
189
|
+
"label": "修改数据来源...",
|
|
190
190
|
"placeholder": "描述要展示的数据,例如:近30天游戏收益对比、各部门人数分布、近90天考勤状态统计"
|
|
191
191
|
},
|
|
192
192
|
"dataSourceModal": {
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import type { IncomingMessage, ServerResponse } from 'http';
|
|
3
4
|
import type { Plugin } from 'vite';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -15,7 +16,9 @@ export function devShellPlugin(): Plugin {
|
|
|
15
16
|
name: 'dev-shell',
|
|
16
17
|
apply: 'serve',
|
|
17
18
|
configureServer(server) {
|
|
18
|
-
server.middlewares.use(async (
|
|
19
|
+
server.middlewares.use(async (rawReq, rawRes, next) => {
|
|
20
|
+
const req = rawReq as IncomingMessage;
|
|
21
|
+
const res = rawRes as ServerResponse;
|
|
19
22
|
const url = req.url?.split('?')[0] ?? '/';
|
|
20
23
|
|
|
21
24
|
// POST /canvas-patch — agent 将新组件代码通过 HMR 推送给前端画布
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx
CHANGED
|
@@ -96,6 +96,15 @@ const CanvasEditPage: React.FC = () => {
|
|
|
96
96
|
}
|
|
97
97
|
}, []);
|
|
98
98
|
|
|
99
|
+
// ── 30s 自动保存:有未保存变更时,30 秒后自动调用 handleSave ──
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (!isDirty) return;
|
|
102
|
+
const timer = setTimeout(() => {
|
|
103
|
+
handleSave();
|
|
104
|
+
}, 30_000);
|
|
105
|
+
return () => clearTimeout(timer);
|
|
106
|
+
}, [isDirty, handleSave]);
|
|
107
|
+
|
|
99
108
|
// ── Back to list ──
|
|
100
109
|
const handleBack = useCallback(() => {
|
|
101
110
|
navigate('/admin/canvas');
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
|
2
2
|
import { useNavigate } from 'react-router-dom';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
Card,
|
|
6
|
+
message,
|
|
7
|
+
Tag,
|
|
8
|
+
Spin,
|
|
9
|
+
Modal,
|
|
10
|
+
Input,
|
|
11
|
+
Typography,
|
|
12
|
+
} from 'antd';
|
|
4
13
|
import { PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
|
|
5
14
|
import {
|
|
6
15
|
fetchCanvases,
|
|
@@ -181,166 +190,174 @@ const CanvasListPage: React.FC = () => {
|
|
|
181
190
|
}}
|
|
182
191
|
>
|
|
183
192
|
{/* Header */}
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
193
|
+
<Card style={{ marginBottom: 16 }}>
|
|
194
|
+
<div
|
|
195
|
+
style={{
|
|
196
|
+
display: 'flex',
|
|
197
|
+
justifyContent: 'space-between',
|
|
198
|
+
alignItems: 'center',
|
|
199
|
+
}}
|
|
200
|
+
>
|
|
201
|
+
<Typography.Title level={4} style={{ margin: 0 }}>
|
|
202
|
+
{t('canvas.list.title')}
|
|
203
|
+
</Typography.Title>
|
|
204
|
+
<Button type="primary" icon={<PlusOutlined />} onClick={handleCreate}>
|
|
205
|
+
{t('canvas.list.create')}
|
|
206
|
+
</Button>
|
|
207
|
+
</div>
|
|
208
|
+
</Card>
|
|
199
209
|
|
|
200
210
|
{/* Grid */}
|
|
201
|
-
<
|
|
202
|
-
|
|
203
|
-
display: 'grid',
|
|
204
|
-
gridTemplateColumns: 'repeat(3, 1fr)',
|
|
205
|
-
gap: 20,
|
|
206
|
-
}}
|
|
207
|
-
>
|
|
208
|
-
{canvases.map((canvas) => (
|
|
211
|
+
<Card>
|
|
212
|
+
{canvases.length > 0 ? (
|
|
209
213
|
<div
|
|
210
|
-
key={canvas.id}
|
|
211
214
|
style={{
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
border: '1px solid #e5e5e5',
|
|
216
|
-
cursor: 'pointer',
|
|
217
|
-
transition: 'box-shadow 0.2s',
|
|
218
|
-
}}
|
|
219
|
-
onMouseEnter={(e) => {
|
|
220
|
-
(e.currentTarget as HTMLDivElement).style.boxShadow =
|
|
221
|
-
'0 4px 12px rgba(0,0,0,0.1)';
|
|
215
|
+
display: 'grid',
|
|
216
|
+
gridTemplateColumns: 'repeat(3, 1fr)',
|
|
217
|
+
gap: 20,
|
|
222
218
|
}}
|
|
223
|
-
onMouseLeave={(e) => {
|
|
224
|
-
(e.currentTarget as HTMLDivElement).style.boxShadow = 'none';
|
|
225
|
-
}}
|
|
226
|
-
onClick={() => navigate(`/admin/canvas/edit/${canvas.id}`)}
|
|
227
219
|
>
|
|
228
|
-
{
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
style=
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
) : (
|
|
220
|
+
{canvases.map((canvas) => (
|
|
221
|
+
<div
|
|
222
|
+
key={canvas.id}
|
|
223
|
+
style={{
|
|
224
|
+
background: '#fff',
|
|
225
|
+
borderRadius: 8,
|
|
226
|
+
overflow: 'hidden',
|
|
227
|
+
border: '1px solid #e5e5e5',
|
|
228
|
+
cursor: 'pointer',
|
|
229
|
+
transition: 'box-shadow 0.2s',
|
|
230
|
+
}}
|
|
231
|
+
onMouseEnter={(e) => {
|
|
232
|
+
(e.currentTarget as HTMLDivElement).style.boxShadow =
|
|
233
|
+
'0 4px 12px rgba(0,0,0,0.1)';
|
|
234
|
+
}}
|
|
235
|
+
onMouseLeave={(e) => {
|
|
236
|
+
(e.currentTarget as HTMLDivElement).style.boxShadow = 'none';
|
|
237
|
+
}}
|
|
238
|
+
onClick={() => navigate(`/admin/canvas/edit/${canvas.id}`)}
|
|
239
|
+
>
|
|
240
|
+
{/* Thumbnail */}
|
|
250
241
|
<div
|
|
251
242
|
style={{
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
fontSize: 14,
|
|
243
|
+
height: 180,
|
|
244
|
+
overflow: 'hidden',
|
|
245
|
+
background: '#f0f0f0',
|
|
246
|
+
position: 'relative',
|
|
247
|
+
pointerEvents: 'none',
|
|
258
248
|
}}
|
|
259
249
|
>
|
|
260
|
-
|
|
250
|
+
{canvas.items.length > 0 ? (
|
|
251
|
+
<div
|
|
252
|
+
style={{
|
|
253
|
+
transform: 'scale(0.28)',
|
|
254
|
+
transformOrigin: 'top left',
|
|
255
|
+
width: 1200,
|
|
256
|
+
height: 640,
|
|
257
|
+
}}
|
|
258
|
+
>
|
|
259
|
+
<IsolatedLivePreview code={buildPreviewCode(canvas)} />
|
|
260
|
+
</div>
|
|
261
|
+
) : (
|
|
262
|
+
<div
|
|
263
|
+
style={{
|
|
264
|
+
display: 'flex',
|
|
265
|
+
alignItems: 'center',
|
|
266
|
+
justifyContent: 'center',
|
|
267
|
+
height: '100%',
|
|
268
|
+
color: '#bbb',
|
|
269
|
+
fontSize: 14,
|
|
270
|
+
}}
|
|
271
|
+
>
|
|
272
|
+
空画布
|
|
273
|
+
</div>
|
|
274
|
+
)}
|
|
261
275
|
</div>
|
|
262
|
-
)}
|
|
263
|
-
</div>
|
|
264
276
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
style={{ padding: '12px 16px', borderTop: '1px solid #f0f0f0' }}
|
|
268
|
-
>
|
|
269
|
-
<div
|
|
270
|
-
style={{
|
|
271
|
-
display: 'flex',
|
|
272
|
-
justifyContent: 'space-between',
|
|
273
|
-
alignItems: 'center',
|
|
274
|
-
marginBottom: 8,
|
|
275
|
-
}}
|
|
276
|
-
>
|
|
277
|
-
<span
|
|
277
|
+
{/* Info */}
|
|
278
|
+
<div
|
|
278
279
|
style={{
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
overflow: 'hidden',
|
|
282
|
-
textOverflow: 'ellipsis',
|
|
283
|
-
whiteSpace: 'nowrap',
|
|
284
|
-
maxWidth: 160,
|
|
280
|
+
padding: '12px 16px',
|
|
281
|
+
borderTop: '1px solid #f0f0f0',
|
|
285
282
|
}}
|
|
286
283
|
>
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
</Tag>
|
|
294
|
-
</div>
|
|
295
|
-
<div
|
|
296
|
-
style={{
|
|
297
|
-
display: 'flex',
|
|
298
|
-
justifyContent: 'space-between',
|
|
299
|
-
alignItems: 'center',
|
|
300
|
-
}}
|
|
301
|
-
>
|
|
302
|
-
<span style={{ fontSize: 12, color: '#999' }}>
|
|
303
|
-
修改于 {new Date(canvas.updatedAt).toLocaleString('zh-CN')}
|
|
304
|
-
</span>
|
|
305
|
-
<div style={{ display: 'flex', gap: 4 }}>
|
|
306
|
-
<Button
|
|
307
|
-
type="text"
|
|
308
|
-
size="small"
|
|
309
|
-
icon={<EditOutlined />}
|
|
310
|
-
onClick={(e) => {
|
|
311
|
-
e.stopPropagation();
|
|
312
|
-
openRename(canvas);
|
|
284
|
+
<div
|
|
285
|
+
style={{
|
|
286
|
+
display: 'flex',
|
|
287
|
+
justifyContent: 'space-between',
|
|
288
|
+
alignItems: 'center',
|
|
289
|
+
marginBottom: 8,
|
|
313
290
|
}}
|
|
314
|
-
style={{ fontSize: 12, color: '#666' }}
|
|
315
291
|
>
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
292
|
+
<span
|
|
293
|
+
style={{
|
|
294
|
+
fontWeight: 500,
|
|
295
|
+
fontSize: 14,
|
|
296
|
+
overflow: 'hidden',
|
|
297
|
+
textOverflow: 'ellipsis',
|
|
298
|
+
whiteSpace: 'nowrap',
|
|
299
|
+
maxWidth: 160,
|
|
300
|
+
}}
|
|
301
|
+
>
|
|
302
|
+
{canvas.name}
|
|
303
|
+
</span>
|
|
304
|
+
<Tag color={canvas.publishedPageCode ? 'green' : 'default'}>
|
|
305
|
+
{canvas.publishedPageCode
|
|
306
|
+
? t('canvas.list.published')
|
|
307
|
+
: t('canvas.list.unpublished')}
|
|
308
|
+
</Tag>
|
|
309
|
+
</div>
|
|
310
|
+
<div
|
|
311
|
+
style={{
|
|
312
|
+
display: 'flex',
|
|
313
|
+
justifyContent: 'space-between',
|
|
314
|
+
alignItems: 'center',
|
|
326
315
|
}}
|
|
327
|
-
style={{ fontSize: 12 }}
|
|
328
316
|
>
|
|
329
|
-
{
|
|
330
|
-
|
|
317
|
+
<span style={{ fontSize: 12, color: '#999' }}>
|
|
318
|
+
修改于{' '}
|
|
319
|
+
{new Date(canvas.updatedAt).toLocaleString('zh-CN')}
|
|
320
|
+
</span>
|
|
321
|
+
<div style={{ display: 'flex', gap: 4 }}>
|
|
322
|
+
<Button
|
|
323
|
+
type="text"
|
|
324
|
+
size="small"
|
|
325
|
+
icon={<EditOutlined />}
|
|
326
|
+
onClick={(e) => {
|
|
327
|
+
e.stopPropagation();
|
|
328
|
+
openRename(canvas);
|
|
329
|
+
}}
|
|
330
|
+
style={{ fontSize: 12, color: '#666' }}
|
|
331
|
+
>
|
|
332
|
+
{t('canvas.list.rename')}
|
|
333
|
+
</Button>
|
|
334
|
+
<Button
|
|
335
|
+
type="text"
|
|
336
|
+
size="small"
|
|
337
|
+
danger
|
|
338
|
+
icon={<DeleteOutlined />}
|
|
339
|
+
onClick={(e) => {
|
|
340
|
+
e.stopPropagation();
|
|
341
|
+
setDeleteConfirm(canvas);
|
|
342
|
+
}}
|
|
343
|
+
style={{ fontSize: 12 }}
|
|
344
|
+
>
|
|
345
|
+
{t('canvas.list.deleteBtn')}
|
|
346
|
+
</Button>
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
331
349
|
</div>
|
|
332
350
|
</div>
|
|
333
|
-
|
|
351
|
+
))}
|
|
334
352
|
</div>
|
|
335
|
-
)
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
)}
|
|
353
|
+
) : (
|
|
354
|
+
<div
|
|
355
|
+
style={{ textAlign: 'center', color: '#999', padding: '80px 0' }}
|
|
356
|
+
>
|
|
357
|
+
<p>还没有 Canvas,点击上方按钮新建一个吧</p>
|
|
358
|
+
</div>
|
|
359
|
+
)}
|
|
360
|
+
</Card>
|
|
344
361
|
|
|
345
362
|
{/* 重命名 Modal */}
|
|
346
363
|
<Modal
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx
CHANGED
|
@@ -53,6 +53,13 @@ const COLS = 48;
|
|
|
53
53
|
const ROW_HEIGHT = 10;
|
|
54
54
|
const MARGIN_Y = 8;
|
|
55
55
|
|
|
56
|
+
/** 组件库类型 → 画布实际 componentType 映射 */
|
|
57
|
+
const COMPONENT_TYPE_MAP: Record<string, string> = {
|
|
58
|
+
BarChart: 'MultiChart',
|
|
59
|
+
LineChart: 'MultiChart',
|
|
60
|
+
PieChart: 'MultiChart',
|
|
61
|
+
};
|
|
62
|
+
|
|
56
63
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
57
64
|
|
|
58
65
|
/** Compute the pixel height a component should fill given a grid row count. */
|
|
@@ -234,10 +241,12 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
234
241
|
const id = genId();
|
|
235
242
|
const maxY = layout.reduce((m, l) => Math.max(m, l.y + l.h), 0);
|
|
236
243
|
const h = def.layout.h;
|
|
244
|
+
// 映射实际 componentType(BarChart/LineChart/PieChart → MultiChart)
|
|
245
|
+
const actualType = COMPONENT_TYPE_MAP[type] ?? type;
|
|
237
246
|
onBothChange(
|
|
238
247
|
[
|
|
239
248
|
...items,
|
|
240
|
-
{ id, componentType:
|
|
249
|
+
{ id, componentType: actualType, code: syncCodeHeight(def.code, h) },
|
|
241
250
|
],
|
|
242
251
|
[
|
|
243
252
|
...layout,
|
|
@@ -412,10 +421,13 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
412
421
|
)
|
|
413
422
|
: def.code;
|
|
414
423
|
|
|
424
|
+
// 映射实际 componentType(BarChart/LineChart/PieChart → MultiChart)
|
|
425
|
+
const actualType = COMPONENT_TYPE_MAP[type] ?? type;
|
|
426
|
+
|
|
415
427
|
onBothChange(
|
|
416
428
|
[
|
|
417
429
|
...items,
|
|
418
|
-
{ id, componentType:
|
|
430
|
+
{ id, componentType: actualType, code: syncCodeHeight(baseCode, h) },
|
|
419
431
|
],
|
|
420
432
|
[
|
|
421
433
|
...cleanLayout,
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx
CHANGED
|
@@ -55,6 +55,8 @@ const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
|
55
55
|
borderBottom: '1px solid #eaeaea',
|
|
56
56
|
flexShrink: 0,
|
|
57
57
|
boxShadow: '0 1px 8px rgba(0,0,0,0.04)',
|
|
58
|
+
borderRadius: 8,
|
|
59
|
+
overflow: 'hidden',
|
|
58
60
|
}}
|
|
59
61
|
>
|
|
60
62
|
{/* ── Header row ── */}
|
|
@@ -216,6 +218,66 @@ const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
|
216
218
|
const def = CANVAS_DEFAULTS[type];
|
|
217
219
|
const variants = def?.variants ?? [];
|
|
218
220
|
|
|
221
|
+
// ── 单 variant:thumbnail 直接可拖拽,跳过 Popover ──
|
|
222
|
+
if (variants.length === 1) {
|
|
223
|
+
return (
|
|
224
|
+
<div
|
|
225
|
+
key={type}
|
|
226
|
+
draggable
|
|
227
|
+
onDragStart={(e) =>
|
|
228
|
+
handleVariantDragStart(e, type, variants[0].code)
|
|
229
|
+
}
|
|
230
|
+
style={{
|
|
231
|
+
display: 'flex',
|
|
232
|
+
flexDirection: 'column',
|
|
233
|
+
alignItems: 'center',
|
|
234
|
+
gap: 8,
|
|
235
|
+
cursor: 'grab',
|
|
236
|
+
userSelect: 'none',
|
|
237
|
+
flexShrink: 0,
|
|
238
|
+
width: 140,
|
|
239
|
+
}}
|
|
240
|
+
>
|
|
241
|
+
<div
|
|
242
|
+
style={{
|
|
243
|
+
border: '1px solid #eaeaea',
|
|
244
|
+
borderRadius: 10,
|
|
245
|
+
overflow: 'hidden',
|
|
246
|
+
background: '#fff',
|
|
247
|
+
transition: 'all 200ms cubic-bezier(0.4, 0, 0.2, 1)',
|
|
248
|
+
}}
|
|
249
|
+
onMouseEnter={(e) => {
|
|
250
|
+
const el = e.currentTarget;
|
|
251
|
+
el.style.borderColor = '#4361ee';
|
|
252
|
+
el.style.boxShadow = '0 4px 16px rgba(67,97,238,0.12)';
|
|
253
|
+
el.style.transform = 'translateY(-3px) scale(1.03)';
|
|
254
|
+
}}
|
|
255
|
+
onMouseLeave={(e) => {
|
|
256
|
+
const el = e.currentTarget;
|
|
257
|
+
el.style.borderColor = '#eaeaea';
|
|
258
|
+
el.style.boxShadow = 'none';
|
|
259
|
+
el.style.transform = 'translateY(0) scale(1)';
|
|
260
|
+
}}
|
|
261
|
+
>
|
|
262
|
+
<ComponentThumbnail componentType={type} width={140} />
|
|
263
|
+
</div>
|
|
264
|
+
<span
|
|
265
|
+
style={{
|
|
266
|
+
fontSize: 11,
|
|
267
|
+
color: '#888',
|
|
268
|
+
fontWeight: 500,
|
|
269
|
+
letterSpacing: '0.3px',
|
|
270
|
+
textAlign: 'center',
|
|
271
|
+
pointerEvents: 'none',
|
|
272
|
+
}}
|
|
273
|
+
>
|
|
274
|
+
{getComponentLabel(type, t)}
|
|
275
|
+
</span>
|
|
276
|
+
</div>
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// ── 多 variant:保持 Popover hover 展开 ──
|
|
219
281
|
const popoverContent = (
|
|
220
282
|
<div
|
|
221
283
|
style={{
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/PublishModal.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { Modal, Form, Input, TreeSelect, message } from 'antd';
|
|
|
3
3
|
import type { SavedCanvas } from './types';
|
|
4
4
|
import { publishCanvas } from './canvasApi';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
+
import { customRequest } from 'helpers/http';
|
|
6
7
|
|
|
7
8
|
interface RawPage {
|
|
8
9
|
id: number;
|
|
@@ -80,13 +81,10 @@ const PublishModal: React.FC<PublishModalProps> = ({
|
|
|
80
81
|
useEffect(() => {
|
|
81
82
|
if (!open) return;
|
|
82
83
|
setPagesLoading(true);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
credentials: 'include',
|
|
87
|
-
body: JSON.stringify({ where: {}, orderBy: { sortOrder: 'asc' } }),
|
|
84
|
+
customRequest<{ data: RawPage[] }>('page/findMany', 'POST', {
|
|
85
|
+
where: {},
|
|
86
|
+
orderBy: { sortOrder: 'asc' },
|
|
88
87
|
})
|
|
89
|
-
.then((r) => r.json())
|
|
90
88
|
.then((data) => {
|
|
91
89
|
const pages: RawPage[] = data?.data ?? [];
|
|
92
90
|
setTreeData(buildTree(pages, t('canvas.publishModal.rootPage')));
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasApi.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { SavedCanvas, CanvasItem } from './types';
|
|
2
2
|
import type { LayoutItem } from 'react-grid-layout';
|
|
3
|
-
|
|
4
|
-
const BASE = '/api/canvas';
|
|
3
|
+
import { customRequest } from 'helpers/http';
|
|
5
4
|
|
|
6
5
|
// 服务端返回的 Canvas 形状(createdAt 是 ISO 字符串)
|
|
7
6
|
interface CanvasRecord {
|
|
@@ -29,31 +28,25 @@ function toSavedCanvas(r: CanvasRecord): SavedCanvas {
|
|
|
29
28
|
};
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
async function request<T>(url: string, init?: RequestInit): Promise<T> {
|
|
33
|
-
const res = await fetch(url, {
|
|
34
|
-
headers: { 'Content-Type': 'application/json' },
|
|
35
|
-
credentials: 'include',
|
|
36
|
-
...init,
|
|
37
|
-
});
|
|
38
|
-
if (!res.ok) throw new Error(`Canvas API error: ${res.status}`);
|
|
39
|
-
return res.json() as Promise<T>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
31
|
export async function fetchCanvases(): Promise<SavedCanvas[]> {
|
|
43
|
-
const records = await
|
|
32
|
+
const records = await customRequest<CanvasRecord[]>('canvas', 'GET');
|
|
44
33
|
return records.map(toSavedCanvas);
|
|
45
34
|
}
|
|
46
35
|
|
|
47
36
|
export async function fetchCanvas(id: string): Promise<SavedCanvas | null> {
|
|
48
|
-
const record = await
|
|
37
|
+
const record = await customRequest<CanvasRecord | null>(
|
|
38
|
+
`canvas/${id}`,
|
|
39
|
+
'GET',
|
|
40
|
+
);
|
|
49
41
|
if (!record) return null;
|
|
50
42
|
return toSavedCanvas(record);
|
|
51
43
|
}
|
|
52
44
|
|
|
53
45
|
export async function createCanvas(name: string): Promise<SavedCanvas> {
|
|
54
|
-
const record = await
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
const record = await customRequest<CanvasRecord>('canvas', 'POST', {
|
|
47
|
+
name,
|
|
48
|
+
items: [],
|
|
49
|
+
layout: [],
|
|
57
50
|
});
|
|
58
51
|
return toSavedCanvas(record);
|
|
59
52
|
}
|
|
@@ -67,26 +60,24 @@ export async function updateCanvas(
|
|
|
67
60
|
>
|
|
68
61
|
>,
|
|
69
62
|
): Promise<void> {
|
|
70
|
-
await
|
|
71
|
-
method: 'PUT',
|
|
72
|
-
body: JSON.stringify(patch),
|
|
73
|
-
});
|
|
63
|
+
await customRequest(`canvas/${id}`, 'PUT', patch);
|
|
74
64
|
}
|
|
75
65
|
|
|
76
66
|
export async function deleteCanvas(id: string): Promise<void> {
|
|
77
|
-
await
|
|
67
|
+
await customRequest(`canvas/${id}`, 'DELETE');
|
|
78
68
|
}
|
|
79
69
|
|
|
80
70
|
export async function publishCanvas(
|
|
81
71
|
id: string,
|
|
82
72
|
dto: { slug: string; pageName: string; parentPageCode?: string },
|
|
83
73
|
): Promise<{ success: boolean; pageCode: string }> {
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
74
|
+
return customRequest<{ success: boolean; pageCode: string }>(
|
|
75
|
+
`canvas/${id}/publish`,
|
|
76
|
+
'POST',
|
|
77
|
+
dto,
|
|
78
|
+
);
|
|
88
79
|
}
|
|
89
80
|
|
|
90
81
|
export async function unpublishCanvas(id: string): Promise<void> {
|
|
91
|
-
await
|
|
82
|
+
await customRequest(`canvas/${id}/unpublish`, 'DELETE');
|
|
92
83
|
}
|