@gadmin2n/schematics 0.0.106 → 0.0.108
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/config/.types.d.ts +8 -9
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/AgendaJob.ts +17 -15
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Audit.ts +13 -17
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Event.ts +48 -17
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Game.ts +1 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/ITActivityDay.ts +14 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Log.ts +0 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Page.ts +42 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/PageResource.ts +28 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Resource.ts +42 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Role.ts +1 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/RolePages.ts +14 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/RoleResource.ts +28 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/SavedQuery.ts +13 -17
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/User.ts +14 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowEventOutbox.ts +17 -17
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeInstance.ts +9 -14
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeType.ts +9 -14
- package/dist/lib/application/files/gadmin2-game-angle-demo/gitignore +54 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +7 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +75 -71
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/BulkActions.tsx +36 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/ListPageHeader.tsx +41 -14
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/RowActions.tsx +153 -144
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/inspectorActions.ts +3 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/agentAllowed.tsx +35 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/env.ts +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +8 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/http.ts +20 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +48 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts +40 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +3 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +6 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasCell.tsx +4 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +4 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +99 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +28 -30
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/CanvasAiModal.tsx +80 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/game/list.tsx +6 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +2 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +2 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +2 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +6 -6
- package/package.json +2 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { useIsAgentAllowed } from 'config/agentAllowed';
|
|
3
3
|
import {
|
|
4
4
|
Alert,
|
|
5
5
|
Badge,
|
|
@@ -156,6 +156,7 @@ function formatDuration(ms: number): string {
|
|
|
156
156
|
export default function AgendaJobsPage() {
|
|
157
157
|
const navigate = useNavigate();
|
|
158
158
|
const [jobs, setJobs] = useState<JobItem[]>([]);
|
|
159
|
+
const isAgentAllowed = useIsAgentAllowed();
|
|
159
160
|
const [overview, setOverview] = useState<Overview | null>(null);
|
|
160
161
|
const [metricsOverview, setMetricsOverview] =
|
|
161
162
|
useState<MetricsOverview | null>(null);
|
|
@@ -483,7 +484,7 @@ export default function AgendaJobsPage() {
|
|
|
483
484
|
任务原始表
|
|
484
485
|
</Button>
|
|
485
486
|
</Tooltip>
|
|
486
|
-
{
|
|
487
|
+
{isAgentAllowed && (
|
|
487
488
|
<Button
|
|
488
489
|
type="primary"
|
|
489
490
|
icon={<PlusOutlined />}
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx
CHANGED
|
@@ -177,7 +177,6 @@ export const AgendaJobList: React.FC<IResourceComponentsProps> = () => {
|
|
|
177
177
|
exportLoading={exportSelectedLoading}
|
|
178
178
|
t={t}
|
|
179
179
|
resourceName={resourceName}
|
|
180
|
-
showDelete={false}
|
|
181
180
|
// Render props examples (uncomment to customize):
|
|
182
181
|
// renderDeleteButton={(onClick, loading) => <Button danger onClick={onClick} loading={loading}>Delete</Button>}
|
|
183
182
|
// renderSelectionCount={(count) => <Badge count={count}><Tag>Selected</Tag></Badge>}
|
|
@@ -186,12 +185,15 @@ export const AgendaJobList: React.FC<IResourceComponentsProps> = () => {
|
|
|
186
185
|
),
|
|
187
186
|
extra: (
|
|
188
187
|
<ListPageHeader
|
|
188
|
+
actions={[
|
|
189
|
+
...tableConfig.toolbar.actions,
|
|
190
|
+
...tableConfig.rowSelection.actions,
|
|
191
|
+
]}
|
|
189
192
|
importProps={importProps}
|
|
190
193
|
onExport={triggerExport}
|
|
191
194
|
exportLoading={exportLoading}
|
|
195
|
+
onRefresh={() => tableQueryResult.refetch()}
|
|
192
196
|
resourceName={resourceName}
|
|
193
|
-
showCreate={false}
|
|
194
|
-
showImport={false}
|
|
195
197
|
/>
|
|
196
198
|
),
|
|
197
199
|
}}
|
|
@@ -223,13 +225,11 @@ export const AgendaJobList: React.FC<IResourceComponentsProps> = () => {
|
|
|
223
225
|
<RowActions
|
|
224
226
|
record={record}
|
|
225
227
|
actions={tableConfig.rowActions.actions}
|
|
228
|
+
visibleNum={tableConfig.rowActions.visibleNum}
|
|
226
229
|
onUpdate={batchOps.updateOne}
|
|
227
230
|
updateLoading={batchOps.updateManyIsLoading}
|
|
228
231
|
t={t}
|
|
229
232
|
resourceName={resourceName}
|
|
230
|
-
showEdit={false}
|
|
231
|
-
showDelete={false}
|
|
232
|
-
showClone={false}
|
|
233
233
|
// Render props examples (uncomment to customize):
|
|
234
234
|
// showClone={false}
|
|
235
235
|
// showDelete={false}
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasCell.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import IsolatedLivePreview from './IsolatedLivePreview';
|
|
3
|
-
import {
|
|
3
|
+
import { useIsAgentAllowed } from 'config/agentAllowed';
|
|
4
4
|
|
|
5
5
|
interface CanvasCellProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
6
6
|
code: string;
|
|
@@ -34,6 +34,7 @@ const CanvasCell = React.forwardRef<HTMLDivElement, CanvasCellProps>(
|
|
|
34
34
|
ref,
|
|
35
35
|
) => {
|
|
36
36
|
const isSection = componentType === 'Section';
|
|
37
|
+
const isAgentAllowed = useIsAgentAllowed();
|
|
37
38
|
|
|
38
39
|
return (
|
|
39
40
|
<div
|
|
@@ -54,12 +55,12 @@ const CanvasCell = React.forwardRef<HTMLDivElement, CanvasCellProps>(
|
|
|
54
55
|
onClick(e);
|
|
55
56
|
}}
|
|
56
57
|
onDoubleClick={(e) => {
|
|
57
|
-
if (isPreview || !
|
|
58
|
+
if (isPreview || !isAgentAllowed) return;
|
|
58
59
|
e.stopPropagation();
|
|
59
60
|
onDoubleClick(e);
|
|
60
61
|
}}
|
|
61
62
|
onContextMenu={(e) => {
|
|
62
|
-
if (isPreview || !
|
|
63
|
+
if (isPreview || !isAgentAllowed) return;
|
|
63
64
|
e.preventDefault();
|
|
64
65
|
e.stopPropagation();
|
|
65
66
|
onContextMenu(e);
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx
CHANGED
|
@@ -24,7 +24,7 @@ import IsolatedLivePreview from './IsolatedLivePreview';
|
|
|
24
24
|
import { useTranslation } from 'react-i18next';
|
|
25
25
|
import { useUserPageAccess } from 'hooks/useUserPageAccess';
|
|
26
26
|
import { customRequest } from 'helpers/http';
|
|
27
|
-
import {
|
|
27
|
+
import { useIsAgentAllowed } from 'config/agentAllowed';
|
|
28
28
|
|
|
29
29
|
const COLS = 48;
|
|
30
30
|
const ROW_HEIGHT = 10;
|
|
@@ -71,6 +71,7 @@ const CanvasListPage: React.FC = () => {
|
|
|
71
71
|
const [canvases, setCanvases] = useState<SavedCanvas[]>([]);
|
|
72
72
|
const [loading, setLoading] = useState(true);
|
|
73
73
|
const { t } = useTranslation();
|
|
74
|
+
const isAgentAllowed = useIsAgentAllowed();
|
|
74
75
|
|
|
75
76
|
const { roleNames } = useUserPageAccess();
|
|
76
77
|
const isSystemAdmin = roleNames.includes('SYSTEM_ADMIN');
|
|
@@ -232,7 +233,7 @@ const CanvasListPage: React.FC = () => {
|
|
|
232
233
|
<Typography.Title level={4} style={{ margin: 0 }}>
|
|
233
234
|
{t('canvas.list.title')}
|
|
234
235
|
</Typography.Title>
|
|
235
|
-
{
|
|
236
|
+
{isAgentAllowed && (
|
|
236
237
|
<Button
|
|
237
238
|
type="primary"
|
|
238
239
|
icon={<PlusOutlined />}
|
|
@@ -359,7 +360,7 @@ const CanvasListPage: React.FC = () => {
|
|
|
359
360
|
{new Date(canvas.updatedAt).toLocaleString('zh-CN')}
|
|
360
361
|
</span>
|
|
361
362
|
<div style={{ display: 'flex', gap: 4 }}>
|
|
362
|
-
{
|
|
363
|
+
{isAgentAllowed && (
|
|
363
364
|
<>
|
|
364
365
|
<Button
|
|
365
366
|
type="text"
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx
CHANGED
|
@@ -29,7 +29,7 @@ import { generatePrompt } from '@/components/agentPanel/promptGenerator';
|
|
|
29
29
|
import { CANVAS_CONTEXT_MENU_REGISTRY } from './canvasContextMenuRegistry';
|
|
30
30
|
import type { MenuActionContext } from './canvasContextMenuRegistry';
|
|
31
31
|
import type { CanvasConfigModalProps } from './canvasConfigRegistry';
|
|
32
|
-
import {
|
|
32
|
+
import { useIsAgentAllowed } from 'config/agentAllowed';
|
|
33
33
|
import NumCardDataSourceModal from './components/NumCardDataSourceModal';
|
|
34
34
|
import TableDataSourceModal from './components/TableDataSourceModal';
|
|
35
35
|
import BarChartDataSourceModal from './components/BarChartDataSourceModal';
|
|
@@ -38,6 +38,7 @@ import RadarChartDataSourceModal from './components/RadarChartDataSourceModal';
|
|
|
38
38
|
import MultiChartDataSourceModal from './components/MultiChartDataSourceModal';
|
|
39
39
|
import TableConfigModal from './components/TableConfigModal';
|
|
40
40
|
import PromptModal from './components/PromptModal';
|
|
41
|
+
import CanvasAiModal from './components/CanvasAiModal';
|
|
41
42
|
import { createSectionCompactor } from './sectionCompactor';
|
|
42
43
|
import type { CanvasItem as CanvasItemType } from './types';
|
|
43
44
|
import { useTranslation } from 'react-i18next';
|
|
@@ -149,6 +150,7 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
149
150
|
const [isPreview, setIsPreview] = useState(false);
|
|
150
151
|
const [editingId, setEditingId] = useState<string | null>(null);
|
|
151
152
|
const [isDragging, setIsDragging] = useState(false);
|
|
153
|
+
const isAgentAllowed = useIsAgentAllowed();
|
|
152
154
|
const [configModal, setConfigModal] = useState<{
|
|
153
155
|
id: string;
|
|
154
156
|
componentType: string;
|
|
@@ -160,6 +162,9 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
160
162
|
code: string;
|
|
161
163
|
} | null>(null);
|
|
162
164
|
|
|
165
|
+
// ── AI 配置弹窗 state ──
|
|
166
|
+
const [aiModalOpen, setAiModalOpen] = useState(false);
|
|
167
|
+
|
|
163
168
|
// ── PromptModal state(通用文本输入弹窗)──
|
|
164
169
|
const [promptModal, setPromptModal] = useState<{
|
|
165
170
|
label: string;
|
|
@@ -218,6 +223,56 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
218
223
|
[agent],
|
|
219
224
|
);
|
|
220
225
|
|
|
226
|
+
// ── AI 配置:构造包含全量 canvas skill + 所有 items 上下文的 prompt ──
|
|
227
|
+
const handleAiSubmit = useCallback(
|
|
228
|
+
(userPrompt: string) => {
|
|
229
|
+
if (!agent) return;
|
|
230
|
+
const parts: string[] = [];
|
|
231
|
+
|
|
232
|
+
parts.push(`请帮我实现这个功能:${userPrompt}`);
|
|
233
|
+
parts.push('');
|
|
234
|
+
parts.push('严格按照以下 skill 完成任务:');
|
|
235
|
+
parts.push(
|
|
236
|
+
'1. **canvas-component-edit skill**(位于 .claude/skills/canvas-component-edit/SKILL.md):修改已有组件的流程和推送(POST /canvas-patch)',
|
|
237
|
+
);
|
|
238
|
+
parts.push(
|
|
239
|
+
'2. **canvas-item-create skill**(位于 .claude/skills/canvas-item-create/SKILL.md):新增组件的流程和推送(POST /canvas-add-item)',
|
|
240
|
+
);
|
|
241
|
+
parts.push(
|
|
242
|
+
'3. **canvas-design-standard skill**(位于 .claude/skills/canvas-design-standard/SKILL.md):所有 UI 代码规范,禁止原生 HTML 元素',
|
|
243
|
+
);
|
|
244
|
+
parts.push(
|
|
245
|
+
'4. **canvas-sql-query skill**(位于 .claude/skills/canvas-sql-query/SKILL.md):数据查询相关',
|
|
246
|
+
);
|
|
247
|
+
parts.push(
|
|
248
|
+
'5. **canvas skill**(位于 .claude/skills/canvas/SKILL.md):组件库总规范',
|
|
249
|
+
);
|
|
250
|
+
parts.push('');
|
|
251
|
+
parts.push('### 当前 Canvas 完整内容:');
|
|
252
|
+
parts.push(`共 ${items.length} 个组件:`);
|
|
253
|
+
items.forEach((item, idx) => {
|
|
254
|
+
parts.push('');
|
|
255
|
+
parts.push(
|
|
256
|
+
`#### 组件 ${idx + 1}:${item.componentType}(ID: ${item.id})`,
|
|
257
|
+
);
|
|
258
|
+
parts.push('```tsx');
|
|
259
|
+
parts.push(item.code);
|
|
260
|
+
parts.push('```');
|
|
261
|
+
});
|
|
262
|
+
parts.push('');
|
|
263
|
+
parts.push(
|
|
264
|
+
'- 修改已有组件:按照 canvas-component-edit skill 通过 POST /canvas-patch 推送新代码',
|
|
265
|
+
);
|
|
266
|
+
parts.push(
|
|
267
|
+
'- 新增组件:按照 canvas-item-create skill 通过 POST /canvas-add-item 推送',
|
|
268
|
+
);
|
|
269
|
+
parts.push('- 不要修改任何 .tsx 文件');
|
|
270
|
+
|
|
271
|
+
agent.sendPrompt(parts.join('\n'));
|
|
272
|
+
},
|
|
273
|
+
[agent, items],
|
|
274
|
+
);
|
|
275
|
+
|
|
221
276
|
const { width: containerWidth, containerRef, mounted } = useContainerWidth();
|
|
222
277
|
|
|
223
278
|
const liveRef = useRef({
|
|
@@ -320,6 +375,39 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
320
375
|
};
|
|
321
376
|
}, [updateCode]);
|
|
322
377
|
|
|
378
|
+
// ── canvas:add-item HMR 监听 — agent 通过 POST /canvas-add-item 新增画布组件 ──
|
|
379
|
+
useEffect(() => {
|
|
380
|
+
if (!import.meta.hot) return;
|
|
381
|
+
const handler = ({
|
|
382
|
+
item,
|
|
383
|
+
layout,
|
|
384
|
+
}: {
|
|
385
|
+
item: { id: string; componentType: string; code: string };
|
|
386
|
+
layout: { x: number; y: number; w: number; h: number };
|
|
387
|
+
}) => {
|
|
388
|
+
const { items, layout: currentLayout, onBothChange } = liveRef.current;
|
|
389
|
+
onBothChange(
|
|
390
|
+
[...items, item],
|
|
391
|
+
[
|
|
392
|
+
...currentLayout,
|
|
393
|
+
{
|
|
394
|
+
i: item.id,
|
|
395
|
+
x: layout.x,
|
|
396
|
+
y: layout.y,
|
|
397
|
+
w: layout.w,
|
|
398
|
+
h: layout.h,
|
|
399
|
+
minW: 4,
|
|
400
|
+
minH: 2,
|
|
401
|
+
},
|
|
402
|
+
],
|
|
403
|
+
);
|
|
404
|
+
};
|
|
405
|
+
import.meta.hot.on('canvas:add-item', handler);
|
|
406
|
+
return () => {
|
|
407
|
+
import.meta.hot?.off('canvas:add-item', handler);
|
|
408
|
+
};
|
|
409
|
+
}, []);
|
|
410
|
+
|
|
323
411
|
// ── MultiChart 工具栏切换图表类型时,同步更新代码中的 defaultVariant ──
|
|
324
412
|
useEffect(() => {
|
|
325
413
|
const handler = (e: Event) => {
|
|
@@ -705,6 +793,7 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
705
793
|
onPublish={onPublish}
|
|
706
794
|
onUnpublish={onUnpublish}
|
|
707
795
|
onPreview={() => setIsPreview(true)}
|
|
796
|
+
onAiConfig={() => setAiModalOpen(true)}
|
|
708
797
|
/>
|
|
709
798
|
)}
|
|
710
799
|
|
|
@@ -779,14 +868,14 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
779
868
|
margin: [MARGIN_Y, MARGIN_Y] as const,
|
|
780
869
|
}}
|
|
781
870
|
dragConfig={{
|
|
782
|
-
enabled: !isPreview &&
|
|
871
|
+
enabled: !isPreview && isAgentAllowed,
|
|
783
872
|
handle: '.canvas-item-drag',
|
|
784
873
|
}}
|
|
785
874
|
resizeConfig={{
|
|
786
|
-
enabled: !isPreview &&
|
|
875
|
+
enabled: !isPreview && isAgentAllowed,
|
|
787
876
|
}}
|
|
788
|
-
dropConfig={isPreview || !
|
|
789
|
-
onDrop={isPreview || !
|
|
877
|
+
dropConfig={isPreview || !isAgentAllowed ? undefined : dropConfig}
|
|
878
|
+
onDrop={isPreview || !isAgentAllowed ? undefined : handleDrop}
|
|
790
879
|
compactor={sectionCompactor}
|
|
791
880
|
onResizeStop={handleResizeStop}
|
|
792
881
|
onDragStart={() => setIsDragging(true)}
|
|
@@ -1509,6 +1598,11 @@ const CanvasPage: React.FC<CanvasPageProps> = ({
|
|
|
1509
1598
|
}}
|
|
1510
1599
|
onCancel={() => setPromptModal(null)}
|
|
1511
1600
|
/>
|
|
1601
|
+
<CanvasAiModal
|
|
1602
|
+
open={aiModalOpen}
|
|
1603
|
+
onClose={() => setAiModalOpen(false)}
|
|
1604
|
+
onSubmit={handleAiSubmit}
|
|
1605
|
+
/>
|
|
1512
1606
|
</div>
|
|
1513
1607
|
</div>
|
|
1514
1608
|
);
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
2
|
import { Button, Tooltip, Popover } from 'antd';
|
|
3
|
-
import {
|
|
3
|
+
import { useIsAgentAllowed } from 'config/agentAllowed';
|
|
4
4
|
import {
|
|
5
5
|
SaveOutlined,
|
|
6
6
|
ArrowLeftOutlined,
|
|
7
7
|
RocketOutlined,
|
|
8
|
-
AppstoreOutlined,
|
|
9
8
|
EyeOutlined,
|
|
9
|
+
RobotOutlined,
|
|
10
10
|
} from '@ant-design/icons';
|
|
11
11
|
import ComponentThumbnail from './ComponentThumbnail';
|
|
12
12
|
import { CANVAS_COMPONENTS, CANVAS_DEFAULTS } from './canvasDefaults';
|
|
@@ -22,6 +22,7 @@ interface CanvasToolbarProps {
|
|
|
22
22
|
onPublish: () => void;
|
|
23
23
|
onUnpublish: () => void;
|
|
24
24
|
onPreview: () => void;
|
|
25
|
+
onAiConfig: () => void;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
@@ -33,8 +34,10 @@ const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
|
33
34
|
onPublish,
|
|
34
35
|
onUnpublish,
|
|
35
36
|
onPreview,
|
|
37
|
+
onAiConfig,
|
|
36
38
|
}) => {
|
|
37
39
|
const { t } = useTranslation();
|
|
40
|
+
const isAgentAllowed = useIsAgentAllowed();
|
|
38
41
|
|
|
39
42
|
const handleVariantDragStart = useCallback(
|
|
40
43
|
(e: React.DragEvent, componentType: string, variantCode: string) => {
|
|
@@ -102,31 +105,8 @@ const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
|
102
105
|
</span>
|
|
103
106
|
</div>
|
|
104
107
|
|
|
105
|
-
{/* 中间:
|
|
106
|
-
<div
|
|
107
|
-
style={{
|
|
108
|
-
display: 'flex',
|
|
109
|
-
alignItems: 'center',
|
|
110
|
-
justifyContent: 'center',
|
|
111
|
-
}}
|
|
112
|
-
>
|
|
113
|
-
<Button
|
|
114
|
-
size="small"
|
|
115
|
-
icon={<AppstoreOutlined />}
|
|
116
|
-
style={{
|
|
117
|
-
fontSize: 13,
|
|
118
|
-
fontWeight: 500,
|
|
119
|
-
borderRadius: 8,
|
|
120
|
-
border: 'none',
|
|
121
|
-
background: '#4361ee',
|
|
122
|
-
color: '#fff',
|
|
123
|
-
boxShadow: '0 2px 8px rgba(67,97,238,0.3)',
|
|
124
|
-
cursor: 'default',
|
|
125
|
-
}}
|
|
126
|
-
>
|
|
127
|
-
{t('canvas.componentLib')}
|
|
128
|
-
</Button>
|
|
129
|
-
</div>
|
|
108
|
+
{/* 中间: 占位(保持左右对称布局) */}
|
|
109
|
+
<div />
|
|
130
110
|
|
|
131
111
|
{/* 右侧: 保存 + 发布 */}
|
|
132
112
|
<div
|
|
@@ -138,7 +118,25 @@ const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
|
138
118
|
gap: 10,
|
|
139
119
|
}}
|
|
140
120
|
>
|
|
141
|
-
{
|
|
121
|
+
{isAgentAllowed && (
|
|
122
|
+
<Button
|
|
123
|
+
size="small"
|
|
124
|
+
icon={<RobotOutlined />}
|
|
125
|
+
onClick={onAiConfig}
|
|
126
|
+
style={{
|
|
127
|
+
borderRadius: 8,
|
|
128
|
+
border: 'none',
|
|
129
|
+
background: '#4361ee',
|
|
130
|
+
color: '#fff',
|
|
131
|
+
fontWeight: 500,
|
|
132
|
+
boxShadow: '0 2px 12px rgba(67,97,238,0.45)',
|
|
133
|
+
transition: 'all 200ms ease',
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
AI 配置
|
|
137
|
+
</Button>
|
|
138
|
+
)}
|
|
139
|
+
{isAgentAllowed && (
|
|
142
140
|
<Button
|
|
143
141
|
size="small"
|
|
144
142
|
icon={<SaveOutlined />}
|
|
@@ -186,7 +184,7 @@ const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
|
186
184
|
>
|
|
187
185
|
{t('canvas.preview')}
|
|
188
186
|
</Button>
|
|
189
|
-
{
|
|
187
|
+
{isAgentAllowed && (
|
|
190
188
|
<Button
|
|
191
189
|
size="small"
|
|
192
190
|
icon={<RocketOutlined />}
|
|
@@ -208,7 +206,7 @@ const CanvasToolbar: React.FC<CanvasToolbarProps> = ({
|
|
|
208
206
|
</div>
|
|
209
207
|
|
|
210
208
|
{/* ── Thumbnail row (only in dev) ── */}
|
|
211
|
-
{
|
|
209
|
+
{isAgentAllowed && (
|
|
212
210
|
<div
|
|
213
211
|
style={{
|
|
214
212
|
display: 'flex',
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react';
|
|
2
|
+
import { Modal, Input } from 'antd';
|
|
3
|
+
import type { TextAreaRef } from 'antd/es/input/TextArea';
|
|
4
|
+
import { CANVAS_MODAL_TITLE_STYLE } from './canvasModalProps';
|
|
5
|
+
|
|
6
|
+
export interface CanvasAiModalProps {
|
|
7
|
+
/** 控制弹窗开关 */
|
|
8
|
+
open: boolean;
|
|
9
|
+
/** 关闭回调 */
|
|
10
|
+
onClose: () => void;
|
|
11
|
+
/** 提交回调,返回用户输入的 prompt(已 trim) */
|
|
12
|
+
onSubmit: (prompt: string) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Canvas AI 配置弹窗 —— 用于向 AI 发送对整个 canvas 页面的配置指令。
|
|
17
|
+
* 特点:多行输入、自动聚焦、Ctrl+Enter 确认、ESC 取消。
|
|
18
|
+
*/
|
|
19
|
+
const CanvasAiModal: React.FC<CanvasAiModalProps> = ({
|
|
20
|
+
open,
|
|
21
|
+
onClose,
|
|
22
|
+
onSubmit,
|
|
23
|
+
}) => {
|
|
24
|
+
const [value, setValue] = useState('');
|
|
25
|
+
const textAreaRef = useRef<TextAreaRef>(null);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (open) {
|
|
29
|
+
setValue('');
|
|
30
|
+
requestAnimationFrame(() => {
|
|
31
|
+
textAreaRef.current?.focus();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}, [open]);
|
|
35
|
+
|
|
36
|
+
const handleOk = () => {
|
|
37
|
+
const trimmed = value.trim();
|
|
38
|
+
if (!trimmed) return;
|
|
39
|
+
onSubmit(trimmed);
|
|
40
|
+
onClose();
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<Modal
|
|
45
|
+
width={520}
|
|
46
|
+
centered
|
|
47
|
+
destroyOnClose
|
|
48
|
+
closable={false}
|
|
49
|
+
styles={{
|
|
50
|
+
header: { padding: '16px 20px 0', marginBottom: 0 },
|
|
51
|
+
body: { padding: '12px 20px 16px' },
|
|
52
|
+
footer: { padding: '0 20px 16px', borderTop: 'none' },
|
|
53
|
+
}}
|
|
54
|
+
open={open}
|
|
55
|
+
onCancel={onClose}
|
|
56
|
+
onOk={handleOk}
|
|
57
|
+
okText="发送给 AI"
|
|
58
|
+
cancelText="取消"
|
|
59
|
+
title={<span style={CANVAS_MODAL_TITLE_STYLE}>AI 配置页面</span>}
|
|
60
|
+
>
|
|
61
|
+
<Input.TextArea
|
|
62
|
+
ref={textAreaRef}
|
|
63
|
+
value={value}
|
|
64
|
+
placeholder="描述你想要的页面效果,例如:把所有数字卡片改成蓝色主题,图表数据改为近7天趋势"
|
|
65
|
+
onChange={(e) => setValue(e.target.value)}
|
|
66
|
+
onKeyDown={(e) => {
|
|
67
|
+
if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
handleOk();
|
|
70
|
+
}
|
|
71
|
+
}}
|
|
72
|
+
style={{ borderRadius: 6 }}
|
|
73
|
+
autoSize={{ minRows: 4, maxRows: 10 }}
|
|
74
|
+
allowClear
|
|
75
|
+
/>
|
|
76
|
+
</Modal>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export default CanvasAiModal;
|
|
@@ -180,9 +180,14 @@ export const GameList: React.FC<IResourceComponentsProps> = () => {
|
|
|
180
180
|
),
|
|
181
181
|
extra: (
|
|
182
182
|
<ListPageHeader
|
|
183
|
+
actions={[
|
|
184
|
+
...tableConfig.toolbar.actions,
|
|
185
|
+
...tableConfig.rowSelection.actions,
|
|
186
|
+
]}
|
|
183
187
|
importProps={importProps}
|
|
184
188
|
onExport={triggerExport}
|
|
185
189
|
exportLoading={exportLoading}
|
|
190
|
+
onRefresh={() => tableQueryResult.refetch()}
|
|
186
191
|
resourceName={resourceName}
|
|
187
192
|
/>
|
|
188
193
|
),
|
|
@@ -215,6 +220,7 @@ export const GameList: React.FC<IResourceComponentsProps> = () => {
|
|
|
215
220
|
<RowActions
|
|
216
221
|
record={record}
|
|
217
222
|
actions={tableConfig.rowActions.actions}
|
|
223
|
+
visibleNum={tableConfig.rowActions.visibleNum}
|
|
218
224
|
onUpdate={batchOps.updateOne}
|
|
219
225
|
updateLoading={batchOps.updateManyIsLoading}
|
|
220
226
|
t={t}
|
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx
CHANGED
|
@@ -31,7 +31,7 @@ import { FlowRenderer } from './components/FlowRenderer';
|
|
|
31
31
|
import { NodePropertyPanel } from './components/NodePropertyPanel';
|
|
32
32
|
import { DslView, type DslViewHandle } from './components/DslView';
|
|
33
33
|
import { useWorkflowAgent } from './hooks/useWorkflowAgent';
|
|
34
|
-
import {
|
|
34
|
+
import { useIsAgentAllowed } from 'config/agentAllowed';
|
|
35
35
|
import type {
|
|
36
36
|
Workflow,
|
|
37
37
|
WorkflowDSL,
|
|
@@ -55,6 +55,7 @@ export default function WorkflowEditorPage() {
|
|
|
55
55
|
const [versions, setVersions] = useState<WorkflowVersion[]>([]);
|
|
56
56
|
const [nodeTypes, setNodeTypes] = useState<WorkflowNodeType[]>([]);
|
|
57
57
|
const [loading, setLoading] = useState(!isNewMode);
|
|
58
|
+
const isDev = useIsAgentAllowed();
|
|
58
59
|
|
|
59
60
|
const [dsl, setDsl] = useState<WorkflowDSL | null>(null);
|
|
60
61
|
const [currentVersion, setCurrentVersion] = useState<number | null>(null);
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import type { WorkflowNodeType } from '../../types';
|
|
20
20
|
|
|
21
21
|
const { Title } = Typography;
|
|
22
|
-
import {
|
|
22
|
+
import { useIsAgentAllowed } from 'config/agentAllowed';
|
|
23
23
|
|
|
24
24
|
interface NodeInstanceFormProps {
|
|
25
25
|
form: FormInstance;
|
|
@@ -43,6 +43,7 @@ export function NodeInstanceForm({
|
|
|
43
43
|
onBack,
|
|
44
44
|
}: NodeInstanceFormProps) {
|
|
45
45
|
const [aiModalOpen, setAiModalOpen] = useState(false);
|
|
46
|
+
const isDev = useIsAgentAllowed();
|
|
46
47
|
|
|
47
48
|
const selectedNodeTypeId = Form.useWatch('nodeTypeId', form);
|
|
48
49
|
|
|
@@ -48,7 +48,7 @@ const STATUS_COLOR: Record<string, string> = {
|
|
|
48
48
|
PUBLISHED: 'success',
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
import {
|
|
51
|
+
import { useIsAgentAllowed } from 'config/agentAllowed';
|
|
52
52
|
|
|
53
53
|
export default function WorkflowShowPage() {
|
|
54
54
|
const { id } = useParams<{ id: string }>();
|
|
@@ -58,6 +58,7 @@ export default function WorkflowShowPage() {
|
|
|
58
58
|
const [versions, setVersions] = useState<WorkflowVersion[]>([]);
|
|
59
59
|
const [nodeTypes, setNodeTypes] = useState<WorkflowNodeType[]>([]);
|
|
60
60
|
const [loading, setLoading] = useState(true);
|
|
61
|
+
const isDev = useIsAgentAllowed();
|
|
61
62
|
|
|
62
63
|
const [dsl, setDsl] = useState<WorkflowDSL | null>(null);
|
|
63
64
|
const [currentVersion, setCurrentVersion] = useState<number | null>(null);
|
|
@@ -186,7 +186,6 @@ export const WorkflowEventOutboxList: React.FC<
|
|
|
186
186
|
exportLoading={exportSelectedLoading}
|
|
187
187
|
t={t}
|
|
188
188
|
resourceName={resourceName}
|
|
189
|
-
showDelete={false}
|
|
190
189
|
// Render props examples (uncomment to customize):
|
|
191
190
|
// renderDeleteButton={(onClick, loading) => <Button danger onClick={onClick} loading={loading}>Delete</Button>}
|
|
192
191
|
// renderSelectionCount={(count) => <Badge count={count}><Tag>Selected</Tag></Badge>}
|
|
@@ -195,12 +194,15 @@ export const WorkflowEventOutboxList: React.FC<
|
|
|
195
194
|
),
|
|
196
195
|
extra: (
|
|
197
196
|
<ListPageHeader
|
|
197
|
+
actions={[
|
|
198
|
+
...tableConfig.toolbar.actions,
|
|
199
|
+
...tableConfig.rowSelection.actions,
|
|
200
|
+
]}
|
|
198
201
|
importProps={importProps}
|
|
199
202
|
onExport={triggerExport}
|
|
200
203
|
exportLoading={exportLoading}
|
|
204
|
+
onRefresh={() => tableQueryResult.refetch()}
|
|
201
205
|
resourceName={resourceName}
|
|
202
|
-
showCreate={false}
|
|
203
|
-
showImport={false}
|
|
204
206
|
/>
|
|
205
207
|
),
|
|
206
208
|
}}
|
|
@@ -232,13 +234,11 @@ export const WorkflowEventOutboxList: React.FC<
|
|
|
232
234
|
<RowActions
|
|
233
235
|
record={record}
|
|
234
236
|
actions={tableConfig.rowActions.actions}
|
|
237
|
+
visibleNum={tableConfig.rowActions.visibleNum}
|
|
235
238
|
onUpdate={batchOps.updateOne}
|
|
236
239
|
updateLoading={batchOps.updateManyIsLoading}
|
|
237
240
|
t={t}
|
|
238
241
|
resourceName={resourceName}
|
|
239
|
-
showEdit={false}
|
|
240
|
-
showDelete={false}
|
|
241
|
-
showClone={false}
|
|
242
242
|
// Render props examples (uncomment to customize):
|
|
243
243
|
// showClone={false}
|
|
244
244
|
// showDelete={false}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gadmin2n/schematics",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.108",
|
|
4
4
|
"description": "Gadmin - modern, fast, powerful node.js web framework (@schematics)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
+
"prebuild": "find src/lib -path '*/files*/.gitignore' -exec sh -c 'mv \"$1\" \"$(dirname \"$1\")/gitignore\"' _ {} \\;",
|
|
13
14
|
"postbuild": "npm run copy:collection && npm run copy:lib && npm run scrub:dist",
|
|
14
15
|
"build": "rm -rf dist && tsc --project tsconfig.lib.json",
|
|
15
16
|
"clean": "gulp clean:src",
|