@processmaker/screen-builder 2.27.0 → 2.28.1-B

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,26 +1,17 @@
1
1
  {
2
2
  "name": "@processmaker/screen-builder",
3
- "version": "2.27.0",
3
+ "version": "2.28.1-B",
4
4
  "scripts": {
5
5
  "serve": "vue-cli-service serve",
6
6
  "build": "vue-cli-service build",
7
7
  "test:unit": "vue-cli-service test:unit",
8
- "lint": "vue-cli-service lint --no-fix",
8
+ "lint": "vue-cli-service lint",
9
9
  "build-bundle": "vue-cli-service build --target lib --name vue-form-builder ./src/components/index.js",
10
10
  "lint-fix": "vue-cli-service lint",
11
11
  "open-cypress": "TZ=UTC nyc cypress open",
12
12
  "run-cypress": "TZ=UTC nyc cypress run",
13
13
  "test": "vue-cli-service test:unit"
14
14
  },
15
- "nyc": {
16
- "include": [
17
- "src/**"
18
- ],
19
- "extension": [
20
- ".js",
21
- ".vue"
22
- ]
23
- },
24
15
  "main": "./dist/vue-form-builder.common.js",
25
16
  "files": [
26
17
  "dist/*",
@@ -42,14 +33,16 @@
42
33
  },
43
34
  "devDependencies": {
44
35
  "@4tw/cypress-drag-drop": "~1.3.1",
36
+ "@babel/core": "^7.12.16",
37
+ "@babel/eslint-parser": "^7.12.16",
45
38
  "@cypress/code-coverage": "^3.8.1",
46
39
  "@fortawesome/fontawesome-free": "^5.6.1",
47
40
  "@panter/vue-i18next": "^0.15.2",
48
- "@processmaker/vue-form-elements": "0.28.7",
41
+ "@processmaker/vue-form-elements": "0.29.0",
49
42
  "@processmaker/vue-multiselect": "^2.2.0",
50
43
  "@vue/cli-plugin-babel": "^3.6.0",
51
44
  "@vue/cli-plugin-e2e-cypress": "^4.0.3",
52
- "@vue/cli-plugin-eslint": "^3.6.0",
45
+ "@vue/cli-plugin-eslint": "~5.0.0",
53
46
  "@vue/cli-plugin-unit-jest": "^4.3.0",
54
47
  "@vue/cli-service": "^3.6.0",
55
48
  "@vue/test-utils": "^1.1.1",
@@ -57,18 +50,21 @@
57
50
  "babel-core": "7.0.0-bridge.0",
58
51
  "bootstrap": "^4.5.3",
59
52
  "bootstrap-vue": "^2.19.0",
53
+ "css-loader": "^5.2.7",
60
54
  "css-tree": "^1.0.0-alpha.29",
61
55
  "cypress": "^3.8.0",
62
56
  "cypress-wait-until": "^1.7.1",
57
+ "eslint": "^7.32.0",
63
58
  "eslint-plugin-jest": "^22.4.1",
59
+ "eslint-plugin-vue": "^8.0.3",
64
60
  "expr-eval": "^2.0.2",
65
61
  "i18next": "^15.0.8",
66
62
  "identity-obj-proxy": "^3.0.0",
67
- "inputmask": "^5.0.6",
63
+ "inputmask": "^5.0.7",
68
64
  "monaco-editor-webpack-plugin": "~1.7.0",
69
65
  "mustache": "^3.0.1",
70
- "node-sass": "^6.0.1",
71
66
  "nyc": "^15.1.0",
67
+ "sass": "^1.51.0",
72
68
  "sass-loader": "^10.2.0",
73
69
  "v-calendar": "^0.9.7",
74
70
  "validatorjs": "^3.14.2",
@@ -86,7 +82,7 @@
86
82
  },
87
83
  "peerDependencies": {
88
84
  "@panter/vue-i18next": "^0.15.0",
89
- "@processmaker/vue-form-elements": "0.28.7",
85
+ "@processmaker/vue-form-elements": "0.29.0",
90
86
  "i18next": "^15.0.8",
91
87
  "vue": "^2.6.12",
92
88
  "vuex": "^3.1.1"
@@ -100,5 +96,18 @@
100
96
  "> 1%",
101
97
  "last 2 versions",
102
98
  "not ie <= 8"
103
- ]
99
+ ],
100
+ "engines": {
101
+ "npm": ">=8",
102
+ "node": ">=16 <18"
103
+ },
104
+ "nyc": {
105
+ "include": [
106
+ "src/**"
107
+ ],
108
+ "extension": [
109
+ ".js",
110
+ ".vue"
111
+ ]
112
+ }
104
113
  }
@@ -175,6 +175,11 @@ export default {
175
175
  const fileId = this.value ? this.value : _.get(this.requestData, this.fileDataName, null);
176
176
  let endpoint = this.endpoint;
177
177
 
178
+ if (this.requestFiles) {
179
+ this.filesInfo.push(_.get(this.requestFiles, this.fileDataName, null));
180
+ return;
181
+ }
182
+
178
183
  if (!this.requestId || !fileId) {
179
184
  return;
180
185
  }
@@ -193,7 +198,7 @@ export default {
193
198
  this.filesInfo.push(fileInfo);
194
199
  } else {
195
200
  window.ProcessMaker.alert(
196
- this.$t('File Download Missing File'),
201
+ this.$t('File ID does not exist'),
197
202
  'danger'
198
203
  );
199
204
  }
@@ -18,7 +18,7 @@
18
18
  >
19
19
  <uploader-unsupport/>
20
20
 
21
- <uploader-drop class="form-control-file">
21
+ <uploader-drop v-if="uploaderLoaded" class="form-control-file">
22
22
  <p>{{ $t('Drop a file here to upload or') }}</p>
23
23
  <uploader-btn
24
24
  :attrs="nativeButtonAttrs"
@@ -33,15 +33,20 @@
33
33
  <span v-if="validation === 'required' && !value" class="required">{{ $t('Required') }}</span>
34
34
  </uploader-drop>
35
35
  <uploader-list>
36
- <template>
37
- <ul>
36
+ <template slot-scope = "{ fileList }">
37
+ <ul v-if="uploading">
38
+ <li v-for="file in fileList" :key="file.id">
39
+ <uploader-file :file="file" :list="true"/>
40
+ </li>
41
+ </ul>
42
+ <ul v-else>
38
43
  <li v-for="(file, i) in files " :key="i" :data-cy="file.id">
39
44
  <div class="">
40
45
  <div class="" style="display:flex; background:rgb(226 238 255)">
41
- <div v-if="nativeFiles[file.id]" style="flex: 1" :data-cy="file.file_name.replace(/[^0-9a-zA-Z\-]/g, '-')">
46
+ <div v-if="nativeFiles[file.id]" style="flex: 1" class="overflow-hidden" :data-cy="file.file_name.replace(/[^0-9a-zA-Z\-]/g, '-')">
42
47
  <uploader-file :file="nativeFiles[file.id]" :list="true" />
43
48
  </div>
44
- <div v-else style="flex: 1">
49
+ <div v-else class="text-truncate" :title="file.file_name" style="flex: 1">
45
50
  <i class="fas fa-paperclip"/> {{ file.file_name }}
46
51
  </div>
47
52
  <div class="pt-1">
@@ -282,9 +287,13 @@ export default {
282
287
  disabled: false,
283
288
  files: [],
284
289
  nativeFiles: {},
290
+ uploading: false,
285
291
  };
286
292
  },
287
293
  methods: {
294
+ uploaderLoaded() {
295
+ return this.$refs['uploader'];
296
+ },
288
297
  setFiles() {
289
298
  if (_.isEqual(this.filesData, this.files)) {
290
299
  return;
@@ -378,7 +387,7 @@ export default {
378
387
  }
379
388
  }
380
389
  },
381
- async removeFile(file) {
390
+ async removeFile(file) {
382
391
  const id = file.id;
383
392
  const token = file.token ? file.token : null;
384
393
 
@@ -386,13 +395,13 @@ export default {
386
395
  if (!isNaN(id)) {
387
396
  await this.$dataProvider.deleteFile(id, token);
388
397
  }
389
-
398
+
390
399
  this.removeFromFiles(id);
391
400
  },
392
401
  removeFromFiles(id) {
393
402
  const idx = this.files.findIndex(f => f.id === id);
394
403
  this.$delete(this.files, idx);
395
-
404
+
396
405
  if (this.nativeFiles[id]) {
397
406
  if (this.$refs.uploader) {
398
407
  this.$refs.uploader.uploader.removeFile(this.nativeFiles[id]);
@@ -470,6 +479,7 @@ export default {
470
479
  }
471
480
  },
472
481
  fileUploaded(rootFile, file, message) {
482
+ this.uploading = false;
473
483
  let name = file.name;
474
484
  if (message) {
475
485
  const msg = JSON.parse(message);
@@ -478,13 +488,13 @@ export default {
478
488
  if (this.collection) {
479
489
  id = msg.id;
480
490
  }
481
-
491
+
482
492
  const fileInfo = {
483
493
  id,
484
494
  file_name: name,
485
495
  mime_type: rootFile.fileType,
486
496
  };
487
-
497
+
488
498
  this.$set(this.nativeFiles, id, rootFile);
489
499
  this.addToFiles(fileInfo);
490
500
  } else {
@@ -511,6 +521,7 @@ export default {
511
521
  return null;
512
522
  },
513
523
  start() {
524
+ this.uploading = true;
514
525
  if (this.parentRecordList(this) === null) {
515
526
  this.row_id = null;
516
527
  }
@@ -38,10 +38,11 @@ export default {
38
38
  computed: {
39
39
  classList() {
40
40
  let variant = this.variant || 'primary';
41
+ let isInvalid = this.$store.getters['globalErrorsModule/isValidScreen'] === false;
41
42
  return {
42
43
  btn: true,
43
44
  ['btn-' + variant]: true,
44
- disabled: this.errors,
45
+ disabled: this.event === 'submit' && isInvalid,
45
46
  };
46
47
  },
47
48
  options() {
@@ -92,6 +92,27 @@ export default {
92
92
 
93
93
  });
94
94
  },
95
+ disableForm(config) {
96
+ config.forEach(item => {
97
+
98
+ //If the element has containers
99
+ if (Array.isArray(item)) {
100
+ this.disableForm(item);
101
+ }
102
+
103
+ //If the element has items
104
+ if (item.items) {
105
+ this.disableForm(item.items);
106
+ }
107
+
108
+ //Disable element
109
+ if (item && item.config) {
110
+ item.config.disabled = true;
111
+ item.config.readonly = true;
112
+ item.config.editable = false;
113
+ }
114
+ });
115
+ },
95
116
  loadScreen(id) {
96
117
  this.config = defaultConfig;
97
118
  this.computed = [];
@@ -109,6 +130,10 @@ export default {
109
130
  this.watchers = response.data.watchers;
110
131
  this.screenTitle = response.data.title;
111
132
 
133
+ if (this.$attrs['disabled']) {
134
+ this.disableForm(this.config);
135
+ }
136
+
112
137
  if (this.ancestorScreens.includes(this.screenTitle)) {
113
138
  globalObject.ProcessMaker.alert(`Rendering of nested "${this.screenTitle}" screen was disallowed to prevent loop.`, 'warning');
114
139
  } else {
@@ -370,7 +370,7 @@ export default {
370
370
  showEditForm(index, rowId) {
371
371
  let pageIndex = ((this.currentPage-1) * this.perPage) + index;
372
372
  // Reset edit to be a copy of our data model item
373
- this.editItem = _.find(this.tableData.data, {'row_id': rowId});
373
+ this.editItem = JSON.parse(JSON.stringify(_.find(this.tableData.data, {'row_id': rowId})));
374
374
  this.editIndex = pageIndex;
375
375
  // rebuild the edit screen to avoid
376
376
  this.editFormVersion++;
@@ -387,7 +387,7 @@ export default {
387
387
 
388
388
  // Edit the item in our model and emit change
389
389
  let data = this.tableData.data ? JSON.parse(JSON.stringify(this.tableData.data)) : [];
390
- var index = _.findIndex(data, {'row_id': this.editItem.rowId});
390
+ var index = _.findIndex(data, {'row_id': this.editItem.row_id});
391
391
  data[index] = JSON.parse(JSON.stringify(this.editItem));
392
392
 
393
393
  // Remove the parent object
@@ -327,17 +327,25 @@ export default {
327
327
  this.redirecting = task.process_request_id;
328
328
  this.$emit('redirect', task.id, true);
329
329
  return;
330
- } else if (this.task && requestId == this.task.process_request_id && this.parentRequest && this.task.process_request.status === 'COMPLETED') {
331
- // Only emit completed after getting the subprocess tasks and there are no tasks and process is completed
332
- this.$emit('completed', this.parentRequest);
330
+ } else {
331
+ this.emitIfTaskCompleted(requestId);
333
332
  }
334
333
  this.taskId = task.id;
335
334
  this.nodeId = task.element_id;
336
- } else if (this.parentRequest) {
335
+ } else if (this.parentRequest && ['COMPLETED', 'CLOSED'].includes(this.task.process_request.status)) {
337
336
  this.$emit('completed', this.parentRequest);
338
337
  }
339
338
  });
340
339
  },
340
+ emitIfTaskCompleted(requestId) {
341
+ // Only emit completed after getting the subprocess tasks and there are no tasks and process is completed
342
+ if (this.task
343
+ && this.parentRequest
344
+ && requestId == this.task.process_request_id
345
+ && this.task.process_request.status === 'COMPLETED') {
346
+ this.$emit('completed', this.parentRequest);
347
+ }
348
+ },
341
349
  classHeaderCard(status) {
342
350
  let header = 'bg-success';
343
351
  switch (status) {
@@ -536,13 +536,13 @@ export default {
536
536
  }
537
537
  }
538
538
  if (item.items) {
539
- this.checkForCaptcha(item.items, true);
539
+ this.checkForCaptcha(item.items, true, nestedScreen);
540
540
  }
541
- if (item.component == 'FormNestedScreen' && insideLoop && item.config.screen && window.nestedScreens) {
541
+ if (item.component == 'FormNestedScreen' && item.config.screen && window.nestedScreens) {
542
542
  let nestedScreenItems = window.nestedScreens['id_' + item.config.screen];
543
543
  if (nestedScreenItems) {
544
544
  nestedScreenItems.forEach(nestedScreenPage => {
545
- this.checkForCaptcha(nestedScreenPage.items, true, item);
545
+ this.checkForCaptcha(nestedScreenPage.items, insideLoop, item);
546
546
  });
547
547
  }
548
548
  }
@@ -850,7 +850,7 @@ export default {
850
850
  registerStoreModule(moduleName, storeModule) {
851
851
  const store = this.$store;
852
852
 
853
- if (!(store && store.state && store.state[moduleName])) {
853
+ if (store && store.state && !store.state[moduleName]) {
854
854
  store.registerModule(moduleName, storeModule);
855
855
  }
856
856
  },
@@ -874,6 +874,7 @@ export default {
874
874
  },
875
875
  mounted() {
876
876
  this.loadVariablesTree();
877
+ this.checkForCaptchaInLoops();
877
878
  this.$root.$on('nested-screen-updated', () => {
878
879
  this.checkForCaptchaInLoops();
879
880
  });
@@ -17,7 +17,7 @@ import globalErrorsModule from '@/store/modules/global-errors';
17
17
 
18
18
  const csstree = require('css-tree');
19
19
  const Scrollparent = require('scrollparent');
20
-
20
+
21
21
  export default {
22
22
  name: 'VueFormRenderer',
23
23
  components: { CustomCssOutput },
@@ -123,7 +123,7 @@ export default {
123
123
  registerStoreModule(moduleName, storeModule) {
124
124
  const store = this.$store;
125
125
 
126
- if (!(store && store.state && store.state[moduleName])) {
126
+ if (store && store.state && !store.state[moduleName]) {
127
127
  store.registerModule(moduleName, storeModule);
128
128
  }
129
129
  },
@@ -4,6 +4,7 @@ export default {
4
4
  pageNavigate() {},
5
5
  pageNavigationProperties({ properties }) {
6
6
  properties['@page-navigate'] = 'pageNavigate';
7
+ properties[':validate'] = '$v';
7
8
  },
8
9
  pageNavigationBuild(screen) {
9
10
  this.addData(screen, 'currentPage__', 'this._initialPage');
@@ -19,7 +20,7 @@ export default {
19
20
  mounted() {
20
21
  this.extensions.push({
21
22
  onloadproperties(params) {
22
- if (params.componentName === 'FormButton') {
23
+ if (params.element.component === 'FormButton' && params.element.config.event === 'pageNavigate') {
23
24
  this.pageNavigationProperties(params);
24
25
  }
25
26
  },