@processmaker/screen-builder 2.30.1 → 2.40.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.30.1",
3
+ "version": "2.40.0",
4
4
  "scripts": {
5
5
  "serve": "vue-cli-service serve",
6
6
  "build": "vue-cli-service build",
@@ -38,7 +38,7 @@
38
38
  "@cypress/code-coverage": "^3.8.1",
39
39
  "@fortawesome/fontawesome-free": "^5.6.1",
40
40
  "@panter/vue-i18next": "^0.15.2",
41
- "@processmaker/vue-form-elements": "0.29.1",
41
+ "@processmaker/vue-form-elements": "0.30.0",
42
42
  "@processmaker/vue-multiselect": "^2.2.0",
43
43
  "@vue/cli-plugin-babel": "^3.6.0",
44
44
  "@vue/cli-plugin-e2e-cypress": "^4.0.3",
@@ -54,9 +54,13 @@
54
54
  "css-tree": "^1.0.0-alpha.29",
55
55
  "cypress": "^3.8.0",
56
56
  "cypress-wait-until": "^1.7.1",
57
- "eslint": "^7.32.0",
57
+ "eslint": "^8.21.0",
58
+ "eslint-config-airbnb-base": "^15.0.0",
59
+ "eslint-config-prettier": "^8.5.0",
60
+ "eslint-plugin-import": "^2.26.0",
58
61
  "eslint-plugin-jest": "^22.4.1",
59
- "eslint-plugin-vue": "^8.0.3",
62
+ "eslint-plugin-prettier": "^4.2.1",
63
+ "eslint-plugin-vue": "^9.3.0",
60
64
  "expr-eval": "^2.0.2",
61
65
  "i18next": "^15.0.8",
62
66
  "identity-obj-proxy": "^3.0.0",
@@ -64,6 +68,7 @@
64
68
  "monaco-editor-webpack-plugin": "~1.7.0",
65
69
  "mustache": "^3.0.1",
66
70
  "nyc": "^15.1.0",
71
+ "prettier": "2.7.1",
67
72
  "sass": "^1.53.0",
68
73
  "sass-loader": "^10.3.1",
69
74
  "v-calendar": "^0.9.7",
@@ -82,7 +87,7 @@
82
87
  },
83
88
  "peerDependencies": {
84
89
  "@panter/vue-i18next": "^0.15.0",
85
- "@processmaker/vue-form-elements": "0.29.1",
90
+ "@processmaker/vue-form-elements": "0.30.0",
86
91
  "i18next": "^15.0.8",
87
92
  "vue": "^2.6.12",
88
93
  "vuex": "^3.1.1"
package/src/App.vue CHANGED
@@ -74,13 +74,6 @@
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">&times;</span>
82
- </button>
83
- </div>
84
77
  <vue-form-renderer ref="renderer"
85
78
  :key="rendererKey"
86
79
  v-model="previewData"
@@ -458,7 +451,7 @@ export default {
458
451
  if (customCSS) {
459
452
  this.customCSS = customCSS;
460
453
  }
461
-
454
+
462
455
  if (computed) {
463
456
  this.computed = JSON.parse(computed);
464
457
  }
@@ -611,7 +604,7 @@ export default {
611
604
  .modal-backdrop {
612
605
  opacity: 0.5;
613
606
  }
614
-
607
+
615
608
  .form-group--error {
616
609
  animation: none;
617
610
  }
@@ -136,7 +136,23 @@ export default {
136
136
  }
137
137
  url += this.authQueryString();
138
138
 
139
- return this.post(url, params, { timeout: 0});
139
+ if (window.ProcessMaker && window.ProcessMaker.debounce !== undefined && window.ProcessMaker.debounce === false) {
140
+ return this.post(url, params, { timeout: 0});
141
+ }
142
+
143
+ if (window.ProcessMaker.cachedDataSources === undefined) {
144
+ window.ProcessMaker.cachedDataSources = [];
145
+ }
146
+ let cachedDataSources = window.ProcessMaker.cachedDataSources;
147
+ let cached = cachedDataSources.find(item => item.url === url);
148
+ if (cached) {
149
+ return cached.value;
150
+ }
151
+ else {
152
+ let post = this.post(url, params, { timeout: 0});
153
+ cachedDataSources.push({url, value: post});
154
+ return post;
155
+ }
140
156
  },
141
157
 
142
158
  authQueryString() {
@@ -112,6 +112,11 @@ export default {
112
112
  requestEndpoint(file) {
113
113
  let endpoint = this.endpoint;
114
114
 
115
+ if (_.has(window, 'PM4ConfigOverrides.useDefaultUrlDownload') && window.PM4ConfigOverrides.useDefaultUrlDownload) {
116
+ // Use default endpoint when coming from a package.
117
+ return `../files/${file.id}/contents`;
118
+ }
119
+
115
120
  if (_.has(window, 'PM4ConfigOverrides.getFileEndpoint')) {
116
121
  endpoint = window.PM4ConfigOverrides.getFileEndpoint;
117
122
  return `${endpoint}/${file.id}`;
@@ -109,10 +109,12 @@ export default {
109
109
  this.setValue(this.$parent, this.name, this.fieldValue);
110
110
  }
111
111
  if (this.event === 'submit') {
112
- this.$emit('input', this.fieldValue);
113
- this.$nextTick(()=>{
114
- this.$emit('submit', this.eventData);
115
- });
112
+ window.setTimeout(() => {
113
+ this.$emit('input', this.fieldValue);
114
+ this.$nextTick(()=>{
115
+ this.$emit('submit', this.eventData);
116
+ });
117
+ }, 600);
116
118
  return;
117
119
  }
118
120
  this.$emit(this.event, this.eventData);
@@ -4,7 +4,8 @@
4
4
  <component
5
5
  v-if="componentType!=='input'"
6
6
  :is="componentType"
7
- v-model="localValue"
7
+ :value="internalValue"
8
+ @input="updateInternalValue"
8
9
  v-bind="componentConfig"
9
10
  v-uni-id="name"
10
11
  :name="name"
@@ -13,7 +14,8 @@
13
14
  type="text"
14
15
  />
15
16
  <input v-else
16
- v-model="localValue"
17
+ :value="internalValue"
18
+ @input="updateInternalValue"
17
19
  v-bind="componentConfig"
18
20
  v-uni-id="name"
19
21
  :name="name"
@@ -41,6 +43,7 @@ import { TheMask } from 'vue-the-mask';
41
43
  import { getUserDateFormat, getUserDateTimeFormat } from '@processmaker/vue-form-elements/src/dateUtils';
42
44
  import ValidationMixin from '@processmaker/vue-form-elements/src/components/mixins/validation';
43
45
  import moment from 'moment';
46
+ import InputDebounce from '@processmaker/vue-form-elements/src/components/mixins/InputDebounce';
44
47
 
45
48
  const uniqIdsMixin = createUniqIdsMixin();
46
49
  const componentTypes = {
@@ -61,7 +64,7 @@ const componentTypesConfigs = {
61
64
  export default {
62
65
  inheritAttrs: false,
63
66
  components: { TheMask, Inputmasked },
64
- mixins: [ uniqIdsMixin, ValidationMixin ],
67
+ mixins: [ uniqIdsMixin, ValidationMixin, InputDebounce ],
65
68
  props: [
66
69
  'value',
67
70
  'label',
@@ -223,12 +226,12 @@ export default {
223
226
  },
224
227
  watch: {
225
228
  value(value) {
226
- if (this.localValue !== value) {
229
+ if (!this.touched) {
227
230
  this.localValue = value;
228
231
  }
229
232
  },
230
233
  localValue(value) {
231
- if (value != this.value) {
234
+ if (value !== this.value) {
232
235
  this.$emit('input', this.convertToData(value));
233
236
  }
234
237
  },
@@ -236,7 +239,6 @@ export default {
236
239
  data() {
237
240
  return {
238
241
  validator: null,
239
- localValue: null,
240
242
  validationRules: {
241
243
  'percentage': 'regex:/^[+-]?\\d+(\\.\\d+)?$/',
242
244
  },
@@ -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, get as getFromObject} from 'lodash';
30
30
 
31
31
  export default {
32
32
  name: 'screen-renderer',
@@ -42,7 +42,28 @@ export default {
42
42
  },
43
43
  mounted() {
44
44
  this.currentDefinition = cloneDeep(this.definition);
45
- this.component = this.buildComponent(this.currentDefinition);
45
+
46
+ let screenName = getFromObject(this.currentDefinition, 'config.0.name');
47
+ const itemName = `hash${this.hash(JSON.stringify(this.currentDefinition))}`;
48
+
49
+ if (['empty', undefined, null].includes(screenName)) {
50
+ this.component = this.buildComponent(this.currentDefinition);
51
+ return;
52
+ }
53
+
54
+ if (window.ProcessMaker.cachedScreens === undefined) {
55
+ window.ProcessMaker.cachedScreens = [];
56
+ }
57
+ let cachedScreen = window.ProcessMaker.cachedScreens.find(x => x.name === itemName);
58
+ if (cachedScreen) {
59
+ this.component = cachedScreen.component;
60
+ }
61
+ else {
62
+ let component = this.buildComponent(this.currentDefinition);
63
+ this.component = component;
64
+ window.ProcessMaker.cachedScreens.push({name: itemName, component: cloneDeep(component), definition: this.definition});
65
+ }
66
+
46
67
  },
47
68
  watch: {
48
69
  definition: {
@@ -52,12 +73,19 @@ export default {
52
73
  },
53
74
  },
54
75
  },
55
- methods: {
56
- rebuildScreen(definition) {
76
+ created() {
77
+ this.rebuildScreen = debounce(function(definition) {
57
78
  if (!isEqual(definition, this.currentDefinition)) {
58
79
  this.currentDefinition = cloneDeep(definition);
59
80
  this.component = this.buildComponent(this.currentDefinition);
60
81
  }
82
+ }, 500);
83
+ },
84
+ methods: {
85
+ hash(s) {
86
+ for (var i=0,h=9;i<s.length;)
87
+ h=Math.imul(h^s.charCodeAt(i++),9**9);
88
+ return h^h>>>9;
61
89
  },
62
90
  onAsyncWatcherOn() {
63
91
  this.displayAsyncLoading = typeof this._parent === 'undefined';
@@ -8,13 +8,6 @@
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">&times;</span>
16
- </button>
17
- </div>
18
11
  <vue-form-renderer
19
12
  ref="renderer"
20
13
  v-model="requestData"
@@ -250,7 +243,7 @@ export default {
250
243
  this.task = response.data;
251
244
  this.checkTaskStatus();
252
245
  if (window.PM4ConfigOverrides.getScreenEndpoint && window.PM4ConfigOverrides.getScreenEndpoint.includes('tasks/')) {
253
- const screenPath = window.PM4ConfigOverrides.getScreenEndpoint.split('/');
246
+ const screenPath = window.PM4ConfigOverrides.getScreenEndpoint.split('/');
254
247
  screenPath[1] = this.task.id;
255
248
  window.PM4ConfigOverrides.getScreenEndpoint = screenPath.join('/');
256
249
  }
@@ -6,12 +6,12 @@
6
6
  </template>
7
7
 
8
8
  <script>
9
- import _ from 'lodash';
9
+ import {size, cloneDeep, debounce, get} from 'lodash';
10
10
  import CustomCssOutput from './custom-css-output';
11
11
  import currencies from '../currency.json';
12
12
  import Inputmask from 'inputmask';
13
- import { getItemsFromConfig } from '../itemProcessingUtils';
14
- import { ValidatorFactory } from '../factories/ValidatorFactory';
13
+ import {getItemsFromConfig} from '@/itemProcessingUtils';
14
+ import {ValidatorFactory} from '@/factories/ValidatorFactory';
15
15
  import CurrentPageProperty from '../mixins/CurrentPageProperty';
16
16
  import globalErrorsModule from '@/store/modules/global-errors';
17
17
 
@@ -19,9 +19,9 @@ const csstree = require('css-tree');
19
19
  const Scrollparent = require('scrollparent');
20
20
 
21
21
  export default {
22
- name: 'VueFormRenderer',
23
- components: { CustomCssOutput },
24
- mixins: [CurrentPageProperty],
22
+ name: 'VueFormRenderer',
23
+ components: {CustomCssOutput},
24
+ mixins: [CurrentPageProperty],
25
25
  props: ['config', 'data', '_parent', 'page', 'computed', 'customCss', 'mode', 'watchers', 'isLoop', 'ancestorScreens', 'loopContext', 'showErrors', 'testScreenDefinition'],
26
26
  model: {
27
27
  prop: 'data',
@@ -69,7 +69,7 @@ export default {
69
69
  };
70
70
  return function(text) {
71
71
  const params = JSON.parse(`[${text}]`);
72
- return format(_.get(this, params[0]), params[1]);
72
+ return format(get(this, params[0]), params[1]);
73
73
  };
74
74
  },
75
75
  },
@@ -91,8 +91,8 @@ export default {
91
91
  data: {
92
92
  deep: true,
93
93
  handler() {
94
- this.$emit('update', this.data);
95
- },
94
+ this.debouncedWatch();
95
+ },
96
96
  },
97
97
  computed: {
98
98
  deep: true,
@@ -108,9 +108,13 @@ export default {
108
108
  },
109
109
  },
110
110
  created() {
111
+ this.debouncedWatch = debounce(() => this.$emit('update', this.data), 500);
111
112
  this.registerStoreModule('globalErrorsModule', globalErrorsModule);
112
- this.parseCss = _.debounce(this.parseCss, 500, {leading: true});
113
+ this.parseCss = debounce(this.parseCss, 500, {leading: true});
113
114
  },
115
+ beforeUnmount() {
116
+ this.debouncedWatch.cancel();
117
+ },
114
118
  mounted() {
115
119
  this.parseCss();
116
120
  this.registerCustomFunctions();
@@ -162,7 +166,7 @@ export default {
162
166
  */
163
167
  isValid() {
164
168
  const items = getItemsFromConfig(this.definition.config);
165
- let config = _.cloneDeep(this.definition.config);
169
+ let config = cloneDeep(this.definition.config);
166
170
 
167
171
  this.checkForRecordList(items, config);
168
172
  this.dataTypeValidator = ValidatorFactory(config, this.data);
@@ -171,7 +175,7 @@ export default {
171
175
  if (this.errors) {
172
176
  this.formSubmitErrorClass = 'invalid-form-submission';
173
177
  }
174
- return _.size(this.errors) === 0;
178
+ return size(this.errors) === 0;
175
179
  },
176
180
  registerCustomFunctions(node=this) {
177
181
  if (node.registerCustomFunction instanceof Function) {
package/src/main.js CHANGED
@@ -93,6 +93,7 @@ window.exampleScreens = [
93
93
  },
94
94
  ];
95
95
  window.ProcessMaker = {
96
+ debounce: false,
96
97
  isStub: true,
97
98
  user: {
98
99
  id: 1,
@@ -375,7 +375,7 @@ export default {
375
375
  }
376
376
  });
377
377
  };
378
- updateValidationRules = debounce(updateValidationRules, 25);
378
+ updateValidationRules = debounce(updateValidationRules, 100);
379
379
  component.methods.loadValidationRules = function() {
380
380
  // Asynchronous loading of validations
381
381
  const validations = {};
@@ -7,12 +7,28 @@ const stringFormats = ['string', 'datetime', 'date', 'password'];
7
7
  export default {
8
8
  schema: [
9
9
  function() {
10
+ if (window.ProcessMaker.cachedSchemas === undefined) {
11
+ window.ProcessMaker.cachedSchemas = [];
12
+ }
13
+
14
+
10
15
  if (window.ProcessMaker && window.ProcessMaker.packages && window.ProcessMaker.packages.includes('package-vocabularies')) {
11
16
  if (window.ProcessMaker.VocabulariesSchemaUrl) {
12
- let response = window.ProcessMaker.apiClient.get(window.ProcessMaker.VocabulariesSchemaUrl);
13
- return response.then(response => {
14
- return response.data;
15
- });
17
+ let cachedSchemas = window.ProcessMaker.cachedSchemas;
18
+ let schemaUrl = window.ProcessMaker.VocabulariesSchemaUrl;
19
+ let cached = cachedSchemas.find(item => item.url === schemaUrl);
20
+ if (cached) {
21
+ return cached.value;
22
+ }
23
+ else {
24
+ let response = window.ProcessMaker.apiClient.get(window.ProcessMaker.VocabulariesSchemaUrl);
25
+ let result = response.then(response => {
26
+ window.ProcessMaker.cachedSchema = response.data;
27
+ return response.data;
28
+ });
29
+ cachedSchemas.push({url: schemaUrl, value: result});
30
+ return result;
31
+ }
16
32
  }
17
33
  if (window.ProcessMaker.VocabulariesPreview) {
18
34
  return window.ProcessMaker.VocabulariesPreview;
@@ -111,6 +127,8 @@ export default {
111
127
  },
112
128
  submitForm() {
113
129
  if (this.$v.$invalid) {
130
+ let msgError = this.$store.getters['globalErrorsModule/getErrorMessage'];
131
+ window.ProcessMaker.alert(msgError, 'danger');
114
132
  //if the form is not valid the data is not emitted
115
133
  return;
116
134
  }
@@ -176,6 +194,10 @@ export default {
176
194
  return;
177
195
  }
178
196
 
197
+ if (Number.isNaN(originalValue)) {
198
+ delete object[attr];
199
+ }
200
+
179
201
  this.$set(
180
202
  object,
181
203
  attr,
@@ -14,7 +14,7 @@ export default {
14
14
 
15
15
  const data = new Proxy(Object.assign({}, this), {
16
16
  get(data, name) {
17
- if (data[name] === undefined || !isEqual(data[name]), self.vdata[name]) {
17
+ if (data[name] === undefined || !isEqual(data[name], self.vdata[name])) {
18
18
  return self.vdata[name];
19
19
  } else {
20
20
  return data[name];