@processmaker/screen-builder 2.16.1 → 2.16.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@processmaker/screen-builder",
3
- "version": "2.16.1",
3
+ "version": "2.16.5",
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.25.0",
1742
- "resolved": "https://registry.npmjs.org/@processmaker/vue-form-elements/-/vue-form-elements-0.25.0.tgz",
1743
- "integrity": "sha512-yf0EBslncJTDrpjbquvIBBYMjyrg8wRcjRF5W506jV9GR4UHrRBQ9QBITGDj951zTbLIX9jebAEjPCXPb676qg==",
1741
+ "version": "0.25.3",
1742
+ "resolved": "https://registry.npmjs.org/@processmaker/vue-form-elements/-/vue-form-elements-0.25.3.tgz",
1743
+ "integrity": "sha512-KMXcd97nrrAOx8SXoMH4ZElUKVAJumYOdbbPVvkzrcZjKfevHHQjNblOvBHz8VfJDeAWWMIP2whmyYM6aoMw0w==",
1744
1744
  "dev": true,
1745
1745
  "requires": {
1746
1746
  "@tinymce/tinymce-vue": "2.0.0",
@@ -1750,7 +1750,7 @@
1750
1750
  "moment": "^2.29.1",
1751
1751
  "moment-timezone": "^0.5.26",
1752
1752
  "popper.js": "^1.14.4",
1753
- "tinymce": "5.2.2",
1753
+ "tinymce": "5.7.1",
1754
1754
  "v-calendar": "^0.9.7",
1755
1755
  "validatorjs": "^3.14.2",
1756
1756
  "vue": "^2.6.12",
@@ -17414,9 +17414,9 @@
17414
17414
  "dev": true
17415
17415
  },
17416
17416
  "tinymce": {
17417
- "version": "5.2.2",
17418
- "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.2.2.tgz",
17419
- "integrity": "sha512-G1KZOxHIrokeP/rhJuvwctmeAuHDAeH8AI1ubnVcdMZtmC6mUh3SfESqFJrFWoiF143OUMC61GkVhi920pIP0A==",
17417
+ "version": "5.7.1",
17418
+ "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.7.1.tgz",
17419
+ "integrity": "sha512-1gY8RClc734srSlkYwY0MQzmkS1j73PuPC+nYtNtrrQVPY9VNcZ4bOiRwzTbdjPPD8GOtv6BAk8Ww/H2RiqKpA==",
17420
17420
  "dev": true
17421
17421
  },
17422
17422
  "tmp": {
@@ -17959,9 +17959,9 @@
17959
17959
  }
17960
17960
  },
17961
17961
  "url-parse": {
17962
- "version": "1.5.1",
17963
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
17964
- "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
17962
+ "version": "1.5.3",
17963
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
17964
+ "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
17965
17965
  "dev": true,
17966
17966
  "requires": {
17967
17967
  "querystringify": "^2.1.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@processmaker/screen-builder",
3
- "version": "2.16.1",
3
+ "version": "2.16.5",
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.25.0",
47
+ "@processmaker/vue-form-elements": "0.25.3",
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",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "peerDependencies": {
85
85
  "@panter/vue-i18next": "^0.15.0",
86
- "@processmaker/vue-form-elements": "0.25.0",
86
+ "@processmaker/vue-form-elements": "0.25.3",
87
87
  "i18next": "^15.0.8",
88
88
  "vue": "^2.6.12",
89
89
  "vuex": "^3.1.1"
package/src/.DS_Store CHANGED
Binary file
package/src/App.vue CHANGED
@@ -204,6 +204,7 @@ import VueJsonPretty from 'vue-json-pretty';
204
204
  import MonacoEditor from 'vue-monaco';
205
205
  import canOpenJsonFile from './mixins/canOpenJsonFile';
206
206
  import { cloneDeep, debounce } from 'lodash';
207
+ import 'vue-json-pretty/lib/styles.css';
207
208
 
208
209
  // Bring in our initial set of controls
209
210
  import controlConfig from './form-builder-controls';
@@ -51,9 +51,9 @@ export default {
51
51
  baseURL() {
52
52
  return localStorage.getItem('baseURL');
53
53
  },
54
-
54
+
55
55
  // Methods below are used in the components
56
-
56
+
57
57
  getTasks(params) {
58
58
  const endpoint = _.get(window, 'PM4ConfigOverrides.getTasksEndpoint', '/tasks');
59
59
  return this.get(endpoint + params).then(response => {
@@ -83,7 +83,8 @@ export default {
83
83
  const cache = this.screensCache.find(screen => screen.id == id);
84
84
  if (cache) {
85
85
  resolve({data: cache});
86
- } else {
86
+ }
87
+ if (!cache && id != undefined) {
87
88
  const request = this.get(endpoint + `/${id}${query}`);
88
89
  request.then(response => {
89
90
  if (response.data.nested) {
@@ -94,7 +95,7 @@ export default {
94
95
  }
95
96
  });
96
97
  },
97
-
98
+
98
99
  postScript(id, params, options = {}) {
99
100
  let endpoint = _.get(
100
101
  window,
@@ -1,6 +1,7 @@
1
1
  import { validators } from './mixins/ValidationRules';
2
2
  import DataProvider from './DataProvider';
3
3
  import { get, set } from 'lodash';
4
+ import { Parser } from 'expr-eval';
4
5
 
5
6
  let globalObject = typeof window === 'undefined'
6
7
  ? global
@@ -8,6 +9,7 @@ let globalObject = typeof window === 'undefined'
8
9
  class Validations {
9
10
  screen = null;
10
11
  firstPage = 0;
12
+ data = {};
11
13
  constructor(element, options) {
12
14
  this.element = element;
13
15
  Object.assign(this, options);
@@ -33,7 +35,7 @@ class Validations {
33
35
  class ArrayOfFieldsValidations extends Validations {
34
36
  async addValidations(validations) {
35
37
  for (const item of this.element) {
36
- await ValidationsFactory(item, { screen: this.screen }).addValidations(validations);
38
+ await ValidationsFactory(item, { screen: this.screen, data: this.data }).addValidations(validations);
37
39
  }
38
40
  }
39
41
  }
@@ -46,7 +48,7 @@ class ScreenValidations extends Validations {
46
48
  // add validations for page 1
47
49
  if (this.element.config[this.firstPage]) {
48
50
  this.element.pagesValidated = [this.firstPage];
49
- const screenValidations = ValidationsFactory(this.element.config[this.firstPage].items, { screen: this.element });
51
+ const screenValidations = ValidationsFactory(this.element.config[this.firstPage].items, { screen: this.element, data: this.data });
50
52
  await screenValidations.addValidations(validations);
51
53
  delete this.element.pagesValidated;
52
54
  }
@@ -60,7 +62,7 @@ class FormNestedScreenValidations extends Validations {
60
62
  async addValidations(validations) {
61
63
  const definition = await this.loadScreen(this.element.config.screen);
62
64
  if (definition && definition[0] && definition[0].items) {
63
- await ValidationsFactory(definition[0].items, { screen: this.screen }).addValidations(validations);
65
+ await ValidationsFactory(definition[0].items, { screen: this.screen, data: this.data }).addValidations(validations);
64
66
  }
65
67
  }
66
68
 
@@ -86,7 +88,8 @@ class FormLoopValidations extends Validations {
86
88
  set(validations, this.element.config.name, {});
87
89
  const loopField = get(validations, this.element.config.name);
88
90
  loopField['$each'] = [];
89
- await ValidationsFactory(this.element.items, { screen: this.screen }).addValidations(loopField['$each']);
91
+ const firstRow = this.data[0] || {};
92
+ await ValidationsFactory(this.element.items, { screen: this.screen, data: {_parent: this.data, ...firstRow } }).addValidations(loopField['$each']);
90
93
  }
91
94
  }
92
95
 
@@ -95,7 +98,7 @@ class FormLoopValidations extends Validations {
95
98
  */
96
99
  class FormMultiColumnValidations extends Validations {
97
100
  async addValidations(validations) {
98
- await ValidationsFactory(this.element.items, { screen: this.screen }).addValidations(validations);
101
+ await ValidationsFactory(this.element.items, { screen: this.screen, data: this.data }).addValidations(validations);
99
102
  }
100
103
  }
101
104
 
@@ -107,7 +110,7 @@ class PageNavigateValidations extends Validations {
107
110
  if (!this.screen.pagesValidated.includes(parseInt(this.element.config.eventData))) {
108
111
  this.screen.pagesValidated.push(parseInt(this.element.config.eventData));
109
112
  if (this.screen.config[this.element.config.eventData] && this.screen.config[this.element.config.eventData].items) {
110
- await ValidationsFactory(this.screen.config[this.element.config.eventData].items, { screen: this.screen }).addValidations(validations);
113
+ await ValidationsFactory(this.screen.config[this.element.config.eventData].items, { screen: this.screen, data: this.data }).addValidations(validations);
111
114
  }
112
115
  }
113
116
  }
@@ -133,6 +136,19 @@ class FormElementValidations extends Validations {
133
136
  const fieldName = this.element.config.name;
134
137
  const validationConfig = this.element.config.validation;
135
138
 
139
+ // Disable validations if field is hidden
140
+ if (this.element.config.conditionalHide) {
141
+ let visible = true;
142
+ try {
143
+ visible = !!Parser.evaluate(this.element.config.conditionalHide, this.data);
144
+ } catch (error) {
145
+ visible = false;
146
+ }
147
+ if (!visible) {
148
+ return;
149
+ }
150
+ }
151
+
136
152
  set(validations, fieldName, get(validations, fieldName, {}));
137
153
  const fieldValidation = get(validations, fieldName);
138
154
  if (validationConfig instanceof Array) {
@@ -166,7 +182,7 @@ class FormElementValidations extends Validations {
166
182
  fieldValidation[validationConfig] = validationFn;
167
183
  }
168
184
  if (this.element.items) {
169
- ValidationsFactory(this.element.items, { screen: this.screen }).addValidations(validations);
185
+ ValidationsFactory(this.element.items, { screen: this.screen, data: this.data }).addValidations(validations);
170
186
  }
171
187
  }
172
188
  camelCase(name) {
Binary file
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div>
3
- <div class="form-group border-bottom pb-3">
3
+ <div v-if="screenType == 'form'" class="form-group border-bottom pb-3">
4
4
  <label for="type">{{ $t('Data Source') }}</label>
5
5
  <b-form-select id="type" v-model="settings.type" :options="options" data-cy="inspector-source"/>
6
6
  </div>
@@ -17,7 +17,7 @@
17
17
  </div>
18
18
 
19
19
 
20
- <div v-if="settings.type === 'new'" class="form-group border-bottom">
20
+ <div v-if="screenType == 'form' && settings.type === 'new'" class="form-group border-bottom">
21
21
  <FormInput
22
22
  v-model="settings.times"
23
23
  :label="$t('Default Loop Count')"
@@ -28,7 +28,7 @@
28
28
  />
29
29
  </div>
30
30
 
31
- <form-checkbox name="add"
31
+ <form-checkbox v-if="screenType == 'form'" name="add"
32
32
  :label="$t('Allow additional loops')"
33
33
  v-model="settings.add"
34
34
  :helper="$t('Check this box to allow task assignee to add additional loops')"
@@ -41,7 +41,7 @@
41
41
  import { FormInput, FormCheckbox } from '@processmaker/vue-form-elements';
42
42
 
43
43
  export default {
44
- props: ['value'],
44
+ props: ['value', 'screenType'],
45
45
  inheritAttrs: false,
46
46
  components: { FormInput, FormCheckbox },
47
47
  data() {
@@ -444,10 +444,7 @@ export default {
444
444
  },
445
445
  methods: {
446
446
  monacoMounted(editor) {
447
- editor.updateOptions({ readOnly: false });
448
- editor.getAction('editor.action.formatDocument').run().then(() => {
449
- editor.updateOptions({ readOnly: true });
450
- });
447
+ editor.getAction('editor.action.formatDocument').run();
451
448
  },
452
449
  getDataSourceList() {
453
450
  this.$dataProvider
@@ -20,7 +20,16 @@
20
20
 
21
21
  <uploader-drop class="form-control-file">
22
22
  <p>{{ $t('Drop a file here to upload or') }}</p>
23
- <uploader-btn tabindex="0" v-on:keyup.native="browse" :aria-label="$attrs['aria-label']" class="btn btn-secondary text-white">{{ $t('select file') }}</uploader-btn>
23
+ <uploader-btn
24
+ :attrs="nativeButtonAttrs"
25
+ :class="{disabled: disabled}"
26
+ tabindex="0"
27
+ v-on:keyup.native="browse"
28
+ :aria-label="$attrs['aria-label']"
29
+ class="btn btn-secondary text-white"
30
+ >
31
+ {{ $t('select file') }}
32
+ </uploader-btn>
24
33
  <span v-if="validation === 'required' && !value" class="required">{{ $t('Required') }}</span>
25
34
  </uploader-drop>
26
35
  <uploader-list>
@@ -92,6 +101,8 @@ export default {
92
101
  if (this.$refs['uploader']) {
93
102
  this.$refs['uploader'].$forceUpdate();
94
103
  }
104
+
105
+ this.disabled = _.get(window, 'ProcessMaker.isSelfService', false);
95
106
  },
96
107
  errorCaptured(err) {
97
108
  if (ignoreErrors.includes(err.message)) {
@@ -99,6 +110,13 @@ export default {
99
110
  }
100
111
  },
101
112
  computed: {
113
+ nativeButtonAttrs() {
114
+ const attrs = { 'data-cy':'file-upload-button' };
115
+ if (this.disabled) {
116
+ attrs.disabled = true;
117
+ }
118
+ return attrs;
119
+ },
102
120
  required() {
103
121
  if (this.config && this.config.validation) {
104
122
  return this.config.validation === 'required';
@@ -205,6 +223,7 @@ export default {
205
223
  attrs: {
206
224
  accept: this.accept,
207
225
  },
226
+ disabled: false,
208
227
  };
209
228
  },
210
229
  methods: {
@@ -286,6 +305,11 @@ export default {
286
305
  });
287
306
  },
288
307
  addFile(file) {
308
+ if (this.disabled) {
309
+ file.ignored = true;
310
+ return false;
311
+ }
312
+
289
313
  if (this.filesAccept) {
290
314
  file.ignored = true;
291
315
  if (this.filesAccept.indexOf(file.fileType) !== -1) {
@@ -322,7 +346,7 @@ export default {
322
346
  },
323
347
  fileUploaded(rootFile, file, message) {
324
348
  if (this.fileType == 'request') {
325
- let id = '';
349
+ let id = file.name;
326
350
  if (message) {
327
351
  const msg = JSON.parse(message);
328
352
  if (!_.has(window, 'PM4ConfigOverrides')) {
@@ -435,10 +435,10 @@ export default {
435
435
  return this;
436
436
  },
437
437
  canUndo() {
438
- return this.$store.getters[`page-${this.currentPage}/canUndo`];
438
+ return this.$store.getters['undoRedoModule/canUndo'];
439
439
  },
440
440
  canRedo() {
441
- return this.$store.getters[`page-${this.currentPage}/canRedo`];
441
+ return this.$store.getters['undoRedoModule/canRedo'];
442
442
  },
443
443
  displayDelete() {
444
444
  return this.config.length > 1;
@@ -662,18 +662,19 @@ export default {
662
662
  });
663
663
  },
664
664
  updateState() {
665
- const items = this.config[this.currentPage].items;
666
- this.$store.dispatch(`page-${this.currentPage}/pushState`, JSON.stringify(items));
665
+ this.$store.dispatch('undoRedoModule/pushState', {'config': JSON.stringify(this.config), 'currentPage': this.currentPage});
667
666
  },
668
667
  undo() {
669
668
  this.inspect();
670
- this.$store.dispatch(`page-${this.currentPage}/undo`);
671
- this.config[this.currentPage].items = JSON.parse(this.$store.getters[`page-${this.currentPage}/currentState`]);
669
+ this.$store.dispatch('undoRedoModule/undo');
670
+ this.config = JSON.parse(this.$store.getters['undoRedoModule/currentState'].config);
671
+ this.currentPage = JSON.parse(this.$store.getters['undoRedoModule/currentState'].currentPage);
672
672
  },
673
673
  redo() {
674
674
  this.inspect();
675
- this.$store.dispatch(`page-${this.currentPage}/redo`);
676
- this.config[this.currentPage].items = JSON.parse(this.$store.getters[`page-${this.currentPage}/currentState`]);
675
+ this.$store.dispatch('undoRedoModule/redo');
676
+ this.config = JSON.parse(this.$store.getters['undoRedoModule/currentState'].config);
677
+ this.currentPage = JSON.parse(this.$store.getters['undoRedoModule/currentState'].currentPage);
677
678
  },
678
679
  updateConfig(items) {
679
680
  this.config[this.currentPage].items = items;
@@ -738,12 +739,12 @@ export default {
738
739
  this.config.push({ name: this.addPageName, items: [] });
739
740
  this.currentPage = this.config.length - 1;
740
741
  this.addPageName = '';
741
- this.$store.registerModule(`page-${this.currentPage}`, undoRedoModule);
742
742
  this.updateState();
743
743
  },
744
744
  deletePage() {
745
- this.currentPage = 0;
746
745
  this.config.splice(this.pageDelete, 1);
746
+ this.currentPage = (this.pageDelete - 1 >= 0 ? this.pageDelete - 1 : 0);
747
+ this.$store.dispatch('undoRedoModule/pushState', {'config': JSON.stringify(this.config), 'currentPage': this.currentPage, 'deletedPage': true});
747
748
  },
748
749
  inspect(element = {}) {
749
750
  this.inspection = element;
@@ -813,11 +814,8 @@ export default {
813
814
  },
814
815
  this.$t('Must be unique')
815
816
  );
816
-
817
- this.config.forEach((config, index) => {
818
- this.$store.registerModule(`page-${index}`, undoRedoModule);
819
- this.$store.dispatch(`page-${index}/pushState`, JSON.stringify(config.items));
820
- });
817
+ this.$store.registerModule('undoRedoModule', undoRedoModule);
818
+ this.$store.dispatch('undoRedoModule/pushState', {'config': JSON.stringify(this.config), 'currentPage': this.currentPage});
821
819
  this.initiateLanguageSupport();
822
820
  },
823
821
  mounted() {
@@ -216,6 +216,7 @@ export default [
216
216
  colorProperty,
217
217
  bgcolorProperty,
218
218
  defaultValueProperty,
219
+ readonlyProperty,
219
220
  ],
220
221
  },
221
222
  },
@@ -335,8 +335,11 @@ export default {
335
335
  component.methods.loadValidationRules = function() {
336
336
  // Asynchronous loading of validations
337
337
  const validations = {};
338
- ValidationsFactory(definition, { screen: definition, firstPage }).addValidations(validations).then(() => {
338
+ ValidationsFactory(definition, { screen: definition, firstPage, data: this.vdata }).addValidations(validations).then(() => {
339
339
  this.ValidationRules__ = validations;
340
+ this.$nextTick(() => {
341
+ this.$v.$touch();
342
+ });
340
343
  });
341
344
  };
342
345
  component.mounted.push('this.loadValidationRules()');
@@ -8,6 +8,7 @@ export default {
8
8
  data() {
9
9
  return {
10
10
  ValidationRules__: {},
11
+ hiddenFields__: [],
11
12
  };
12
13
  },
13
14
  props: {
@@ -116,6 +117,7 @@ export default {
116
117
  setValue
117
118
  );
118
119
  object = get(object, attr);
120
+ defaults = get(defaults, attr);
119
121
  });
120
122
  }
121
123
  },
@@ -67,9 +67,9 @@ export const custom_date = (date) => {
67
67
  return checkDate.isValid();
68
68
  };
69
69
 
70
- export const after = (after) => helpers.withParams({after}, function(date, data) {
70
+ export const after = (after) => helpers.withParams({after}, function(date) {
71
71
  // Get check date
72
- const dataWithParent = {today: moment().format('YYYY-MM-DD'), _parent: this._parent, ...data};
72
+ const dataWithParent = {today: moment().format('YYYY-MM-DD'), _parent: this._parent, ...this.vdata};
73
73
  const checkDate = moment(get(dataWithParent, after, after));
74
74
  if (!checkDate.isValid()) {
75
75
  return false;
@@ -81,9 +81,9 @@ export const after = (after) => helpers.withParams({after}, function(date, data)
81
81
  return inputDate > afterDate;
82
82
  });
83
83
 
84
- export const after_or_equal = (after_or_equal) => helpers.withParams({after_or_equal}, function(date, data) {
84
+ export const after_or_equal = (after_or_equal) => helpers.withParams({after_or_equal}, function(date) {
85
85
  // Get check date
86
- const dataWithParent = {today: moment().format('YYYY-MM-DD'), _parent: this._parent, ...data};
86
+ const dataWithParent = {today: moment().format('YYYY-MM-DD'), _parent: this._parent, ...this.vdata};
87
87
  const checkDate = moment(get(dataWithParent, after_or_equal, after_or_equal));
88
88
  if (!checkDate.isValid()) {
89
89
  return false;
@@ -94,9 +94,9 @@ export const after_or_equal = (after_or_equal) => helpers.withParams({after_or_e
94
94
  return inputDate >= equalOrAfterDate;
95
95
  });
96
96
 
97
- export const before = (before) => helpers.withParams({before}, function(date, data) {
97
+ export const before = (before) => helpers.withParams({before}, function(date) {
98
98
  // Get check date
99
- const dataWithParent = {today: moment().format('YYYY-MM-DD'), _parent: this._parent, ...data};
99
+ const dataWithParent = {today: moment().format('YYYY-MM-DD'), _parent: this._parent, ...this.vdata};
100
100
  const checkDate = moment(get(dataWithParent, before, before));
101
101
  if (!checkDate.isValid()) {
102
102
  return false;
@@ -107,9 +107,9 @@ export const before = (before) => helpers.withParams({before}, function(date, da
107
107
  return inputDate < beforeDate;
108
108
  });
109
109
 
110
- export const before_or_equal = (before_or_equal) => helpers.withParams({before_or_equal}, function(date, data) {
110
+ export const before_or_equal = (before_or_equal) => helpers.withParams({before_or_equal}, function(date) {
111
111
  // Get check date
112
- const dataWithParent = {today: moment().format('YYYY-MM-DD'), _parent: this._parent, ...data};
112
+ const dataWithParent = {today: moment().format('YYYY-MM-DD'), _parent: this._parent, ...this.vdata};
113
113
  const checkDate = moment(get(dataWithParent, before_or_equal, before_or_equal));
114
114
  if (!checkDate.isValid()) {
115
115
  return false;
@@ -150,20 +150,32 @@ export const required = (value) => {
150
150
  return value instanceof Array ? value.length > 0 : !!value;
151
151
  };
152
152
 
153
- export const requiredIf = (variable, expected) => helpers.withParams({variable, expected}, function(value, data) {
154
- const dataWithParent = {_parent: this._parent, ...data};
155
- if (get(dataWithParent, variable) != expected) return true;
153
+ export const requiredIf = (variable, expected) => helpers.withParams({variable, expected}, function(value) {
154
+ const dataWithParent = {_parent: this._parent, ...this.vdata};
155
+ const variableValue = get(dataWithParent, variable);
156
+ const isBoolean = (variableValue === true || variableValue === false);
157
+ let expectedValue = expected;
158
+ if (isBoolean) {
159
+ expectedValue = expected === 'true' || expected === '1';
160
+ }
161
+ if (variableValue != expectedValue) return true;
156
162
  return value instanceof Array ? value.length > 0 : !!value;
157
163
  });
158
164
 
159
- export const requiredUnless = (variable, expected) => helpers.withParams({variable, expected}, function(value, data) {
160
- const dataWithParent = {_parent: this._parent, ...data};
161
- if (get(dataWithParent, variable) == expected) return true;
165
+ export const requiredUnless = (variable, expected) => helpers.withParams({variable, expected}, function(value) {
166
+ const dataWithParent = {_parent: this._parent, ...this.vdata};
167
+ const variableValue = get(dataWithParent, variable);
168
+ const isBoolean = (variableValue === true || variableValue === false);
169
+ let expectedValue = expected;
170
+ if (isBoolean) {
171
+ expectedValue = expected === 'true' || expected === '1';
172
+ }
173
+ if (variableValue == expectedValue) return true;
162
174
  return value instanceof Array ? value.length > 0 : !!value;
163
175
  });
164
176
 
165
- export const sameAs = (field) => helpers.withParams({field}, function(value, data) {
166
- const dataWithParent = {_parent: this._parent, ...data};
177
+ export const sameAs = (field) => helpers.withParams({field}, function(value) {
178
+ const dataWithParent = {_parent: this._parent, ...this.vdata};
167
179
  const valueSameAs = get(dataWithParent, field);
168
180
  return value == valueSameAs;
169
181
  });
@@ -1,10 +1,28 @@
1
1
  import { Parser } from 'expr-eval';
2
2
 
3
3
  export default {
4
+ mounted() {
5
+ this.$root.$on('refresh-validation-rules', () => {
6
+ this.loadValidationRules();
7
+ });
8
+ },
4
9
  methods: {
5
- visibilityRuleIsVisible(rule) {
10
+ visibilityRuleIsVisible(rule, fieldName) {
6
11
  try {
7
- return !!Parser.evaluate(rule, Object.assign({}, this, this.vdata));
12
+ const data = Object.assign({ _parent: this._parent }, this.vdata);
13
+ const isVisible = !!Parser.evaluate(rule, Object.assign({}, this, data));
14
+
15
+ // Update the array of hidden fields
16
+ const fieldExists = this.hiddenFields__.indexOf(fieldName) !== -1;
17
+ if (isVisible && fieldExists) {
18
+ this.hiddenFields__ = this.hiddenFields__.filter((f) => f !== fieldName);
19
+ this.$root.$emit('refresh-validation-rules');
20
+ } else if (!isVisible && !fieldExists) {
21
+ this.hiddenFields__.push(fieldName);
22
+ this.$root.$emit('refresh-validation-rules');
23
+ }
24
+
25
+ return isVisible;
8
26
  } catch (e) {
9
27
  return false;
10
28
  }
@@ -5,7 +5,11 @@ export default {
5
5
  this.extensions.push({
6
6
  onloaditems({ element, wrapper }) {
7
7
  if (element.config.conditionalHide) {
8
- wrapper.setAttribute('v-show', `visibilityRuleIsVisible(${JSON.stringify(element.config.conditionalHide)})`);
8
+ wrapper.setAttribute(
9
+ 'v-show',
10
+ `visibilityRuleIsVisible(${JSON.stringify(element.config.conditionalHide)},
11
+ ${JSON.stringify(element.config.name)})`
12
+ );
9
13
  }
10
14
  },
11
15
  onbuild({ screen }) {
@@ -13,8 +13,21 @@ const undoRedoModule = {
13
13
  canRedo(state) {
14
14
  return state.position < state.stack.length - 1;
15
15
  },
16
- currentState(state) {
17
- return state.stack[state.position];
16
+ currentState(state, getters) {
17
+ let currentState = state.stack[state.position];
18
+
19
+ if (getters.nextState && getters.nextState.deletedPage) {
20
+ currentState.currentPage = getters.nextState.currentPage;
21
+ }
22
+
23
+ return currentState;
24
+ },
25
+ nextState(state, getters) {
26
+ if (getters.canRedo) {
27
+ return state.stack[state.position + 1];
28
+ }
29
+
30
+ return false;
18
31
  },
19
32
  },
20
33
  mutations: {
@@ -22,13 +35,12 @@ const undoRedoModule = {
22
35
  state.position = position;
23
36
  },
24
37
  setState(state, newState) {
25
- state.stack = state.stack.slice(0, state.position + 1);
26
38
  state.stack.push(newState);
27
39
  },
28
40
  },
29
41
  actions: {
30
42
  pushState({ state, getters, commit }, newState) {
31
- if (newState === getters.currentState) {
43
+ if (newState.config === getters.currentState) {
32
44
  return;
33
45
  }
34
46