@steedos-labs/plugin-workflow 3.0.43 → 3.0.45
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/designer/dist/amis-renderer/amis-renderer.css +1 -1
- package/designer/dist/amis-renderer/amis-renderer.js +1 -1
- package/designer/dist/assets/{index-C3K_lyOl.css → index-B5zmn1Wt.css} +1 -1
- package/designer/dist/assets/{index-XZWBSnmF.js → index-D7W5yEF4.js} +268 -268
- package/designer/dist/index.html +3 -3
- package/main/default/objects/instance_tasks/buttons/instance_new.button.yml +1 -1
- package/main/default/objects/instances/buttons/instance_new.button.yml +1 -1
- package/main/default/objects/workflow_designer_backups.object.yml +5 -0
- package/main/default/pages/flowdetail.page.amis.json +0 -31
- package/main/default/routes/am.router.js +1 -2
- package/main/default/routes/api_workflow_ai_form_design_stream.router.js +36 -1
- package/main/default/routes/api_workflow_next_step.router.js +8 -1
- package/main/default/routes/api_workflow_next_step_users.router.js +4 -1
- package/main/default/routes/api_workflow_submit.router.js +31 -2
- package/main/default/routes/flow_form_design.ejs +2 -1
- package/main/default/routes/object_workflows.router.js +3 -3
- package/main/default/test/test_migrateApprovalCommentsField.js +220 -0
- package/main/default/test/test_rollbackApprovalCommentsField.js +235 -0
- package/main/default/triggers/amis_form_design.trigger.js +2 -1
- package/main/default/utils/designerManager.js +2 -5
- package/package.json +1 -1
- package/public/amis-renderer/amis-renderer.css +1 -1
- package/public/amis-renderer/amis-renderer.js +1 -1
- package/public/workflow/index.css +24 -1
- package/src/rests/approvalCommentsConsole.js +9 -0
- package/src/rests/getPageSchema.js +58 -0
- package/src/rests/index.js +1 -0
- package/src/rests/migrateApprovalCommentsField.js +31 -12
- package/src/rests/rollbackApprovalCommentsField.js +32 -21
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const mod = require('../../../src/rests/rollbackApprovalCommentsField');
|
|
3
|
+
|
|
4
|
+
const { processFieldsArrayForRollback } = mod._helpers;
|
|
5
|
+
|
|
6
|
+
let suitePassed = 0;
|
|
7
|
+
let suiteFailed = 0;
|
|
8
|
+
|
|
9
|
+
function runSuite(name, fn) {
|
|
10
|
+
let passed = 0;
|
|
11
|
+
let failed = 0;
|
|
12
|
+
const suiteAssert = {
|
|
13
|
+
strictEqual(a, b, msg) {
|
|
14
|
+
try {
|
|
15
|
+
assert.strictEqual(a, b, msg);
|
|
16
|
+
passed++;
|
|
17
|
+
} catch (e) {
|
|
18
|
+
failed++;
|
|
19
|
+
console.error(` FAIL: ${msg || e.message}`);
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
ok(val, msg) {
|
|
23
|
+
try {
|
|
24
|
+
assert.ok(val, msg);
|
|
25
|
+
passed++;
|
|
26
|
+
} catch (e) {
|
|
27
|
+
failed++;
|
|
28
|
+
console.error(` FAIL: ${msg || e.message}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
fn(suiteAssert);
|
|
33
|
+
suitePassed += passed;
|
|
34
|
+
suiteFailed += failed;
|
|
35
|
+
if (failed === 0) {
|
|
36
|
+
console.log(` ${name}: ${passed} assertions passed.`);
|
|
37
|
+
} else {
|
|
38
|
+
console.log(` ${name}: ${passed} passed, ${failed} FAILED.`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
console.log('[test_rollbackApprovalCommentsField] running tests...');
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Flat (first-level) transformed field
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
runSuite('processFieldsArrayForRollback (flat)', (t) => {
|
|
48
|
+
const fields = [
|
|
49
|
+
{
|
|
50
|
+
code: 'mgr_comments',
|
|
51
|
+
type: 'steedos-field',
|
|
52
|
+
__approval_comments_transformed: true,
|
|
53
|
+
__approval_comments_original_type: 'input',
|
|
54
|
+
__approval_comments_original_formula: '{traces.主管审核}',
|
|
55
|
+
config: { type: 'approval_comments' }
|
|
56
|
+
},
|
|
57
|
+
{ code: 'plain_field', type: 'text' } // not transformed
|
|
58
|
+
];
|
|
59
|
+
const { updates, unsets, fieldCount } = processFieldsArrayForRollback(
|
|
60
|
+
fields, 'current.fields', 'form1', 'TestForm'
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
t.strictEqual(fieldCount, 1, 'fieldCount should be 1');
|
|
64
|
+
t.ok(updates.some(u => u.path === 'current.fields.0.type' && u.value === 'input'),
|
|
65
|
+
'type path and value restored');
|
|
66
|
+
t.ok(updates.some(u => u.path === 'current.fields.0.formula' && u.value === '{traces.主管审核}'),
|
|
67
|
+
'formula path and value restored');
|
|
68
|
+
t.ok(unsets.includes('current.fields.0.__approval_comments_transformed'),
|
|
69
|
+
'__approval_comments_transformed unset');
|
|
70
|
+
t.ok(unsets.includes('current.fields.0.config'), 'config unset');
|
|
71
|
+
t.ok(unsets.includes('current.fields.0.__approval_comments_original_type'),
|
|
72
|
+
'__approval_comments_original_type backup removed');
|
|
73
|
+
t.ok(unsets.includes('current.fields.0.__approval_comments_original_formula'),
|
|
74
|
+
'__approval_comments_original_formula backup removed');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Nested (section container) — primary regression scenario
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
runSuite('processFieldsArrayForRollback (nested sections)', (t) => {
|
|
81
|
+
const fields = [
|
|
82
|
+
{ code: 'plain_top', type: 'text' }, // index 0, not transformed
|
|
83
|
+
{
|
|
84
|
+
code: 'section_a',
|
|
85
|
+
type: 'section',
|
|
86
|
+
fields: [
|
|
87
|
+
{ code: 'nested_plain', type: 'text' }, // index 0, not transformed
|
|
88
|
+
{
|
|
89
|
+
code: 'dept_comments',
|
|
90
|
+
type: 'steedos-field',
|
|
91
|
+
__approval_comments_transformed: true,
|
|
92
|
+
__approval_comments_original_type: 'input',
|
|
93
|
+
__approval_comments_original_formula: '{traces.部门审核}',
|
|
94
|
+
config: { type: 'approval_comments' }
|
|
95
|
+
} // index 1
|
|
96
|
+
]
|
|
97
|
+
} // index 1
|
|
98
|
+
];
|
|
99
|
+
const { updates, unsets, fieldCount } = processFieldsArrayForRollback(
|
|
100
|
+
fields, 'current.fields', 'form1', 'TestForm'
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
t.strictEqual(fieldCount, 1, 'fieldCount should be 1 (only nested field)');
|
|
104
|
+
t.ok(updates.some(u => u.path === 'current.fields.1.fields.1.type' && u.value === 'input'),
|
|
105
|
+
'nested type restored at correct path');
|
|
106
|
+
t.ok(updates.some(u => u.path === 'current.fields.1.fields.1.formula'),
|
|
107
|
+
'nested formula restored at correct path');
|
|
108
|
+
t.ok(unsets.includes('current.fields.1.fields.1.__approval_comments_transformed'),
|
|
109
|
+
'nested: __approval_comments_transformed unset at correct path');
|
|
110
|
+
t.ok(unsets.includes('current.fields.1.fields.1.config'),
|
|
111
|
+
'nested: config unset at correct path');
|
|
112
|
+
t.ok(unsets.includes('current.fields.1.fields.1.__approval_comments_original_type'),
|
|
113
|
+
'nested: original_type backup removed');
|
|
114
|
+
t.ok(unsets.includes('current.fields.1.fields.1.__approval_comments_original_formula'),
|
|
115
|
+
'nested: original_formula backup removed');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// Deeply nested (section > panel)
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
runSuite('processFieldsArrayForRollback (deeply nested)', (t) => {
|
|
122
|
+
const fields = [
|
|
123
|
+
{
|
|
124
|
+
code: 'section1', type: 'section',
|
|
125
|
+
fields: [
|
|
126
|
+
{
|
|
127
|
+
code: 'panel1', type: 'panel',
|
|
128
|
+
fields: [
|
|
129
|
+
{
|
|
130
|
+
code: 'deep_field',
|
|
131
|
+
type: 'steedos-field',
|
|
132
|
+
__approval_comments_transformed: true,
|
|
133
|
+
__approval_comments_original_type: 'textarea',
|
|
134
|
+
config: {}
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
const { updates, fieldCount } = processFieldsArrayForRollback(
|
|
142
|
+
fields, 'current.fields', 'form1', 'TestForm'
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
t.strictEqual(fieldCount, 1, 'deep: fieldCount=1');
|
|
146
|
+
t.ok(updates.some(u => u.path === 'current.fields.0.fields.0.fields.0.type' && u.value === 'textarea'),
|
|
147
|
+
'deeply nested type restored at correct path');
|
|
148
|
+
t.ok(!updates.some(u => u.path === 'current.fields.0.type'),
|
|
149
|
+
'section container itself not touched');
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Mixed: top-level and nested transformed fields
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
runSuite('processFieldsArrayForRollback (mixed top-level and nested)', (t) => {
|
|
156
|
+
const fields = [
|
|
157
|
+
{
|
|
158
|
+
code: 'top_comments',
|
|
159
|
+
type: 'steedos-field',
|
|
160
|
+
__approval_comments_transformed: true,
|
|
161
|
+
__approval_comments_original_type: 'input',
|
|
162
|
+
config: {}
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
code: 'section_b', type: 'section',
|
|
166
|
+
fields: [
|
|
167
|
+
{
|
|
168
|
+
code: 'nested_comments',
|
|
169
|
+
type: 'steedos-field',
|
|
170
|
+
__approval_comments_transformed: true,
|
|
171
|
+
__approval_comments_original_type: 'input',
|
|
172
|
+
config: {}
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
];
|
|
177
|
+
const { updates, fieldCount } = processFieldsArrayForRollback(
|
|
178
|
+
fields, 'current.fields', 'form1', 'TestForm'
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
t.strictEqual(fieldCount, 2, 'mixed: fieldCount=2 (one top-level, one nested)');
|
|
182
|
+
t.ok(updates.some(u => u.path === 'current.fields.0.type'), 'top-level type restored');
|
|
183
|
+
t.ok(updates.some(u => u.path === 'current.fields.1.fields.0.type'), 'nested type restored');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
// historys prefix
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
runSuite('processFieldsArrayForRollback (historys prefix)', (t) => {
|
|
190
|
+
const fields = [
|
|
191
|
+
{
|
|
192
|
+
code: 'hist_comments',
|
|
193
|
+
type: 'steedos-field',
|
|
194
|
+
__approval_comments_transformed: true,
|
|
195
|
+
__approval_comments_original_type: 'input',
|
|
196
|
+
config: {}
|
|
197
|
+
}
|
|
198
|
+
];
|
|
199
|
+
const { updates, fieldCount } = processFieldsArrayForRollback(
|
|
200
|
+
fields, 'historys.0.fields', 'form1', 'TestForm'
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
t.strictEqual(fieldCount, 1, 'historys: fieldCount=1');
|
|
204
|
+
t.ok(updates.some(u => u.path === 'historys.0.fields.0.type'), 'historys prefix in path');
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Non-transformed fields not touched
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
runSuite('processFieldsArrayForRollback (non-transformed skipped)', (t) => {
|
|
211
|
+
const fields = [
|
|
212
|
+
{ code: 'f1', type: 'text' },
|
|
213
|
+
{ code: 'section', type: 'section', fields: [
|
|
214
|
+
{ code: 'f2', type: 'input' }
|
|
215
|
+
]}
|
|
216
|
+
];
|
|
217
|
+
const { updates, unsets, fieldCount } = processFieldsArrayForRollback(
|
|
218
|
+
fields, 'current.fields', 'form1', 'TestForm'
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
t.strictEqual(fieldCount, 0, 'non-transformed: fieldCount=0');
|
|
222
|
+
t.strictEqual(updates.length, 0, 'non-transformed: no updates');
|
|
223
|
+
t.strictEqual(unsets.length, 0, 'non-transformed: no unsets');
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// ---------------------------------------------------------------------------
|
|
227
|
+
// Summary
|
|
228
|
+
// ---------------------------------------------------------------------------
|
|
229
|
+
if (suiteFailed === 0) {
|
|
230
|
+
console.log('[test_rollbackApprovalCommentsField] All assertions passed.');
|
|
231
|
+
process.exit(0);
|
|
232
|
+
} else {
|
|
233
|
+
console.error(`[test_rollbackApprovalCommentsField] ${suiteFailed} assertions FAILED.`);
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
@@ -105,7 +105,8 @@ function getFormInputFields(formSchema) {
|
|
|
105
105
|
// 考虑使用steedos-field组件时 name配置到config的情况
|
|
106
106
|
field.name = field.name || (field.config && field.config.name);
|
|
107
107
|
if(field.type === 'steedos-field-group'){
|
|
108
|
-
field
|
|
108
|
+
// steedos-field-group 去重时优先取 title,若 title 为 undefined(历史表单无 name 时生成的 schema 没有 title),则 fallback 到 label 或 name,防止 undefined===undefined 导致后续分组字段被误判为重复而丢失
|
|
109
|
+
field.name = field.title || field.label || field.name
|
|
109
110
|
}
|
|
110
111
|
// 如果要添加的field重复 无需再添加
|
|
111
112
|
if (field.name === item.name) {
|
|
@@ -187,8 +187,7 @@ async function updateForm(formId, form, forms, flows, currentUserId) {
|
|
|
187
187
|
pass = true;
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
|
-
|
|
191
|
-
if (pass === true && ff["current"]["start_date"]) { // 升级表单
|
|
190
|
+
if (pass === true) { // 升级表单
|
|
192
191
|
formUpdateObj.$push = {
|
|
193
192
|
'historys': ff["current"]
|
|
194
193
|
};
|
|
@@ -196,9 +195,7 @@ async function updateForm(formId, form, forms, flows, currentUserId) {
|
|
|
196
195
|
current._rev = ff["current"]["_rev"] + 1;
|
|
197
196
|
current.created = now;
|
|
198
197
|
current.created_by = currentUserId;
|
|
199
|
-
|
|
200
|
-
current.start_date = now;
|
|
201
|
-
}
|
|
198
|
+
current.start_date = now;
|
|
202
199
|
// 更新流程版本
|
|
203
200
|
let flowCursor = await flowCollection.find({form: formId});
|
|
204
201
|
let flowList = await flowCursor.toArray();
|