@processmaker/screen-builder 3.0.2 → 3.0.3
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 +1576 -1506
- package/dist/vue-form-builder.es.js.map +1 -1
- package/dist/vue-form-builder.umd.js +37 -37
- package/dist/vue-form-builder.umd.js.map +1 -1
- package/package.json +3 -3
- package/src/components/ScreenTemplateCard.vue +4 -2
- package/src/components/editor/loop.vue +26 -0
- package/src/components/editor/multi-column.vue +26 -0
- package/src/components/inspector/collection-data-source.vue +3 -0
- package/src/components/inspector/collection-designer-mode.vue +9 -1
- package/src/components/inspector/encrypted-config.vue +1 -1
- package/src/components/renderer/file-upload.vue +31 -1
- package/src/components/renderer/form-collection-record-control.vue +5 -4
- package/src/components/renderer/form-collection-view-control.vue +2 -2
- package/src/components/renderer/form-masked-input.vue +7 -5
- package/src/components/task.vue +81 -38
- package/src/components/vue-form-builder.vue +36 -2
- package/src/main.js +8 -0
- package/src/mixins/Clipboard.js +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@processmaker/screen-builder",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "VITE_COVERAGE=true vite",
|
|
6
6
|
"build": "vite build",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"@fortawesome/fontawesome-free": "^5.6.1",
|
|
58
58
|
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
|
59
59
|
"@panter/vue-i18next": "^0.15.2",
|
|
60
|
-
"@processmaker/vue-form-elements": "0.61.
|
|
60
|
+
"@processmaker/vue-form-elements": "0.61.1",
|
|
61
61
|
"@processmaker/vue-multiselect": "2.3.0",
|
|
62
62
|
"@storybook/addon-essentials": "^7.6.13",
|
|
63
63
|
"@storybook/addon-interactions": "^7.6.13",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
},
|
|
117
117
|
"peerDependencies": {
|
|
118
118
|
"@panter/vue-i18next": "^0.15.0",
|
|
119
|
-
"@processmaker/vue-form-elements": "0.61.
|
|
119
|
+
"@processmaker/vue-form-elements": "0.61.1",
|
|
120
120
|
"i18next": "^15.0.8",
|
|
121
121
|
"vue": "^2.6.12",
|
|
122
122
|
"vuex": "^3.1.1"
|
|
@@ -24,9 +24,11 @@
|
|
|
24
24
|
<hr class="card-divider" />
|
|
25
25
|
<b-card-body class="p-1">
|
|
26
26
|
<div class="template-details">
|
|
27
|
-
<span class="template-name d-block pt-1">{{
|
|
27
|
+
<span class="template-name d-block pt-1">{{
|
|
28
|
+
truncateText(template.name, 45)
|
|
29
|
+
}}</span>
|
|
28
30
|
<span class="template-description d-block">{{
|
|
29
|
-
truncateText(template.description,
|
|
31
|
+
truncateText(template.description, 60)
|
|
30
32
|
}}</span>
|
|
31
33
|
</div>
|
|
32
34
|
<b-collapse v-model="isApplyOptionsActive">
|
|
@@ -27,6 +27,15 @@
|
|
|
27
27
|
class="mr-2 ml-1"
|
|
28
28
|
/>
|
|
29
29
|
{{ element.config.name || $t("Variable Name") }}
|
|
30
|
+
<b-badge
|
|
31
|
+
v-if="isInClipboard(items[index])"
|
|
32
|
+
data-cy="copied-badge"
|
|
33
|
+
class="m-2 custom-badge"
|
|
34
|
+
pill
|
|
35
|
+
>
|
|
36
|
+
<i class="far fa-check-circle"></i>
|
|
37
|
+
<span class="pl-2">{{ $t('Copied')}}</span>
|
|
38
|
+
</b-badge>
|
|
30
39
|
<div class="ml-auto">
|
|
31
40
|
<clipboard-button
|
|
32
41
|
:index="index"
|
|
@@ -91,6 +100,15 @@
|
|
|
91
100
|
class="mr-2 ml-1"
|
|
92
101
|
/>
|
|
93
102
|
{{ element.config.name || $t("Variable Name") }}
|
|
103
|
+
<b-badge
|
|
104
|
+
v-if="isInClipboard(items[index])"
|
|
105
|
+
data-cy="copied-badge"
|
|
106
|
+
class="m-2 custom-badge"
|
|
107
|
+
pill
|
|
108
|
+
>
|
|
109
|
+
<i class="far fa-check-circle"></i>
|
|
110
|
+
<span class="pl-2">{{ $t('Copied')}}</span>
|
|
111
|
+
</b-badge>
|
|
94
112
|
<div class="ml-auto">
|
|
95
113
|
<clipboard-button
|
|
96
114
|
:index="index"
|
|
@@ -334,4 +352,12 @@ export default {
|
|
|
334
352
|
box-shadow: 0 0 0 13px rgba(0, 0, 0, 0);
|
|
335
353
|
}
|
|
336
354
|
}
|
|
355
|
+
.custom-badge {
|
|
356
|
+
background-color: #D1F4D7 !important;
|
|
357
|
+
color: #06723A !important;
|
|
358
|
+
padding: 0.5rem 0.75rem;
|
|
359
|
+
border-radius: 8px;
|
|
360
|
+
font-weight: 500;
|
|
361
|
+
font-size: 14px;
|
|
362
|
+
}
|
|
337
363
|
</style>
|
|
@@ -42,6 +42,15 @@
|
|
|
42
42
|
class="mr-2 ml-1"
|
|
43
43
|
/>
|
|
44
44
|
{{ element.config.name || $t("Variable Name") }}
|
|
45
|
+
<b-badge
|
|
46
|
+
v-if="isInClipboard(element)"
|
|
47
|
+
data-cy="copied-badge"
|
|
48
|
+
class="m-2 custom-badge"
|
|
49
|
+
pill
|
|
50
|
+
>
|
|
51
|
+
<i class="far fa-check-circle"></i>
|
|
52
|
+
<span class="pl-2">{{ $t('Copied')}}</span>
|
|
53
|
+
</b-badge>
|
|
45
54
|
<div class="ml-auto">
|
|
46
55
|
<clipboard-button
|
|
47
56
|
:index="index"
|
|
@@ -108,6 +117,15 @@
|
|
|
108
117
|
class="mr-2 ml-1"
|
|
109
118
|
/>
|
|
110
119
|
{{ element.config.name || $t("Variable Name") }}
|
|
120
|
+
<b-badge
|
|
121
|
+
v-if="isInClipboard(element)"
|
|
122
|
+
data-cy="copied-badge"
|
|
123
|
+
class="m-2 custom-badge"
|
|
124
|
+
pill
|
|
125
|
+
>
|
|
126
|
+
<i class="far fa-check-circle"></i>
|
|
127
|
+
<span class="pl-2">{{ $t('Copied')}}</span>
|
|
128
|
+
</b-badge>
|
|
111
129
|
<div class="ml-auto">
|
|
112
130
|
<clipboard-button
|
|
113
131
|
:index="index"
|
|
@@ -375,4 +393,12 @@ export default {
|
|
|
375
393
|
box-shadow: 0 0 0 13px rgba(0, 0, 0, 0);
|
|
376
394
|
}
|
|
377
395
|
}
|
|
396
|
+
.custom-badge {
|
|
397
|
+
background-color: #D1F4D7 !important;
|
|
398
|
+
color: #06723A !important;
|
|
399
|
+
padding: 0.5rem 0.75rem;
|
|
400
|
+
border-radius: 8px;
|
|
401
|
+
font-weight: 500;
|
|
402
|
+
font-size: 14px;
|
|
403
|
+
}
|
|
378
404
|
</style>
|
|
@@ -36,6 +36,9 @@
|
|
|
36
36
|
],
|
|
37
37
|
};
|
|
38
38
|
},
|
|
39
|
+
mounted () {
|
|
40
|
+
this.callBuilder(this.designerOptions);
|
|
41
|
+
},
|
|
39
42
|
computed: {
|
|
40
43
|
options() {
|
|
41
44
|
return Object.fromEntries(
|
|
@@ -56,10 +59,15 @@
|
|
|
56
59
|
options: {
|
|
57
60
|
handler() {
|
|
58
61
|
this.$emit("input", this.options);
|
|
59
|
-
this
|
|
62
|
+
this.callBuilder(this.options.designerOptions);
|
|
60
63
|
},
|
|
61
64
|
deep: true
|
|
62
65
|
},
|
|
63
66
|
},
|
|
67
|
+
methods: {
|
|
68
|
+
callBuilder(option) {
|
|
69
|
+
this.$root.$emit("style-mode", option);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
64
72
|
};
|
|
65
73
|
</script>
|
|
@@ -158,6 +158,10 @@ export default {
|
|
|
158
158
|
this.removeDefaultClasses();
|
|
159
159
|
},
|
|
160
160
|
mounted() {
|
|
161
|
+
if (this.value) {
|
|
162
|
+
this.fetchFiles();
|
|
163
|
+
}
|
|
164
|
+
|
|
161
165
|
this.$root.$on('set-upload-data-name',
|
|
162
166
|
(recordList, index, id) => this.listenRecordList(recordList, index, id));
|
|
163
167
|
|
|
@@ -597,6 +601,10 @@ export default {
|
|
|
597
601
|
}
|
|
598
602
|
|
|
599
603
|
if (displayMessage.length > 0) {
|
|
604
|
+
const data = JSON.parse(displayMessage);
|
|
605
|
+
if (data.message) {
|
|
606
|
+
displayMessage = data.message;
|
|
607
|
+
}
|
|
600
608
|
window.ProcessMaker.alert(`${this.$t('File Upload Error:')} ${displayMessage}`, 'danger');
|
|
601
609
|
}
|
|
602
610
|
|
|
@@ -699,7 +707,29 @@ export default {
|
|
|
699
707
|
},
|
|
700
708
|
cfSkipFileUpload() {
|
|
701
709
|
this.$emit('cf-skip-file-upload');
|
|
702
|
-
}
|
|
710
|
+
},
|
|
711
|
+
async fetchFiles() {
|
|
712
|
+
const fileIds = Array.isArray(this.value) ? this.value : [this.value];
|
|
713
|
+
|
|
714
|
+
const fetchPromises = fileIds.map(async (file) => {
|
|
715
|
+
const id = file?.file ?? file;
|
|
716
|
+
const endpoint = `files/${id}`;
|
|
717
|
+
try {
|
|
718
|
+
const response = await ProcessMaker.apiClient.get(endpoint);
|
|
719
|
+
if (response?.data) {
|
|
720
|
+
const fileExists = this.files.some(existingFile => existingFile.id === response.data.id);
|
|
721
|
+
// Check if the file already exists in the list before adding it.
|
|
722
|
+
if (!fileExists) {
|
|
723
|
+
this.files.push(response.data);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
} catch (error) {
|
|
727
|
+
console.error(`Failed to fetch file ${id}`, error);
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
return await Promise.all(fetchPromises);
|
|
732
|
+
},
|
|
703
733
|
},
|
|
704
734
|
};
|
|
705
735
|
</script>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
<script>
|
|
17
17
|
import VueFormRenderer from "../vue-form-renderer.vue";
|
|
18
18
|
import CollectionRecordsList from "../inspector/collection-records-list.vue";
|
|
19
|
+
import _ from 'lodash';
|
|
19
20
|
|
|
20
21
|
const globalObject = typeof window === "undefined" ? global : window;
|
|
21
22
|
|
|
@@ -179,12 +180,12 @@ export default {
|
|
|
179
180
|
this.selDisplayMode === "View" ? viewScreen : editScreen;
|
|
180
181
|
|
|
181
182
|
this.loadScreen(this.screenCollectionId);
|
|
182
|
-
|
|
183
|
+
|
|
183
184
|
//This section validates if Collection has draft data
|
|
184
185
|
if(this.taskDraft?.draft?.data == null || this.taskDraft.draft.data === '') {
|
|
185
186
|
this.localData = respData;
|
|
186
187
|
}else{
|
|
187
|
-
this.localData = this.taskDraft.draft.data;
|
|
188
|
+
this.localData = _.merge({}, respData, this.taskDraft.draft.data);
|
|
188
189
|
}
|
|
189
190
|
|
|
190
191
|
})
|
|
@@ -212,9 +213,9 @@ export default {
|
|
|
212
213
|
},
|
|
213
214
|
record(record) {
|
|
214
215
|
this.hasMustache = false;
|
|
215
|
-
if (record && !isNaN(record) && record > 0 && this.collection) {
|
|
216
|
+
if (record && !isNaN(record) && record > 0 && this.collection.collectionId) {
|
|
216
217
|
this.selRecordId = record;
|
|
217
|
-
this.loadRecordCollection(this.
|
|
218
|
+
this.loadRecordCollection(this.collection.collectionId, record, this.selDisplayMode);
|
|
218
219
|
} else {
|
|
219
220
|
if (this.isMustache(record)) {
|
|
220
221
|
this.callbackRecord();
|
|
@@ -206,9 +206,9 @@ export default {
|
|
|
206
206
|
},
|
|
207
207
|
record(record) {
|
|
208
208
|
this.hasMustache = false;
|
|
209
|
-
if (record && !isNaN(record) && record > 0 && this.collection) {
|
|
209
|
+
if (record && !isNaN(record) && record > 0 && this.collection.collectionId) {
|
|
210
210
|
this.selRecordId = record;
|
|
211
|
-
this.loadRecordCollection(this.
|
|
211
|
+
this.loadRecordCollection(this.collection.collectionId, record, this.collectionmode);
|
|
212
212
|
} else {
|
|
213
213
|
if (this.isMustache(record)) {
|
|
214
214
|
this.callbackRecord();
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
<input
|
|
42
42
|
v-else
|
|
43
43
|
v-model="localValue"
|
|
44
|
-
v-bind="
|
|
44
|
+
v-bind="componentConfigEncField"
|
|
45
45
|
v-uni-id="name"
|
|
46
46
|
:name="name"
|
|
47
47
|
class="form-control"
|
|
@@ -231,6 +231,7 @@ export default {
|
|
|
231
231
|
labelBtn: '',
|
|
232
232
|
errorEncryptedField: '',
|
|
233
233
|
concealExecuted: false,
|
|
234
|
+
componentConfigEncField: null,
|
|
234
235
|
};
|
|
235
236
|
},
|
|
236
237
|
computed: {
|
|
@@ -289,17 +290,18 @@ export default {
|
|
|
289
290
|
* "encrypted" attribute is enabled
|
|
290
291
|
*/
|
|
291
292
|
if (this.encryptedConfig?.encrypted) {
|
|
293
|
+
this.componentConfigEncField = JSON.parse(JSON.stringify(this.componentConfig));
|
|
292
294
|
if (uuidValidate(this.localValue)) {
|
|
293
295
|
this.inputType = "password";
|
|
294
296
|
this.iconBtn = "fas fa-eye";
|
|
295
297
|
this.labelBtn = this.$t("Reveal");
|
|
296
298
|
this.concealExecuted = true;
|
|
297
|
-
this.
|
|
299
|
+
this.componentConfigEncField.readonly = true;
|
|
298
300
|
} else {
|
|
299
301
|
this.inputType = "text";
|
|
300
302
|
this.iconBtn = "fas fa-eye-slash";
|
|
301
303
|
this.labelBtn = this.$t("Conceal");
|
|
302
|
-
this.
|
|
304
|
+
this.componentConfigEncField.readonly = this.componentConfig.readonly;
|
|
303
305
|
}
|
|
304
306
|
} else {
|
|
305
307
|
this.inputType = this.dataType;
|
|
@@ -381,7 +383,7 @@ export default {
|
|
|
381
383
|
this.iconBtn = "fas fa-eye";
|
|
382
384
|
this.labelBtn = this.$t("Reveal");
|
|
383
385
|
this.concealExecuted = true;
|
|
384
|
-
this.
|
|
386
|
+
this.componentConfigEncField.readonly = true;
|
|
385
387
|
this.errorEncryptedField = "";
|
|
386
388
|
|
|
387
389
|
// Assign uuid from encrypted data
|
|
@@ -392,7 +394,7 @@ export default {
|
|
|
392
394
|
this.inputType = this.dataType;
|
|
393
395
|
this.iconBtn = "fas fa-eye-slash";
|
|
394
396
|
this.labelBtn = this.$t("Conceal");
|
|
395
|
-
this.
|
|
397
|
+
this.componentConfigEncField.readonly = this.componentConfig.readonly;
|
|
396
398
|
|
|
397
399
|
// Assign value decrypted
|
|
398
400
|
this.localValue = decryptedValue;
|
package/src/components/task.vue
CHANGED
|
@@ -107,6 +107,7 @@ export default {
|
|
|
107
107
|
alwaysAllowEditing: { type: Boolean, default: false },
|
|
108
108
|
disableInterstitial: { type: Boolean, default: false },
|
|
109
109
|
waitLoadingListeners: { type: Boolean, default: false },
|
|
110
|
+
isWebEntry: { type: Boolean, default: false },
|
|
110
111
|
},
|
|
111
112
|
data() {
|
|
112
113
|
return {
|
|
@@ -677,55 +678,97 @@ export default {
|
|
|
677
678
|
return null;
|
|
678
679
|
}
|
|
679
680
|
},
|
|
681
|
+
|
|
680
682
|
/**
|
|
681
|
-
* Handles
|
|
682
|
-
* @
|
|
683
|
-
* @param {
|
|
684
|
-
* @param {
|
|
683
|
+
* Handles redirection upon process completion, considering destination type and user task validation.
|
|
684
|
+
* @async
|
|
685
|
+
* @param {Object} data - Contains information about the end event destination.
|
|
686
|
+
* @param {number} userId - ID of the current user.
|
|
687
|
+
* @param {number} requestId - ID of the request to complete.
|
|
688
|
+
* @returns {Promise<void>}
|
|
685
689
|
*/
|
|
686
690
|
async processCompletedRedirect(data, userId, requestId) {
|
|
691
|
+
// Emit completion event if accessed through web entry.
|
|
692
|
+
if (this.isWebEntry) {
|
|
693
|
+
this.$emit("completed", requestId);
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
|
|
687
697
|
try {
|
|
688
|
-
|
|
689
|
-
if (
|
|
690
|
-
|
|
691
|
-
window.location.href = data?.endEventDestination.value;
|
|
692
|
-
} else {
|
|
693
|
-
window.location.href = `/requests/${this.requestId}`;
|
|
694
|
-
}
|
|
698
|
+
const destinationUrl = this.resolveDestinationUrl(data);
|
|
699
|
+
if (destinationUrl) {
|
|
700
|
+
window.location.href = destinationUrl;
|
|
695
701
|
return;
|
|
696
702
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
);
|
|
701
|
-
// Get the next request using retry logic
|
|
702
|
-
const nextRequest = await this.retryApiCall(() =>
|
|
703
|
-
this.getNextRequest(
|
|
704
|
-
endEventDestination.processId,
|
|
705
|
-
endEventDestination.startEvent
|
|
706
|
-
)
|
|
707
|
-
);
|
|
708
|
-
|
|
709
|
-
const params = {
|
|
710
|
-
processRequestId: nextRequest.data.id,
|
|
711
|
-
status: "ACTIVE",
|
|
712
|
-
page: 1,
|
|
713
|
-
perPage: 1
|
|
714
|
-
};
|
|
715
|
-
// Get the tasks for the next request using retry logic
|
|
716
|
-
const response = await this.retryApiCall(() => this.getTasks(params));
|
|
717
|
-
// Handle the first task from the response
|
|
718
|
-
const firstTask = response.data.data[0];
|
|
719
|
-
if (firstTask && firstTask.user_id === userId) {
|
|
720
|
-
this.redirectToTask(firstTask.id);
|
|
721
|
-
} else {
|
|
722
|
-
this.redirectToRequest(requestId);
|
|
723
|
-
}
|
|
703
|
+
|
|
704
|
+
// Proceed to handle redirection to the next request if applicable.
|
|
705
|
+
await this.handleNextRequestRedirection(data, userId, requestId);
|
|
724
706
|
} catch (error) {
|
|
725
707
|
console.error("Error processing completed redirect:", error);
|
|
726
708
|
this.$emit("completed", requestId);
|
|
727
709
|
}
|
|
728
710
|
},
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Resolves the URL to redirect to if the end event is not another process.
|
|
714
|
+
* @param {Object} data - Contains the end event destination data.
|
|
715
|
+
* @returns {string|null} - The URL for redirection, or null if proceeding to another process.
|
|
716
|
+
*/
|
|
717
|
+
resolveDestinationUrl(data) {
|
|
718
|
+
if (data.endEventDestination.type !== "anotherProcess") {
|
|
719
|
+
return data.endEventDestination.value || `/requests/${this.requestId}`;
|
|
720
|
+
}
|
|
721
|
+
return null;
|
|
722
|
+
},
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Handles redirection logic to the next request's task or fallback to the request itself.
|
|
726
|
+
* @async
|
|
727
|
+
* @param {Object} data - Contains the end event destination.
|
|
728
|
+
* @param {number} userId - ID of the current user.
|
|
729
|
+
* @param {number} requestId - ID of the request to complete.
|
|
730
|
+
* @returns {Promise<void>}
|
|
731
|
+
*/
|
|
732
|
+
async handleNextRequestRedirection(data, userId, requestId) {
|
|
733
|
+
const nextRequest = await this.fetchNextRequest(data.endEventDestination);
|
|
734
|
+
const firstTask = await this.fetchFirstTask(nextRequest);
|
|
735
|
+
|
|
736
|
+
if (firstTask?.user_id === userId) {
|
|
737
|
+
this.redirectToTask(firstTask.id);
|
|
738
|
+
} else {
|
|
739
|
+
this.redirectToRequest(requestId);
|
|
740
|
+
}
|
|
741
|
+
},
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Fetch the next request using retry logic.
|
|
745
|
+
* @async
|
|
746
|
+
* @param {Object} endEventDestination - The parsed end event destination object.
|
|
747
|
+
* @returns {Promise<Object>} - The next request data.
|
|
748
|
+
*/
|
|
749
|
+
async fetchNextRequest(endEventDestination) {
|
|
750
|
+
const destinationData = this.parseJsonSafely(endEventDestination.value);
|
|
751
|
+
return await this.retryApiCall(() =>
|
|
752
|
+
this.getNextRequest(destinationData.processId, destinationData.startEvent)
|
|
753
|
+
);
|
|
754
|
+
},
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Fetch the first task from the next request using retry logic.
|
|
758
|
+
* @async
|
|
759
|
+
* @param {Object} nextRequest - The next request object.
|
|
760
|
+
* @returns {Promise<Object|null>} - The first task data, or null if no tasks found.
|
|
761
|
+
*/
|
|
762
|
+
async fetchFirstTask(nextRequest) {
|
|
763
|
+
const params = {
|
|
764
|
+
processRequestId: nextRequest.data.id,
|
|
765
|
+
status: "ACTIVE",
|
|
766
|
+
page: 1,
|
|
767
|
+
perPage: 1
|
|
768
|
+
};
|
|
769
|
+
const response = await this.retryApiCall(() => this.getTasks(params));
|
|
770
|
+
return response.data.data[0] || null;
|
|
771
|
+
},
|
|
729
772
|
getAllowedRequestId() {
|
|
730
773
|
const permissions = this.task.user_request_permission || [];
|
|
731
774
|
const permission = permissions.find(item => item.process_request_id === this.parentRequest)
|
|
@@ -127,6 +127,7 @@
|
|
|
127
127
|
v-if="isClipboardPage(tabPage)"
|
|
128
128
|
variant="link"
|
|
129
129
|
@click="clearClipboard"
|
|
130
|
+
class="no-text-transform"
|
|
130
131
|
>
|
|
131
132
|
{{ $t('Clear All') }}
|
|
132
133
|
</b-button>
|
|
@@ -201,6 +202,15 @@
|
|
|
201
202
|
class="mr-2 ml-1"
|
|
202
203
|
/>
|
|
203
204
|
{{ element.config.name || element.label || $t("Field Name") }}
|
|
205
|
+
<b-badge
|
|
206
|
+
v-if="!isClipboardPage(tabPage) && isInClipboard(extendedPages[tabPage].items[index])"
|
|
207
|
+
data-cy="copied-badge"
|
|
208
|
+
class="m-2 custom-badge"
|
|
209
|
+
pill
|
|
210
|
+
>
|
|
211
|
+
<i class="far fa-check-circle"></i>
|
|
212
|
+
<span class="pl-2">{{ $t('Copied')}}</span>
|
|
213
|
+
</b-badge>
|
|
204
214
|
<div class="ml-auto">
|
|
205
215
|
<clipboard-button
|
|
206
216
|
v-if="!isClipboardPage(tabPage)"
|
|
@@ -245,7 +255,9 @@
|
|
|
245
255
|
v-model="element.items"
|
|
246
256
|
:validation-errors="validationErrors"
|
|
247
257
|
class="card-body"
|
|
248
|
-
:class="styleMode === 'Modern'
|
|
258
|
+
:class="styleMode === 'Modern' && element.component === 'FormRecordList'
|
|
259
|
+
? elementCssClassModern(element)
|
|
260
|
+
: elementCssClass(element)"
|
|
249
261
|
:selected="selected"
|
|
250
262
|
:config="element.config"
|
|
251
263
|
:ai-element="element"
|
|
@@ -266,6 +278,15 @@
|
|
|
266
278
|
class="mr-2 ml-1"
|
|
267
279
|
/>
|
|
268
280
|
{{ element.config.name || $t("Variable Name") }}
|
|
281
|
+
<b-badge
|
|
282
|
+
v-if="!isClipboardPage(tabPage) && isInClipboard(extendedPages[tabPage].items[index])"
|
|
283
|
+
data-cy="copied-badge"
|
|
284
|
+
class="m-2 custom-badge"
|
|
285
|
+
pill
|
|
286
|
+
>
|
|
287
|
+
<i class="far fa-check-circle"></i>
|
|
288
|
+
<span class="pl-2">{{ $t('Copied')}}</span>
|
|
289
|
+
</b-badge>
|
|
269
290
|
<div class="ml-auto">
|
|
270
291
|
<clipboard-button
|
|
271
292
|
v-if="!isClipboardPage(tabPage)"
|
|
@@ -299,7 +320,9 @@
|
|
|
299
320
|
:tabindex="element.config.interactive ? 0 : -1"
|
|
300
321
|
class="card-body m-0 pb-4 pt-4"
|
|
301
322
|
:class="[
|
|
302
|
-
styleMode === 'Modern'
|
|
323
|
+
styleMode === 'Modern' && element.component === 'FormRecordList'
|
|
324
|
+
? elementCssClassModern(element)
|
|
325
|
+
: elementCssClass(element),
|
|
303
326
|
{ 'prevent-interaction': !element.config.interactive }
|
|
304
327
|
]"
|
|
305
328
|
@input="
|
|
@@ -1745,4 +1768,15 @@ $side-bar-font-size: 0.875rem;
|
|
|
1745
1768
|
cursor: not-allowed; /* Cambia el cursor cuando se pasa por encima */
|
|
1746
1769
|
pointer-events: all; /* Permite que el pseudo-elemento reciba eventos del ratón */
|
|
1747
1770
|
}
|
|
1771
|
+
.custom-badge {
|
|
1772
|
+
background-color: #D1F4D7 !important;
|
|
1773
|
+
color: #06723A !important;
|
|
1774
|
+
padding: 0.5rem 0.75rem;
|
|
1775
|
+
border-radius: 8px;
|
|
1776
|
+
font-weight: 500;
|
|
1777
|
+
font-size: 14px;
|
|
1778
|
+
}
|
|
1779
|
+
.no-text-transform {
|
|
1780
|
+
text-transform: none;
|
|
1781
|
+
}
|
|
1748
1782
|
</style>
|
package/src/main.js
CHANGED
|
@@ -325,6 +325,14 @@ window.Echo = {
|
|
|
325
325
|
}, 1000);
|
|
326
326
|
});
|
|
327
327
|
},
|
|
328
|
+
|
|
329
|
+
eventMockNext(event, response) {
|
|
330
|
+
this.listeners.forEach((listener) => {
|
|
331
|
+
setTimeout(() => {
|
|
332
|
+
listener.callback(response);
|
|
333
|
+
}, 1000);
|
|
334
|
+
});
|
|
335
|
+
},
|
|
328
336
|
private() {
|
|
329
337
|
return {
|
|
330
338
|
notification(callback) {
|
package/src/mixins/Clipboard.js
CHANGED
|
@@ -115,6 +115,9 @@ export default {
|
|
|
115
115
|
// replace uuids in clipboard content
|
|
116
116
|
clipboardContent.forEach(this.updateUuids);
|
|
117
117
|
page.items.splice(index, 1, ...clipboardContent);
|
|
118
|
+
if (clipboardContent.length) {
|
|
119
|
+
window.ProcessMaker.alert(this.$t("Clipboard Pasted Succesfully"), "success");
|
|
120
|
+
}
|
|
118
121
|
}
|
|
119
122
|
if (item.items) {
|
|
120
123
|
replaceInPage(item);
|
|
@@ -144,6 +147,7 @@ export default {
|
|
|
144
147
|
}
|
|
145
148
|
);
|
|
146
149
|
if (confirm) {
|
|
150
|
+
this.clipboardPage.items = [];
|
|
147
151
|
this.$store.dispatch("clipboardModule/clearClipboard");
|
|
148
152
|
this.$root.$emit('update-clipboard');
|
|
149
153
|
}
|