@processmaker/screen-builder 2.94.0 → 2.96.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 +883 -772
- package/dist/vue-form-builder.es.js.map +1 -1
- package/dist/vue-form-builder.umd.js +32 -31
- package/dist/vue-form-builder.umd.js.map +1 -1
- package/package.json +3 -3
- package/src/DataProvider.js +1 -1
- package/src/ValidationsFactory.js +4 -0
- package/src/components/renderer/form-list-table.vue +17 -36
- package/src/components/renderer/form-requests.vue +15 -3
- package/src/components/renderer/form-tasks.vue +16 -6
- package/src/components/screen-renderer.vue +1 -1
- package/src/components/task.vue +187 -46
- package/src/components/vue-form-builder.vue +10 -3
- package/src/components/vue-form-renderer.vue +1 -1
- package/src/main.js +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@processmaker/screen-builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.96.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "VITE_COVERAGE=true vite",
|
|
6
6
|
"build": "vite build",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@fortawesome/fontawesome-free": "^5.6.1",
|
|
57
57
|
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
|
58
58
|
"@panter/vue-i18next": "^0.15.2",
|
|
59
|
-
"@processmaker/vue-form-elements": "0.
|
|
59
|
+
"@processmaker/vue-form-elements": "0.59.0",
|
|
60
60
|
"@processmaker/vue-multiselect": "2.3.0",
|
|
61
61
|
"@storybook/addon-essentials": "^7.6.13",
|
|
62
62
|
"@storybook/addon-interactions": "^7.6.13",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
},
|
|
116
116
|
"peerDependencies": {
|
|
117
117
|
"@panter/vue-i18next": "^0.15.0",
|
|
118
|
-
"@processmaker/vue-form-elements": "0.
|
|
118
|
+
"@processmaker/vue-form-elements": "0.59.0",
|
|
119
119
|
"i18next": "^15.0.8",
|
|
120
120
|
"vue": "^2.6.12",
|
|
121
121
|
"vuex": "^3.1.1"
|
package/src/DataProvider.js
CHANGED
|
@@ -199,7 +199,7 @@ export default {
|
|
|
199
199
|
!window.ProcessMaker.screen.cacheEnabled &&
|
|
200
200
|
!window.ProcessMaker.screen.cacheTimeout
|
|
201
201
|
) {
|
|
202
|
-
return this.postDataSource(dataSourceId, null, params);
|
|
202
|
+
return this.postDataSource(dataSourceId, null, params).then(r => [r, nonce]);
|
|
203
203
|
}
|
|
204
204
|
let url = `/requests/data_sources/${dataSourceId}/resources/${params.config.endpoint}/data`;
|
|
205
205
|
url += this.authQueryString();
|
|
@@ -240,6 +240,10 @@ class PageNavigateValidations extends Validations {
|
|
|
240
240
|
*/
|
|
241
241
|
class FormElementValidations extends Validations {
|
|
242
242
|
async addValidations(validations) {
|
|
243
|
+
// Disable validations if field is hidden
|
|
244
|
+
if (!this.isVisible()) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
243
247
|
if (this.element.config && this.element.config.readonly) {
|
|
244
248
|
//readonly elements do not need validation
|
|
245
249
|
return;
|
|
@@ -10,11 +10,7 @@
|
|
|
10
10
|
{{ $t(title) }}
|
|
11
11
|
</p>
|
|
12
12
|
<template v-if="dataControl.dropdownShow === 'requests'">
|
|
13
|
-
<b-dropdown
|
|
14
|
-
variant="outline-secondary"
|
|
15
|
-
offset="-70"
|
|
16
|
-
no-caret
|
|
17
|
-
>
|
|
13
|
+
<b-dropdown variant="outline-secondary" offset="-70" no-caret>
|
|
18
14
|
<template #button-content>
|
|
19
15
|
<i class="fas fa-caret-down" />
|
|
20
16
|
</template>
|
|
@@ -26,7 +22,9 @@
|
|
|
26
22
|
</span>
|
|
27
23
|
</b-dropdown-item>
|
|
28
24
|
<b-dropdown-item
|
|
29
|
-
@click="
|
|
25
|
+
@click="
|
|
26
|
+
handleDropdownSelection('requests_filter', 'as_participant')
|
|
27
|
+
"
|
|
30
28
|
>
|
|
31
29
|
<span class="item-text">
|
|
32
30
|
{{ $t("As Participant") }}
|
|
@@ -42,11 +40,7 @@
|
|
|
42
40
|
<div class="ml-auto d-flex align-items-center">
|
|
43
41
|
<template v-if="dataControl.dropdownShow === 'requests'">
|
|
44
42
|
<div class="mr-4">
|
|
45
|
-
<b-dropdown
|
|
46
|
-
variant="outline-secondary"
|
|
47
|
-
offset="-50"
|
|
48
|
-
size="sm"
|
|
49
|
-
>
|
|
43
|
+
<b-dropdown variant="outline-secondary" offset="-50" size="sm">
|
|
50
44
|
<template #button-content>
|
|
51
45
|
<span class="text-capitalize">
|
|
52
46
|
{{ $t(titleDropdown) }}
|
|
@@ -66,11 +60,7 @@
|
|
|
66
60
|
</template>
|
|
67
61
|
<template v-if="dataControl.dropdownShow === 'tasks'">
|
|
68
62
|
<div class="mr-4">
|
|
69
|
-
<b-dropdown
|
|
70
|
-
variant="outline-secondary"
|
|
71
|
-
offset="-50"
|
|
72
|
-
size="sm"
|
|
73
|
-
>
|
|
63
|
+
<b-dropdown variant="outline-secondary" offset="-50" size="sm">
|
|
74
64
|
<template #button-content>
|
|
75
65
|
<span class="text-capitalize">
|
|
76
66
|
{{ $t(titleDropdown) }}
|
|
@@ -82,7 +72,7 @@
|
|
|
82
72
|
@click="handleDropdownSelection('tasks', option)"
|
|
83
73
|
>
|
|
84
74
|
<span class="item-text">
|
|
85
|
-
|
|
75
|
+
{{ $t(option) }}
|
|
86
76
|
</span>
|
|
87
77
|
</b-dropdown-item>
|
|
88
78
|
</b-dropdown>
|
|
@@ -122,7 +112,6 @@
|
|
|
122
112
|
</div>
|
|
123
113
|
<div class="card-body list-table">
|
|
124
114
|
<template v-if="listOption === 'My Tasks'">
|
|
125
|
-
<Recommendations :dashboard="true" />
|
|
126
115
|
<FormTasks @tasksCount="getData"></FormTasks>
|
|
127
116
|
</template>
|
|
128
117
|
<template v-if="verifyListCase()">
|
|
@@ -140,12 +129,8 @@ import FormTasks from "./form-tasks.vue";
|
|
|
140
129
|
import FormRequests from "./form-requests.vue";
|
|
141
130
|
import FormNewRequest from "./form-new-request.vue";
|
|
142
131
|
|
|
143
|
-
const Recommendations = (resolve) => {
|
|
144
|
-
resolve(window.SharedComponents?.Recommendations || { template: "<span></span>" });
|
|
145
|
-
};
|
|
146
|
-
|
|
147
132
|
export default {
|
|
148
|
-
components: { FormTasks, FormRequests, FormNewRequest
|
|
133
|
+
components: { FormTasks, FormRequests, FormNewRequest },
|
|
149
134
|
mixins: [],
|
|
150
135
|
props: ["listOption"],
|
|
151
136
|
data() {
|
|
@@ -170,11 +155,7 @@ export default {
|
|
|
170
155
|
"Overdue",
|
|
171
156
|
"View All"
|
|
172
157
|
],
|
|
173
|
-
requestFilterDropdown: [
|
|
174
|
-
"View All",
|
|
175
|
-
"Completed",
|
|
176
|
-
"In Progress",
|
|
177
|
-
]
|
|
158
|
+
requestFilterDropdown: ["View All", "Completed", "In Progress"]
|
|
178
159
|
};
|
|
179
160
|
},
|
|
180
161
|
watch: {
|
|
@@ -331,8 +312,8 @@ export default {
|
|
|
331
312
|
}
|
|
332
313
|
|
|
333
314
|
.item-text {
|
|
334
|
-
color: #
|
|
335
|
-
font-family:
|
|
315
|
+
color: #42526e;
|
|
316
|
+
font-family: "Open Sans", sans-serif;
|
|
336
317
|
font-size: 14px;
|
|
337
318
|
font-weight: 400;
|
|
338
319
|
line-height: 21px;
|
|
@@ -343,13 +324,13 @@ export default {
|
|
|
343
324
|
.dropdown-menu {
|
|
344
325
|
padding: 0px;
|
|
345
326
|
width: 180px;
|
|
346
|
-
box-shadow: 0px 4px 8px 0px #
|
|
327
|
+
box-shadow: 0px 4px 8px 0px #0000001a;
|
|
347
328
|
border-radius: 4px;
|
|
348
329
|
}
|
|
349
330
|
|
|
350
331
|
.dropdown-item {
|
|
351
332
|
padding: 13px 12px;
|
|
352
|
-
font-family:
|
|
333
|
+
font-family: "Open Sans", sans-serif;
|
|
353
334
|
font-size: 16px;
|
|
354
335
|
font-weight: 400;
|
|
355
336
|
line-height: 21.79px;
|
|
@@ -361,10 +342,10 @@ export default {
|
|
|
361
342
|
.btn-outline-secondary:not(:disabled):not(.disabled):active,
|
|
362
343
|
.btn-outline-secondary:not(:disabled):not(.disabled).active,
|
|
363
344
|
.show > .btn-outline-secondary.dropdown-toggle {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
345
|
+
background: none;
|
|
346
|
+
color: #228fed;
|
|
347
|
+
border: none;
|
|
348
|
+
box-shadow: none;
|
|
368
349
|
}
|
|
369
350
|
|
|
370
351
|
.head-filter {
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
<td
|
|
12
12
|
v-for="(header, colIndex) in tableHeaders"
|
|
13
13
|
:key="`${rowIndex}-${colIndex}`"
|
|
14
|
+
:class="{
|
|
15
|
+
'pm-table-filter-applied-tbody': header.sortAsc || header.sortDesc
|
|
16
|
+
}"
|
|
14
17
|
>
|
|
15
18
|
<template v-if="containsHTML(getNestedPropertyValue(row, header))">
|
|
16
19
|
<div
|
|
@@ -24,6 +27,10 @@
|
|
|
24
27
|
v-if="header.truncate"
|
|
25
28
|
:target="`element-${rowIndex}-${colIndex}`"
|
|
26
29
|
custom-class="pm-table-tooltip"
|
|
30
|
+
placement="topright"
|
|
31
|
+
trigger="hover"
|
|
32
|
+
boundary="viewport"
|
|
33
|
+
:delay="{ show: 0, hide: 0 }"
|
|
27
34
|
@show="checkIfTooltipIsNeeded"
|
|
28
35
|
>
|
|
29
36
|
{{ sanitizeTooltip(getNestedPropertyValue(row, header)) }}
|
|
@@ -47,6 +54,10 @@
|
|
|
47
54
|
v-if="header.truncate"
|
|
48
55
|
:target="`element-${rowIndex}-${colIndex}`"
|
|
49
56
|
custom-class="pm-table-tooltip"
|
|
57
|
+
placement="topright"
|
|
58
|
+
trigger="hover"
|
|
59
|
+
boundary="viewport"
|
|
60
|
+
:delay="{ show: 0, hide: 0 }"
|
|
50
61
|
@show="checkIfTooltipIsNeeded"
|
|
51
62
|
>
|
|
52
63
|
{{ getNestedPropertyValue(row, header) }}
|
|
@@ -91,7 +102,7 @@ export default {
|
|
|
91
102
|
direction: "desc"
|
|
92
103
|
}
|
|
93
104
|
],
|
|
94
|
-
tableHeaders: []
|
|
105
|
+
tableHeaders: []
|
|
95
106
|
};
|
|
96
107
|
},
|
|
97
108
|
computed: {
|
|
@@ -210,8 +221,9 @@ export default {
|
|
|
210
221
|
if (option === "case_title") {
|
|
211
222
|
attr[option] = value.case_title_formatted || value.case_title || "";
|
|
212
223
|
}
|
|
213
|
-
return
|
|
214
|
-
|
|
224
|
+
return `
|
|
225
|
+
<a href="${this.openRequest(value)}" class="text-nowrap custom-wrap"
|
|
226
|
+
target="_blank">${attr[option]}</a>`;
|
|
215
227
|
},
|
|
216
228
|
openRequest(data) {
|
|
217
229
|
return `/requests/${data.id}`;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div v-if="showTable">
|
|
3
|
+
<Recommendations :dashboard="true" />
|
|
3
4
|
<filter-table
|
|
4
5
|
table-name="form-tasks"
|
|
5
6
|
:headers="tableHeaders"
|
|
@@ -137,8 +138,15 @@ import datatableMixin from "../../mixins/datatable";
|
|
|
137
138
|
import formEmpty from "./form-empty-table.vue";
|
|
138
139
|
|
|
139
140
|
const uniqIdsMixin = createUniqIdsMixin();
|
|
141
|
+
|
|
142
|
+
const Recommendations = (resolve) => {
|
|
143
|
+
resolve(
|
|
144
|
+
window.SharedComponents?.Recommendations || { template: "<span></span>" }
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
140
148
|
export default {
|
|
141
|
-
components: { formEmpty },
|
|
149
|
+
components: { formEmpty, Recommendations },
|
|
142
150
|
mixins: [uniqIdsMixin, datatableMixin],
|
|
143
151
|
data() {
|
|
144
152
|
return {
|
|
@@ -162,10 +170,8 @@ export default {
|
|
|
162
170
|
}
|
|
163
171
|
],
|
|
164
172
|
advancedFilter: "",
|
|
165
|
-
tasksPreview:
|
|
166
|
-
|
|
167
|
-
taskTooltip:
|
|
168
|
-
(window.SharedComponents && window.SharedComponents.TaskTooltip) || {},
|
|
173
|
+
tasksPreview: window.SharedComponents?.TasksHome || {},
|
|
174
|
+
taskTooltip: window.SharedComponents?.TaskTooltip || {},
|
|
169
175
|
rowPosition: {},
|
|
170
176
|
ellipsisShow: false,
|
|
171
177
|
isTooltipVisible: false,
|
|
@@ -568,7 +574,11 @@ export default {
|
|
|
568
574
|
|
|
569
575
|
const rightBorderX = rect.right;
|
|
570
576
|
|
|
571
|
-
|
|
577
|
+
let bottomBorderY = yPosition - topAdjust - elementHeight + 100;
|
|
578
|
+
|
|
579
|
+
if (document.getElementsByClassName("recommendation").length > 0) {
|
|
580
|
+
bottomBorderY += 60;
|
|
581
|
+
}
|
|
572
582
|
|
|
573
583
|
this.rowPosition = {
|
|
574
584
|
x: rightBorderX,
|
package/src/components/task.vue
CHANGED
|
@@ -7,15 +7,16 @@
|
|
|
7
7
|
>
|
|
8
8
|
<template v-if="screen">
|
|
9
9
|
<b-overlay
|
|
10
|
-
:show="disabled"
|
|
10
|
+
:show="disabled || isSelfService"
|
|
11
11
|
id="overlay-background"
|
|
12
|
-
variant="white"
|
|
12
|
+
:variant="isSelfService ? 'white' : 'transparent'"
|
|
13
|
+
:blur="null"
|
|
13
14
|
cardStyles="pointer-events: none;pointer-events: none;inset: 1px"
|
|
14
15
|
rounded="sm"
|
|
15
16
|
>
|
|
16
17
|
<template #overlay>
|
|
17
18
|
<div class="text-center">
|
|
18
|
-
<p>Please claim this task to continue.</p>
|
|
19
|
+
<p v-if="isSelfService">Please claim this task to continue.</p>
|
|
19
20
|
</div>
|
|
20
21
|
</template>
|
|
21
22
|
<div class="card card-body border-top-0 h-100" :class="screenTypeClass">
|
|
@@ -124,6 +125,7 @@ export default {
|
|
|
124
125
|
loadingButton: false,
|
|
125
126
|
loadingTask: false,
|
|
126
127
|
loadingListeners: this.waitLoadingListeners,
|
|
128
|
+
isSelfService: false,
|
|
127
129
|
};
|
|
128
130
|
},
|
|
129
131
|
watch: {
|
|
@@ -359,12 +361,12 @@ export default {
|
|
|
359
361
|
}
|
|
360
362
|
this.prepareTask();
|
|
361
363
|
},
|
|
362
|
-
|
|
364
|
+
setSelfService() {
|
|
363
365
|
this.$nextTick(() => {
|
|
364
366
|
if (window.ProcessMaker.isSelfService) {
|
|
365
|
-
this.
|
|
367
|
+
this.isSelfService = true;
|
|
366
368
|
} else {
|
|
367
|
-
this.
|
|
369
|
+
this.isSelfService = false;
|
|
368
370
|
}
|
|
369
371
|
});
|
|
370
372
|
},
|
|
@@ -446,7 +448,7 @@ export default {
|
|
|
446
448
|
return `/tasks/${firstTask.id}/edit`;
|
|
447
449
|
}
|
|
448
450
|
|
|
449
|
-
return
|
|
451
|
+
return this.getSessionRedirectUrl();
|
|
450
452
|
} catch (error) {
|
|
451
453
|
console.error("Error in getDestinationUrl:", error);
|
|
452
454
|
return null;
|
|
@@ -455,13 +457,35 @@ export default {
|
|
|
455
457
|
|
|
456
458
|
const elementDestinationUrl = elementDestination.value;
|
|
457
459
|
if (elementDestinationUrl) {
|
|
460
|
+
// Save the referring URL to sessionStorage for future verification
|
|
461
|
+
sessionStorage.setItem('sessionUrlActionBlocker', document.referrer);
|
|
458
462
|
return elementDestinationUrl;
|
|
459
463
|
}
|
|
460
464
|
|
|
461
465
|
const sessionStorageUrl = sessionStorage.getItem("elementDestinationURL");
|
|
462
466
|
return sessionStorageUrl || null;
|
|
463
467
|
},
|
|
468
|
+
/**
|
|
469
|
+
* Retrieves the URL from the session storage or the document referrer.
|
|
470
|
+
*
|
|
471
|
+
* This method is used to determine the source of the redirection when the task is claimed.
|
|
472
|
+
* It retrieves the 'sessionUrlSelfService' value from sessionStorage, and if present, removes it.
|
|
473
|
+
* If the value is not found, it returns the document referrer.
|
|
474
|
+
*
|
|
475
|
+
* @returns {string|null} - The URL from the session storage or the document referrer.
|
|
476
|
+
*/
|
|
477
|
+
getSessionRedirectUrl() {
|
|
478
|
+
const urlSelfService = sessionStorage.getItem('sessionUrlSelfService');
|
|
479
|
+
|
|
480
|
+
if (urlSelfService) {
|
|
481
|
+
// Remove 'sessionUrlSelfService' from sessionStorage after retrieving its value
|
|
482
|
+
sessionStorage.removeItem('sessionUrlSelfService');
|
|
483
|
+
// Emit the source of the redirection
|
|
484
|
+
return urlSelfService;
|
|
485
|
+
}
|
|
464
486
|
|
|
487
|
+
return document.referrer || null;
|
|
488
|
+
},
|
|
465
489
|
loadNextAssignedTask(requestId = null) {
|
|
466
490
|
if (!requestId) {
|
|
467
491
|
requestId = this.requestId;
|
|
@@ -488,8 +512,8 @@ export default {
|
|
|
488
512
|
this.emitIfTaskCompleted(requestId);
|
|
489
513
|
}
|
|
490
514
|
this.taskId = task.id;
|
|
491
|
-
this.loadTask();
|
|
492
515
|
this.nodeId = task.element_id;
|
|
516
|
+
this.loadTask();
|
|
493
517
|
} else if (this.parentRequest && ['COMPLETED', 'CLOSED'].includes(this.task.process_request.status)) {
|
|
494
518
|
this.$emit('completed', this.getAllowedRequestId());
|
|
495
519
|
} else if (!this.taskPreview) {
|
|
@@ -543,10 +567,14 @@ export default {
|
|
|
543
567
|
this.task.interstitial_screen['_interstitial'] = true;
|
|
544
568
|
this.screen = this.task.interstitial_screen;
|
|
545
569
|
}
|
|
570
|
+
if (this.task.bpmn_tag_name === 'manualTask') {
|
|
571
|
+
this.checkTaskStatus();
|
|
572
|
+
this.reload();
|
|
573
|
+
}
|
|
546
574
|
},
|
|
547
575
|
onUpdate(data) {
|
|
548
576
|
this.$emit('input', data);
|
|
549
|
-
this.
|
|
577
|
+
this.setSelfService();
|
|
550
578
|
},
|
|
551
579
|
activityAssigned() {
|
|
552
580
|
// This may no longer be needed
|
|
@@ -557,9 +585,6 @@ export default {
|
|
|
557
585
|
requestId = this.getAllowedRequestId();
|
|
558
586
|
this.$emit('completed', requestId);
|
|
559
587
|
}
|
|
560
|
-
if (requestId !== this.requestId) {
|
|
561
|
-
this.processCompletedRedirect(data, this.userId, this.requestId);
|
|
562
|
-
}
|
|
563
588
|
},
|
|
564
589
|
/**
|
|
565
590
|
* Makes an API call with retry logic.
|
|
@@ -641,11 +666,11 @@ export default {
|
|
|
641
666
|
try {
|
|
642
667
|
// Verify if is not anotherProcess type
|
|
643
668
|
if (data.endEventDestination.type !== "anotherProcess") {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
669
|
+
if (data?.endEventDestination.value) {
|
|
670
|
+
window.location.href = data?.endEventDestination.value;
|
|
671
|
+
} else {
|
|
672
|
+
window.location.href = `/requests/${this.requestId}`;
|
|
673
|
+
}
|
|
649
674
|
return;
|
|
650
675
|
}
|
|
651
676
|
// Parse endEventDestination from the provided data
|
|
@@ -671,9 +696,9 @@ export default {
|
|
|
671
696
|
// Handle the first task from the response
|
|
672
697
|
const firstTask = response.data.data[0];
|
|
673
698
|
if (firstTask && firstTask.user_id === userId) {
|
|
674
|
-
this
|
|
699
|
+
this.redirectToTask(firstTask.id);
|
|
675
700
|
} else {
|
|
676
|
-
this
|
|
701
|
+
this.redirectToRequest(requestId);
|
|
677
702
|
}
|
|
678
703
|
} catch (error) {
|
|
679
704
|
console.error("Error processing completed redirect:", error);
|
|
@@ -686,47 +711,139 @@ export default {
|
|
|
686
711
|
const allowed = permission && permission.allowed;
|
|
687
712
|
return allowed ? this.parentRequest : this.requestId
|
|
688
713
|
},
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
714
|
+
redirectToTask(tokenId) {
|
|
715
|
+
this.$emit('redirect', tokenId);
|
|
716
|
+
},
|
|
717
|
+
redirectToRequest(requestId) {
|
|
718
|
+
window.location.href = `/requests/${requestId}`;
|
|
719
|
+
},
|
|
720
|
+
/**
|
|
721
|
+
* Initializes socket listeners for process updates and redirects.
|
|
722
|
+
* This method sets up listeners to handle specific events and reloads
|
|
723
|
+
* the task if necessary.
|
|
724
|
+
*/
|
|
725
|
+
initSocketListeners() {
|
|
726
|
+
this.addProcessUpdateListener();
|
|
727
|
+
this.addRedirectListener();
|
|
728
|
+
this.loadingListeners = false;
|
|
697
729
|
|
|
730
|
+
// Reload to check if there's a task waiting, in case an event was missed
|
|
731
|
+
if (!this.taskId) {
|
|
698
732
|
this.reload();
|
|
699
733
|
}
|
|
734
|
+
},
|
|
700
735
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
this.loadingListeners = false;
|
|
736
|
+
/**
|
|
737
|
+
* Adds a socket listener for process updates.
|
|
738
|
+
* Listens for specific events related to the process and triggers appropriate actions.
|
|
739
|
+
*/
|
|
740
|
+
addProcessUpdateListener() {
|
|
707
741
|
this.addSocketListener(
|
|
708
|
-
`
|
|
742
|
+
`updated-${this.requestId}`,
|
|
709
743
|
`ProcessMaker.Models.ProcessRequest.${this.requestId}`,
|
|
710
|
-
'.
|
|
711
|
-
(data) =>
|
|
712
|
-
this.processCompleted(data);
|
|
713
|
-
}
|
|
744
|
+
'.ProcessUpdated',
|
|
745
|
+
(data) => this.handleProcessUpdate(data)
|
|
714
746
|
);
|
|
747
|
+
},
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Handles process update events.
|
|
751
|
+
* Emits an error if an activity exception event is detected.
|
|
752
|
+
*
|
|
753
|
+
* @param {Object} data - The event data received from the socket listener.
|
|
754
|
+
*/
|
|
755
|
+
handleProcessUpdate(data) {
|
|
756
|
+
if (data.event === 'ACTIVITY_EXCEPTION') {
|
|
757
|
+
this.$emit('error', this.requestId);
|
|
758
|
+
window.location.href = `/requests/${this.requestId}`;
|
|
759
|
+
}
|
|
760
|
+
},
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* Adds a socket listener for redirect events.
|
|
764
|
+
* Listens for specific redirect actions and handles them according to the method provided.
|
|
765
|
+
*/
|
|
766
|
+
addRedirectListener() {
|
|
715
767
|
this.addSocketListener(
|
|
716
|
-
`
|
|
768
|
+
`redirect-${this.requestId}`,
|
|
717
769
|
`ProcessMaker.Models.ProcessRequest.${this.requestId}`,
|
|
718
|
-
'.
|
|
719
|
-
(data) =>
|
|
720
|
-
this.processUpdated(data);
|
|
721
|
-
}
|
|
770
|
+
'.RedirectTo',
|
|
771
|
+
(data) => this.handleRedirect(data)
|
|
722
772
|
);
|
|
773
|
+
},
|
|
723
774
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
775
|
+
/**
|
|
776
|
+
* Handles redirect events based on the method provided in the event data.
|
|
777
|
+
* Calls specific handlers for different redirect methods or falls back to a default redirect.
|
|
778
|
+
*
|
|
779
|
+
* @param {Object} data - The event data received from the socket listener.
|
|
780
|
+
*/
|
|
781
|
+
handleRedirect(data) {
|
|
782
|
+
switch (data.method) {
|
|
783
|
+
case 'redirectToTask':
|
|
784
|
+
this.handleRedirectToTask(data);
|
|
785
|
+
break;
|
|
786
|
+
case 'processUpdated':
|
|
787
|
+
this.handleProcessUpdated(data);
|
|
788
|
+
break;
|
|
789
|
+
case 'processCompletedRedirect':
|
|
790
|
+
this.processCompletedRedirect(
|
|
791
|
+
data.params[0],
|
|
792
|
+
this.userId,
|
|
793
|
+
this.requestId
|
|
794
|
+
);
|
|
795
|
+
break;
|
|
796
|
+
default:
|
|
797
|
+
this.handleDefaultRedirect(data);
|
|
798
|
+
}
|
|
799
|
+
},
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Handles the 'redirectToTask' event by loading the specified task.
|
|
803
|
+
* Updates the current task ID and reloads the task data.
|
|
804
|
+
*
|
|
805
|
+
* @param {Object} data - The event data containing the tokenId of the task.
|
|
806
|
+
*/
|
|
807
|
+
handleRedirectToTask(data) {
|
|
808
|
+
|
|
809
|
+
if (data?.params[0]?.tokenId) {
|
|
810
|
+
this.loadingTask = true;
|
|
811
|
+
this.taskId = data.params[0].tokenId;
|
|
727
812
|
this.reload();
|
|
728
813
|
}
|
|
729
814
|
},
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* Handles the 'processUpdated' event by checking the event type and updating the task if necessary.
|
|
818
|
+
* Reloads the task data if the event is relevant.
|
|
819
|
+
*
|
|
820
|
+
* @param {Object} data - The event data containing the process update information.
|
|
821
|
+
*/
|
|
822
|
+
handleProcessUpdated(data) {
|
|
823
|
+
if (
|
|
824
|
+
['ACTIVITY_ACTIVATED', 'ACTIVITY_COMPLETED'].includes(data.event)
|
|
825
|
+
&& data.elementType === 'task'
|
|
826
|
+
) {
|
|
827
|
+
if (!this.task.elementDestination?.type) {
|
|
828
|
+
this.taskId = data.taskId;
|
|
829
|
+
}
|
|
830
|
+
this.reload();
|
|
831
|
+
}
|
|
832
|
+
if (data.event === 'ACTIVITY_EXCEPTION') {
|
|
833
|
+
this.$emit('error', this.requestId);
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Handles the default redirect action by logging a warning and redirecting the user to the request page.
|
|
839
|
+
*
|
|
840
|
+
* @param {Object} data - The event data that triggered the default redirect.
|
|
841
|
+
*/
|
|
842
|
+
handleDefaultRedirect(data) {
|
|
843
|
+
console.warn('redirect', data);
|
|
844
|
+
window.location.href = `/requests/${this.requestId}`;
|
|
845
|
+
},
|
|
846
|
+
|
|
730
847
|
existsEventMessage(id, data) {
|
|
731
848
|
if (sessionStorage.getItem(id)) {
|
|
732
849
|
return true;
|
|
@@ -797,6 +914,30 @@ export default {
|
|
|
797
914
|
requestIdNode.setAttribute('content', this.requestId);
|
|
798
915
|
}
|
|
799
916
|
},
|
|
917
|
+
/**
|
|
918
|
+
* Checks for the presence of a URL action blocker in sessionStorage and handles it.
|
|
919
|
+
*
|
|
920
|
+
* This method retrieves the 'sessionUrlActionBlocker' value from sessionStorage,
|
|
921
|
+
* and if present, removes it and emits a 'closed' event with the task id and
|
|
922
|
+
* the source of the redirection. It returns false if the blocker was handled,
|
|
923
|
+
* and true otherwise.
|
|
924
|
+
*
|
|
925
|
+
* @returns {boolean} Returns false if the 'sessionUrlActionBlocker' was found and handled, true otherwise.
|
|
926
|
+
*/
|
|
927
|
+
hasUrlActionBlocker() {
|
|
928
|
+
// Retrieve the 'sessionUrlActionBlocker' value from sessionStorage
|
|
929
|
+
const redirectedFrom = sessionStorage.getItem("sessionUrlActionBlocker");
|
|
930
|
+
|
|
931
|
+
if (redirectedFrom) {
|
|
932
|
+
// Remove 'sessionUrlActionBlocker' from sessionStorage after retrieving its value
|
|
933
|
+
sessionStorage.removeItem("sessionUrlActionBlocker");
|
|
934
|
+
|
|
935
|
+
// Emit a 'closed' event with the task id and the source of the redirection
|
|
936
|
+
this.$emit("closed", this.task?.id, redirectedFrom);
|
|
937
|
+
return true;
|
|
938
|
+
}
|
|
939
|
+
return false;
|
|
940
|
+
},
|
|
800
941
|
|
|
801
942
|
},
|
|
802
943
|
mounted() {
|
|
@@ -647,10 +647,17 @@ export default {
|
|
|
647
647
|
|
|
648
648
|
const excludedLabels = [""];
|
|
649
649
|
|
|
650
|
+
let filter = this.filterQuery.toLowerCase();
|
|
650
651
|
const filtered = this.controls.filter((control) => {
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
652
|
+
let result = control.label.toLowerCase().includes(filter);
|
|
653
|
+
if (!control.group) {
|
|
654
|
+
// If the group is not defined
|
|
655
|
+
control.group = 'Advanced';
|
|
656
|
+
}
|
|
657
|
+
if (control.group.toLowerCase().includes(filter)) {
|
|
658
|
+
result = true;
|
|
659
|
+
}
|
|
660
|
+
return result;
|
|
654
661
|
});
|
|
655
662
|
|
|
656
663
|
return filtered;
|