@processmaker/modeler 1.42.1 → 1.43.1
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/modeler.common.js +1421 -380
- package/dist/modeler.common.js.map +1 -1
- package/dist/modeler.umd.js +1421 -380
- package/dist/modeler.umd.js.map +1 -1
- package/dist/modeler.umd.min.js +4 -4
- package/dist/modeler.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/colorUtil.js +78 -0
- package/src/components/aiMessages/AiGenerateButton.vue +77 -0
- package/src/components/aiMessages/AssetsCreatedCard.vue +82 -0
- package/src/components/aiMessages/CreateAssetsCard.vue +92 -0
- package/src/components/aiMessages/CreateAssetsFailCard.vue +27 -0
- package/src/components/aiMessages/GeneratingAssetsCard.vue +77 -0
- package/src/components/modeler/Modeler.vue +190 -3
- package/src/components/multiplayer/remoteCursor/RemoteCursor.vue +14 -21
- package/src/components/railBottom/RailBottom.vue +4 -4
- package/src/components/railBottom/controls/SubmenuPopper/SubmenuPopper.vue +6 -2
- package/src/components/rails/explorer-rail/nodeTypesLoop/nodeTypesLoop.vue +8 -1
- package/src/components/rails/explorer-rail/pmBlocksLoop/pmBlocksLoop.vue +110 -9
- package/src/components/topRail/TopRail.vue +4 -0
- package/src/components/topRail/multiplayerViewUsers/MultiplayerViewUsers.vue +1 -8
- package/src/components/topRail/multiplayerViewUsers/avatar/Avatar.vue +2 -76
- package/src/components/topRail/multiplayerViewUsers/avatar/avatar.scss +0 -1
- package/src/components/welcome/WelcomeMessage.vue +1 -6
- package/src/mixins/clickAndDrop.js +3 -0
- package/src/multiplayer/multiplayer.js +58 -16
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
@close="close"
|
|
24
24
|
@save-state="pushToUndoStack"
|
|
25
25
|
@clearSelection="clearSelection"
|
|
26
|
-
:players="
|
|
26
|
+
:players="filteredPlayers"
|
|
27
27
|
@action="handleToolbarAction"
|
|
28
28
|
/>
|
|
29
29
|
<b-row class="modeler h-100">
|
|
@@ -56,6 +56,29 @@
|
|
|
56
56
|
v-if="showWelcomeMessage"
|
|
57
57
|
/>
|
|
58
58
|
|
|
59
|
+
<CreateAssetsCard
|
|
60
|
+
ref="createAssetsCard"
|
|
61
|
+
v-if="isAiGenerated"
|
|
62
|
+
@onGenerateAssets="generateAssets()"
|
|
63
|
+
@closeCreateAssets="onCloseCreateAssets()"
|
|
64
|
+
/>
|
|
65
|
+
|
|
66
|
+
<GeneratingAssetsCard
|
|
67
|
+
ref="generatingAssetsCard"
|
|
68
|
+
v-if="generatingAi"
|
|
69
|
+
/>
|
|
70
|
+
|
|
71
|
+
<AssetsCreatedCard
|
|
72
|
+
ref="assetsCreatedCard"
|
|
73
|
+
v-if="assetsCreated"
|
|
74
|
+
@closeAssetsCreated="onCloseAssetsCreated()"
|
|
75
|
+
/>
|
|
76
|
+
|
|
77
|
+
<CreateAssetsFailCard
|
|
78
|
+
ref="createAssetsFailCard"
|
|
79
|
+
v-if="false"
|
|
80
|
+
/>
|
|
81
|
+
|
|
59
82
|
<InspectorButton
|
|
60
83
|
ref="inspector-button"
|
|
61
84
|
v-show="showComponent && showInspectorButton"
|
|
@@ -143,6 +166,7 @@
|
|
|
143
166
|
/>
|
|
144
167
|
|
|
145
168
|
<RailBottom
|
|
169
|
+
v-if="!generatingAi"
|
|
146
170
|
:nodeTypes="nodeTypes"
|
|
147
171
|
:paper-manager="paperManager"
|
|
148
172
|
:graph="graph"
|
|
@@ -165,6 +189,11 @@
|
|
|
165
189
|
@save-state="pushToUndoStack"
|
|
166
190
|
:isMultiplayer="isMultiplayer"
|
|
167
191
|
/>
|
|
192
|
+
<RemoteCursor
|
|
193
|
+
v-for="player in filteredPlayers"
|
|
194
|
+
:key="player.id"
|
|
195
|
+
:data="player"
|
|
196
|
+
/>
|
|
168
197
|
</b-row>
|
|
169
198
|
</span>
|
|
170
199
|
</template>
|
|
@@ -172,12 +201,17 @@
|
|
|
172
201
|
<script>
|
|
173
202
|
|
|
174
203
|
import Vue from 'vue';
|
|
204
|
+
|
|
175
205
|
import _ from 'lodash';
|
|
176
206
|
import { dia } from 'jointjs';
|
|
177
207
|
import boundaryEventConfig from '../nodes/boundaryEvent';
|
|
178
208
|
import BpmnModdle from 'bpmn-moddle';
|
|
179
209
|
import ExplorerRail from '../rails/explorer-rail/explorer';
|
|
180
210
|
import WelcomeMessage from '../welcome/WelcomeMessage.vue';
|
|
211
|
+
import CreateAssetsCard from '../aiMessages/CreateAssetsCard.vue';
|
|
212
|
+
import GeneratingAssetsCard from '../aiMessages/GeneratingAssetsCard.vue';
|
|
213
|
+
import AssetsCreatedCard from '../aiMessages/AssetsCreatedCard.vue';
|
|
214
|
+
import CreateAssetsFailCard from '../aiMessages/CreateAssetsFailCard.vue';
|
|
181
215
|
import { isJSON } from 'lodash-contrib';
|
|
182
216
|
import pull from 'lodash/pull';
|
|
183
217
|
import remove from 'lodash/remove';
|
|
@@ -251,6 +285,10 @@ export default {
|
|
|
251
285
|
Selection,
|
|
252
286
|
RailBottom,
|
|
253
287
|
WelcomeMessage,
|
|
288
|
+
CreateAssetsCard,
|
|
289
|
+
GeneratingAssetsCard,
|
|
290
|
+
AssetsCreatedCard,
|
|
291
|
+
CreateAssetsFailCard,
|
|
254
292
|
RemoteCursor,
|
|
255
293
|
},
|
|
256
294
|
props: {
|
|
@@ -348,6 +386,12 @@ export default {
|
|
|
348
386
|
isResizingPreview: false,
|
|
349
387
|
currentCursorPosition: 0,
|
|
350
388
|
previewPanelWidth: 600,
|
|
389
|
+
isAiGenerated: window.ProcessMaker?.modeler?.isAiGenerated,
|
|
390
|
+
generatingAi: false,
|
|
391
|
+
assetsCreated: false,
|
|
392
|
+
// ^ TODO: To be changed depending on microservice response
|
|
393
|
+
currentNonce: null,
|
|
394
|
+
promptSessionId: '',
|
|
351
395
|
flowTypes: [
|
|
352
396
|
'processmaker-modeler-sequence-flow',
|
|
353
397
|
'processmaker-modeler-message-flow',
|
|
@@ -401,6 +445,12 @@ export default {
|
|
|
401
445
|
},
|
|
402
446
|
},
|
|
403
447
|
computed: {
|
|
448
|
+
filteredPlayers() {
|
|
449
|
+
const allPlayers = _.uniqBy(this.players, 'name');
|
|
450
|
+
return allPlayers.filter(player => {
|
|
451
|
+
return player.name.toLowerCase() !== window.ProcessMaker.user?.fullName.toLowerCase();
|
|
452
|
+
});
|
|
453
|
+
},
|
|
404
454
|
showWelcomeMessage() {
|
|
405
455
|
return !this.selectedNode && !this.nodes.length && !store.getters.isReadOnly && this.isLoaded;
|
|
406
456
|
},
|
|
@@ -1613,6 +1663,7 @@ export default {
|
|
|
1613
1663
|
},
|
|
1614
1664
|
pointerMoveHandler(event) {
|
|
1615
1665
|
const { clientX: x, clientY: y } = event;
|
|
1666
|
+
window.ProcessMaker.EventBus.$emit('multiplayer-updateMousePosition', { top: y, left: x });
|
|
1616
1667
|
if (store.getters.isReadOnly) {
|
|
1617
1668
|
if (this.canvasDragPosition && !this.clientLeftPaper) {
|
|
1618
1669
|
this.paperManager.translate(
|
|
@@ -1662,8 +1713,23 @@ export default {
|
|
|
1662
1713
|
enableMultiplayer(value) {
|
|
1663
1714
|
store.commit('enableMultiplayer', value);
|
|
1664
1715
|
},
|
|
1665
|
-
|
|
1666
|
-
this.players
|
|
1716
|
+
emptyPlayers(){
|
|
1717
|
+
this.players = [];
|
|
1718
|
+
},
|
|
1719
|
+
addPlayer(data) {
|
|
1720
|
+
const player = this.players.find(player => player.id === data.id);
|
|
1721
|
+
if (!player) {
|
|
1722
|
+
this.players.push(data);
|
|
1723
|
+
}
|
|
1724
|
+
},
|
|
1725
|
+
/**
|
|
1726
|
+
* Update Client Cursor
|
|
1727
|
+
* @param {Object} data
|
|
1728
|
+
*/
|
|
1729
|
+
updateClientCursor(data) {
|
|
1730
|
+
if (data) {
|
|
1731
|
+
this.players = this.players.map((item) => (item.id === data.id ? { ...item, ...data } : item));
|
|
1732
|
+
}
|
|
1667
1733
|
},
|
|
1668
1734
|
removePlayer(playerId) {
|
|
1669
1735
|
const playerIndex = this.players.findIndex(player => player.id === playerId);
|
|
@@ -1678,6 +1744,119 @@ export default {
|
|
|
1678
1744
|
updateLasso(){
|
|
1679
1745
|
this.$refs.selector.updateSelectionBox();
|
|
1680
1746
|
},
|
|
1747
|
+
getNonce() {
|
|
1748
|
+
const max = 999999999999999;
|
|
1749
|
+
const nonce = Math.floor(Math.random() * max);
|
|
1750
|
+
this.currentNonce = nonce;
|
|
1751
|
+
localStorage.currentNonce = this.currentNonce;
|
|
1752
|
+
},
|
|
1753
|
+
getPromptSessionForUser() {
|
|
1754
|
+
// Get sessions list
|
|
1755
|
+
let promptSessions = localStorage.getItem('promptSessions');
|
|
1756
|
+
|
|
1757
|
+
// If promptSessions does not exist, set it as an empty array
|
|
1758
|
+
promptSessions = promptSessions ? JSON.parse(promptSessions) : [];
|
|
1759
|
+
let item = promptSessions.find(item => item.userId === window.ProcessMaker?.modeler?.process?.user_id && item.server === window.location.host);
|
|
1760
|
+
|
|
1761
|
+
if (item) {
|
|
1762
|
+
return item.promptSessionId;
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
return '';
|
|
1766
|
+
},
|
|
1767
|
+
setPromptSessions(promptSessionId) {
|
|
1768
|
+
let index = 'userId';
|
|
1769
|
+
let id = window.ProcessMaker?.modeler?.process?.user_id;
|
|
1770
|
+
|
|
1771
|
+
// Get sessions list
|
|
1772
|
+
let promptSessions = localStorage.getItem('promptSessions');
|
|
1773
|
+
|
|
1774
|
+
// If promptSessions does not exist, set it as an empty array
|
|
1775
|
+
promptSessions = promptSessions ? JSON.parse(promptSessions) : [];
|
|
1776
|
+
|
|
1777
|
+
let item = promptSessions.find(item => item[index] === id && item.server === window.location.host);
|
|
1778
|
+
|
|
1779
|
+
if (item) {
|
|
1780
|
+
item.promptSessionId = promptSessionId;
|
|
1781
|
+
} else {
|
|
1782
|
+
promptSessions.push({ [index]: id, server: window.location.host, promptSessionId });
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
localStorage.setItem('promptSessions', JSON.stringify(promptSessions));
|
|
1786
|
+
},
|
|
1787
|
+
removePromptSessionForUser() {
|
|
1788
|
+
// Get sessions list
|
|
1789
|
+
let promptSessions = localStorage.getItem('promptSessions');
|
|
1790
|
+
|
|
1791
|
+
// If promptSessions does not exist, set it as an empty array
|
|
1792
|
+
promptSessions = promptSessions ? JSON.parse(promptSessions) : [];
|
|
1793
|
+
|
|
1794
|
+
let item = promptSessions.find(item => item.userId === window.ProcessMaker?.modeler?.process?.user_id && item.server === window.location.host);
|
|
1795
|
+
|
|
1796
|
+
if (item) {
|
|
1797
|
+
item.promptSessionId = '';
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
localStorage.setItem('promptSessions', JSON.stringify(promptSessions));
|
|
1801
|
+
},
|
|
1802
|
+
fetchHistory() {
|
|
1803
|
+
let url = '/package-ai/getPromptSessionHistory';
|
|
1804
|
+
|
|
1805
|
+
let params = {
|
|
1806
|
+
server: window.location.host,
|
|
1807
|
+
processId: this.processId,
|
|
1808
|
+
};
|
|
1809
|
+
|
|
1810
|
+
if (this.promptSessionId && this.promptSessionId !== null && this.promptSessionId !== '') {
|
|
1811
|
+
params = {
|
|
1812
|
+
promptSessionId: this.promptSessionId,
|
|
1813
|
+
};
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
window.ProcessMaker.apiClient.post(url, params)
|
|
1817
|
+
.then(response => {
|
|
1818
|
+
this.setPromptSessions((response.data.promptSessionId));
|
|
1819
|
+
this.promptSessionId = (response.data.promptSessionId);
|
|
1820
|
+
localStorage.promptSessionId = (response.data.promptSessionId);
|
|
1821
|
+
}).catch((error) => {
|
|
1822
|
+
const errorMsg = error.response?.data?.message || error.message;
|
|
1823
|
+
|
|
1824
|
+
if (error.response.status === 404) {
|
|
1825
|
+
this.removePromptSessionForUser();
|
|
1826
|
+
localStorage.promptSessionId = '';
|
|
1827
|
+
this.promptSessionId = '';
|
|
1828
|
+
} else {
|
|
1829
|
+
window.ProcessMaker.alert(errorMsg, 'danger');
|
|
1830
|
+
}
|
|
1831
|
+
});
|
|
1832
|
+
},
|
|
1833
|
+
generateAssets() {
|
|
1834
|
+
this.getNonce();
|
|
1835
|
+
|
|
1836
|
+
// TODO: Add endpoint to get the promprSessionId
|
|
1837
|
+
|
|
1838
|
+
const params = {
|
|
1839
|
+
promptSessionId: this.promptSessionId,
|
|
1840
|
+
nonce: this.currentNonce,
|
|
1841
|
+
processId: window.ProcessMaker?.modeler?.process?.id,
|
|
1842
|
+
};
|
|
1843
|
+
|
|
1844
|
+
const url = '/package-ai/generateProcessArtifacts';
|
|
1845
|
+
|
|
1846
|
+
window.ProcessMaker.apiClient.post(url, params)
|
|
1847
|
+
.then(() => {
|
|
1848
|
+
})
|
|
1849
|
+
.catch((error) => {
|
|
1850
|
+
const errorMsg = error.response?.data?.message || error.message;
|
|
1851
|
+
window.ProcessMaker.alert(errorMsg, 'danger');
|
|
1852
|
+
});
|
|
1853
|
+
},
|
|
1854
|
+
onCloseCreateAssets() {
|
|
1855
|
+
this.isAiGenerated = false;
|
|
1856
|
+
},
|
|
1857
|
+
onCloseAssetsCreated() {
|
|
1858
|
+
this.assetsCreated = false;
|
|
1859
|
+
},
|
|
1681
1860
|
},
|
|
1682
1861
|
created() {
|
|
1683
1862
|
if (runningInCypressTest()) {
|
|
@@ -1866,6 +2045,14 @@ export default {
|
|
|
1866
2045
|
this.redirect(redirectUrl);
|
|
1867
2046
|
}
|
|
1868
2047
|
});
|
|
2048
|
+
|
|
2049
|
+
// AI Setup
|
|
2050
|
+
this.currentNonce = localStorage.currentNonce;
|
|
2051
|
+
if (!localStorage.getItem('promptSessions') || localStorage.getItem('promptSessions') === 'null') {
|
|
2052
|
+
localStorage.setItem('promptSessions', JSON.stringify([]));
|
|
2053
|
+
}
|
|
2054
|
+
this.promptSessionId = this.getPromptSessionForUser();
|
|
2055
|
+
this.fetchHistory();
|
|
1869
2056
|
},
|
|
1870
2057
|
};
|
|
1871
2058
|
</script>
|
|
@@ -1,33 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="remote-cursor" :style="{ left: left + 'px', top: top + 'px' }">
|
|
3
|
-
<
|
|
4
|
-
|
|
2
|
+
<div class="remote-cursor" :style="{ left: data.cursor.left + 'px', top: data.cursor.top + 'px' }">
|
|
3
|
+
<svg width="23" height="19" viewBox="0 0 23 19" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
+
<path d="M11.5 17.5L2 1L20.5 7L13 9L11.5 17.5Z" :stroke="stroke" :fill="data.color"/>
|
|
5
|
+
</svg>
|
|
5
6
|
<div class="remote-username">
|
|
6
|
-
{{
|
|
7
|
+
{{ data.name }}
|
|
7
8
|
</div>
|
|
8
9
|
</div>
|
|
9
10
|
</template>
|
|
10
11
|
|
|
11
12
|
<script>
|
|
12
|
-
import InlineSvg from 'vue-inline-svg';
|
|
13
|
-
|
|
14
13
|
export default {
|
|
15
|
-
components: {
|
|
16
|
-
InlineSvg,
|
|
17
|
-
},
|
|
18
14
|
props: {
|
|
19
|
-
|
|
20
|
-
type:
|
|
21
|
-
default: '#000000',
|
|
22
|
-
},
|
|
23
|
-
username: {
|
|
24
|
-
type: String,
|
|
25
|
-
},
|
|
26
|
-
top: {
|
|
27
|
-
type: Number,
|
|
28
|
-
},
|
|
29
|
-
left: {
|
|
30
|
-
type: Number,
|
|
15
|
+
data: {
|
|
16
|
+
type: Object,
|
|
31
17
|
},
|
|
32
18
|
},
|
|
33
19
|
data() {
|
|
@@ -35,6 +21,12 @@ export default {
|
|
|
35
21
|
cursorIcon: require('@/components/multiplayer/remoteCursor/cursor.svg'),
|
|
36
22
|
};
|
|
37
23
|
},
|
|
24
|
+
computed: {
|
|
25
|
+
stroke: () => {
|
|
26
|
+
return '#212529';
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
|
|
38
30
|
};
|
|
39
31
|
</script>
|
|
40
32
|
|
|
@@ -45,6 +37,7 @@ export default {
|
|
|
45
37
|
display: flex;
|
|
46
38
|
width: auto;
|
|
47
39
|
height: 34px;
|
|
40
|
+
z-index: 2;
|
|
48
41
|
}
|
|
49
42
|
|
|
50
43
|
&-username {
|
|
@@ -84,12 +84,12 @@ export default {
|
|
|
84
84
|
// Control coordinates
|
|
85
85
|
const controlEl = entries[0].target.getBoundingClientRect();
|
|
86
86
|
// Zoom coordinates
|
|
87
|
-
const zoomEl = this.$refs.zoomBox
|
|
87
|
+
const zoomEl = this.$refs.zoomBox?.$el.getBoundingClientRect();
|
|
88
88
|
// Undo/Redo coordinates
|
|
89
|
-
const undoRedoEl = this.$refs.undoRedoBox
|
|
89
|
+
const undoRedoEl = this.$refs.undoRedoBox?.$el.getBoundingClientRect();
|
|
90
90
|
|
|
91
91
|
// Checks overlapping
|
|
92
|
-
if (this.overlap) {
|
|
92
|
+
if (this.overlap && undoRedoEl) {
|
|
93
93
|
if (controlEl.width < this.widthOverlapControl) {
|
|
94
94
|
// Get the computed styles of the ZoomControl
|
|
95
95
|
const zoomStyles = window.getComputedStyle(this.$refs.zoomBox.$el);
|
|
@@ -107,7 +107,7 @@ export default {
|
|
|
107
107
|
this.overlap = false;
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
} else if (undoRedoEl
|
|
110
|
+
} else if (undoRedoEl?.left < zoomEl?.right) {
|
|
111
111
|
this.overlap = true;
|
|
112
112
|
this.widthOverlapControl = controlEl.width;
|
|
113
113
|
this.leftOverlapUndoRedo = undoRedoEl.left;
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span />
|
|
38
38
|
</div>
|
|
39
39
|
<i v-if="!containsSvg(data.icon)" :class="data.icon" class="fa-lg"/>
|
|
40
|
-
<inline-svg :src="data.icon" />
|
|
40
|
+
<inline-svg v-else :src="data.icon" />
|
|
41
41
|
</a>
|
|
42
42
|
</popper>
|
|
43
43
|
<a v-else class="control-submenu-item"
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
v-b-tooltip.hover.viewport.d50="{ customClass: 'no-pointer-events' }"
|
|
47
47
|
>
|
|
48
48
|
<i v-if="!containsSvg(data.icon)" :class="data.icon" class="fa-lg"/>
|
|
49
|
-
<inline-svg :src="data.icon" />
|
|
49
|
+
<inline-svg v-else :src="data.icon" />
|
|
50
50
|
</a>
|
|
51
51
|
</template>
|
|
52
52
|
|
|
@@ -101,6 +101,10 @@ export default ({
|
|
|
101
101
|
width: 24px;
|
|
102
102
|
height: 24px;
|
|
103
103
|
}
|
|
104
|
+
& > i {
|
|
105
|
+
color: #000000;
|
|
106
|
+
padding: 5px;
|
|
107
|
+
}
|
|
104
108
|
&.active {
|
|
105
109
|
background-color: #EBEEF2;
|
|
106
110
|
}
|
|
@@ -33,7 +33,14 @@ export default {
|
|
|
33
33
|
},
|
|
34
34
|
computed: {
|
|
35
35
|
pinnedObjects() {
|
|
36
|
-
|
|
36
|
+
const pinnedNodeTypes = nodeTypesStore.getters.getPinnedNodeTypes;
|
|
37
|
+
|
|
38
|
+
// Filter pinnedNodeTypes to exclude objects with PM Blocks type.
|
|
39
|
+
const filteredPinnedNodeTypes = pinnedNodeTypes.filter(obj => {
|
|
40
|
+
return !obj.type?.includes('processmaker-pm-block');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return filteredPinnedNodeTypes;
|
|
37
44
|
},
|
|
38
45
|
objects() {
|
|
39
46
|
return nodeTypesStore.getters.getNodeTypes;
|
|
@@ -1,11 +1,51 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import pinIcon from '@/assets/pin-angle.svg';
|
|
3
|
+
import pinFillIcon from '@/assets/pin-angle-fill.svg';
|
|
2
4
|
import nodeTypesStore from '@/nodeTypesStore';
|
|
3
5
|
import clickAndDrop from '@/mixins/clickAndDrop';
|
|
6
|
+
import iconHelper from '@/mixins/iconHelper';
|
|
4
7
|
|
|
5
8
|
export default {
|
|
6
9
|
name: 'PmBlocksLoop',
|
|
7
|
-
mixins: [clickAndDrop],
|
|
10
|
+
mixins: [clickAndDrop, iconHelper],
|
|
11
|
+
data() {
|
|
12
|
+
return {
|
|
13
|
+
pinIcon,
|
|
14
|
+
pinFillIcon,
|
|
15
|
+
showPin: false,
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
created() {
|
|
19
|
+
nodeTypesStore.dispatch('getUserPinnedObjects');
|
|
20
|
+
},
|
|
21
|
+
methods: {
|
|
22
|
+
blockAlreadyPinned(object, type) {
|
|
23
|
+
return !!this.pinnedBlocks.find(obj => obj.type === type);
|
|
24
|
+
},
|
|
25
|
+
unPin(object) {
|
|
26
|
+
this.deselect();
|
|
27
|
+
return nodeTypesStore.dispatch('removeUserPinnedObject', object);
|
|
28
|
+
},
|
|
29
|
+
addPin(object) {
|
|
30
|
+
this.deselect();
|
|
31
|
+
return nodeTypesStore.dispatch('addUserPinnedObject', object);
|
|
32
|
+
},
|
|
33
|
+
},
|
|
8
34
|
computed: {
|
|
35
|
+
pinnedBlocks() {
|
|
36
|
+
const pinnedNodeTypes = nodeTypesStore.getters.getPinnedNodeTypes;
|
|
37
|
+
|
|
38
|
+
//Filter pinnedNodeTypes to only return objects with PM Blocks type.
|
|
39
|
+
const filteredPinnedNodeTypes = pinnedNodeTypes.filter(obj => {
|
|
40
|
+
return obj.type?.includes('processmaker-pm-block');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return filteredPinnedNodeTypes;
|
|
44
|
+
},
|
|
45
|
+
unpinnedBlocks() {
|
|
46
|
+
const objects = this.pmBlockNodeTypes;
|
|
47
|
+
return objects.filter((obj) => !this.pinnedBlocks.some(pinnedObj => pinnedObj.type === obj.type));
|
|
48
|
+
},
|
|
9
49
|
pmBlockNodeTypes() {
|
|
10
50
|
return nodeTypesStore.getters.getPmBlockNodeTypes;
|
|
11
51
|
},
|
|
@@ -25,30 +65,78 @@ export default {
|
|
|
25
65
|
<template v-for="object in filteredPmBlockNodes">
|
|
26
66
|
<div
|
|
27
67
|
class="node-types__item"
|
|
68
|
+
:data-test="object.type"
|
|
28
69
|
:key="object.id"
|
|
70
|
+
@mouseover="showPin = true"
|
|
71
|
+
@mouseleave="showPin = false"
|
|
29
72
|
@click.stop="onClickHandler($event, object)"
|
|
30
73
|
>
|
|
31
74
|
<div class="d-flex">
|
|
32
75
|
<i v-if="!object.svgIcon" class="node-types__item__icon" :class="object.customIcon"/>
|
|
33
76
|
<img v-else class="node-types__item__icon" :src="object.svgIcon" :alt="$t(object.label)">
|
|
34
77
|
<label>{{ $t(object.label) }}</label>
|
|
78
|
+
<img
|
|
79
|
+
v-if="blockAlreadyPinned(object, object.type)"
|
|
80
|
+
:src="pinFillIcon"
|
|
81
|
+
class="pinIcon"
|
|
82
|
+
alt="Unpin Element"
|
|
83
|
+
@click="unPin(object)"
|
|
84
|
+
>
|
|
85
|
+
<img
|
|
86
|
+
v-else
|
|
87
|
+
:src="pinIcon"
|
|
88
|
+
class="pinIcon"
|
|
89
|
+
alt="Pin Element"
|
|
90
|
+
@click="addPin(object)"
|
|
91
|
+
>
|
|
35
92
|
</div>
|
|
36
93
|
</div>
|
|
37
94
|
</template>
|
|
38
95
|
</div>
|
|
39
96
|
<template v-if="filteredPmBlockNodes.length === 0 && !searchTerm">
|
|
40
|
-
<div class="
|
|
41
|
-
<
|
|
97
|
+
<div class="pinnedBlocks" v-if="pinnedBlocks.length > 0">
|
|
98
|
+
<p>{{ $t('Pinned PM Blocks') }}</p>
|
|
99
|
+
<template v-for="pinnedBlock in pinnedBlocks">
|
|
42
100
|
<div
|
|
43
|
-
class="
|
|
101
|
+
class="node-types__item"
|
|
102
|
+
:data-test="pinnedBlock.type"
|
|
103
|
+
:key="pinnedBlock.id"
|
|
104
|
+
@mouseover="showPin = true"
|
|
105
|
+
@mouseleave="showPin = false"
|
|
106
|
+
@click.stop="onClickHandler($event, pinnedBlock)"
|
|
107
|
+
>
|
|
108
|
+
<i v-if="!containsSvg(pinnedBlock.icon)" :class="pinnedBlock.customIcon" class="fa-lg"/>
|
|
109
|
+
<img v-else class="node-types__item__icon" :src="pinnedBlock.svgIcon" :alt="$t(pinnedBlock.label)">
|
|
110
|
+
<span>{{ $t(pinnedBlock.label) }}</span>
|
|
111
|
+
<img
|
|
112
|
+
:src="pinFillIcon"
|
|
113
|
+
class="pinIcon"
|
|
114
|
+
alt="Pin/Unpin Element"
|
|
115
|
+
@click="unPin(pinnedBlock)"
|
|
116
|
+
>
|
|
117
|
+
</div>
|
|
118
|
+
</template>
|
|
119
|
+
</div>
|
|
120
|
+
<div class="objectCategory">
|
|
121
|
+
<p>{{ $t('PM Block Category') }}</p>
|
|
122
|
+
<template v-for="nodeType in unpinnedBlocks">
|
|
123
|
+
<div
|
|
124
|
+
class="node-types__item"
|
|
125
|
+
:data-test="nodeType.type"
|
|
44
126
|
:key="nodeType.id"
|
|
127
|
+
@mouseover="showPin = true"
|
|
128
|
+
@mouseleave="showPin = false"
|
|
45
129
|
@click.stop="onClickHandler($event, nodeType)"
|
|
46
130
|
>
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
131
|
+
<i v-if="!containsSvg(nodeType.icon)" :class="nodeType.customIcon" class="fa-lg"/>
|
|
132
|
+
<img v-else class="node-types__item__icon" :src="nodeType.svgIcon" :alt="$t(nodeType.label)">
|
|
133
|
+
<span>{{ $t(nodeType.label) }}</span>
|
|
134
|
+
<img
|
|
135
|
+
:src="pinIcon"
|
|
136
|
+
class="pinIcon"
|
|
137
|
+
alt="Pin/Unpin Element"
|
|
138
|
+
@click="addPin(nodeType)"
|
|
139
|
+
>
|
|
52
140
|
</div>
|
|
53
141
|
</template>
|
|
54
142
|
</div>
|
|
@@ -57,6 +145,11 @@ export default {
|
|
|
57
145
|
</template>
|
|
58
146
|
|
|
59
147
|
<style lang="scss">
|
|
148
|
+
#pmBlockNodeTypesList {
|
|
149
|
+
.pinnedBlocks {
|
|
150
|
+
margin-bottom: 1rem;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
60
153
|
.pm-block-node-types {
|
|
61
154
|
&__item {
|
|
62
155
|
display: block;
|
|
@@ -66,6 +159,9 @@ export default {
|
|
|
66
159
|
margin-bottom: 8px;
|
|
67
160
|
&:hover {
|
|
68
161
|
background-color: #EBEEF2;
|
|
162
|
+
.pinIcon {
|
|
163
|
+
background-color: #DADDDF;
|
|
164
|
+
}
|
|
69
165
|
}
|
|
70
166
|
&__icon {
|
|
71
167
|
width: 1.5rem;
|
|
@@ -81,6 +177,11 @@ export default {
|
|
|
81
177
|
font-size: 13px;
|
|
82
178
|
color:#6C757D;
|
|
83
179
|
}
|
|
180
|
+
.pinIcon {
|
|
181
|
+
margin-left: auto;
|
|
182
|
+
border-radius: 4px;
|
|
183
|
+
padding: 0.3rem;
|
|
184
|
+
}
|
|
84
185
|
}
|
|
85
186
|
}
|
|
86
187
|
</style>
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
@openPanel="handleOpenPanel"
|
|
8
8
|
/>
|
|
9
9
|
|
|
10
|
+
<AiGenerateButton/>
|
|
11
|
+
|
|
10
12
|
<ValidateButton @openIssue="handleOpenIssue" />
|
|
11
13
|
|
|
12
14
|
<ValidatePanel
|
|
@@ -22,11 +24,13 @@
|
|
|
22
24
|
import store from '@/store';
|
|
23
25
|
import { ValidateButton, ValidateIssue, ValidatePanel } from '@/components/topRail/validateControl';
|
|
24
26
|
import MultiplayerViewUsers from '@/components/topRail/multiplayerViewUsers/MultiplayerViewUsers';
|
|
27
|
+
import AiGenerateButton from '../aiMessages/AiGenerateButton.vue';
|
|
25
28
|
export default {
|
|
26
29
|
components: {
|
|
27
30
|
ValidateButton,
|
|
28
31
|
ValidateIssue,
|
|
29
32
|
ValidatePanel,
|
|
33
|
+
AiGenerateButton,
|
|
30
34
|
MultiplayerViewUsers,
|
|
31
35
|
},
|
|
32
36
|
props: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<b-avatar-group class="container" v-show="isMultiplayer">
|
|
3
|
-
<template v-for="item in
|
|
3
|
+
<template v-for="item in players" >
|
|
4
4
|
<Avatar
|
|
5
5
|
:badgeBackgroundColor="item.color"
|
|
6
6
|
:imgSrc="item.avatar"
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
</template>
|
|
14
14
|
|
|
15
15
|
<script>
|
|
16
|
-
import { uniqBy } from 'lodash';
|
|
17
16
|
import Avatar from '@/components/topRail/multiplayerViewUsers/avatar/Avatar';
|
|
18
17
|
import store from '@/store';
|
|
19
18
|
|
|
@@ -28,12 +27,6 @@ export default {
|
|
|
28
27
|
},
|
|
29
28
|
},
|
|
30
29
|
computed: {
|
|
31
|
-
filteredPlayers() {
|
|
32
|
-
const allPlayers = uniqBy(this.players, 'name');
|
|
33
|
-
return allPlayers.filter(player => {
|
|
34
|
-
return player.name.toLowerCase() !== window.ProcessMaker.user?.fullName.toLowerCase();
|
|
35
|
-
});
|
|
36
|
-
},
|
|
37
30
|
isMultiplayer: () => store.getters.isMultiplayer,
|
|
38
31
|
},
|
|
39
32
|
};
|