@processmaker/screen-builder 2.94.0 → 2.95.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 +89 -66
- package/dist/vue-form-builder.es.js.map +1 -1
- package/dist/vue-form-builder.umd.js +7 -6
- 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 +45 -11
- package/src/components/vue-form-builder.vue +6 -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.95.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
|
},
|
|
@@ -455,6 +457,8 @@ 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
|
|
|
@@ -488,8 +492,8 @@ export default {
|
|
|
488
492
|
this.emitIfTaskCompleted(requestId);
|
|
489
493
|
}
|
|
490
494
|
this.taskId = task.id;
|
|
491
|
-
this.loadTask();
|
|
492
495
|
this.nodeId = task.element_id;
|
|
496
|
+
this.loadTask();
|
|
493
497
|
} else if (this.parentRequest && ['COMPLETED', 'CLOSED'].includes(this.task.process_request.status)) {
|
|
494
498
|
this.$emit('completed', this.getAllowedRequestId());
|
|
495
499
|
} else if (!this.taskPreview) {
|
|
@@ -543,10 +547,14 @@ export default {
|
|
|
543
547
|
this.task.interstitial_screen['_interstitial'] = true;
|
|
544
548
|
this.screen = this.task.interstitial_screen;
|
|
545
549
|
}
|
|
550
|
+
if (this.task.bpmn_tag_name === 'manualTask') {
|
|
551
|
+
this.checkTaskStatus();
|
|
552
|
+
this.reload();
|
|
553
|
+
}
|
|
546
554
|
},
|
|
547
555
|
onUpdate(data) {
|
|
548
556
|
this.$emit('input', data);
|
|
549
|
-
this.
|
|
557
|
+
this.setSelfService();
|
|
550
558
|
},
|
|
551
559
|
activityAssigned() {
|
|
552
560
|
// This may no longer be needed
|
|
@@ -688,10 +696,10 @@ export default {
|
|
|
688
696
|
},
|
|
689
697
|
processUpdated: _.debounce(function(data) {
|
|
690
698
|
if (
|
|
691
|
-
data.event
|
|
699
|
+
['ACTIVITY_ACTIVATED', 'ACTIVITY_COMPLETED'].includes(data.event)
|
|
692
700
|
&& data.elementType === 'task'
|
|
693
701
|
) {
|
|
694
|
-
if (!this.task
|
|
702
|
+
if (!this.task?.elementDestination?.type) {
|
|
695
703
|
this.taskId = data.taskId;
|
|
696
704
|
}
|
|
697
705
|
|
|
@@ -797,6 +805,30 @@ export default {
|
|
|
797
805
|
requestIdNode.setAttribute('content', this.requestId);
|
|
798
806
|
}
|
|
799
807
|
},
|
|
808
|
+
/**
|
|
809
|
+
* Checks for the presence of a URL action blocker in sessionStorage and handles it.
|
|
810
|
+
*
|
|
811
|
+
* This method retrieves the 'sessionUrlActionBlocker' value from sessionStorage,
|
|
812
|
+
* and if present, removes it and emits a 'closed' event with the task id and
|
|
813
|
+
* the source of the redirection. It returns false if the blocker was handled,
|
|
814
|
+
* and true otherwise.
|
|
815
|
+
*
|
|
816
|
+
* @returns {boolean} Returns false if the 'sessionUrlActionBlocker' was found and handled, true otherwise.
|
|
817
|
+
*/
|
|
818
|
+
hasUrlActionBlocker() {
|
|
819
|
+
// Retrieve the 'sessionUrlActionBlocker' value from sessionStorage
|
|
820
|
+
const redirectedFrom = sessionStorage.getItem("sessionUrlActionBlocker");
|
|
821
|
+
|
|
822
|
+
if (redirectedFrom) {
|
|
823
|
+
// Remove 'sessionUrlActionBlocker' from sessionStorage after retrieving its value
|
|
824
|
+
sessionStorage.removeItem("sessionUrlActionBlocker");
|
|
825
|
+
|
|
826
|
+
// Emit a 'closed' event with the task id and the source of the redirection
|
|
827
|
+
this.$emit("closed", this.task?.id, redirectedFrom);
|
|
828
|
+
return true;
|
|
829
|
+
}
|
|
830
|
+
return false;
|
|
831
|
+
},
|
|
800
832
|
|
|
801
833
|
},
|
|
802
834
|
mounted() {
|
|
@@ -807,7 +839,9 @@ export default {
|
|
|
807
839
|
this.nodeId = this.initialNodeId;
|
|
808
840
|
this.requestData = this.value;
|
|
809
841
|
this.loopContext = this.initialLoopContext;
|
|
810
|
-
this.
|
|
842
|
+
if (!this.hasUrlActionBlocker()) {
|
|
843
|
+
this.loadTask();
|
|
844
|
+
}
|
|
811
845
|
},
|
|
812
846
|
destroyed() {
|
|
813
847
|
this.unsubscribeSocketListeners();
|
|
@@ -647,10 +647,13 @@ 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.toLowerCase().includes(filter)) {
|
|
654
|
+
result = true;
|
|
655
|
+
}
|
|
656
|
+
return result;
|
|
654
657
|
});
|
|
655
658
|
|
|
656
659
|
return filtered;
|
package/src/main.js
CHANGED
|
@@ -38,6 +38,17 @@ Vue.component("Required", {
|
|
|
38
38
|
template: '<div class="text-right"><small>* = Required</small></div>'
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
+
// Mock PmqlInput for test/standalone
|
|
42
|
+
Vue.component("PmqlInput", {
|
|
43
|
+
props: {
|
|
44
|
+
value: {
|
|
45
|
+
type: String,
|
|
46
|
+
default: ""
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
template: '<div>PMQL: {{ value }}</div>'
|
|
50
|
+
});
|
|
51
|
+
|
|
41
52
|
const store = new Vuex.Store({
|
|
42
53
|
modules: {
|
|
43
54
|
globalErrorsModule,
|