@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.
Files changed (42) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +1 -0
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.seed-timestamp +1 -0
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +2 -1
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permission.seed.ts +23 -44
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +25 -4
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +74 -64
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +0 -7
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-cancellation.spec.ts +17 -0
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +58 -3
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +66 -6
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution-idempotency.spec.ts +61 -149
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +1 -1
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-runtime.controller.spec.ts +1 -1
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-runtime.controller.ts +1 -1
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle.service.spec.ts +2 -2
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.spec.ts +38 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +18 -7
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +1 -0
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +131 -242
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.test.ts +7 -5
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +6 -36
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +0 -4
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +29 -7
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +29 -7
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/people-groups/index.tsx +20 -17
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/person-directory/index.tsx +38 -35
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.tsx +6 -1
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.tsx +24 -22
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/EnhancedFlowRenderer.tsx +0 -11
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +24 -0
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.tsx +20 -18
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +7 -0
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +28 -79
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +5 -0
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +0 -1
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DbExecuteConfigEditor.tsx +227 -97
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SimplifiedNodeEditors.test.tsx +62 -0
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/settings/index.tsx +73 -0
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +21 -46
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +2 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +1 -0
  42. 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" style={PAGE_WRAPPER_STYLE}>
285
- <Card {...HEADER_CARD_PROPS}>
280
+ <div className="workflow-page-stack">
281
+ {!loading && !loadError && existing && (
286
282
  <div
287
283
  style={{
288
284
  display: 'flex',
289
- alignItems: 'center',
290
- justifyContent: 'space-between',
291
- gap: 16,
292
- flexWrap: 'wrap',
285
+ justifyContent: 'flex-end',
293
286
  }}
294
287
  >
295
- <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
288
+ <Space>
296
289
  <Button
297
- type="text"
298
- icon={<ArrowLeftOutlined />}
299
- onClick={() => navigate(-1)}
300
- />
301
- <div>
302
- <Title level={4} style={{ margin: 0 }}>
303
- 服务注册
304
- </Title>
305
- <Text type="secondary" style={{ fontSize: 12 }}>
306
- 管理本 GAdmin 与 Temporal Worker 的连接配置
307
- </Text>
308
- </div>
309
- </div>
310
-
311
- {!loading && !loadError && existing && (
312
- <Space>
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
- </Card>
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 {
@@ -96,6 +96,7 @@ export function withNewNodeDefaults(
96
96
  }
97
97
  if (nodeType === 'db_execute') {
98
98
  return {
99
+ mode: 'FUNCTION',
99
100
  argumentBindings: [],
100
101
  timeoutSeconds: 30,
101
102
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gadmin2n/schematics",
3
- "version": "0.0.151",
3
+ "version": "0.0.153",
4
4
  "description": "Gadmin - modern, fast, powerful node.js web framework (@schematics)",
5
5
  "main": "dist/index.js",
6
6
  "files": [