@processmaker/screen-builder 2.20.1 → 2.21.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.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@processmaker/screen-builder",
3
- "version": "2.20.1",
3
+ "version": "2.21.0",
4
4
  "scripts": {
5
5
  "serve": "vue-cli-service serve",
6
6
  "build": "vue-cli-service build",
@@ -88,10 +88,14 @@ export default {
88
88
  }
89
89
  else {
90
90
  const endpoint = _.get(window, 'PM4ConfigOverrides.getScreenEndpoint', '/screens');
91
- const request = this.get(endpoint + `/${id}${query}`);
91
+
92
+ const screensCacheHit = this.screensCache.find(screen => screen.id == id);
93
+ if (screensCacheHit) {
94
+ return Promise.resolve({data: screensCacheHit});
95
+ }
92
96
 
93
97
  let screenPromise = new Promise((resolve, reject) => {
94
- request
98
+ this.get(endpoint + `/${id}${query}`)
95
99
  .then(response => {
96
100
  if (response.data.nested) {
97
101
  this.addNestedScreenCache(response.data.nested);
@@ -26,7 +26,7 @@ import Json2Vue from '../mixins/Json2Vue';
26
26
  import CurrentPageProperty from '../mixins/CurrentPageProperty';
27
27
  import WatchersSynchronous from '@/components/watchers-synchronous';
28
28
  import ScreenRendererError from '../components/renderer/screen-renderer-error';
29
- import { cloneDeep, isEqual } from 'lodash';
29
+ import { cloneDeep, isEqual, debounce } from 'lodash';
30
30
 
31
31
  export default {
32
32
  name: 'screen-renderer',
@@ -43,19 +43,23 @@ export default {
43
43
  mounted() {
44
44
  this.currentDefinition = cloneDeep(this.definition);
45
45
  this.component = this.buildComponent(this.currentDefinition);
46
+ this.rebuildScreen = debounce(this.rebuildScreen, 25);
46
47
  },
47
48
  watch: {
48
49
  definition: {
49
50
  deep: true,
50
51
  handler(definition) {
51
- if (!isEqual(definition, this.currentDefinition)) {
52
- this.currentDefinition = cloneDeep(definition);
53
- this.component = this.buildComponent(this.currentDefinition);
54
- }
52
+ this.rebuildScreen(definition);
55
53
  },
56
54
  },
57
55
  },
58
56
  methods: {
57
+ rebuildScreen(definition) {
58
+ if (!isEqual(definition, this.currentDefinition)) {
59
+ this.currentDefinition = cloneDeep(definition);
60
+ this.component = this.buildComponent(this.currentDefinition);
61
+ }
62
+ },
59
63
  onAsyncWatcherOn() {
60
64
  this.displayAsyncLoading = typeof this._parent === 'undefined';
61
65
  },
@@ -2,7 +2,7 @@ import extensions from './extensions';
2
2
  import ScreenBase from './ScreenBase';
3
3
  import CountElements from '../CountElements';
4
4
  import ValidationsFactory from '../ValidationsFactory';
5
- import _ from 'lodash';
5
+ import _, { debounce, isEqual } from 'lodash';
6
6
 
7
7
  let screenRenderer;
8
8
 
@@ -214,7 +214,12 @@ export default {
214
214
  return name && typeof name === 'string' && name.match(/^[a-zA-Z_][0-9a-zA-Z_.]*$/);
215
215
  },
216
216
  isComputedVariable(name, definition) {
217
- return definition.computed && definition.computed.find(c => c.property === name);
217
+ return definition.computed && definition.computed.some(computed => {
218
+ // Check if the first part of an element's name (up to the first `.`)
219
+ // matches the name of a computed property.
220
+ const regex = new RegExp(`^${computed.property}(\\.|$)`, 'i');
221
+ return regex.test(name);
222
+ });
218
223
  },
219
224
  registerVariable(name, element = {}) {
220
225
  if (!this.validVariableName(name)) {
@@ -336,19 +341,43 @@ export default {
336
341
  },
337
342
  addValidationRulesLoader(component, definition) {
338
343
  const firstPage = parseInt(this.currentPage) || 0;
344
+ function getKeys(input) {
345
+ if (input instanceof Array) {
346
+ const response = [];
347
+ input.forEach((item) => {
348
+ response.push(getKeys(item));
349
+ });
350
+ return response;
351
+ }
352
+ if (!(input instanceof Object)) {
353
+ return typeof input;
354
+ }
355
+ const keys = Object.keys(input);
356
+ const response = {};
357
+ keys.forEach((key) => {
358
+ response[key] = getKeys(input[key]);
359
+ });
360
+ return response;
361
+ }
362
+ let updateValidationRules = function(screenComponent, validations) {
363
+ const a = getKeys(screenComponent.ValidationRules__);
364
+ const b = getKeys(validations);
365
+ if (isEqual(a, b)) {
366
+ return;
367
+ }
368
+ screenComponent.ValidationRules__ = validations;
369
+ screenComponent.$nextTick(() => {
370
+ if (screenComponent.$v) {
371
+ screenComponent.$v.$touch();
372
+ }
373
+ });
374
+ };
375
+ updateValidationRules = debounce(updateValidationRules, 25);
339
376
  component.methods.loadValidationRules = function() {
340
377
  // Asynchronous loading of validations
341
378
  const validations = {};
342
379
  ValidationsFactory(definition, { screen: definition, firstPage, data: {_parent: this._parent, ...this.vdata} }).addValidations(validations).then(() => {
343
- if (_.isEqual(this.ValidationRules__, validations)) {
344
- return;
345
- }
346
- this.ValidationRules__ = validations;
347
- this.$nextTick(() => {
348
- if (this.$v) {
349
- this.$v.$touch();
350
- }
351
- });
380
+ updateValidationRules(this, validations);
352
381
  });
353
382
  };
354
383
  component.mounted.push('this.loadValidationRules()');
@@ -69,7 +69,7 @@ export default {
69
69
  properties[':form-computed'] = JSON.stringify(definition.computed);
70
70
  properties[':form-watchers'] = JSON.stringify(definition.watchers);
71
71
  // Check if control is assigned to a calculated property
72
- const isCalcProp = definition.computed && !!definition.computed.find(computed => computed.property == element.config.name);
72
+ const isCalcProp = this.isComputedVariable(element.config.name, definition);
73
73
  properties[':readonly'] = isCalcProp || element.config.readonly;
74
74
  properties[':disabled'] = isCalcProp || element.config.disabled;
75
75
  // Events