@gadmin2n/schematics 0.0.151 → 0.0.153
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/prisma/workflow.prisma +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/.seed-timestamp +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +2 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permission.seed.ts +23 -44
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +25 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +74 -64
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +0 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-cancellation.spec.ts +17 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +58 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +66 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution-idempotency.spec.ts +61 -149
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-runtime.controller.spec.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-runtime.controller.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle.service.spec.ts +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.spec.ts +38 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +18 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +131 -242
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.test.ts +7 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +6 -36
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +0 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +29 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +29 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/people-groups/index.tsx +20 -17
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/person-directory/index.tsx +38 -35
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.tsx +6 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.tsx +24 -22
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/EnhancedFlowRenderer.tsx +0 -11
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +24 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.tsx +20 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +7 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +28 -79
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +5 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +0 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DbExecuteConfigEditor.tsx +227 -97
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SimplifiedNodeEditors.test.tsx +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/settings/index.tsx +73 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +21 -46
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +2 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +1 -0
- package/package.json +1 -1
|
@@ -533,6 +533,7 @@ describe('simplified workflow node editors', () => {
|
|
|
533
533
|
);
|
|
534
534
|
|
|
535
535
|
expect(onChange).toHaveBeenCalledWith({
|
|
536
|
+
mode: 'FUNCTION',
|
|
536
537
|
functionRef: {
|
|
537
538
|
schema: 'workflow_api',
|
|
538
539
|
name: 'approve_request',
|
|
@@ -549,4 +550,65 @@ describe('simplified workflow node editors', () => {
|
|
|
549
550
|
'GET',
|
|
550
551
|
);
|
|
551
552
|
});
|
|
553
|
+
|
|
554
|
+
it('switches a database node to Raw SQL without removing its Function config', async () => {
|
|
555
|
+
await i18n.changeLanguage('zh_CN');
|
|
556
|
+
customRequest.mockResolvedValueOnce([]);
|
|
557
|
+
const onChange = vi.fn();
|
|
558
|
+
render(
|
|
559
|
+
<DbExecuteConfigEditor
|
|
560
|
+
value={{
|
|
561
|
+
mode: 'FUNCTION',
|
|
562
|
+
functionRef: {
|
|
563
|
+
schema: 'workflow_api',
|
|
564
|
+
name: 'approve_request',
|
|
565
|
+
identityArguments: 'p_request_id bigint',
|
|
566
|
+
},
|
|
567
|
+
argumentBindings: [{ source: 'INPUT', path: 'request_id' }],
|
|
568
|
+
timeoutSeconds: 30,
|
|
569
|
+
}}
|
|
570
|
+
onChange={onChange}
|
|
571
|
+
schema={schema}
|
|
572
|
+
/>,
|
|
573
|
+
);
|
|
574
|
+
|
|
575
|
+
await screen.findByRole('combobox', { name: '数据库 Function' });
|
|
576
|
+
fireEvent.click(screen.getByText('Raw SQL'));
|
|
577
|
+
|
|
578
|
+
expect(onChange).toHaveBeenLastCalledWith({
|
|
579
|
+
mode: 'SQL',
|
|
580
|
+
functionRef: {
|
|
581
|
+
schema: 'workflow_api',
|
|
582
|
+
name: 'approve_request',
|
|
583
|
+
identityArguments: 'p_request_id bigint',
|
|
584
|
+
},
|
|
585
|
+
argumentBindings: [{ source: 'INPUT', path: 'request_id' }],
|
|
586
|
+
timeoutSeconds: 30,
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
it('shows the SQL editor when a database node uses Raw SQL mode', async () => {
|
|
591
|
+
await i18n.changeLanguage('zh_CN');
|
|
592
|
+
customRequest.mockResolvedValueOnce([]);
|
|
593
|
+
render(
|
|
594
|
+
<DbExecuteConfigEditor
|
|
595
|
+
value={{
|
|
596
|
+
mode: 'SQL',
|
|
597
|
+
allowWrite: false,
|
|
598
|
+
sql: 'SELECT id FROM users WHERE id = $1',
|
|
599
|
+
parameters: [{ source: 'INPUT', path: 'id' }],
|
|
600
|
+
timeoutSeconds: 30,
|
|
601
|
+
}}
|
|
602
|
+
onChange={vi.fn()}
|
|
603
|
+
schema={schema}
|
|
604
|
+
/>,
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
expect(screen.getByRole('textbox', { name: 'SQL 语句' })).toHaveValue(
|
|
608
|
+
'SELECT id FROM users WHERE id = $1',
|
|
609
|
+
);
|
|
610
|
+
expect(
|
|
611
|
+
screen.queryByRole('combobox', { name: '数据库 Function' }),
|
|
612
|
+
).not.toBeInTheDocument();
|
|
613
|
+
});
|
|
552
614
|
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Tabs } from 'antd';
|
|
2
|
+
import { PageHeader } from 'components';
|
|
3
|
+
import { PAGE_WRAPPER_STYLE } from 'constants/layout';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { useSearchParams } from 'react-router-dom';
|
|
6
|
+
import PersonDirectoryPage from 'routes/person-directory';
|
|
7
|
+
import PeopleGroupsPage from 'routes/people-groups';
|
|
8
|
+
import BusinessEventCatalogPage from '../business-events';
|
|
9
|
+
import ConnectionsPage from '../connections';
|
|
10
|
+
import TemporalTenantPage from '../temporal-tenant';
|
|
11
|
+
|
|
12
|
+
const TAB_KEYS = [
|
|
13
|
+
'tenant',
|
|
14
|
+
'connections',
|
|
15
|
+
'events',
|
|
16
|
+
'people',
|
|
17
|
+
'groups',
|
|
18
|
+
] as const;
|
|
19
|
+
type TabKey = (typeof TAB_KEYS)[number];
|
|
20
|
+
|
|
21
|
+
function parseTab(value: string | null): TabKey {
|
|
22
|
+
return (TAB_KEYS as readonly string[]).includes(value ?? '')
|
|
23
|
+
? (value as TabKey)
|
|
24
|
+
: 'tenant';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default function WorkflowSettingsPage() {
|
|
28
|
+
const { t } = useTranslation('workflow');
|
|
29
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
30
|
+
const activeKey = parseTab(searchParams.get('tab'));
|
|
31
|
+
|
|
32
|
+
const items = [
|
|
33
|
+
{
|
|
34
|
+
key: 'tenant',
|
|
35
|
+
label: t('settings.tabTenant'),
|
|
36
|
+
children: <TemporalTenantPage />,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
key: 'connections',
|
|
40
|
+
label: t('settings.tabConnections'),
|
|
41
|
+
children: <ConnectionsPage />,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
key: 'events',
|
|
45
|
+
label: t('settings.tabEvents'),
|
|
46
|
+
children: <BusinessEventCatalogPage />,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
key: 'people',
|
|
50
|
+
label: t('settings.tabPeople'),
|
|
51
|
+
children: <PersonDirectoryPage />,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
key: 'groups',
|
|
55
|
+
label: t('settings.tabGroups'),
|
|
56
|
+
children: <PeopleGroupsPage />,
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div style={PAGE_WRAPPER_STYLE}>
|
|
62
|
+
<PageHeader
|
|
63
|
+
title={t('settings.title')}
|
|
64
|
+
subtitle={t('settings.subtitle')}
|
|
65
|
+
/>
|
|
66
|
+
<Tabs
|
|
67
|
+
activeKey={activeKey}
|
|
68
|
+
items={items}
|
|
69
|
+
onChange={(key) => setSearchParams({ tab: key }, { replace: true })}
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ApiOutlined,
|
|
3
|
-
ArrowLeftOutlined,
|
|
4
3
|
CheckCircleFilled,
|
|
5
4
|
EditOutlined,
|
|
6
5
|
EyeInvisibleOutlined,
|
|
@@ -27,10 +26,8 @@ import {
|
|
|
27
26
|
message,
|
|
28
27
|
theme,
|
|
29
28
|
} from 'antd';
|
|
30
|
-
import { HEADER_CARD_PROPS, PAGE_WRAPPER_STYLE } from 'constants/layout';
|
|
31
29
|
import { customRequest } from 'helpers/http';
|
|
32
30
|
import { useCallback, useEffect, useState } from 'react';
|
|
33
|
-
import { useNavigate } from 'react-router-dom';
|
|
34
31
|
import '../workflow-ui.css';
|
|
35
32
|
import { useWorkflowFormValidation } from '../useWorkflowFormValidation';
|
|
36
33
|
|
|
@@ -134,7 +131,6 @@ function SensitiveValue({
|
|
|
134
131
|
}
|
|
135
132
|
|
|
136
133
|
export default function TemporalTenantPage() {
|
|
137
|
-
const navigate = useNavigate();
|
|
138
134
|
const [form] = Form.useForm<TenantConfigFormValues>();
|
|
139
135
|
const formValidation = useWorkflowFormValidation();
|
|
140
136
|
const { token } = theme.useToken();
|
|
@@ -281,55 +277,34 @@ export default function TemporalTenantPage() {
|
|
|
281
277
|
}
|
|
282
278
|
|
|
283
279
|
return (
|
|
284
|
-
<div className="workflow-page-stack"
|
|
285
|
-
|
|
280
|
+
<div className="workflow-page-stack">
|
|
281
|
+
{!loading && !loadError && existing && (
|
|
286
282
|
<div
|
|
287
283
|
style={{
|
|
288
284
|
display: 'flex',
|
|
289
|
-
|
|
290
|
-
justifyContent: 'space-between',
|
|
291
|
-
gap: 16,
|
|
292
|
-
flexWrap: 'wrap',
|
|
285
|
+
justifyContent: 'flex-end',
|
|
293
286
|
}}
|
|
294
287
|
>
|
|
295
|
-
<
|
|
288
|
+
<Space>
|
|
296
289
|
<Button
|
|
297
|
-
|
|
298
|
-
icon={<
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
<Button
|
|
314
|
-
aria-label="测试连通性"
|
|
315
|
-
icon={<ApiOutlined />}
|
|
316
|
-
loading={testing}
|
|
317
|
-
onClick={() => testConnection(toFormValues(existing))}
|
|
318
|
-
>
|
|
319
|
-
测试连通性
|
|
320
|
-
</Button>
|
|
321
|
-
<Button
|
|
322
|
-
type="primary"
|
|
323
|
-
aria-label="修改配置"
|
|
324
|
-
icon={<EditOutlined />}
|
|
325
|
-
onClick={openEditor}
|
|
326
|
-
>
|
|
327
|
-
修改配置
|
|
328
|
-
</Button>
|
|
329
|
-
</Space>
|
|
330
|
-
)}
|
|
290
|
+
aria-label="测试连通性"
|
|
291
|
+
icon={<ApiOutlined />}
|
|
292
|
+
loading={testing}
|
|
293
|
+
onClick={() => testConnection(toFormValues(existing))}
|
|
294
|
+
>
|
|
295
|
+
测试连通性
|
|
296
|
+
</Button>
|
|
297
|
+
<Button
|
|
298
|
+
type="primary"
|
|
299
|
+
aria-label="修改配置"
|
|
300
|
+
icon={<EditOutlined />}
|
|
301
|
+
onClick={openEditor}
|
|
302
|
+
>
|
|
303
|
+
修改配置
|
|
304
|
+
</Button>
|
|
305
|
+
</Space>
|
|
331
306
|
</div>
|
|
332
|
-
|
|
307
|
+
)}
|
|
333
308
|
|
|
334
309
|
<Card>
|
|
335
310
|
{loading ? (
|
|
@@ -66,6 +66,7 @@ export interface Workflow {
|
|
|
66
66
|
runs?: {
|
|
67
67
|
pending: number;
|
|
68
68
|
running: number;
|
|
69
|
+
waiting_retry: number;
|
|
69
70
|
completed: number;
|
|
70
71
|
failed: number;
|
|
71
72
|
cancelled: number;
|
|
@@ -93,6 +94,7 @@ export interface WorkflowOverview {
|
|
|
93
94
|
};
|
|
94
95
|
running: number;
|
|
95
96
|
pending: number;
|
|
97
|
+
waitingRetry: number;
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
export interface WorkflowNodeType {
|