@processmaker/screen-builder 2.99.2 → 3.0.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/dist/vue-form-builder.css +1 -1
- package/dist/vue-form-builder.es.js +9092 -7133
- package/dist/vue-form-builder.es.js.map +1 -1
- package/dist/vue-form-builder.umd.js +53 -53
- package/dist/vue-form-builder.umd.js.map +1 -1
- package/package.json +2 -1
- package/src/App.vue +14 -2
- package/src/DataProvider.js +42 -1
- package/src/VariableDataTypeProperties.js +1 -1
- package/src/components/ClipboardButton.vue +77 -0
- package/src/components/CssIcon.vue +21 -0
- package/src/components/ScreenTemplateCard.vue +257 -0
- package/src/components/ScreenTemplates.vue +216 -0
- package/src/components/ScreenToolbar.vue +24 -2
- package/src/components/SelectUserGroup.vue +274 -0
- package/src/components/TabsBar.vue +47 -1
- package/src/components/accordions.js +7 -1
- package/src/components/editor/loop.vue +22 -1
- package/src/components/editor/multi-column.vue +22 -2
- package/src/components/editor/pagesDropdown.vue +20 -2
- package/src/components/index.js +7 -1
- package/src/components/inspector/collection-data-source.vue +200 -0
- package/src/components/inspector/collection-display-mode.vue +87 -0
- package/src/components/inspector/collection-records-list.vue +156 -0
- package/src/components/inspector/column-setup.vue +123 -7
- package/src/components/inspector/encrypted-config.vue +78 -0
- package/src/components/inspector/index.js +4 -0
- package/src/components/inspector/page-select.vue +1 -0
- package/src/components/renderer/file-upload.vue +136 -3
- package/src/components/renderer/form-collection-record-control.vue +248 -0
- package/src/components/renderer/form-collection-view-control.vue +236 -0
- package/src/components/renderer/form-masked-input.vue +194 -9
- package/src/components/renderer/form-record-list.vue +271 -69
- package/src/components/renderer/index.js +2 -0
- package/src/components/screen-renderer.vue +2 -0
- package/src/components/task.vue +3 -1
- package/src/components/vue-form-builder.vue +156 -22
- package/src/components/vue-form-renderer.vue +10 -2
- package/src/form-builder-controls.js +168 -21
- package/src/global-properties.js +8 -0
- package/src/main.js +60 -1
- package/src/mixins/Clipboard.js +153 -0
- package/src/mixins/ScreenBase.js +7 -1
- package/src/mixins/index.js +1 -0
- package/src/store/modules/ClipboardManager.js +79 -0
- package/src/store/modules/clipboardModule.js +210 -0
- package/src/stories/ClipboardButton.stories.js +66 -0
- package/src/stories/PagesDropdown.stories.js +11 -8
|
@@ -15,70 +15,98 @@
|
|
|
15
15
|
</button>
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
18
|
-
<div v-if="!value">
|
|
18
|
+
<div v-if="!value && !tableData.data">
|
|
19
19
|
{{ $t("This record list is empty or contains no data.") }}
|
|
20
20
|
</div>
|
|
21
21
|
<template v-else>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<template
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
22
|
+
<b-table
|
|
23
|
+
ref="vuetable"
|
|
24
|
+
:per-page="perPage"
|
|
25
|
+
:data-manager="dataManager"
|
|
26
|
+
:fields="tableFields"
|
|
27
|
+
:items="tableData.data"
|
|
28
|
+
:sort-compare-options="{ numeric: false }"
|
|
29
|
+
:sort-null-last="true"
|
|
30
|
+
sort-icon-left
|
|
31
|
+
:css="css"
|
|
32
|
+
:empty-text="$t('No Data Available')"
|
|
33
|
+
:current-page="currentPage"
|
|
34
|
+
data-cy="table"
|
|
35
|
+
>
|
|
36
|
+
<!-- Slot header for checkbox (Select All) -->
|
|
37
|
+
<template #head(checkbox)="data">
|
|
38
|
+
<b-form-checkbox
|
|
39
|
+
v-model="allRowsSelected"
|
|
40
|
+
@change="selectAllRows"
|
|
41
|
+
:indeterminate="indeterminate"
|
|
42
|
+
aria-label="Select All"
|
|
43
|
+
/>
|
|
44
44
|
</template>
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
|
|
46
|
+
<template #cell(checkbox)="{ index, item }">
|
|
47
|
+
<b-form-checkbox
|
|
48
|
+
v-model="selectedRows"
|
|
49
|
+
:value="item"
|
|
50
|
+
@change="onMultipleSelectionChange(index)"
|
|
51
|
+
/>
|
|
47
52
|
</template>
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
|
|
54
|
+
<template #cell(radio)="{ index, item }">
|
|
55
|
+
<b-form-radio
|
|
56
|
+
v-model="selectedRow"
|
|
57
|
+
:value="item"
|
|
58
|
+
@change="onRadioChange(item, index)"
|
|
59
|
+
|
|
60
|
+
/>
|
|
50
61
|
</template>
|
|
51
62
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
>
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
<template #cell()="{ index, field, item }">
|
|
64
|
+
|
|
65
|
+
<template v-if="isFiledownload(field, item)">
|
|
66
|
+
<span href="#" @click="downloadFile(item, field.key, index)">{{
|
|
67
|
+
mustache(field.key, item)
|
|
68
|
+
}}</span>
|
|
69
|
+
</template>
|
|
70
|
+
<template v-else-if="isImage(field, item)">
|
|
71
|
+
<img :src="mustache(field.key, item)" style="record-list-image" />
|
|
72
|
+
</template>
|
|
73
|
+
<template v-else-if="isWebEntryFile(field, item)">
|
|
74
|
+
{{ formatIfWebEntryFile(field, item) }}
|
|
75
|
+
</template>
|
|
76
|
+
<template v-else>
|
|
77
|
+
{{ formatIfDate(mustache(field.key, item)) }}
|
|
78
|
+
</template>
|
|
79
|
+
|
|
80
|
+
</template>
|
|
81
|
+
<template #cell(__actions)="{ index, item }">
|
|
82
|
+
<div class="actions">
|
|
83
|
+
<div
|
|
84
|
+
class="btn-group btn-group-sm"
|
|
85
|
+
role="group"
|
|
86
|
+
aria-label="Actions"
|
|
73
87
|
>
|
|
74
|
-
<
|
|
75
|
-
|
|
88
|
+
<button
|
|
89
|
+
class="btn btn-primary"
|
|
90
|
+
:title="$t('Edit')"
|
|
91
|
+
data-cy="edit-row"
|
|
92
|
+
@click="showEditForm(index, item.row_id)"
|
|
93
|
+
>
|
|
94
|
+
<i class="fas fa-edit" />
|
|
95
|
+
</button>
|
|
96
|
+
<button
|
|
97
|
+
class="btn btn-danger"
|
|
98
|
+
:title="$t('Delete')"
|
|
99
|
+
data-cy="remove-row"
|
|
100
|
+
@click="showDeleteConfirmation(index, item.row_id)"
|
|
101
|
+
>
|
|
102
|
+
<i class="fas fa-trash-alt" />
|
|
103
|
+
</button>
|
|
104
|
+
</div>
|
|
76
105
|
</div>
|
|
77
|
-
</
|
|
78
|
-
</
|
|
79
|
-
</b-table>
|
|
106
|
+
</template>
|
|
107
|
+
</b-table>
|
|
80
108
|
<b-pagination
|
|
81
|
-
v-if="tableData.total > perPage"
|
|
109
|
+
v-if="tableData.total > perPage && (perPage !== 0)"
|
|
82
110
|
v-model="currentPage"
|
|
83
111
|
data-cy="table-pagination"
|
|
84
112
|
:total-rows="tableData.total"
|
|
@@ -211,7 +239,9 @@ export default {
|
|
|
211
239
|
"formConfig",
|
|
212
240
|
"formComputed",
|
|
213
241
|
"formWatchers",
|
|
214
|
-
"_perPage"
|
|
242
|
+
"_perPage",
|
|
243
|
+
"source",
|
|
244
|
+
"paginationOption"
|
|
215
245
|
],
|
|
216
246
|
data() {
|
|
217
247
|
return {
|
|
@@ -242,10 +272,19 @@ export default {
|
|
|
242
272
|
}
|
|
243
273
|
},
|
|
244
274
|
initFormValues: {},
|
|
245
|
-
currentRowIndex: null
|
|
275
|
+
currentRowIndex: null,
|
|
276
|
+
collectionData: {},
|
|
277
|
+
selectedRow: null,
|
|
278
|
+
selectedRows: [],
|
|
279
|
+
selectedIndex: null,
|
|
280
|
+
rows: [],
|
|
281
|
+
selectAll: false
|
|
246
282
|
};
|
|
247
283
|
},
|
|
248
284
|
computed: {
|
|
285
|
+
indeterminate() {
|
|
286
|
+
return this.selectedRows.length > 0 && this.selectedRows.length < this.tableData.data.length;
|
|
287
|
+
},
|
|
249
288
|
popupConfig() {
|
|
250
289
|
const config = [];
|
|
251
290
|
config[this.form] = this.formConfig[this.form];
|
|
@@ -279,7 +318,14 @@ export default {
|
|
|
279
318
|
console.log("refs vuetable not exists");
|
|
280
319
|
},
|
|
281
320
|
tableData() {
|
|
282
|
-
const value = this.
|
|
321
|
+
const value = Array.isArray(this.collectionData) && this.collectionData.length
|
|
322
|
+
? this.collectionData
|
|
323
|
+
: (Array.isArray(this.value) ? this.value : []);
|
|
324
|
+
|
|
325
|
+
if(this.value) {
|
|
326
|
+
this.selectedIndex = this.value.selectedRowIndex;
|
|
327
|
+
}
|
|
328
|
+
|
|
283
329
|
const from = this.paginatorPage - 1;
|
|
284
330
|
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
|
285
331
|
this.lastPage = Math.ceil(value.length / this.perPage);
|
|
@@ -296,7 +342,23 @@ export default {
|
|
|
296
342
|
data: value,
|
|
297
343
|
lastSortConfig: false
|
|
298
344
|
};
|
|
299
|
-
|
|
345
|
+
|
|
346
|
+
// Enable Radio button selected when process finishes
|
|
347
|
+
if (this.selectedIndex !== null && this.selectedIndex < data.data.length) {
|
|
348
|
+
this.selectedRow = data.data[this.selectedIndex];
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
//Enable Checkbox selected when process finishes
|
|
352
|
+
if (Array.isArray(this.value) && this.value.length > 0) {
|
|
353
|
+
if(this.rows.length === 0) {
|
|
354
|
+
this.value.forEach(item => {
|
|
355
|
+
if (item.hasOwnProperty('selectedRowsIndex')) {
|
|
356
|
+
this.selectedRows.push(data.data[item.selectedRowsIndex]);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return data;
|
|
300
362
|
},
|
|
301
363
|
// The fields used for our vue table
|
|
302
364
|
tableFields() {
|
|
@@ -306,6 +368,23 @@ export default {
|
|
|
306
368
|
fields.push(jsonOptionsActionsColumn);
|
|
307
369
|
}
|
|
308
370
|
|
|
371
|
+
// Adds radio buttons or checkbox to the table depending selected option
|
|
372
|
+
if (['single-field', 'single-record'].includes(this.source?.dataSelectionOptions)) {
|
|
373
|
+
fields.unshift({
|
|
374
|
+
key: 'radio',
|
|
375
|
+
label: '',
|
|
376
|
+
sortable: false,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (this.source?.dataSelectionOptions === 'multiple-records') {
|
|
381
|
+
fields.unshift({
|
|
382
|
+
key: 'checkbox',
|
|
383
|
+
label: '',
|
|
384
|
+
sortable: false
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
|
|
309
388
|
return fields;
|
|
310
389
|
},
|
|
311
390
|
// Determines if the form used for add/edit is self referencing. If so, we should not show it
|
|
@@ -322,7 +401,7 @@ export default {
|
|
|
322
401
|
this.currentPage > totalPages ? totalPages : this.currentPage;
|
|
323
402
|
this.currentPage = this.currentPage == 0 ? 1 : this.currentPage;
|
|
324
403
|
}
|
|
325
|
-
}
|
|
404
|
+
},
|
|
326
405
|
},
|
|
327
406
|
mounted() {
|
|
328
407
|
if (this._perPage) {
|
|
@@ -332,8 +411,121 @@ export default {
|
|
|
332
411
|
this.updateRowDataNamePrefix,
|
|
333
412
|
100
|
|
334
413
|
);
|
|
414
|
+
|
|
415
|
+
if (this.paginationOption != null) {
|
|
416
|
+
this.perPage = this.paginationOption;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if(this.source?.sourceOptions === "Collection") {
|
|
420
|
+
this.onCollectionChange(this.source?.collectionFields?.collectionId, this.source?.collectionFields?.pmql);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
this.$root.$emit("record-list-option", this.source?.sourceOptions);
|
|
335
424
|
},
|
|
336
425
|
methods: {
|
|
426
|
+
selectAllRows() {
|
|
427
|
+
if (this.allRowsSelected) {
|
|
428
|
+
const updatedRows = this.tableData.data.map((item, index) => {
|
|
429
|
+
return {
|
|
430
|
+
...item,
|
|
431
|
+
selectedRowsIndex: index
|
|
432
|
+
};
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
this.selectedRows = updatedRows;
|
|
436
|
+
this.collectionData = updatedRows;
|
|
437
|
+
this.onMultipleSelectionChange();
|
|
438
|
+
} else {
|
|
439
|
+
this.selectedRows = [];
|
|
440
|
+
this.onMultipleSelectionChange();
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
componentOutput(data) {
|
|
444
|
+
this.$emit('input', data);
|
|
445
|
+
},
|
|
446
|
+
onRadioChange(selectedItem, index) {
|
|
447
|
+
const globalIndex = (this.currentPage - 1) * this.perPage + index;
|
|
448
|
+
if(this.source?.singleField) {
|
|
449
|
+
let valueOfColumn = selectedItem[this.source.singleField];
|
|
450
|
+
this.componentOutput(valueOfColumn);
|
|
451
|
+
} else {
|
|
452
|
+
selectedItem = { ...selectedItem, selectedRowIndex: globalIndex};
|
|
453
|
+
this.componentOutput(selectedItem);
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
onMultipleSelectionChange(selIndex) {
|
|
457
|
+
this.collectionData.forEach((item, index) => {
|
|
458
|
+
this.selectedRows.forEach((selectedItem) => {
|
|
459
|
+
// Compares both objects all keys and values
|
|
460
|
+
if (this.areObjectsEqual(selectedItem, item)) {
|
|
461
|
+
// Adds`selectedRowIndex` with index iteration
|
|
462
|
+
selectedItem.selectedRowsIndex = index;
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
this.componentOutput(this.selectedRows);
|
|
467
|
+
this.rows.push(selIndex);
|
|
468
|
+
},
|
|
469
|
+
areObjectsEqual(obj1, obj2) {
|
|
470
|
+
const keys1 = Object.keys(obj1);
|
|
471
|
+
const keys2 = Object.keys(obj2);
|
|
472
|
+
|
|
473
|
+
if (keys1.length !== keys2.length) return false;
|
|
474
|
+
|
|
475
|
+
return keys1.every(key => obj1[key] === obj2[key]);
|
|
476
|
+
},
|
|
477
|
+
onCollectionChange(collectionId,pmql) {
|
|
478
|
+
let param = {params:{pmql:pmql}};
|
|
479
|
+
let rowsCollection = [];
|
|
480
|
+
this.$dataProvider
|
|
481
|
+
.getCollectionRecordsList(collectionId, param)
|
|
482
|
+
.then((response) => {
|
|
483
|
+
rowsCollection = response.data;
|
|
484
|
+
|
|
485
|
+
this.changeCollectionColumns(rowsCollection,this.fields);
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
this.$emit('change', this.field);
|
|
489
|
+
},
|
|
490
|
+
changeCollectionColumns(collectionFieldsColumns,columnsSelected) {
|
|
491
|
+
|
|
492
|
+
const optionsList = columnsSelected.optionsList;
|
|
493
|
+
|
|
494
|
+
collectionFieldsColumns.forEach(column => {
|
|
495
|
+
let dataObject = column.data;
|
|
496
|
+
let newDataObject = {};
|
|
497
|
+
|
|
498
|
+
Object.keys(dataObject).forEach(dataKey => {
|
|
499
|
+
const matchingOption = optionsList.find(option => option.content === dataKey);
|
|
500
|
+
|
|
501
|
+
if (matchingOption) {
|
|
502
|
+
newDataObject[matchingOption.key] = dataObject[dataKey];
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
column.data = newDataObject;
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
this.setCollectionIntoList(collectionFieldsColumns);
|
|
510
|
+
|
|
511
|
+
},
|
|
512
|
+
setCollectionIntoList(arrayCollection) {
|
|
513
|
+
const result = [];
|
|
514
|
+
arrayCollection.forEach((row) => {
|
|
515
|
+
if (row.hasOwnProperty('data')) {
|
|
516
|
+
const dataObject = row.data;
|
|
517
|
+
const extracted = {};
|
|
518
|
+
|
|
519
|
+
for (const [key, value] of Object.entries(dataObject)) {
|
|
520
|
+
extracted[key] = value;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
result.push(extracted);
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
//sets Collection result(columns and rows) into this.collectionData
|
|
527
|
+
this.collectionData = result;
|
|
528
|
+
},
|
|
337
529
|
updateRowDataNamePrefix() {
|
|
338
530
|
this.setUploadDataNamePrefix(this.currentRowIndex);
|
|
339
531
|
},
|
|
@@ -377,21 +569,31 @@ export default {
|
|
|
377
569
|
} else if (this.addItem) {
|
|
378
570
|
rowId = this.addItem.row_id;
|
|
379
571
|
}
|
|
380
|
-
|
|
381
572
|
this.$root.$emit("set-upload-data-name", this, index, rowId);
|
|
382
573
|
},
|
|
383
574
|
getTableFieldsFromDataSource() {
|
|
384
575
|
const { jsonData, key, value, dataName } = this.fields;
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
576
|
+
|
|
577
|
+
let convertToVuetableFormat = {};
|
|
578
|
+
if(this.source?.sourceOptions === "Collection") {
|
|
579
|
+
convertToVuetableFormat = (option) => {
|
|
580
|
+
return {
|
|
581
|
+
key: option[key || "key"],
|
|
582
|
+
sortable: true,
|
|
583
|
+
label: option[key || "key"],
|
|
584
|
+
tdClass: "table-column"
|
|
585
|
+
};
|
|
393
586
|
};
|
|
394
|
-
}
|
|
587
|
+
} else {
|
|
588
|
+
convertToVuetableFormat = (option) => {
|
|
589
|
+
return {
|
|
590
|
+
key: option[key || "value"],
|
|
591
|
+
sortable: true,
|
|
592
|
+
label: option[value || "content"],
|
|
593
|
+
tdClass: "table-column"
|
|
594
|
+
};
|
|
595
|
+
};
|
|
596
|
+
}
|
|
395
597
|
|
|
396
598
|
return this.getValidFieldData(jsonData, dataName).map(
|
|
397
599
|
convertToVuetableFormat
|
|
@@ -19,3 +19,5 @@ export { default as FormAnalyticsChart } from "./form-analytics-chart.vue";
|
|
|
19
19
|
export { default as FormRequests } from "./form-requests.vue";
|
|
20
20
|
export { default as FormTasks } from "./form-tasks.vue";
|
|
21
21
|
export { default as LinkButton } from "./link-button.vue";
|
|
22
|
+
export { default as FormCollectionRecordControl } from "./form-collection-record-control.vue";
|
|
23
|
+
export { default as FormCollectionViewControl } from "./form-collection-view-control.vue";
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
:vdata="value"
|
|
40
40
|
:_parent="_parent || value._parent"
|
|
41
41
|
:_initial-page="currentPage"
|
|
42
|
+
:taskdraft="taskdraft"
|
|
42
43
|
@after-submit="afterSubmit"
|
|
43
44
|
@submit="submit"
|
|
44
45
|
@asyncWatcherTriggered="onAsyncWatcherOn"
|
|
@@ -70,6 +71,7 @@ export default {
|
|
|
70
71
|
type: String,
|
|
71
72
|
default: ""
|
|
72
73
|
},
|
|
74
|
+
taskdraft: Object
|
|
73
75
|
},
|
|
74
76
|
data() {
|
|
75
77
|
return {
|
package/src/components/task.vue
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
:watchers="screen.watchers"
|
|
32
32
|
:key="refreshScreen"
|
|
33
33
|
:loop-context="loopContext"
|
|
34
|
+
:taskdraft="this.task"
|
|
34
35
|
@update="onUpdate"
|
|
35
36
|
@after-submit="afterSubmit"
|
|
36
37
|
@submit="submit"
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
:watchers="screen.watchers"
|
|
50
51
|
:data="requestData"
|
|
51
52
|
:type="screen.type"
|
|
53
|
+
@update="onUpdate"
|
|
52
54
|
@after-submit="afterSubmit"
|
|
53
55
|
@submit="submit"
|
|
54
56
|
/>
|
|
@@ -471,7 +473,6 @@ export default {
|
|
|
471
473
|
|
|
472
474
|
return this.getSessionRedirectUrl();
|
|
473
475
|
} catch (error) {
|
|
474
|
-
console.error("Error in getDestinationUrl:", error);
|
|
475
476
|
return null;
|
|
476
477
|
}
|
|
477
478
|
}
|
|
@@ -1001,6 +1002,7 @@ export default {
|
|
|
1001
1002
|
this.requestData = this.value;
|
|
1002
1003
|
this.loopContext = this.initialLoopContext;
|
|
1003
1004
|
this.loadTask(true);
|
|
1005
|
+
this.setSelfService();
|
|
1004
1006
|
},
|
|
1005
1007
|
destroyed() {
|
|
1006
1008
|
this.unsubscribeSocketListeners();
|