@gadmin2n/schematics 0.0.147 → 0.0.149

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 (106) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +2 -1
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permission.seed.ts +67 -15
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +83 -53
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/config/index.ts +5 -0
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/structured-all-exceptions.filter.spec.ts +24 -0
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/lib/structured-all-exceptions.filter.ts +15 -0
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.controller.ts +4 -0
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.service.ts +31 -4
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.spec.ts +2 -6
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-subject-source.util.spec.ts +28 -29
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-subject-source.util.ts +16 -34
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.dto.ts +3 -3
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.spec.ts +61 -6
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.spec.ts +2 -2
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +2 -0
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.controller.ts +11 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.service.spec.ts +126 -0
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.service.ts +136 -0
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/staffDirectory/staff-directory.controller.ts +24 -0
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/staffDirectory/staff-directory.dto.ts +8 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/staffDirectory/staff-directory.service.spec.ts +62 -0
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/staffDirectory/staff-directory.service.ts +94 -0
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/staffDirectory/staff-directory.types.ts +6 -0
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/staffDirectory/staffDirectory.module.ts +10 -0
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/subjectProvider/providers/user.provider.ts +6 -2
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.spec.ts +20 -12
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.ts +21 -19
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.controller.ts +11 -0
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.service.spec.ts +97 -0
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.service.ts +150 -2
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/userGroup/user-group.controller.ts +13 -1
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/userGroup/user-group.dto.ts +13 -1
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/userGroup/user-group.errors.ts +1 -0
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/userGroup/user-group.service.spec.ts +125 -0
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/userGroup/user-group.service.ts +118 -5
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-cancellation.spec.ts +20 -3
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +6 -9
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-event-catalog.spec.ts +166 -17
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-event-trigger.pg.spec.ts +82 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-runtime.facade.ts +2 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.spec.ts +4 -1
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +5 -1
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +7 -2
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +44 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +106 -37
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/node-config-validator.service.spec.ts +59 -3
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/subject-config-validator.service.spec.ts +33 -22
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/subject-config-validator.service.ts +10 -23
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/StaffSelect/StaffSelect.test.tsx +69 -0
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/StaffSelect/StaffSelect.tsx +145 -0
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/StaffSelect/index.ts +2 -0
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/StaffSelect/staff-directory.api.ts +16 -0
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/index.ts +1 -0
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.test.ts +10 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +20 -2
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +6 -0
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +60 -14
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +60 -14
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +41 -1
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/people-groups/PeopleGroupModal.tsx +181 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/people-groups/index.tsx +203 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/people-groups/people-groups.api.ts +145 -0
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/person-directory/PersonModal.tsx +112 -0
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/person-directory/index.tsx +214 -0
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/person-directory/person-directory.api.ts +79 -0
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/form-modal.tsx +7 -11
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/list.tsx +7 -7
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/RegisterBusinessEventModal.test.tsx +46 -5
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/RegisterBusinessEventModal.tsx +14 -10
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.test.tsx +1 -1
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.tsx +2 -1
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.test.tsx +1 -1
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.tsx +2 -2
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.test.tsx +20 -0
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.test.tsx +97 -28
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +87 -119
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowCodeEditor.test.tsx +22 -1
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowCodeEditor.tsx +8 -2
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/connections.css +8 -46
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/connectionsApi.ts +7 -0
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.test.tsx +32 -3
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.tsx +163 -106
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +8 -1
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.test.tsx +26 -0
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +34 -6
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/node-config.css +13 -16
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/node-instance-show.css +185 -0
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +224 -105
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.test.tsx +1 -1
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DbExecuteConfigEditor.tsx +21 -12
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/EventTriggerConfigEditor.test.tsx +140 -0
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/EventTriggerConfigEditor.tsx +124 -62
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.test.tsx +160 -8
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.tsx +125 -55
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SimplifiedNodeEditors.test.tsx +78 -17
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubjectPicker.test.tsx +33 -1
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubjectPicker.tsx +28 -46
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/event-catalog.api.ts +4 -2
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/human-approval-config.css +16 -0
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/subject-provider.api.ts +0 -6
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.test.tsx +24 -0
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +14 -17
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +1 -0
  104. package/package.json +1 -1
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CreateNodeInstanceDrawer.tsx +0 -162
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/UserGroupCreateModal.tsx +0 -72
@@ -0,0 +1,145 @@
1
+ import { Empty, Select, Space, Spin, Typography, type SelectProps } from 'antd';
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
+ import {
4
+ searchStaffDirectory,
5
+ type StaffDirectoryPerson,
6
+ } from './staff-directory.api';
7
+
8
+ export interface StaffSelectProps {
9
+ value?: string;
10
+ onChange?(value?: string): void;
11
+ onPersonChange?(person?: StaffDirectoryPerson): void;
12
+ disabled?: boolean;
13
+ placeholder?: string;
14
+ allowClear?: boolean;
15
+ initialPerson?: StaffDirectoryPerson;
16
+ style?: SelectProps['style'];
17
+ }
18
+
19
+ export function StaffSelect({
20
+ value,
21
+ onChange,
22
+ onPersonChange,
23
+ disabled,
24
+ placeholder = '输入姓名或企业微信账号搜索',
25
+ allowClear = true,
26
+ initialPerson,
27
+ style,
28
+ }: StaffSelectProps) {
29
+ const [people, setPeople] = useState<StaffDirectoryPerson[]>(
30
+ initialPerson ? [initialPerson] : [],
31
+ );
32
+ const [loading, setLoading] = useState(false);
33
+ const [searched, setSearched] = useState(false);
34
+ const [error, setError] = useState(false);
35
+ const timer = useRef<ReturnType<typeof setTimeout>>();
36
+ const requestSequence = useRef(0);
37
+
38
+ useEffect(
39
+ () => () => {
40
+ clearTimeout(timer.current);
41
+ requestSequence.current += 1;
42
+ },
43
+ [],
44
+ );
45
+
46
+ const peopleById = useMemo(
47
+ () => new Map(people.map((person) => [person.userId, person])),
48
+ [people],
49
+ );
50
+
51
+ function search(keyword: string) {
52
+ clearTimeout(timer.current);
53
+ const query = keyword.trim();
54
+ if (!query) {
55
+ requestSequence.current += 1;
56
+ setPeople(initialPerson ? [initialPerson] : []);
57
+ setLoading(false);
58
+ setSearched(false);
59
+ setError(false);
60
+ return;
61
+ }
62
+ const sequence = ++requestSequence.current;
63
+ timer.current = setTimeout(async () => {
64
+ setLoading(true);
65
+ setSearched(true);
66
+ setError(false);
67
+ try {
68
+ const result = await searchStaffDirectory(query);
69
+ if (sequence !== requestSequence.current) return;
70
+ const selected = value ? peopleById.get(value) : undefined;
71
+ setPeople(
72
+ selected &&
73
+ !result.some((person) => person.userId === selected.userId)
74
+ ? [selected, ...result]
75
+ : result,
76
+ );
77
+ } catch {
78
+ if (sequence === requestSequence.current) {
79
+ setPeople(initialPerson ? [initialPerson] : []);
80
+ setError(true);
81
+ }
82
+ } finally {
83
+ if (sequence === requestSequence.current) setLoading(false);
84
+ }
85
+ }, 300);
86
+ }
87
+
88
+ return (
89
+ <Select
90
+ showSearch
91
+ value={value}
92
+ disabled={disabled}
93
+ allowClear={allowClear}
94
+ placeholder={placeholder}
95
+ filterOption={false}
96
+ loading={loading}
97
+ onSearch={search}
98
+ onChange={(nextValue?: string) => {
99
+ const person = nextValue ? peopleById.get(nextValue) : undefined;
100
+ onChange?.(nextValue);
101
+ onPersonChange?.(person);
102
+ }}
103
+ options={people.map((person) => ({
104
+ value: person.userId,
105
+ label: `${person.displayName} (${person.userId})`,
106
+ person,
107
+ }))}
108
+ optionRender={(option) => {
109
+ const person = option.data.person as StaffDirectoryPerson;
110
+ const organization = [person.businessGroup, person.department]
111
+ .filter(Boolean)
112
+ .join(' · ');
113
+ return (
114
+ <Space direction="vertical" size={0}>
115
+ <Typography.Text>
116
+ {person.displayName} ({person.userId})
117
+ </Typography.Text>
118
+ {organization && (
119
+ <Typography.Text type="secondary" style={{ fontSize: 12 }}>
120
+ {organization}
121
+ </Typography.Text>
122
+ )}
123
+ </Space>
124
+ );
125
+ }}
126
+ notFoundContent={
127
+ loading ? (
128
+ <Spin size="small" />
129
+ ) : error ? (
130
+ <Typography.Text type="danger">
131
+ 人员搜索暂时不可用,请稍后重试
132
+ </Typography.Text>
133
+ ) : searched ? (
134
+ <Empty
135
+ image={Empty.PRESENTED_IMAGE_SIMPLE}
136
+ description="未找到人员"
137
+ />
138
+ ) : (
139
+ <Typography.Text type="secondary">输入关键词开始搜索</Typography.Text>
140
+ )
141
+ }
142
+ style={{ width: '100%', ...style }}
143
+ />
144
+ );
145
+ }
@@ -0,0 +1,2 @@
1
+ export * from './StaffSelect';
2
+ export type { StaffDirectoryPerson } from './staff-directory.api';
@@ -0,0 +1,16 @@
1
+ import { customRequest } from 'helpers/http';
2
+
3
+ export interface StaffDirectoryPerson {
4
+ userId: string;
5
+ displayName: string;
6
+ businessGroup?: string;
7
+ department?: string;
8
+ }
9
+
10
+ export function searchStaffDirectory(keyword: string) {
11
+ return customRequest<StaffDirectoryPerson[]>(
12
+ 'staff-directory/search',
13
+ 'GET',
14
+ { keyword },
15
+ );
16
+ }
@@ -8,3 +8,4 @@ export * from './pagination-total';
8
8
  export * from './tags';
9
9
  export * from './text';
10
10
  export * from './WorkflowActionButton';
11
+ export * from './StaffSelect';
@@ -8,3 +8,13 @@ describe('workflow route placement', () => {
8
8
  );
9
9
  });
10
10
  });
11
+
12
+ describe('person and access routes', () => {
13
+ it('keeps people, groups and access authorization as separate pages', () => {
14
+ expect(getRoutePath('person_directory')).toBe('/admin/permission/people');
15
+ expect(getRoutePath('people_group')).toBe(
16
+ '/admin/permission/people-groups',
17
+ );
18
+ expect(getRoutePath('user')).toBe('/admin/permission/user');
19
+ });
20
+ });
@@ -191,14 +191,32 @@ export const routeRegistry: Record<string, RouteEntry> = {
191
191
  })),
192
192
  ),
193
193
  },
194
- // 用户管理 — sortOrder 1030, code: admin.permission.user
194
+ // 人员目录 — code: person_directory
195
+ person_directory: {
196
+ path: 'people',
197
+ component: lazyWithReload(() =>
198
+ import('routes/person-directory').then((m) => ({
199
+ default: m.default,
200
+ })),
201
+ ),
202
+ },
203
+ // 访问授权 — 保留 user code/path,兼容既有页面权限和链接
195
204
  user: {
196
205
  path: 'user',
197
206
  component: lazyWithReload(() =>
198
207
  import('routes/user').then((m) => ({ default: m.UserListPage })),
199
208
  ),
200
209
  },
201
- // 角色管理 — sortOrder 1040, code: admin.permission.role
210
+ // 人员组 — code: people_group
211
+ people_group: {
212
+ path: 'people-groups',
213
+ component: lazyWithReload(() =>
214
+ import('routes/people-groups').then((m) => ({
215
+ default: m.default,
216
+ })),
217
+ ),
218
+ },
219
+ // 角色管理
202
220
  role: {
203
221
  path: 'role-list',
204
222
  component: lazyWithReload(() =>
@@ -6,6 +6,9 @@ import {
6
6
  BgColorsOutlined,
7
7
  ScheduleOutlined,
8
8
  ApartmentOutlined,
9
+ SafetyCertificateOutlined,
10
+ TeamOutlined,
11
+ UserOutlined,
9
12
  } from '@ant-design/icons';
10
13
  import { getRoutePath } from 'config/routeRegistry';
11
14
  import { useUserPageAccess } from './useUserPageAccess';
@@ -46,6 +49,9 @@ export const iconMapping: Record<string, React.ReactNode> = {
46
49
  canvas: <BgColorsOutlined />,
47
50
  agenda: <ScheduleOutlined />,
48
51
  workflow: <ApartmentOutlined />,
52
+ person_directory: <UserOutlined />,
53
+ user: <SafetyCertificateOutlined />,
54
+ people_group: <TeamOutlined />,
49
55
  };
50
56
 
51
57
  // Pages whose children are tabs (not separate menu items)
@@ -162,18 +162,21 @@
162
162
  "taskDetailValue": "Field value",
163
163
  "whoCanApprove": "Who can approve",
164
164
  "description": "Choose fixed approvers or call an API inside this node to look them up dynamically.",
165
- "fixedApprovers": "Fixed approvers",
165
+ "fixedApprovers": "Fixed approver sources",
166
+ "fixedUsers": "Fixed people",
167
+ "fixedUserGroups": "Fixed people groups",
168
+ "addFixedUsers": "Add people",
169
+ "addFixedUserGroups": "Add people group",
170
+ "removeFixedSource": "Remove {{name}}",
171
+ "noFixedApprovers": "No fixed people or people groups added",
166
172
  "approvedBranch": "Approved",
167
173
  "rejectedBranch": "Rejected",
168
174
  "dynamicApprovers": "Dynamic approvers",
169
- "addUsers": "Add dynamic users",
170
- "addGroups": "Add dynamic user groups",
175
+ "addUsers": "Add dynamic approvers",
171
176
  "noDynamicInputs": "No dynamic approvers added",
172
177
  "lookupDescription": "Calls an API and transforms its response into one or more approver IDs",
173
- "dynamicUsers": "Look up users",
174
- "dynamicGroups": "Look up user groups",
178
+ "dynamicUsers": "Look up approvers",
175
179
  "dynamicUserDefaultName": "Look up approvers",
176
- "dynamicGroupDefaultName": "Look up approver groups",
177
180
  "dynamicLookupName": "Lookup name",
178
181
  "dynamicLookupNamePlaceholder": "For example: Find direct manager",
179
182
  "lookupRequest": "Look up approvers",
@@ -229,7 +232,7 @@
229
232
  "input": "The result received by the approval node from the previous node.",
230
233
  "workflow": "The original data received when the Workflow started.",
231
234
  "response": "The approver lookup response: { status, data, headers }.",
232
- "return": "Return { subjects: [{ provider, refs }] } to select approvers for this task."
235
+ "return": "Return an array of user IDs, for example ['alice', 'bob']."
233
236
  },
234
237
  "approvalCreation": {
235
238
  "input": "The result received by the approval node from the previous node.",
@@ -293,6 +296,11 @@
293
296
  "loadFailed": "Unable to load connections",
294
297
  "disabled": "Disabled",
295
298
  "edit": "Edit connection",
299
+ "deleteAria": "Delete {{name}}",
300
+ "deleteConfirm": "Delete connection {{name}}?",
301
+ "deleteDescription": "This cannot be undone. Connections used by a Workflow cannot be deleted.",
302
+ "deleteSuccess": "Connection deleted",
303
+ "deleteFailed": "Unable to delete connection",
296
304
  "create": "Create connection",
297
305
  "saveChanges": "Save changes",
298
306
  "authentication": "Authentication",
@@ -363,7 +371,7 @@
363
371
  "registerFailed": "Registration failed. Try again.",
364
372
  "source": "Database table",
365
373
  "operation": "Operation",
366
- "watchedFields": "Watched fields",
374
+ "watchedFields": "Fields watched on update",
367
375
  "allFields": "All fields",
368
376
  "allFieldsHint": "INSERT and DELETE trigger whenever a row is inserted or deleted, and the event includes every field in that row.",
369
377
  "sourceLoadFailed": "Database metadata could not be loaded",
@@ -544,7 +552,8 @@
544
552
  "EQ": "Equals",
545
553
  "NEQ": "Does not equal",
546
554
  "EMPTY": "Is empty",
547
- "NOT_EMPTY": "Is not empty"
555
+ "NOT_EMPTY": "Is not empty",
556
+ "IN": "Is one of"
548
557
  },
549
558
  "processing": "Event processing",
550
559
  "parallel": "Process in parallel",
@@ -556,10 +565,19 @@
556
565
  "primaryKey": "Primary key",
557
566
  "sameKeyPreview": "Events with the same {{field}} are processed in arrival order",
558
567
  "advanced": "Advanced settings",
559
- "maxConcurrency": "Maximum concurrent objects"
568
+ "maxConcurrency": "Maximum concurrent objects",
569
+ "neverStart": "Do not start",
570
+ "valueListHint": "Enter a value and press Enter",
571
+ "operations": {
572
+ "INSERT": "On insert",
573
+ "UPDATE": "On update",
574
+ "DELETE": "On delete"
575
+ }
560
576
  },
561
577
  "database": {
562
578
  "sql": "SQL statement",
579
+ "readOnly": "Read-only SQL",
580
+ "writeEnabled": "Writes enabled",
563
581
  "allowWrite": "Allow writes",
564
582
  "readOnlyDescription": "When off, this node can only query data.",
565
583
  "readWriteDescription": "When on, this node can query, insert, update, or delete data.",
@@ -622,10 +640,16 @@
622
640
  "enableConfirm": "Enable this node instance?",
623
641
  "disableConfirm": "Disable this node instance?",
624
642
  "detailDescription": "Review this reusable configuration and the Workflows that reference it.",
643
+ "detailSummaryDescription": "Review the instance purpose, node type, and maintenance details.",
625
644
  "referencesLoadFailed": "References could not be loaded",
626
645
  "createdAt": "Created",
646
+ "instanceId": "Instance ID",
647
+ "referenceCount": "References",
648
+ "noDescription": "No description",
627
649
  "noConfiguration": "This instance has no configuration",
650
+ "configurationDescription": "Review the saved {{name}} execution parameters in read-only mode.",
628
651
  "referencedBy": "Referenced by",
652
+ "referencesDescription": "These Workflows currently use this reusable configuration.",
629
653
  "noReferences": "No Workflows reference this instance",
630
654
  "node": "Node",
631
655
  "new": "New Instance",
@@ -734,7 +758,12 @@
734
758
  "add": "Add",
735
759
  "template": "Node template",
736
760
  "templateOptional": "Use a template or configure this node directly",
737
- "createTemplate": "New template",
761
+ "saveCurrentAsTemplate": "Save current configuration as template",
762
+ "saveCurrentAsTemplateHint": "Create a template from the current node configuration and immediately use it for this node. Save the Workflow from the top of the page to persist this reference.",
763
+ "saveAndUseTemplate": "Save and use template",
764
+ "templateName": "Template name",
765
+ "templateSavedAndApplied": "Template created and applied to this node",
766
+ "templateSaveFailed": "Failed to save template",
738
767
  "selectTemplate": "Select a template",
739
768
  "noTemplates": "No templates available",
740
769
  "loadingInstances": "Loading templates…",
@@ -777,6 +806,14 @@
777
806
  "string": "Text"
778
807
  },
779
808
  "fieldLabels": {
809
+ "event_trigger": {
810
+ "operation": "Operation type",
811
+ "table": "Source table",
812
+ "primaryKey": "Primary key",
813
+ "before": "Data before the change",
814
+ "after": "Data after the change",
815
+ "changedFields": "Changed fields"
816
+ },
780
817
  "webhook_trigger": {
781
818
  "body": "Request body",
782
819
  "headers": "Request headers",
@@ -813,6 +850,14 @@
813
850
  }
814
851
  },
815
852
  "fields": {
853
+ "event_trigger": {
854
+ "operation": "Database operation: INSERT, UPDATE, or DELETE",
855
+ "table": "The changed table, including its schema and table name",
856
+ "primaryKey": "The primary key of the changed row",
857
+ "before": "The complete row before the change; null for INSERT",
858
+ "after": "The complete row after the change; null for DELETE",
859
+ "changedFields": "Changed watched fields for UPDATE; all row fields for INSERT or DELETE"
860
+ },
816
861
  "webhook_trigger": {
817
862
  "body": "",
818
863
  "headers": "",
@@ -859,12 +904,9 @@
859
904
  "anyValue": "Output is determined at runtime"
860
905
  }
861
906
  },
862
- "saveAsInstance": "Also save as a template",
863
- "instanceNamePlaceholder": "Template name (required)",
864
907
  "aiEditHint": "Describe what to change",
865
908
  "aiEditPlaceholder": "For example: change the timeout to 30 minutes",
866
909
  "send": "Send",
867
- "saveChanges": "Save changes",
868
910
  "aiGenerating": "AI is generating workflow…",
869
911
  "aiGeneratingHint": "Please wait. The workflow canvas will update automatically.",
870
912
  "untitled": "Untitled Workflow",
@@ -988,6 +1030,7 @@
988
1030
  "completed": "Completed",
989
1031
  "running": "Running",
990
1032
  "failed": "Failed",
1033
+ "cancelled": "Cancelled",
991
1034
  "publishedStatus": "Published",
992
1035
  "status": "Status",
993
1036
  "version": "Version",
@@ -1038,6 +1081,9 @@
1038
1081
  "openTemporal": "Open in Temporal",
1039
1082
  "cancel": "Cancel run",
1040
1083
  "executionDetails": "Run information",
1084
+ "cancellationRequestedBy": "Cancelled by",
1085
+ "cancellationRequestedAt": "Cancelled at",
1086
+ "cancellationReason": "Cancellation reason",
1041
1087
  "result": "Final result",
1042
1088
  "retryAll": "Run entire Workflow again",
1043
1089
  "retryAllConfirm": "Run the entire Workflow again?",
@@ -162,18 +162,21 @@
162
162
  "taskDetailValue": "字段值",
163
163
  "whoCanApprove": "审批人设置",
164
164
  "description": "选择固定审批人,或在节点内调用接口动态查询审批人。",
165
- "fixedApprovers": "固定审批人",
165
+ "fixedApprovers": "固定审批来源",
166
+ "fixedUsers": "固定人员",
167
+ "fixedUserGroups": "固定人员组",
168
+ "addFixedUsers": "添加人员",
169
+ "addFixedUserGroups": "添加人员组",
170
+ "removeFixedSource": "删除{{name}}",
171
+ "noFixedApprovers": "暂未添加固定人员或人员组",
166
172
  "approvedBranch": "通过",
167
173
  "rejectedBranch": "拒绝",
168
174
  "dynamicApprovers": "动态审批人",
169
- "addUsers": "添加动态用户",
170
- "addGroups": "添加动态用户组",
175
+ "addUsers": "添加动态审批人",
171
176
  "noDynamicInputs": "暂未添加动态审批人",
172
177
  "lookupDescription": "调用接口并把响应转换为一个或多个审批人 ID",
173
- "dynamicUsers": "动态查询用户",
174
- "dynamicGroups": "动态查询用户组",
178
+ "dynamicUsers": "动态查询审批人",
175
179
  "dynamicUserDefaultName": "查询审批人",
176
- "dynamicGroupDefaultName": "查询审批用户组",
177
180
  "dynamicLookupName": "查询名称",
178
181
  "dynamicLookupNamePlaceholder": "例如:查询直属领导",
179
182
  "lookupRequest": "查询审批人",
@@ -229,7 +232,7 @@
229
232
  "input": "人工审批节点从上一个节点收到的结果。",
230
233
  "workflow": "Workflow 最初收到的启动数据。",
231
234
  "response": "查询审批人接口返回的 { status, data, headers }。",
232
- "return": "返回 { subjects: [{ provider, refs }] },用于确定本次审批人。"
235
+ "return": "返回人员 ID 数组,例如 ['zhangsan', 'lisi']。"
233
236
  },
234
237
  "approvalCreation": {
235
238
  "input": "人工审批节点从上一个节点收到的结果。",
@@ -293,6 +296,11 @@
293
296
  "loadFailed": "加载连接失败",
294
297
  "disabled": "停用",
295
298
  "edit": "编辑连接",
299
+ "deleteAria": "删除 {{name}}",
300
+ "deleteConfirm": "删除连接 {{name}}?",
301
+ "deleteDescription": "删除后将无法恢复。正在被 Workflow 使用的连接不能删除。",
302
+ "deleteSuccess": "连接已删除",
303
+ "deleteFailed": "连接删除失败",
296
304
  "create": "创建连接",
297
305
  "saveChanges": "保存修改",
298
306
  "authentication": "认证方式",
@@ -363,7 +371,7 @@
363
371
  "registerFailed": "登记失败,请重试",
364
372
  "source": "数据库表",
365
373
  "operation": "数据操作",
366
- "watchedFields": "监听字段",
374
+ "watchedFields": "修改时监听字段",
367
375
  "allFields": "全部字段",
368
376
  "allFieldsHint": "INSERT 和 DELETE 会在任意一行插入或删除时触发,事件包含该行的全部字段。",
369
377
  "sourceLoadFailed": "数据库表结构加载失败",
@@ -544,7 +552,8 @@
544
552
  "EQ": "等于",
545
553
  "NEQ": "不等于",
546
554
  "EMPTY": "为空",
547
- "NOT_EMPTY": "不为空"
555
+ "NOT_EMPTY": "不为空",
556
+ "IN": "属于以下任一值"
548
557
  },
549
558
  "processing": "事件处理方式",
550
559
  "parallel": "并行处理",
@@ -556,10 +565,19 @@
556
565
  "primaryKey": "主键",
557
566
  "sameKeyPreview": "{{field}} 相同的事件会按到达顺序处理",
558
567
  "advanced": "高级设置",
559
- "maxConcurrency": "最大同时处理数"
568
+ "maxConcurrency": "最大同时处理数",
569
+ "neverStart": "不启动",
570
+ "valueListHint": "输入值并按回车添加",
571
+ "operations": {
572
+ "INSERT": "新增时",
573
+ "UPDATE": "修改时",
574
+ "DELETE": "删除时"
575
+ }
560
576
  },
561
577
  "database": {
562
578
  "sql": "SQL 语句",
579
+ "readOnly": "只读 SQL",
580
+ "writeEnabled": "允许写入",
563
581
  "allowWrite": "允许写入",
564
582
  "readOnlyDescription": "关闭时只能查询数据。",
565
583
  "readWriteDescription": "开启后可以查询、新增、更新或删除数据。",
@@ -622,10 +640,16 @@
622
640
  "enableConfirm": "确定启用此节点实例吗?",
623
641
  "disableConfirm": "确定停用此节点实例吗?",
624
642
  "detailDescription": "查看可复用配置及引用它的工作流。",
643
+ "detailSummaryDescription": "确认实例用途、节点类型和维护信息。",
625
644
  "referencesLoadFailed": "引用关系加载失败",
626
645
  "createdAt": "创建时间",
646
+ "instanceId": "实例 ID",
647
+ "referenceCount": "引用数",
648
+ "noDescription": "暂无描述",
627
649
  "noConfiguration": "此实例没有配置项",
650
+ "configurationDescription": "只读查看 {{name}} 当前保存的执行参数。",
628
651
  "referencedBy": "引用此实例的工作流",
652
+ "referencesDescription": "以下 Workflow 当前正在使用这份可复用配置。",
629
653
  "noReferences": "暂无工作流引用此实例",
630
654
  "node": "节点",
631
655
  "new": "新建实例",
@@ -734,7 +758,12 @@
734
758
  "add": "添加",
735
759
  "template": "节点模板",
736
760
  "templateOptional": "可以使用模板,也可以直接配置",
737
- "createTemplate": "新建模板",
761
+ "saveCurrentAsTemplate": "将当前配置保存为模板",
762
+ "saveCurrentAsTemplateHint": "将使用当前节点配置创建模板,并立即让当前节点引用该模板。Workflow 仍需通过页面顶部的“保存”进行保存。",
763
+ "saveAndUseTemplate": "保存并使用模板",
764
+ "templateName": "模板名称",
765
+ "templateSavedAndApplied": "模板已创建并应用到当前节点",
766
+ "templateSaveFailed": "保存模板失败",
738
767
  "selectTemplate": "选择模板",
739
768
  "noTemplates": "暂无可用模板",
740
769
  "loadingInstances": "正在加载模板…",
@@ -777,6 +806,14 @@
777
806
  "string": "文本"
778
807
  },
779
808
  "fieldLabels": {
809
+ "event_trigger": {
810
+ "operation": "操作类型",
811
+ "table": "数据表",
812
+ "primaryKey": "主键",
813
+ "before": "变更前的数据",
814
+ "after": "变更后的数据",
815
+ "changedFields": "发生变化的字段"
816
+ },
780
817
  "webhook_trigger": {
781
818
  "body": "请求内容",
782
819
  "headers": "请求头",
@@ -813,6 +850,14 @@
813
850
  }
814
851
  },
815
852
  "fields": {
853
+ "event_trigger": {
854
+ "operation": "数据库操作类型:INSERT(新增)、UPDATE(更新)或 DELETE(删除)",
855
+ "table": "发生变化的数据表,包含 schema 和表名",
856
+ "primaryKey": "发生变化的这一行数据的主键",
857
+ "before": "变更前的整行数据;新增时为 null",
858
+ "after": "变更后的整行数据;删除时为 null",
859
+ "changedFields": "更新时为实际变化的监听字段;新增或删除时为整行字段"
860
+ },
816
861
  "webhook_trigger": {
817
862
  "body": "",
818
863
  "headers": "",
@@ -859,12 +904,9 @@
859
904
  "anyValue": "输出内容在运行时确定"
860
905
  }
861
906
  },
862
- "saveAsInstance": "同时保存为模板",
863
- "instanceNamePlaceholder": "模板名称(必填)",
864
907
  "aiEditHint": "描述要修改的内容",
865
908
  "aiEditPlaceholder": "例如:将超时时间改为 30 分钟",
866
909
  "send": "发送",
867
- "saveChanges": "保存修改",
868
910
  "aiGenerating": "AI 正在生成工作流…",
869
911
  "aiGeneratingHint": "请稍候,工作流画布会自动更新。",
870
912
  "untitled": "未命名工作流",
@@ -988,6 +1030,7 @@
988
1030
  "completed": "已完成",
989
1031
  "running": "运行中",
990
1032
  "failed": "失败",
1033
+ "cancelled": "已取消",
991
1034
  "publishedStatus": "已发布",
992
1035
  "status": "状态",
993
1036
  "version": "版本",
@@ -1038,6 +1081,9 @@
1038
1081
  "openTemporal": "在 Temporal 中查看",
1039
1082
  "cancel": "取消运行",
1040
1083
  "executionDetails": "运行信息",
1084
+ "cancellationRequestedBy": "取消人",
1085
+ "cancellationRequestedAt": "取消时间",
1086
+ "cancellationReason": "取消原因",
1041
1087
  "result": "最终结果",
1042
1088
  "retryAll": "重新运行整个流程",
1043
1089
  "retryAllConfirm": "确定重新运行整个流程吗?",