@processmaker/screen-builder 2.25.0 → 2.27.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/package-lock.json +6 -1
- package/package.json +3 -2
- package/src/.DS_Store +0 -0
- package/src/App.vue +10 -0
- package/src/DataProvider.js +4 -0
- package/src/ValidationsFactory.js +17 -15
- package/src/components/inspector/screen-selector.vue +11 -1
- package/src/components/renderer/form-button.vue +23 -28
- package/src/components/renderer/form-nested-screen.vue +1 -0
- package/src/components/renderer/form-record-list.vue +15 -29
- package/src/components/task.vue +7 -0
- package/src/components/vue-form-builder.vue +49 -1
- package/src/components/vue-form-renderer.vue +9 -0
- package/src/mixins/multiselectApi.js +3 -1
- package/src/store/modules/global-errors.js +30 -0
- package/dist/demo.html +0 -10
- package/dist/vue-form-builder.common.js +0 -194602
- package/dist/vue-form-builder.common.js.map +0 -1
- package/dist/vue-form-builder.css +0 -1
- package/dist/vue-form-builder.umd.js +0 -194612
- package/dist/vue-form-builder.umd.js.map +0 -1
- package/dist/vue-form-builder.umd.min.js +0 -324
- package/dist/vue-form-builder.umd.min.js.map +0 -1
package/package-lock.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@processmaker/screen-builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.27.0",
|
|
4
4
|
"lockfileVersion": 1,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"dependencies": {
|
|
@@ -10192,6 +10192,11 @@
|
|
|
10192
10192
|
"integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
|
|
10193
10193
|
"dev": true
|
|
10194
10194
|
},
|
|
10195
|
+
"is-proxy": {
|
|
10196
|
+
"version": "1.0.6",
|
|
10197
|
+
"resolved": "https://registry.npmjs.org/is-proxy/-/is-proxy-1.0.6.tgz",
|
|
10198
|
+
"integrity": "sha512-RzUROKx085vc7tpo9zCinKAmsD7ihAnXJ7HvKdcsc3m0XW/vpJDFSvZgutqMam0aBxpYBmDVYv48+T/+AMYl1g=="
|
|
10199
|
+
},
|
|
10195
10200
|
"is-regex": {
|
|
10196
10201
|
"version": "1.1.3",
|
|
10197
10202
|
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@processmaker/screen-builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.27.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"serve": "vue-cli-service serve",
|
|
6
6
|
"build": "vue-cli-service build",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"*.js"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
+
"is-proxy": "^1.0.6",
|
|
33
34
|
"lodash": "^4.17.20",
|
|
34
35
|
"moment": "^2.29.1",
|
|
35
36
|
"moment-timezone": "^0.5.27",
|
|
@@ -85,7 +86,7 @@
|
|
|
85
86
|
},
|
|
86
87
|
"peerDependencies": {
|
|
87
88
|
"@panter/vue-i18next": "^0.15.0",
|
|
88
|
-
"@processmaker/vue-form-elements": "0.28.
|
|
89
|
+
"@processmaker/vue-form-elements": "0.28.7",
|
|
89
90
|
"i18next": "^15.0.8",
|
|
90
91
|
"vue": "^2.6.12",
|
|
91
92
|
"vuex": "^3.1.1"
|
package/src/.DS_Store
CHANGED
|
Binary file
|
package/src/App.vue
CHANGED
|
@@ -74,6 +74,13 @@
|
|
|
74
74
|
<!-- Preview -->
|
|
75
75
|
<b-row class="h-100 m-0" id="preview" v-show="displayPreview" data-cy="preview">
|
|
76
76
|
<b-col class="overflow-auto h-100" data-cy="preview-content">
|
|
77
|
+
<div v-if="$store.getters['globalErrorsModule/isValidScreen'] === false" class="alert alert-danger mt-3">
|
|
78
|
+
<i class="fas fa-exclamation-circle"/>
|
|
79
|
+
{{ $store.getters['globalErrorsModule/getErrorMessage'] }}
|
|
80
|
+
<button type="button" class="close" aria-label="Close" @click="$store.dispatch('globalErrorsModule/close')">
|
|
81
|
+
<span aria-hidden="true">×</span>
|
|
82
|
+
</button>
|
|
83
|
+
</div>
|
|
77
84
|
<vue-form-renderer ref="renderer"
|
|
78
85
|
:key="rendererKey"
|
|
79
86
|
v-model="previewData"
|
|
@@ -422,10 +429,13 @@ export default {
|
|
|
422
429
|
this.previewData = this.previewInputValid ? JSON.parse(this.previewInput) : {};
|
|
423
430
|
this.rendererKey++;
|
|
424
431
|
if (mode == 'preview') {
|
|
432
|
+
this.$dataProvider.flushScreenCache();
|
|
425
433
|
this.preview.config = cloneDeep(this.config);
|
|
426
434
|
this.preview.computed = cloneDeep(this.computed);
|
|
427
435
|
this.preview.customCSS = cloneDeep(this.customCSS);
|
|
428
436
|
this.preview.watchers = cloneDeep(this.watchers);
|
|
437
|
+
} else {
|
|
438
|
+
this.$refs.builder.refreshContent();
|
|
429
439
|
}
|
|
430
440
|
},
|
|
431
441
|
loadFromLocalStorage() {
|
package/src/DataProvider.js
CHANGED
|
@@ -10,6 +10,7 @@ class Validations {
|
|
|
10
10
|
screen = null;
|
|
11
11
|
firstPage = 0;
|
|
12
12
|
data = {};
|
|
13
|
+
insideLoop = false;
|
|
13
14
|
constructor(element, options) {
|
|
14
15
|
this.element = element;
|
|
15
16
|
Object.assign(this, options);
|
|
@@ -51,7 +52,7 @@ class Validations {
|
|
|
51
52
|
class ArrayOfFieldsValidations extends Validations {
|
|
52
53
|
async addValidations(validations) {
|
|
53
54
|
for (const item of this.element) {
|
|
54
|
-
await ValidationsFactory(item, { screen: this.screen, data: this.data, parentVisibilityRule: this.parentVisibilityRule }).addValidations(validations);
|
|
55
|
+
await ValidationsFactory(item, { screen: this.screen, data: this.data, parentVisibilityRule: this.parentVisibilityRule, insideLoop: this.insideLoop }).addValidations(validations);
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -114,13 +115,16 @@ class FormLoopValidations extends Validations {
|
|
|
114
115
|
const loopField = get(validations, this.element.config.name);
|
|
115
116
|
loopField['$each'] = {};
|
|
116
117
|
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
|
+
await ValidationsFactory(this.element.items, { screen: this.screen, data: {_parent: this.data, noData:true }, parentVisibilityRule: this.element.config.conditionalHide, insideLoop: true }).addValidations(loopField['$each']);
|
|
118
119
|
}
|
|
119
120
|
checkForSiblings(validations) {
|
|
120
121
|
const siblings = [];
|
|
121
122
|
const siblingValidations = [];
|
|
122
123
|
// Find loops that reference the same variable
|
|
123
124
|
this.screen.config.forEach(page => {
|
|
125
|
+
if (!page || !page.items) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
124
128
|
page.items.filter(item => {
|
|
125
129
|
if (item.component === 'FormLoop' && item.config.name === this.element.config.name) {
|
|
126
130
|
siblings.push(item);
|
|
@@ -215,6 +219,7 @@ class FormElementValidations extends Validations {
|
|
|
215
219
|
const validationConfig = this.element.config.validation;
|
|
216
220
|
const conditionalHide = this.element.config.conditionalHide;
|
|
217
221
|
const parentVisibilityRule = this.parentVisibilityRule;
|
|
222
|
+
const insideLoop = this.insideLoop || false;
|
|
218
223
|
|
|
219
224
|
set(validations, fieldName, get(validations, fieldName, {}));
|
|
220
225
|
const fieldValidation = get(validations, fieldName);
|
|
@@ -240,16 +245,14 @@ class FormElementValidations extends Validations {
|
|
|
240
245
|
}
|
|
241
246
|
fieldValidation[rule] = function(...props) {
|
|
242
247
|
const data = props[1];
|
|
243
|
-
|
|
244
|
-
const
|
|
245
|
-
if (nestedDataWithParent) {
|
|
246
|
-
dataWithParent = Object.assign(nestedDataWithParent, dataWithParent);
|
|
247
|
-
}
|
|
248
|
-
// Check Parent Visibility
|
|
248
|
+
const level = fieldName.split('.').length - 1;
|
|
249
|
+
const dataWithParent = this.getDataAccordingToFieldLevel(this.getRootScreen().addReferenceToParents(data), level);
|
|
249
250
|
if (parentVisibilityRule) {
|
|
251
|
+
const nextParentLevel = insideLoop ? 1 : 0;
|
|
252
|
+
const parentDataWithParent = this.getDataAccordingToFieldLevel(this.getRootScreen().addReferenceToParents(data), level + nextParentLevel);
|
|
250
253
|
let isParentVisible = true;
|
|
251
254
|
try {
|
|
252
|
-
isParentVisible = !!Parser.evaluate(parentVisibilityRule,
|
|
255
|
+
isParentVisible = !!Parser.evaluate(parentVisibilityRule, parentDataWithParent);
|
|
253
256
|
} catch (error) {
|
|
254
257
|
isParentVisible = false;
|
|
255
258
|
}
|
|
@@ -282,16 +285,15 @@ class FormElementValidations extends Validations {
|
|
|
282
285
|
}
|
|
283
286
|
fieldValidation[validationConfig] = function(...props) {
|
|
284
287
|
const data = props[1];
|
|
285
|
-
|
|
286
|
-
const
|
|
287
|
-
if (nestedDataWithParent) {
|
|
288
|
-
dataWithParent = Object.assign(nestedDataWithParent, dataWithParent);
|
|
289
|
-
}
|
|
288
|
+
const level = fieldName.split('.').length - 1;
|
|
289
|
+
const dataWithParent = this.getDataAccordingToFieldLevel(this.getRootScreen().addReferenceToParents(data), level);
|
|
290
290
|
// Check Parent Visibility
|
|
291
291
|
if (parentVisibilityRule) {
|
|
292
|
+
const nextParentLevel = insideLoop ? 1 : 0;
|
|
293
|
+
const parentDataWithParent = this.getDataAccordingToFieldLevel(this.getRootScreen().addReferenceToParents(data), level + nextParentLevel);
|
|
292
294
|
let isParentVisible = true;
|
|
293
295
|
try {
|
|
294
|
-
isParentVisible = !!Parser.evaluate(parentVisibilityRule,
|
|
296
|
+
isParentVisible = !!Parser.evaluate(parentVisibilityRule, parentDataWithParent);
|
|
295
297
|
} catch (error) {
|
|
296
298
|
isParentVisible = false;
|
|
297
299
|
}
|
|
@@ -95,10 +95,19 @@ export default {
|
|
|
95
95
|
return false;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
|
|
98
|
+
const id = this.storeId ? get(value, this.trackBy) : value;
|
|
99
|
+
// Make sure to load latest config from screen and nested screens
|
|
100
|
+
this.$dataProvider.flushScreenCache();
|
|
101
|
+
this.$emit('input', id);
|
|
99
102
|
},
|
|
100
103
|
},
|
|
101
104
|
mounted() {
|
|
105
|
+
this.$root.$on('remove-nested', (nestedScreenId) => {
|
|
106
|
+
if (this.value === nestedScreenId) {
|
|
107
|
+
this.$emit('input', null);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
102
111
|
let pmql = '(type = "FORM" or type = "DISPLAY")';
|
|
103
112
|
if (this.screenType === formTypes.display) {
|
|
104
113
|
pmql = '(type = "DISPLAY")';
|
|
@@ -107,6 +116,7 @@ export default {
|
|
|
107
116
|
pmql += ' and id != ' + this.builder.screen.id;
|
|
108
117
|
}
|
|
109
118
|
this.pmql = pmql;
|
|
119
|
+
this.fields = 'screens.id,title';
|
|
110
120
|
},
|
|
111
121
|
};
|
|
112
122
|
</script>
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="form-group" style="overflow-x: hidden">
|
|
3
|
-
<div class="alert alert-danger" v-if="!valid">
|
|
4
|
-
<i class="fas fa-exclamation-circle"/>
|
|
5
|
-
{{ message }}
|
|
6
|
-
</div>
|
|
7
3
|
<button v-b-tooltip="options" @click="click" :class="classList" :name="name" :aria-label="$attrs['aria-label']" :tabindex="$attrs['tabindex']">
|
|
8
4
|
{{ label }}
|
|
9
5
|
</button>
|
|
@@ -13,17 +9,39 @@
|
|
|
13
9
|
<script>
|
|
14
10
|
import Mustache from 'mustache';
|
|
15
11
|
import { getValidPath } from '@/mixins';
|
|
12
|
+
import { isProxy } from 'is-proxy';
|
|
16
13
|
|
|
17
14
|
export default {
|
|
18
15
|
mixins: [getValidPath],
|
|
19
16
|
props: ['variant', 'label', 'event', 'eventData', 'name', 'fieldValue', 'value', 'tooltip', 'transientData'],
|
|
17
|
+
watch: {
|
|
18
|
+
'$attrs.validate': {
|
|
19
|
+
deep: true,
|
|
20
|
+
handler(validate) {
|
|
21
|
+
if (validate && !isProxy(validate.vdata.$model)) {
|
|
22
|
+
this.errors = 0;
|
|
23
|
+
let message = '';
|
|
24
|
+
if (validate.$invalid) {
|
|
25
|
+
this.countErrors(validate.vdata);
|
|
26
|
+
this.countErrors(validate.schema);
|
|
27
|
+
message = this.errors === 1
|
|
28
|
+
? 'There is a validation error in your form.'
|
|
29
|
+
: 'There are {{items}} validation errors in your form.';
|
|
30
|
+
message = this.$t(message, {items: this.errors});
|
|
31
|
+
}
|
|
32
|
+
this.$store.commit('globalErrorsModule/basic', {key: 'valid', value: !validate.$invalid});
|
|
33
|
+
this.$store.commit('globalErrorsModule/basic', {key: 'message', value: message});
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
20
38
|
computed: {
|
|
21
39
|
classList() {
|
|
22
40
|
let variant = this.variant || 'primary';
|
|
23
41
|
return {
|
|
24
42
|
btn: true,
|
|
25
43
|
['btn-' + variant]: true,
|
|
26
|
-
disabled:
|
|
44
|
+
disabled: this.errors,
|
|
27
45
|
};
|
|
28
46
|
},
|
|
29
47
|
options() {
|
|
@@ -45,26 +63,6 @@ export default {
|
|
|
45
63
|
boundary: 'window',
|
|
46
64
|
};
|
|
47
65
|
},
|
|
48
|
-
valid() {
|
|
49
|
-
if (this.$attrs.validate) {
|
|
50
|
-
return !this.$attrs.validate.$invalid;
|
|
51
|
-
}
|
|
52
|
-
return true;
|
|
53
|
-
},
|
|
54
|
-
message() {
|
|
55
|
-
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
|
56
|
-
this.errors = 0;
|
|
57
|
-
if (!this.valid) {
|
|
58
|
-
this.countErrors(this.$attrs.validate.vdata);
|
|
59
|
-
this.countErrors(this.$attrs.validate.schema);
|
|
60
|
-
let message = 'There are {{items}} validation errors in your form.';
|
|
61
|
-
if (this.errors === 1) {
|
|
62
|
-
message = 'There is a validation error in your form.';
|
|
63
|
-
}
|
|
64
|
-
return this.$t(message, {items: this.errors});
|
|
65
|
-
}
|
|
66
|
-
return '';
|
|
67
|
-
},
|
|
68
66
|
},
|
|
69
67
|
data() {
|
|
70
68
|
return {
|
|
@@ -124,6 +122,3 @@ export default {
|
|
|
124
122
|
},
|
|
125
123
|
};
|
|
126
124
|
</script>
|
|
127
|
-
|
|
128
|
-
<style lang="scss">
|
|
129
|
-
</style>
|
|
@@ -21,12 +21,11 @@
|
|
|
21
21
|
:fields="tableFields"
|
|
22
22
|
:items="tableData.data"
|
|
23
23
|
:sort-compare-options="{ numeric: false }"
|
|
24
|
+
:sort-null-last="true"
|
|
24
25
|
sort-icon-left
|
|
25
26
|
:css="css"
|
|
26
27
|
:empty-text="$t('No Data Available')"
|
|
27
28
|
:current-page="currentPage"
|
|
28
|
-
@sort-changed="sortChanged"
|
|
29
|
-
@input="onInput"
|
|
30
29
|
data-cy="table"
|
|
31
30
|
>
|
|
32
31
|
<template #cell()="{index,field,item}">
|
|
@@ -40,13 +39,13 @@
|
|
|
40
39
|
{{ formatIfDate(mustache(field.key, item)) }}
|
|
41
40
|
</template>
|
|
42
41
|
</template>
|
|
43
|
-
<template #cell(__actions)="{index}">
|
|
42
|
+
<template #cell(__actions)="{index,item}">
|
|
44
43
|
<div class="actions">
|
|
45
44
|
<div class="btn-group btn-group-sm" role="group" aria-label="Actions">
|
|
46
|
-
<button @click="showEditForm(index)" class="btn btn-primary" :title="$t('Edit')" data-cy="edit-row">
|
|
45
|
+
<button @click="showEditForm(index, item.row_id)" class="btn btn-primary" :title="$t('Edit')" data-cy="edit-row">
|
|
47
46
|
<i class="fas fa-edit"/>
|
|
48
47
|
</button>
|
|
49
|
-
<button @click="showDeleteConfirmation(index)" class="btn btn-danger" :title="$t('Delete')" data-cy="remove-row">
|
|
48
|
+
<button @click="showDeleteConfirmation(index, item.row_id)" class="btn btn-danger" :title="$t('Delete')" data-cy="remove-row">
|
|
50
49
|
<i class="fas fa-trash-alt"/>
|
|
51
50
|
</button>
|
|
52
51
|
</div>
|
|
@@ -287,21 +286,6 @@ export default {
|
|
|
287
286
|
updateRowDataNamePrefix() {
|
|
288
287
|
this.setUploadDataNamePrefix(this.currentRowIndex);
|
|
289
288
|
},
|
|
290
|
-
sortChanged(payload) {
|
|
291
|
-
this.lastSortConfig = payload;
|
|
292
|
-
this.tableData.data = this.sort(this.tableData.data, payload);
|
|
293
|
-
},
|
|
294
|
-
onInput() {
|
|
295
|
-
if (this.lastSortConfig) {
|
|
296
|
-
this.tableData.data = this.sort(this.tableData.data, this.lastSortConfig);
|
|
297
|
-
}
|
|
298
|
-
},
|
|
299
|
-
sort(data, options) {
|
|
300
|
-
if (options.sortDesc) {
|
|
301
|
-
return data.sort((b,a) => a[options.sortBy].localeCompare(b[options.sortBy], 0, {numeric: false}));
|
|
302
|
-
}
|
|
303
|
-
return data.sort((a,b) => a[options.sortBy].localeCompare(b[options.sortBy], 0, {numeric: false}));
|
|
304
|
-
},
|
|
305
289
|
emitShownEvent() {
|
|
306
290
|
window.ProcessMaker.EventBus.$emit('modal-shown');
|
|
307
291
|
},
|
|
@@ -383,10 +367,10 @@ export default {
|
|
|
383
367
|
this.paginatorPage = this.lastPage;
|
|
384
368
|
}
|
|
385
369
|
},
|
|
386
|
-
showEditForm(index) {
|
|
370
|
+
showEditForm(index, rowId) {
|
|
387
371
|
let pageIndex = ((this.currentPage-1) * this.perPage) + index;
|
|
388
372
|
// Reset edit to be a copy of our data model item
|
|
389
|
-
this.editItem =
|
|
373
|
+
this.editItem = _.find(this.tableData.data, {'row_id': rowId});
|
|
390
374
|
this.editIndex = pageIndex;
|
|
391
375
|
// rebuild the edit screen to avoid
|
|
392
376
|
this.editFormVersion++;
|
|
@@ -403,10 +387,11 @@ export default {
|
|
|
403
387
|
|
|
404
388
|
// Edit the item in our model and emit change
|
|
405
389
|
let data = this.tableData.data ? JSON.parse(JSON.stringify(this.tableData.data)) : [];
|
|
406
|
-
|
|
390
|
+
var index = _.findIndex(data, {'row_id': this.editItem.rowId});
|
|
391
|
+
data[index] = JSON.parse(JSON.stringify(this.editItem));
|
|
407
392
|
|
|
408
393
|
// Remove the parent object
|
|
409
|
-
delete data[
|
|
394
|
+
delete data[index]._parent;
|
|
410
395
|
|
|
411
396
|
// Emit the newly updated data model
|
|
412
397
|
this.$emit('input', data);
|
|
@@ -450,9 +435,8 @@ export default {
|
|
|
450
435
|
this.$refs.addModal.hide();
|
|
451
436
|
});
|
|
452
437
|
},
|
|
453
|
-
showDeleteConfirmation(index) {
|
|
454
|
-
|
|
455
|
-
this.deleteIndex = pageIndex;
|
|
438
|
+
showDeleteConfirmation(index, rowId) {
|
|
439
|
+
this.deleteIndex = _.find(this.tableData.data, {'row_id': rowId});
|
|
456
440
|
this.$refs.deleteModal.show();
|
|
457
441
|
},
|
|
458
442
|
downloadFile(rowData, rowField, rowIndex) {
|
|
@@ -489,9 +473,11 @@ export default {
|
|
|
489
473
|
// Add the item to our model and emit change
|
|
490
474
|
// @todo Also check that value is an array type, if not, reset it to an array
|
|
491
475
|
let data = this.tableData.data ? JSON.parse(JSON.stringify(this.tableData.data)) : [];
|
|
492
|
-
let recordData =
|
|
476
|
+
let recordData = this.deleteIndex;
|
|
493
477
|
// Remove item from data array
|
|
494
|
-
|
|
478
|
+
_.remove(data, {
|
|
479
|
+
'row_id': this.deleteIndex.row_id,
|
|
480
|
+
});
|
|
495
481
|
// Emit the newly updated data model
|
|
496
482
|
this.$emit('input', data);
|
|
497
483
|
this.$root.$emit('removed-record', this, recordData);
|
package/src/components/task.vue
CHANGED
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
<template v-if="screen">
|
|
9
9
|
<div class="card card-body border-top-0 h-100" :class="screenTypeClass">
|
|
10
10
|
<div v-if="renderComponent === 'task-screen'">
|
|
11
|
+
<div v-if="$store.getters['globalErrorsModule/isValidScreen'] === false" class="alert alert-danger mt-3">
|
|
12
|
+
<i class="fas fa-exclamation-circle"/>
|
|
13
|
+
{{ $store.getters['globalErrorsModule/getErrorMessage'] }}
|
|
14
|
+
<button type="button" class="close" aria-label="Close" @click="$store.dispatch('globalErrorsModule/close')">
|
|
15
|
+
<span aria-hidden="true">×</span>
|
|
16
|
+
</button>
|
|
17
|
+
</div>
|
|
11
18
|
<vue-form-renderer
|
|
12
19
|
ref="renderer"
|
|
13
20
|
v-model="requestData"
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
class="h-100"
|
|
103
103
|
ghost-class="form-control-ghost"
|
|
104
104
|
:value="config[currentPage].items"
|
|
105
|
+
:key="editorContentKey"
|
|
105
106
|
@input="updateConfig"
|
|
106
107
|
v-bind="{
|
|
107
108
|
group: {name: 'controls'},
|
|
@@ -311,6 +312,7 @@ import * as renderer from './renderer';
|
|
|
311
312
|
import * as inspector from './inspector';
|
|
312
313
|
import '@processmaker/vue-form-elements/dist/vue-form-elements.css';
|
|
313
314
|
import undoRedoModule from '../undoRedoModule';
|
|
315
|
+
import globalErrorsModule from '@/store/modules/global-errors';
|
|
314
316
|
import accordions from './accordions';
|
|
315
317
|
import { keyNameProperty } from '../form-control-common-properties';
|
|
316
318
|
import VariableNameGenerator from '@/components/VariableNameGenerator';
|
|
@@ -437,6 +439,7 @@ export default {
|
|
|
437
439
|
variablesTree: [],
|
|
438
440
|
language: 'en',
|
|
439
441
|
collator: null,
|
|
442
|
+
editorContentKey: 0,
|
|
440
443
|
};
|
|
441
444
|
},
|
|
442
445
|
computed: {
|
|
@@ -471,6 +474,7 @@ export default {
|
|
|
471
474
|
watch: {
|
|
472
475
|
config: {
|
|
473
476
|
handler() {
|
|
477
|
+
this.checkForCaptchaInLoops();
|
|
474
478
|
this.$emit('change', this.config);
|
|
475
479
|
this.loadVariablesTree();
|
|
476
480
|
},
|
|
@@ -511,6 +515,39 @@ export default {
|
|
|
511
515
|
},
|
|
512
516
|
},
|
|
513
517
|
methods: {
|
|
518
|
+
refreshContent() {
|
|
519
|
+
this.editorContentKey++;
|
|
520
|
+
},
|
|
521
|
+
checkForCaptchaInLoops() {
|
|
522
|
+
this.config.forEach(page => {
|
|
523
|
+
this.checkForCaptcha(page.items);
|
|
524
|
+
});
|
|
525
|
+
},
|
|
526
|
+
checkForCaptcha(items, insideLoop = false, nestedScreen = null) {
|
|
527
|
+
items.forEach(item => {
|
|
528
|
+
if (!item.items && item.component == 'Captcha' && insideLoop) {
|
|
529
|
+
if (nestedScreen && nestedScreen.config.screen) {
|
|
530
|
+
this.$root.$emit('remove-nested', nestedScreen.config.screen);
|
|
531
|
+
nestedScreen.config.screen = null;
|
|
532
|
+
globalObject.ProcessMaker.alert(this.$t('You are trying to place a nested screen within CAPTCHA elements inside a loop. CAPTCHA controls cannot be placed within a Loop control.'), 'danger');
|
|
533
|
+
} else {
|
|
534
|
+
items.splice(items.indexOf(item), 1);
|
|
535
|
+
globalObject.ProcessMaker.alert(this.$t('CAPTCHA controls cannot be placed within a Loop control.'), 'danger');
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (item.items) {
|
|
539
|
+
this.checkForCaptcha(item.items, true);
|
|
540
|
+
}
|
|
541
|
+
if (item.component == 'FormNestedScreen' && insideLoop && item.config.screen && window.nestedScreens) {
|
|
542
|
+
let nestedScreenItems = window.nestedScreens['id_' + item.config.screen];
|
|
543
|
+
if (nestedScreenItems) {
|
|
544
|
+
nestedScreenItems.forEach(nestedScreenPage => {
|
|
545
|
+
this.checkForCaptcha(nestedScreenPage.items, true, item);
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
},
|
|
514
551
|
loadVariablesTree() {
|
|
515
552
|
const definition = {
|
|
516
553
|
config : this.$parent.config,
|
|
@@ -810,6 +847,13 @@ export default {
|
|
|
810
847
|
}
|
|
811
848
|
this.collator = Intl.Collator(this.language);
|
|
812
849
|
},
|
|
850
|
+
registerStoreModule(moduleName, storeModule) {
|
|
851
|
+
const store = this.$store;
|
|
852
|
+
|
|
853
|
+
if (!(store && store.state && store.state[moduleName])) {
|
|
854
|
+
store.registerModule(moduleName, storeModule);
|
|
855
|
+
}
|
|
856
|
+
},
|
|
813
857
|
},
|
|
814
858
|
created() {
|
|
815
859
|
this.loadVariablesTree = _.debounce(this.loadVariablesTree, 2000);
|
|
@@ -823,12 +867,16 @@ export default {
|
|
|
823
867
|
},
|
|
824
868
|
this.$t('Must be unique')
|
|
825
869
|
);
|
|
826
|
-
this
|
|
870
|
+
this.registerStoreModule('globalErrorsModule', globalErrorsModule);
|
|
871
|
+
this.registerStoreModule('undoRedoModule', undoRedoModule);
|
|
827
872
|
this.$store.dispatch('undoRedoModule/pushState', {'config': JSON.stringify(this.config), 'currentPage': this.currentPage});
|
|
828
873
|
this.initiateLanguageSupport();
|
|
829
874
|
},
|
|
830
875
|
mounted() {
|
|
831
876
|
this.loadVariablesTree();
|
|
877
|
+
this.$root.$on('nested-screen-updated', () => {
|
|
878
|
+
this.checkForCaptchaInLoops();
|
|
879
|
+
});
|
|
832
880
|
},
|
|
833
881
|
};
|
|
834
882
|
</script>
|
|
@@ -13,6 +13,7 @@ import Inputmask from 'inputmask';
|
|
|
13
13
|
import { getItemsFromConfig } from '../itemProcessingUtils';
|
|
14
14
|
import { ValidatorFactory } from '../factories/ValidatorFactory';
|
|
15
15
|
import CurrentPageProperty from '../mixins/CurrentPageProperty';
|
|
16
|
+
import globalErrorsModule from '@/store/modules/global-errors';
|
|
16
17
|
|
|
17
18
|
const csstree = require('css-tree');
|
|
18
19
|
const Scrollparent = require('scrollparent');
|
|
@@ -107,6 +108,7 @@ export default {
|
|
|
107
108
|
},
|
|
108
109
|
},
|
|
109
110
|
created() {
|
|
111
|
+
this.registerStoreModule('globalErrorsModule', globalErrorsModule);
|
|
110
112
|
this.parseCss = _.debounce(this.parseCss, 500, {leading: true});
|
|
111
113
|
},
|
|
112
114
|
mounted() {
|
|
@@ -118,6 +120,13 @@ export default {
|
|
|
118
120
|
this.scrollable = Scrollparent(this.$el);
|
|
119
121
|
},
|
|
120
122
|
methods: {
|
|
123
|
+
registerStoreModule(moduleName, storeModule) {
|
|
124
|
+
const store = this.$store;
|
|
125
|
+
|
|
126
|
+
if (!(store && store.state && store.state[moduleName])) {
|
|
127
|
+
store.registerModule(moduleName, storeModule);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
121
130
|
countElements(config) {
|
|
122
131
|
const definition = { config };
|
|
123
132
|
return this.$refs.renderer.countElements(definition);
|
|
@@ -31,6 +31,7 @@ export default {
|
|
|
31
31
|
pmql: null,
|
|
32
32
|
options: [],
|
|
33
33
|
selectedOption: null,
|
|
34
|
+
fields: null,
|
|
34
35
|
};
|
|
35
36
|
},
|
|
36
37
|
watch: {
|
|
@@ -50,8 +51,9 @@ export default {
|
|
|
50
51
|
},
|
|
51
52
|
loadOptions(filter) {
|
|
52
53
|
const pmql = this.pmql;
|
|
54
|
+
const fields = this.fields || undefined;
|
|
53
55
|
window.ProcessMaker.apiClient
|
|
54
|
-
.get(this.api, { params: { filter, pmql } })
|
|
56
|
+
.get(this.api, { params: { filter, pmql, fields } })
|
|
55
57
|
.then(response => {
|
|
56
58
|
this.options = response.data.data || [];
|
|
57
59
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const namespaced = true;
|
|
2
|
+
const globalErrorsModule = {
|
|
3
|
+
namespaced,
|
|
4
|
+
state: () => {
|
|
5
|
+
return {
|
|
6
|
+
valid: true,
|
|
7
|
+
message: '',
|
|
8
|
+
};
|
|
9
|
+
},
|
|
10
|
+
getters: {
|
|
11
|
+
isValidScreen(state) {
|
|
12
|
+
return state.valid;
|
|
13
|
+
},
|
|
14
|
+
getErrorMessage(state) {
|
|
15
|
+
return state.message;
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
mutations: {
|
|
19
|
+
basic(state, payload) {
|
|
20
|
+
state[payload.key] = payload.value;
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
actions: {
|
|
24
|
+
close({ commit }) {
|
|
25
|
+
commit('basic', { key: 'valid', value: true });
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default globalErrorsModule;
|
package/dist/demo.html
DELETED