@processmaker/screen-builder 2.5.28 → 2.5.30-PATCH4

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.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@processmaker/screen-builder",
3
- "version": "2.5.28",
3
+ "version": "2.5.30-PATCH4",
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.18.4-P",
47
+ "@processmaker/vue-form-elements": "0.18.4-R",
48
48
  "@vue/cli-plugin-babel": "^3.6.0",
49
49
  "@vue/cli-plugin-e2e-cypress": "^4.0.3",
50
50
  "@vue/cli-plugin-eslint": "^3.6.0",
@@ -84,7 +84,7 @@
84
84
  },
85
85
  "peerDependencies": {
86
86
  "@panter/vue-i18next": "^0.15.0",
87
- "@processmaker/vue-form-elements": "0.18.4-P",
87
+ "@processmaker/vue-form-elements": "0.18.4-R",
88
88
  "i18next": "^15.0.8",
89
89
  "vue": "^2.6.12",
90
90
  "vuex": "^3.1.1"
package/src/.DS_Store CHANGED
Binary file
@@ -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,7 @@ 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
- const firstRow = (get(this.data, this.element.config.name) || [{}])[0];
116
- await ValidationsFactory(this.element.items, { screen: this.screen, data: {_parent: this.data, ...firstRow } }).addValidations(loopField['$each']);
116
+ await ValidationsFactory(this.element.items, { screen: this.screen, data: {_parent: this.data, noData: true}, parentVisibilityRule: this.element.config.conditionalHide}).addValidations(loopField['$each']);
117
117
  }
118
118
  }
119
119
 
@@ -126,7 +126,7 @@ class FormMultiColumnValidations extends Validations {
126
126
  if (!this.isVisible()) {
127
127
  return;
128
128
  }
129
- await ValidationsFactory(this.element.items, { screen: this.screen, data: this.data }).addValidations(validations);
129
+ await ValidationsFactory(this.element.items, { screen: this.screen, data: this.data, parentVisibilityRule: this.element.config.conditionalHide }).addValidations(validations);
130
130
  }
131
131
  }
132
132
 
@@ -167,20 +167,8 @@ class FormElementValidations extends Validations {
167
167
  }
168
168
  const fieldName = this.element.config.name;
169
169
  const validationConfig = this.element.config.validation;
170
-
171
- // Disable validations if field is hidden
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
- }
183
-
170
+ const conditionalHide = this.element.config.conditionalHide;
171
+ const parentVisibilityRule = this.parentVisibilityRule;
184
172
  set(validations, fieldName, get(validations, fieldName, {}));
185
173
  const fieldValidation = get(validations, fieldName);
186
174
  if (validationConfig instanceof Array) {
@@ -203,7 +191,40 @@ class FormElementValidations extends Validations {
203
191
  params.push(fieldName);
204
192
  validationFn = validationFn(...params);
205
193
  }
206
- fieldValidation[rule] = validationFn;
194
+ fieldValidation[rule] = function(...props) {
195
+ const data = props[1];
196
+ let dataWithParent = this.addReferenceToParents(data);
197
+ const nestedDataWithParent = this.addReferenceToParents(this.findParent(data));
198
+ if (nestedDataWithParent) {
199
+ dataWithParent = Object.assign(nestedDataWithParent, dataWithParent);
200
+ }
201
+ // Check Parent Visibility
202
+ if (parentVisibilityRule) {
203
+ let isParentVisible = true;
204
+ try {
205
+ isParentVisible = !!Parser.evaluate(parentVisibilityRule, dataWithParent);
206
+ } catch (error) {
207
+ isParentVisible = false;
208
+ }
209
+
210
+ if (!isParentVisible ) {
211
+ return true;
212
+ }
213
+ }
214
+ // Check Field Visibility
215
+ let visible = true;
216
+ if (conditionalHide) {
217
+ try {
218
+ visible = !!Parser.evaluate(conditionalHide, dataWithParent);
219
+ } catch (error) {
220
+ visible = false;
221
+ }
222
+ }
223
+ if (!visible) {
224
+ return true;
225
+ }
226
+ return validationFn.apply(this,props);
227
+ };
207
228
  });
208
229
  } else if (typeof validationConfig === 'string' && validationConfig) {
209
230
  let validationFn = validators[validationConfig];
@@ -212,7 +233,40 @@ class FormElementValidations extends Validations {
212
233
  console.error(`Undefined validation rule "${validationConfig}"`);
213
234
  return;
214
235
  }
215
- fieldValidation[validationConfig] = validationFn;
236
+ fieldValidation[validationConfig] = function(...props) {
237
+ const data = props[1];
238
+ let dataWithParent = this.addReferenceToParents(data);
239
+ const nestedDataWithParent = this.addReferenceToParents(this.findParent(data));
240
+ if (nestedDataWithParent) {
241
+ dataWithParent = Object.assign(nestedDataWithParent, dataWithParent);
242
+ }
243
+ // Check Parent Visibility
244
+ if (parentVisibilityRule) {
245
+ let isParentVisible = true;
246
+ try {
247
+ isParentVisible = !!Parser.evaluate(parentVisibilityRule, dataWithParent);
248
+ } catch (error) {
249
+ isParentVisible = false;
250
+ }
251
+
252
+ if (!isParentVisible) {
253
+ return true;
254
+ }
255
+ }
256
+ // Check Field Visibility
257
+ let visible = true;
258
+ if (conditionalHide) {
259
+ try {
260
+ visible = !!Parser.evaluate(conditionalHide, dataWithParent);
261
+ } catch (error) {
262
+ visible = false;
263
+ }
264
+ }
265
+ if (!visible) {
266
+ return true;
267
+ }
268
+ return validationFn.apply(this,props);
269
+ };
216
270
  }
217
271
  if (this.element.items) {
218
272
  ValidationsFactory(this.element.items, { screen: this.screen, data: this.data }).addValidations(validations);
@@ -222,7 +276,6 @@ class FormElementValidations extends Validations {
222
276
  return name.replace(/_\w/g, m => m.substr(1, 1).toUpperCase());
223
277
  }
224
278
  }
225
-
226
279
  function ValidationsFactory(element, options) {
227
280
  if (element instanceof Array) {
228
281
  return new ArrayOfFieldsValidations(element, options);
@@ -110,7 +110,7 @@ export default {
110
110
  listenRecordList(recordList, index, id) {
111
111
  const parent = this.parentRecordList(this);
112
112
  if (_.has(window, 'PM4ConfigOverrides.requestFiles') && parent === recordList) {
113
- const prefix = (this.parentRecordList(this) === null) ? '' : recordList.name + '.';
113
+ const prefix = (this.parentRecordList(this) === null) ? '' : this.prefix;
114
114
  const fileDataName = prefix + this.name + (id ? '.' + id : '');
115
115
  this.fileInfo = window.PM4ConfigOverrides.requestFiles[fileDataName];
116
116
  this.loading = false;
@@ -94,8 +94,6 @@ export default {
94
94
  (loop, removed) => this.listenRemovedLoop(loop, removed));
95
95
 
96
96
  this.removeDefaultClasses();
97
-
98
- this.checkIfInRecordList();
99
97
 
100
98
  this.setPrefix();
101
99
  if (this.$refs['uploader']) {
@@ -288,15 +286,6 @@ export default {
288
286
  this.prefix = parent.loopContext + '.';
289
287
  }
290
288
  },
291
- setFileUploadNameForChildren(children, prefix) {
292
- children.forEach(child => {
293
- if (_.get(child, '$options.name') === 'FileUpload') {
294
- child.prefix = prefix;
295
- } else if (_.get(child, '$children', []).length > 0) {
296
- this.setFileUploadNameForChildren(child.$children, prefix);
297
- }
298
- });
299
- },
300
289
  addFile(file) {
301
290
  if (this.disabled) {
302
291
  file.ignored = true;
@@ -420,14 +409,6 @@ export default {
420
409
  : null;
421
410
  }
422
411
  },
423
- checkIfInRecordList() {
424
- const parent = this.parentRecordList(this);
425
- if (parent !== null) {
426
- const recordList = parent;
427
- const prefix = recordList.name + '.';
428
- this.setFileUploadNameForChildren(recordList.$children, prefix);
429
- }
430
- },
431
412
  },
432
413
  };
433
414
  </script>
@@ -5,7 +5,6 @@
5
5
  </template>
6
6
 
7
7
  <script>
8
- import Mustache from 'mustache';
9
8
  import { getValidPath } from '@/mixins';
10
9
 
11
10
  export default {
@@ -19,45 +18,6 @@ export default {
19
18
  ['btn-' + variant]: true,
20
19
  };
21
20
  },
22
- options() {
23
- if (!this.tooltip || this.event === 'submit') {
24
- return {};
25
- }
26
-
27
- let content = '';
28
- try {
29
- content = Mustache.render(this.tooltip.content || '', this.transientData);
30
- } catch (error) { error; }
31
-
32
- return {
33
- title: content,
34
- html: true,
35
- placement: this.tooltip.position || '',
36
- trigger: 'hover',
37
- variant: this.tooltip.variant || '',
38
- boundary: 'window',
39
- };
40
- },
41
- valid() {
42
- if (this.$attrs.validate) {
43
- return !this.$attrs.validate.$invalid;
44
- }
45
- return true;
46
- },
47
- message() {
48
- // eslint-disable-next-line vue/no-side-effects-in-computed-properties
49
- this.errors = 0;
50
- if (!this.valid) {
51
- this.countErrors(this.$attrs.validate.vdata);
52
- this.countErrors(this.$attrs.validate.schema);
53
- let message = 'There are {{items}} validation errors in your form.';
54
- if (this.errors === 1) {
55
- message = 'There is a validation error in your form.';
56
- }
57
- return this.$t(message, {items: this.errors});
58
- }
59
- return '';
60
- },
61
21
  },
62
22
  data() {
63
23
  return {
@@ -73,6 +73,7 @@
73
73
  :title="$t('Add')"
74
74
  header-close-content="&times;"
75
75
  data-cy="modal-add"
76
+ @shown="emitShownEvent"
76
77
  >
77
78
  <vue-form-renderer
78
79
  :page="0"
@@ -85,6 +86,7 @@
85
86
  debug-context="Record List Add"
86
87
  :key="Array.isArray(value) ? value.length : 0"
87
88
  :_parent="validationData"
89
+ @update="updateRowDataNamePrefix"
88
90
  />
89
91
  </b-modal>
90
92
  <b-modal
@@ -98,6 +100,7 @@
98
100
  :title="$t('Edit Record')"
99
101
  header-close-content="&times;"
100
102
  data-cy="modal-edit"
103
+ @shown="emitShownEvent"
101
104
  >
102
105
  <vue-form-renderer
103
106
  :page="0"
@@ -110,6 +113,7 @@
110
113
  debug-context="Record List Edit"
111
114
  :_parent="validationData"
112
115
  :key="editFormVersion"
116
+ @update="updateRowDataNamePrefix"
113
117
  />
114
118
  </b-modal>
115
119
  <b-modal
@@ -162,6 +166,7 @@ export default {
162
166
  props: ['name', 'label', 'fields', 'value', 'editable', '_config', 'form', 'validationData', 'formConfig', 'formComputed', 'formWatchers'],
163
167
  data() {
164
168
  return {
169
+ currentRowIndex: null,
165
170
  editFormVersion: 0,
166
171
  single: '',
167
172
  plural: '',
@@ -257,6 +262,12 @@ export default {
257
262
  },
258
263
  },
259
264
  methods: {
265
+ updateRowDataNamePrefix() {
266
+ this.setUploadDataNamePrefix(this.currentRowIndex);
267
+ },
268
+ emitShownEvent() {
269
+ window.ProcessMaker.EventBus.$emit('modal-shown');
270
+ },
260
271
  isImage(field, item) {
261
272
  const content = _.get(item, field.key);
262
273
  return typeof content === 'string' && content.substr(0,11) === 'data:image/';
@@ -265,6 +276,7 @@ export default {
265
276
  return field.key === '__filedownload';
266
277
  },
267
278
  setUploadDataNamePrefix(index = null) {
279
+ this.currentRowIndex = index;
268
280
  let rowId = null;
269
281
  if (index !== null && this.editItem) {
270
282
  rowId = this.editItem.row_id;
@@ -336,7 +348,7 @@ export default {
336
348
  // Reset edit to be a copy of our data model item
337
349
  this.editItem = JSON.parse(JSON.stringify(this.value[pageIndex]));
338
350
  this.editIndex = pageIndex;
339
- // rebuild the edit screen to avoid
351
+ // rebuild the edit screen to avoid
340
352
  this.editFormVersion++;
341
353
  this.$nextTick(() => {
342
354
  this.setUploadDataNamePrefix(pageIndex);
@@ -446,6 +458,9 @@ export default {
446
458
  this.$root.$emit('removed-record', this, recordData);
447
459
  },
448
460
  },
461
+ mounted() {
462
+ this.updateRowDataNamePrefix = _.debounce(this.updateRowDataNamePrefix, 100);
463
+ },
449
464
  };
450
465
  </script>
451
466
 
@@ -95,7 +95,8 @@ export const keyNameProperty = {
95
95
  config: {
96
96
  label: 'Variable Name',
97
97
  name: 'Variable Name',
98
- validation: 'regex:/^(?:[A-Za-z])(?:[0-9A-Z_a-z])*(?:\\.[0-9A-Z_a-z]+)*$/|required|not_in:' + javascriptReservedKeywords,
98
+ // Update tests/e2e/specs/Builder.spec.js when changing this
99
+ validation: 'regex:/^([a-zA-Z]([a-zA-Z0-9_]?)+\\.?)+(?<!\\.)$/|required|not_in:' + javascriptReservedKeywords,
99
100
  helper: 'A variable name is a symbolic name to reference information.',
100
101
  },
101
102
  };
@@ -21,6 +21,7 @@ import {
21
21
  not,
22
22
  or,
23
23
  and,
24
+ type,
24
25
  } from 'vuelidate/lib/validators';
25
26
 
26
27
  export const ValidationMsg = {
@@ -55,6 +56,7 @@ export const ValidationMsg = {
55
56
  invalid_default_value: 'Invalid default value',
56
57
  customDate: 'Must be a valid Date',
57
58
  regex: 'Invalid value',
59
+ type: 'Invalid type.',
58
60
  };
59
61
 
60
62
  export const custom_date = (date) => {
@@ -225,4 +227,5 @@ export const validators = {
225
227
  notIn,
226
228
  regex,
227
229
  afterOrEqual: after_or_equal,
230
+ type,
228
231
  };