@processmaker/screen-builder 2.21.1 → 2.24.0
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/vue-form-builder.common.js +12072 -9222
- package/dist/vue-form-builder.common.js.map +1 -1
- package/dist/vue-form-builder.umd.js +12072 -9222
- package/dist/vue-form-builder.umd.js.map +1 -1
- package/dist/vue-form-builder.umd.min.js +33 -33
- package/dist/vue-form-builder.umd.min.js.map +1 -1
- package/package-lock.json +4 -4
- package/package.json +3 -3
- package/src/ValidationsFactory.js +123 -22
- package/src/components/renderer/form-record-list.vue +48 -8
- package/src/components/task.vue +23 -9
- package/src/form-control-common-properties.js +2 -1
- package/src/main.js +11 -1
- package/src/mixins/ScreenBase.js +20 -14
- package/src/mixins/ValidationRules.js +3 -0
- package/src/mixins/computedFields.js +6 -8
- package/src/mixins/extensions/ComputedFields.js +19 -5
- package/src/mixins/extensions/DefaultValues.js +1 -5
- package/src/.DS_Store +0 -0
- package/src/components/.DS_Store +0 -0
package/package-lock.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@processmaker/screen-builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.24.0",
|
|
4
4
|
"lockfileVersion": 1,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"dependencies": {
|
|
@@ -1738,9 +1738,9 @@
|
|
|
1738
1738
|
}
|
|
1739
1739
|
},
|
|
1740
1740
|
"@processmaker/vue-form-elements": {
|
|
1741
|
-
"version": "0.28.
|
|
1742
|
-
"resolved": "https://registry.npmjs.org/@processmaker/vue-form-elements/-/vue-form-elements-0.28.
|
|
1743
|
-
"integrity": "sha512-
|
|
1741
|
+
"version": "0.28.6",
|
|
1742
|
+
"resolved": "https://registry.npmjs.org/@processmaker/vue-form-elements/-/vue-form-elements-0.28.6.tgz",
|
|
1743
|
+
"integrity": "sha512-uxHsOkCNLJEF4mJu7dK4+qn2SL/mWDswdoV1kQjNjQkwBk10uGXDdAbtliHRbld3HDMAPUQAu69c+1fS8pDqjA==",
|
|
1744
1744
|
"dev": true,
|
|
1745
1745
|
"requires": {
|
|
1746
1746
|
"@tinymce/tinymce-vue": "2.0.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@processmaker/screen-builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.24.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"serve": "vue-cli-service serve",
|
|
6
6
|
"build": "vue-cli-service build",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@cypress/code-coverage": "^3.8.1",
|
|
45
45
|
"@fortawesome/fontawesome-free": "^5.6.1",
|
|
46
46
|
"@panter/vue-i18next": "^0.15.2",
|
|
47
|
-
"@processmaker/vue-form-elements": "0.28.
|
|
47
|
+
"@processmaker/vue-form-elements": "0.28.6",
|
|
48
48
|
"@processmaker/vue-multiselect": "^2.2.0",
|
|
49
49
|
"@vue/cli-plugin-babel": "^3.6.0",
|
|
50
50
|
"@vue/cli-plugin-e2e-cypress": "^4.0.3",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
87
|
"@panter/vue-i18next": "^0.15.0",
|
|
88
|
-
"@processmaker/vue-form-elements": "0.28.
|
|
88
|
+
"@processmaker/vue-form-elements": "0.28.6",
|
|
89
89
|
"i18next": "^15.0.8",
|
|
90
90
|
"vue": "^2.6.12",
|
|
91
91
|
"vuex": "^3.1.1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { validators } from './mixins/ValidationRules';
|
|
2
2
|
import DataProvider from './DataProvider';
|
|
3
|
-
import { get, set } from 'lodash';
|
|
3
|
+
import { get, set, merge } from 'lodash';
|
|
4
4
|
import { Parser } from 'expr-eval';
|
|
5
5
|
|
|
6
6
|
let globalObject = typeof window === 'undefined'
|
|
@@ -34,7 +34,7 @@ class Validations {
|
|
|
34
34
|
isVisible() {
|
|
35
35
|
// Disable validations if field is hidden
|
|
36
36
|
let visible = true;
|
|
37
|
-
if (this.element.config.conditionalHide) {
|
|
37
|
+
if (!this.data.noData && this.element.config.conditionalHide) {
|
|
38
38
|
try {
|
|
39
39
|
visible = !!Parser.evaluate(this.element.config.conditionalHide, this.data);
|
|
40
40
|
} catch (error) {
|
|
@@ -51,7 +51,7 @@ class Validations {
|
|
|
51
51
|
class ArrayOfFieldsValidations extends Validations {
|
|
52
52
|
async addValidations(validations) {
|
|
53
53
|
for (const item of this.element) {
|
|
54
|
-
await ValidationsFactory(item, { screen: this.screen, data: this.data }).addValidations(validations);
|
|
54
|
+
await ValidationsFactory(item, { screen: this.screen, data: this.data, parentVisibilityRule: this.parentVisibilityRule }).addValidations(validations);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -81,8 +81,9 @@ class FormNestedScreenValidations extends Validations {
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
const definition = await this.loadScreen(this.element.config.screen);
|
|
84
|
+
let parentVisibilityRule = this.parentVisibilityRule ? this.parentVisibilityRule : this.element.config.conditionalHide;
|
|
84
85
|
if (definition && definition[0] && definition[0].items) {
|
|
85
|
-
await ValidationsFactory(definition[0].items, { screen: this.screen, data: this.data }).addValidations(validations);
|
|
86
|
+
await ValidationsFactory(definition[0].items, { screen: this.screen, data: this.data, parentVisibilityRule }).addValidations(validations);
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
|
|
@@ -112,8 +113,53 @@ class FormLoopValidations extends Validations {
|
|
|
112
113
|
set(validations, this.element.config.name, {});
|
|
113
114
|
const loopField = get(validations, this.element.config.name);
|
|
114
115
|
loopField['$each'] = {};
|
|
115
|
-
|
|
116
|
-
await ValidationsFactory(this.element.items, { screen: this.screen, data: {_parent: this.data,
|
|
116
|
+
this.checkForSiblings(validations);
|
|
117
|
+
await ValidationsFactory(this.element.items, { screen: this.screen, data: {_parent: this.data, noData:true }, parentVisibilityRule: this.element.config.conditionalHide }).addValidations(loopField['$each']);
|
|
118
|
+
}
|
|
119
|
+
checkForSiblings(validations) {
|
|
120
|
+
const siblings = [];
|
|
121
|
+
const siblingValidations = [];
|
|
122
|
+
// Find loops that reference the same variable
|
|
123
|
+
this.screen.config.forEach(page => {
|
|
124
|
+
page.items.filter(item => {
|
|
125
|
+
if (item.component === 'FormLoop' && item.config.name === this.element.config.name) {
|
|
126
|
+
siblings.push(item);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Get siblings validations
|
|
131
|
+
if (siblings) {
|
|
132
|
+
siblings.forEach(sibling => {
|
|
133
|
+
sibling.items.filter(item => {
|
|
134
|
+
if (!item.config.validation) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
item.config.validation.forEach(validation => {
|
|
139
|
+
const rule = this.camelCase(validation.value.split(':')[0]);
|
|
140
|
+
const validationFn = validators[rule];
|
|
141
|
+
const obj = {};
|
|
142
|
+
let ruleObj = {};
|
|
143
|
+
ruleObj[rule] = validationFn;
|
|
144
|
+
obj[item.config.name] = ruleObj;
|
|
145
|
+
merge(siblingValidations, obj);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
if (Object.keys(siblingValidations).length != 0) {
|
|
153
|
+
// Update the loop validations with its siblings.
|
|
154
|
+
const loopValidations = get(validations, this.element.config.name);
|
|
155
|
+
if (loopValidations.hasOwnProperty('$each')) {
|
|
156
|
+
merge(loopValidations['$each'], siblingValidations);
|
|
157
|
+
}
|
|
158
|
+
set(validations[this.element.config.name]['$each'], loopValidations);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
camelCase(name) {
|
|
162
|
+
return name.replace(/_\w/g, m => m.substr(1, 1).toUpperCase());
|
|
117
163
|
}
|
|
118
164
|
}
|
|
119
165
|
|
|
@@ -126,7 +172,7 @@ class FormMultiColumnValidations extends Validations {
|
|
|
126
172
|
if (!this.isVisible()) {
|
|
127
173
|
return;
|
|
128
174
|
}
|
|
129
|
-
await ValidationsFactory(this.element.items, { screen: this.screen, data: this.data }).addValidations(validations);
|
|
175
|
+
await ValidationsFactory(this.element.items, { screen: this.screen, data: this.data, parentVisibilityRule: this.element.config.conditionalHide }).addValidations(validations);
|
|
130
176
|
}
|
|
131
177
|
}
|
|
132
178
|
|
|
@@ -167,19 +213,8 @@ class FormElementValidations extends Validations {
|
|
|
167
213
|
}
|
|
168
214
|
const fieldName = this.element.config.name;
|
|
169
215
|
const validationConfig = this.element.config.validation;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (this.element.config.conditionalHide) {
|
|
173
|
-
let visible = true;
|
|
174
|
-
try {
|
|
175
|
-
visible = !!Parser.evaluate(this.element.config.conditionalHide, this.data);
|
|
176
|
-
} catch (error) {
|
|
177
|
-
visible = false;
|
|
178
|
-
}
|
|
179
|
-
if (!visible) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
216
|
+
const conditionalHide = this.element.config.conditionalHide;
|
|
217
|
+
const parentVisibilityRule = this.parentVisibilityRule;
|
|
183
218
|
|
|
184
219
|
set(validations, fieldName, get(validations, fieldName, {}));
|
|
185
220
|
const fieldValidation = get(validations, fieldName);
|
|
@@ -203,7 +238,40 @@ class FormElementValidations extends Validations {
|
|
|
203
238
|
params.push(fieldName);
|
|
204
239
|
validationFn = validationFn(...params);
|
|
205
240
|
}
|
|
206
|
-
fieldValidation[rule] =
|
|
241
|
+
fieldValidation[rule] = function(...props) {
|
|
242
|
+
const data = props[1];
|
|
243
|
+
let dataWithParent = this.addReferenceToParents(data);
|
|
244
|
+
const nestedDataWithParent = this.addReferenceToParents(this.findParent(data));
|
|
245
|
+
if (nestedDataWithParent) {
|
|
246
|
+
dataWithParent = Object.assign(nestedDataWithParent, dataWithParent);
|
|
247
|
+
}
|
|
248
|
+
// Check Parent Visibility
|
|
249
|
+
if (parentVisibilityRule) {
|
|
250
|
+
let isParentVisible = true;
|
|
251
|
+
try {
|
|
252
|
+
isParentVisible = !!Parser.evaluate(parentVisibilityRule, dataWithParent);
|
|
253
|
+
} catch (error) {
|
|
254
|
+
isParentVisible = false;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (!isParentVisible ) {
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Check Field Visibility
|
|
262
|
+
let visible = true;
|
|
263
|
+
if (conditionalHide) {
|
|
264
|
+
try {
|
|
265
|
+
visible = !!Parser.evaluate(conditionalHide, dataWithParent);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
visible = false;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (!visible) {
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
return validationFn.apply(this,props);
|
|
274
|
+
};
|
|
207
275
|
});
|
|
208
276
|
} else if (typeof validationConfig === 'string' && validationConfig) {
|
|
209
277
|
let validationFn = validators[validationConfig];
|
|
@@ -212,7 +280,40 @@ class FormElementValidations extends Validations {
|
|
|
212
280
|
console.error(`Undefined validation rule "${validationConfig}"`);
|
|
213
281
|
return;
|
|
214
282
|
}
|
|
215
|
-
fieldValidation[validationConfig] =
|
|
283
|
+
fieldValidation[validationConfig] = function(...props) {
|
|
284
|
+
const data = props[1];
|
|
285
|
+
let dataWithParent = this.addReferenceToParents(data);
|
|
286
|
+
const nestedDataWithParent = this.addReferenceToParents(this.findParent(data));
|
|
287
|
+
if (nestedDataWithParent) {
|
|
288
|
+
dataWithParent = Object.assign(nestedDataWithParent, dataWithParent);
|
|
289
|
+
}
|
|
290
|
+
// Check Parent Visibility
|
|
291
|
+
if (parentVisibilityRule) {
|
|
292
|
+
let isParentVisible = true;
|
|
293
|
+
try {
|
|
294
|
+
isParentVisible = !!Parser.evaluate(parentVisibilityRule, dataWithParent);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
isParentVisible = false;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (!isParentVisible) {
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Check Field Visibility
|
|
304
|
+
let visible = true;
|
|
305
|
+
if (conditionalHide) {
|
|
306
|
+
try {
|
|
307
|
+
visible = !!Parser.evaluate(conditionalHide, dataWithParent);
|
|
308
|
+
} catch (error) {
|
|
309
|
+
visible = false;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (!visible) {
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
return validationFn.apply(this,props);
|
|
316
|
+
};
|
|
216
317
|
}
|
|
217
318
|
if (this.element.items) {
|
|
218
319
|
ValidationsFactory(this.element.items, { screen: this.screen, data: this.data }).addValidations(validations);
|
|
@@ -20,10 +20,13 @@
|
|
|
20
20
|
:data-manager="dataManager"
|
|
21
21
|
:fields="tableFields"
|
|
22
22
|
:items="tableData.data"
|
|
23
|
+
:sort-compare-options="{ numeric: false }"
|
|
23
24
|
sort-icon-left
|
|
24
25
|
:css="css"
|
|
25
26
|
:empty-text="$t('No Data Available')"
|
|
26
27
|
:current-page="currentPage"
|
|
28
|
+
@sort-changed="sortChanged"
|
|
29
|
+
@input="onInput"
|
|
27
30
|
data-cy="table"
|
|
28
31
|
>
|
|
29
32
|
<template #cell()="{index,field,item}">
|
|
@@ -74,6 +77,7 @@
|
|
|
74
77
|
:title="$t('Add')"
|
|
75
78
|
header-close-content="×"
|
|
76
79
|
data-cy="modal-add"
|
|
80
|
+
@shown="emitShownEvent"
|
|
77
81
|
>
|
|
78
82
|
<vue-form-renderer
|
|
79
83
|
:page="0"
|
|
@@ -99,6 +103,7 @@
|
|
|
99
103
|
:title="$t('Edit Record')"
|
|
100
104
|
header-close-content="×"
|
|
101
105
|
data-cy="modal-edit"
|
|
106
|
+
@shown="emitShownEvent"
|
|
102
107
|
>
|
|
103
108
|
<vue-form-renderer
|
|
104
109
|
:page="0"
|
|
@@ -161,7 +166,7 @@ const jsonOptionsActionsColumn = {
|
|
|
161
166
|
|
|
162
167
|
export default {
|
|
163
168
|
mixins: [mustacheEvaluation],
|
|
164
|
-
props: ['name', 'label', 'fields', 'value', 'editable', '_config', 'form', 'validationData', 'formConfig', 'formComputed', 'formWatchers'],
|
|
169
|
+
props: ['name', 'label', 'fields', 'value', 'editable', '_config', 'form', 'validationData', 'formConfig', 'formComputed', 'formWatchers', '_perPage'],
|
|
165
170
|
data() {
|
|
166
171
|
return {
|
|
167
172
|
editFormVersion: 0,
|
|
@@ -192,6 +197,11 @@ export default {
|
|
|
192
197
|
initFormValues: {},
|
|
193
198
|
};
|
|
194
199
|
},
|
|
200
|
+
mounted() {
|
|
201
|
+
if (this._perPage) {
|
|
202
|
+
this.perPage = this._perPage;
|
|
203
|
+
}
|
|
204
|
+
},
|
|
195
205
|
computed: {
|
|
196
206
|
popupConfig() {
|
|
197
207
|
const config = [];
|
|
@@ -240,6 +250,7 @@ export default {
|
|
|
240
250
|
from,
|
|
241
251
|
to: value.length,
|
|
242
252
|
data: value,
|
|
253
|
+
lastSortConfig: false,
|
|
243
254
|
};
|
|
244
255
|
return data;
|
|
245
256
|
},
|
|
@@ -258,7 +269,35 @@ export default {
|
|
|
258
269
|
return this.form && this.form === this.$parent.currentPage;
|
|
259
270
|
},
|
|
260
271
|
},
|
|
272
|
+
watch: {
|
|
273
|
+
'tableData.total': {
|
|
274
|
+
deep: true,
|
|
275
|
+
handler(total) {
|
|
276
|
+
let totalPages = Math.ceil(total / this.perPage);
|
|
277
|
+
this.currentPage = (this.currentPage > totalPages ? totalPages : this.currentPage);
|
|
278
|
+
this.currentPage = (this.currentPage == 0 ? 1 : this.currentPage);
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
},
|
|
261
282
|
methods: {
|
|
283
|
+
sortChanged(payload) {
|
|
284
|
+
this.lastSortConfig = payload;
|
|
285
|
+
this.tableData.data = this.sort(this.tableData.data, payload);
|
|
286
|
+
},
|
|
287
|
+
onInput() {
|
|
288
|
+
if (this.lastSortConfig) {
|
|
289
|
+
this.tableData.data = this.sort(this.tableData.data, this.lastSortConfig);
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
sort(data, options) {
|
|
293
|
+
if (options.sortDesc) {
|
|
294
|
+
return data.sort((b,a) => a[options.sortBy].localeCompare(b[options.sortBy], 0, {numeric: false}));
|
|
295
|
+
}
|
|
296
|
+
return data.sort((a,b) => a[options.sortBy].localeCompare(b[options.sortBy], 0, {numeric: false}));
|
|
297
|
+
},
|
|
298
|
+
emitShownEvent() {
|
|
299
|
+
window.ProcessMaker.EventBus.$emit('modal-shown');
|
|
300
|
+
},
|
|
262
301
|
formatIfDate(string) {
|
|
263
302
|
return dateUtils.formatIfDate(string);
|
|
264
303
|
},
|
|
@@ -337,9 +376,9 @@ export default {
|
|
|
337
376
|
}
|
|
338
377
|
},
|
|
339
378
|
showEditForm(index) {
|
|
340
|
-
let pageIndex = ((this.
|
|
379
|
+
let pageIndex = ((this.currentPage-1) * this.perPage) + index;
|
|
341
380
|
// Reset edit to be a copy of our data model item
|
|
342
|
-
this.editItem = JSON.parse(JSON.stringify(this.
|
|
381
|
+
this.editItem = JSON.parse(JSON.stringify(this.tableData.data[pageIndex]));
|
|
343
382
|
this.editIndex = pageIndex;
|
|
344
383
|
// rebuild the edit screen to avoid
|
|
345
384
|
this.editFormVersion++;
|
|
@@ -349,13 +388,13 @@ export default {
|
|
|
349
388
|
});
|
|
350
389
|
},
|
|
351
390
|
edit(event) {
|
|
352
|
-
if (this.$refs.editRenderer.$refs.renderer.$refs.component.$v.$invalid) {
|
|
391
|
+
if (this.$refs.editRenderer.$refs.renderer.$refs.component.$v.vdata.$invalid) {
|
|
353
392
|
event.preventDefault();
|
|
354
393
|
return;
|
|
355
394
|
}
|
|
356
395
|
|
|
357
396
|
// Edit the item in our model and emit change
|
|
358
|
-
let data = this.
|
|
397
|
+
let data = this.tableData.data ? JSON.parse(JSON.stringify(this.tableData.data)) : [];
|
|
359
398
|
data[this.editIndex] = JSON.parse(JSON.stringify(this.editItem));
|
|
360
399
|
|
|
361
400
|
// Remove the parent object
|
|
@@ -382,7 +421,7 @@ export default {
|
|
|
382
421
|
handleOk(bvModalEvt) {
|
|
383
422
|
bvModalEvt.preventDefault();
|
|
384
423
|
|
|
385
|
-
if (this.$refs.addRenderer.$refs.renderer.$refs.component.$v.$invalid) {
|
|
424
|
+
if (this.$refs.addRenderer.$refs.renderer.$refs.component.$v.vdata.$invalid) {
|
|
386
425
|
return;
|
|
387
426
|
}
|
|
388
427
|
|
|
@@ -405,7 +444,7 @@ export default {
|
|
|
405
444
|
});
|
|
406
445
|
},
|
|
407
446
|
showDeleteConfirmation(index) {
|
|
408
|
-
let pageIndex = ((this.
|
|
447
|
+
let pageIndex = ((this.currentPage-1) * this.perPage) + index;
|
|
409
448
|
this.deleteIndex = pageIndex;
|
|
410
449
|
this.$refs.deleteModal.show();
|
|
411
450
|
},
|
|
@@ -442,7 +481,7 @@ export default {
|
|
|
442
481
|
remove() {
|
|
443
482
|
// Add the item to our model and emit change
|
|
444
483
|
// @todo Also check that value is an array type, if not, reset it to an array
|
|
445
|
-
let data = this.
|
|
484
|
+
let data = this.tableData.data ? JSON.parse(JSON.stringify(this.tableData.data)) : [];
|
|
446
485
|
let recordData = data[this.deleteIndex];
|
|
447
486
|
// Remove item from data array
|
|
448
487
|
data.splice(this.deleteIndex, 1);
|
|
@@ -459,3 +498,4 @@ export default {
|
|
|
459
498
|
max-width: 300px;
|
|
460
499
|
}
|
|
461
500
|
</style>
|
|
501
|
+
|
package/src/components/task.vue
CHANGED
|
@@ -242,6 +242,11 @@ export default {
|
|
|
242
242
|
.then((response) => {
|
|
243
243
|
this.task = response.data;
|
|
244
244
|
this.checkTaskStatus();
|
|
245
|
+
if (window.PM4ConfigOverrides.getScreenEndpoint && window.PM4ConfigOverrides.getScreenEndpoint.includes('tasks/')) {
|
|
246
|
+
const screenPath = window.PM4ConfigOverrides.getScreenEndpoint.split('/');
|
|
247
|
+
screenPath[1] = this.task.id;
|
|
248
|
+
window.PM4ConfigOverrides.getScreenEndpoint = screenPath.join('/');
|
|
249
|
+
}
|
|
245
250
|
})
|
|
246
251
|
.catch(() => {
|
|
247
252
|
this.hasErrors = true;
|
|
@@ -279,19 +284,19 @@ export default {
|
|
|
279
284
|
}
|
|
280
285
|
this.prepareTask();
|
|
281
286
|
},
|
|
282
|
-
closeTask() {
|
|
287
|
+
closeTask(parentRequestId = null) {
|
|
283
288
|
if (this.hasErrors) {
|
|
284
289
|
this.$emit('error', this.requestId);
|
|
285
290
|
return;
|
|
286
291
|
}
|
|
287
292
|
|
|
288
293
|
if (this.task.process_request.status === 'COMPLETED') {
|
|
289
|
-
this.
|
|
294
|
+
this.loadNextAssignedTask(parentRequestId);
|
|
290
295
|
|
|
291
296
|
} else if (this.task.allow_interstitial) {
|
|
292
297
|
this.task.interstitial_screen['_interstitial'] = true;
|
|
293
298
|
this.screen = this.task.interstitial_screen;
|
|
294
|
-
this.loadNextAssignedTask();
|
|
299
|
+
this.loadNextAssignedTask(parentRequestId);
|
|
295
300
|
|
|
296
301
|
} else {
|
|
297
302
|
this.$emit('closed', this.task.id);
|
|
@@ -313,11 +318,16 @@ export default {
|
|
|
313
318
|
}
|
|
314
319
|
this.unsubscribeSocketListeners();
|
|
315
320
|
this.redirecting = task.process_request_id;
|
|
316
|
-
this.$emit('redirect', task);
|
|
321
|
+
this.$emit('redirect', task.id, true);
|
|
317
322
|
return;
|
|
323
|
+
} else if (this.task && requestId == this.task.process_request_id && this.parentRequest && this.task.process_request.status === 'COMPLETED') {
|
|
324
|
+
// Only emit completed after getting the subprocess tasks and there are no tasks and process is completed
|
|
325
|
+
this.$emit('completed', this.parentRequest);
|
|
318
326
|
}
|
|
319
327
|
this.taskId = task.id;
|
|
320
328
|
this.nodeId = task.element_id;
|
|
329
|
+
} else {
|
|
330
|
+
this.$emit('completed', (this.parentRequest ? this.parentRequest : requestId));
|
|
321
331
|
}
|
|
322
332
|
});
|
|
323
333
|
},
|
|
@@ -361,9 +371,8 @@ export default {
|
|
|
361
371
|
// This may no longer be needed
|
|
362
372
|
},
|
|
363
373
|
processCompleted() {
|
|
364
|
-
if (this.parentRequest
|
|
365
|
-
|
|
366
|
-
return;
|
|
374
|
+
if (this.parentRequest) {
|
|
375
|
+
this.$emit('completed', this.parentRequest);
|
|
367
376
|
}
|
|
368
377
|
this.$emit('completed', this.requestId);
|
|
369
378
|
},
|
|
@@ -412,8 +421,13 @@ export default {
|
|
|
412
421
|
`ProcessMaker.Models.ProcessRequest.${this.parentRequest}`,
|
|
413
422
|
'.ProcessUpdated',
|
|
414
423
|
(data) => {
|
|
415
|
-
if (['
|
|
416
|
-
this.
|
|
424
|
+
if (['ACTIVITY_ACTIVATED'].includes(data.event)) {
|
|
425
|
+
this.closeTask(this.parentRequest);
|
|
426
|
+
}
|
|
427
|
+
if (['ACTIVITY_COMPLETED'].includes(data.event)) {
|
|
428
|
+
if (this.task.process_request.status === 'COMPLETED') {
|
|
429
|
+
this.processCompleted();
|
|
430
|
+
}
|
|
417
431
|
}
|
|
418
432
|
if (data.event === 'ACTIVITY_EXCEPTION') {
|
|
419
433
|
this.$emit('error', this.requestId);
|
|
@@ -96,7 +96,8 @@ export const keyNameProperty = {
|
|
|
96
96
|
config: {
|
|
97
97
|
label: 'Variable Name',
|
|
98
98
|
name: 'Variable Name',
|
|
99
|
-
|
|
99
|
+
// Update tests/e2e/specs/Builder.spec.js when changing this
|
|
100
|
+
validation: 'regex:/^([a-zA-Z]([a-zA-Z0-9_]?)+\\.?)+(?<!\\.)$/|required|not_in:' + javascriptReservedKeywords,
|
|
100
101
|
helper: 'A variable name is a symbolic name to reference information.',
|
|
101
102
|
},
|
|
102
103
|
};
|
package/src/main.js
CHANGED
|
@@ -152,7 +152,7 @@ window.ProcessMaker = {
|
|
|
152
152
|
{value: 2, content: 'John'},
|
|
153
153
|
{value: 3, content: 'Mary'},
|
|
154
154
|
{value: 4, content: 'Patricia'},
|
|
155
|
-
],
|
|
155
|
+
],
|
|
156
156
|
}});
|
|
157
157
|
break;
|
|
158
158
|
default:
|
|
@@ -201,6 +201,16 @@ window.Echo = {
|
|
|
201
201
|
}, 1000);
|
|
202
202
|
});
|
|
203
203
|
},
|
|
204
|
+
eventMocks(event, response) {
|
|
205
|
+
this.listeners.forEach((listener) => {
|
|
206
|
+
setTimeout(() => {
|
|
207
|
+
listener.callback({
|
|
208
|
+
type: event,
|
|
209
|
+
response,
|
|
210
|
+
});
|
|
211
|
+
}, 1000);
|
|
212
|
+
});
|
|
213
|
+
},
|
|
204
214
|
private() {
|
|
205
215
|
return {
|
|
206
216
|
notification(callback) {
|
package/src/mixins/ScreenBase.js
CHANGED
|
@@ -93,7 +93,8 @@ export default {
|
|
|
93
93
|
},
|
|
94
94
|
tryFormField(variableName, callback, defaultValue = null) {
|
|
95
95
|
try {
|
|
96
|
-
|
|
96
|
+
let result = callback();
|
|
97
|
+
return (result === undefined) ? null : result;
|
|
97
98
|
} catch (e) {
|
|
98
99
|
set(this.$v, `${variableName}.$invalid`, true);
|
|
99
100
|
set(this.$v, `${variableName}.invalid_default_value`, false);
|
|
@@ -102,7 +103,15 @@ export default {
|
|
|
102
103
|
},
|
|
103
104
|
mustache(text) {
|
|
104
105
|
try {
|
|
105
|
-
const data =
|
|
106
|
+
const data = new Proxy(this, {
|
|
107
|
+
get(target, name) {
|
|
108
|
+
if (name === '_parent') {
|
|
109
|
+
return target._parent;
|
|
110
|
+
} else {
|
|
111
|
+
return target.vdata[name];
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
});
|
|
106
115
|
return text && Mustache.render(text, data);
|
|
107
116
|
} catch (e) {
|
|
108
117
|
return 'MUSTACHE: ' + e.message;
|
|
@@ -146,21 +155,17 @@ export default {
|
|
|
146
155
|
},
|
|
147
156
|
setValue(name, value, object = this, defaults = object) {
|
|
148
157
|
if (object && value !== undefined) {
|
|
149
|
-
const
|
|
150
|
-
splittedName.forEach((attr, index) => {
|
|
158
|
+
const parsedName = name.split('.');
|
|
151
159
|
|
|
152
|
-
|
|
153
|
-
|
|
160
|
+
for (const attr of parsedName) {
|
|
161
|
+
let setValue;
|
|
162
|
+
let index = parsedName.indexOf(attr);
|
|
163
|
+
let isLastElement = index === parsedName.length - 1;
|
|
154
164
|
|
|
155
|
-
|
|
156
|
-
isLastElement = true;
|
|
157
|
-
} else {
|
|
158
|
-
isLastElement = false;
|
|
159
|
-
}
|
|
165
|
+
const originalValue = get(object, attr);
|
|
160
166
|
|
|
161
167
|
if (isLastElement) {
|
|
162
168
|
setValue = value;
|
|
163
|
-
|
|
164
169
|
} else {
|
|
165
170
|
setValue = originalValue;
|
|
166
171
|
|
|
@@ -168,7 +173,7 @@ export default {
|
|
|
168
173
|
// Check defaults
|
|
169
174
|
setValue = get(defaults, attr);
|
|
170
175
|
}
|
|
171
|
-
|
|
176
|
+
|
|
172
177
|
if (!setValue) {
|
|
173
178
|
// Still no value? Set empty object
|
|
174
179
|
setValue = {};
|
|
@@ -184,9 +189,10 @@ export default {
|
|
|
184
189
|
attr,
|
|
185
190
|
setValue
|
|
186
191
|
);
|
|
192
|
+
|
|
187
193
|
object = get(object, attr);
|
|
188
194
|
defaults = get(defaults, attr);
|
|
189
|
-
}
|
|
195
|
+
}
|
|
190
196
|
}
|
|
191
197
|
},
|
|
192
198
|
validationMessage(validation) {
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
and,
|
|
24
24
|
maxItems,
|
|
25
25
|
minItems,
|
|
26
|
+
type,
|
|
26
27
|
} from 'vuelidate/lib/validators';
|
|
27
28
|
|
|
28
29
|
export const ValidationMsg = {
|
|
@@ -59,6 +60,7 @@ export const ValidationMsg = {
|
|
|
59
60
|
regex: 'Invalid value',
|
|
60
61
|
maxItems: 'Should NOT have more than {max} items',
|
|
61
62
|
minItems: 'Must have at least {min}',
|
|
63
|
+
type: 'Invalid type',
|
|
62
64
|
};
|
|
63
65
|
|
|
64
66
|
export const custom_date = (date) => {
|
|
@@ -231,4 +233,5 @@ export const validators = {
|
|
|
231
233
|
afterOrEqual: after_or_equal,
|
|
232
234
|
maxItems,
|
|
233
235
|
minItems,
|
|
236
|
+
type,
|
|
234
237
|
};
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
1
|
import { Parser } from 'expr-eval';
|
|
3
2
|
|
|
4
3
|
export default {
|
|
5
4
|
methods: {
|
|
6
5
|
evaluateExpression(expression, type) {
|
|
6
|
+
const self = this;
|
|
7
7
|
let value = null;
|
|
8
8
|
|
|
9
|
-
const merged = {};
|
|
10
|
-
_.merge(merged, this.vdata, this._data);
|
|
11
|
-
|
|
12
9
|
try {
|
|
13
|
-
//
|
|
14
|
-
//in this way the event is not
|
|
15
|
-
|
|
10
|
+
// Monitor if variable belongs to data (defined variables) or
|
|
11
|
+
// vdata (external variables)in this way the event is not
|
|
12
|
+
// executed again when the variable is update
|
|
13
|
+
const data = new Proxy(Object.assign({}, self, self.vdata), {
|
|
16
14
|
get(data, name) {
|
|
17
|
-
return data[name];
|
|
15
|
+
return undefined === data[name] ? self.vdata[name] : data[name];
|
|
18
16
|
},
|
|
19
17
|
set() {
|
|
20
18
|
throw 'You are not allowed to set properties from inside an expression';
|
|
@@ -3,14 +3,28 @@ import computedFields from '../computedFields';
|
|
|
3
3
|
export default {
|
|
4
4
|
methods: {
|
|
5
5
|
computedFields(screen, definition) {
|
|
6
|
+
// Add computed fields
|
|
6
7
|
screen.mixins.push(computedFields);
|
|
7
|
-
|
|
8
|
+
|
|
9
|
+
for (const computed of definition.computed) {
|
|
8
10
|
screen.computed[computed.property] = {
|
|
9
|
-
get:
|
|
10
|
-
|
|
11
|
+
get: (() => {
|
|
12
|
+
const formula = JSON.stringify(computed.formula);
|
|
13
|
+
const type = JSON.stringify(computed.type);
|
|
14
|
+
|
|
15
|
+
return new Function(`return this.evaluateExpression(${formula}, ${type});`);
|
|
16
|
+
})(),
|
|
17
|
+
set() {
|
|
18
|
+
// Do nothing (as it's not allowed)
|
|
19
|
+
},
|
|
11
20
|
};
|
|
12
|
-
|
|
13
|
-
|
|
21
|
+
|
|
22
|
+
this.addWatch(
|
|
23
|
+
screen,
|
|
24
|
+
computed.property,
|
|
25
|
+
`this.setValue(${JSON.stringify(computed.property)}, value, this.vdata);`
|
|
26
|
+
);
|
|
27
|
+
}
|
|
14
28
|
},
|
|
15
29
|
},
|
|
16
30
|
mounted() {
|