@processmaker/modeler 1.39.6 → 1.39.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@processmaker/modeler",
3
- "version": "1.39.6",
3
+ "version": "1.39.7",
4
4
  "scripts": {
5
5
  "serve": "vue-cli-service serve",
6
6
  "test:unit": "vue-cli-service test:unit",
@@ -23,6 +23,7 @@
23
23
  @close="close"
24
24
  @save-state="pushToUndoStack"
25
25
  @clearSelection="clearSelection"
26
+ :players="players"
26
27
  @action="handleToolbarAction"
27
28
  />
28
29
  <b-row class="modeler h-100">
@@ -153,6 +154,15 @@
153
154
  @save-state="pushToUndoStack"
154
155
  />
155
156
  </b-row>
157
+
158
+ <RemoteCursor
159
+ v-for="player in players"
160
+ :cursor-color="player.color"
161
+ :username="player.name"
162
+ :key="player.id"
163
+ :top="player.top"
164
+ :left="player.left"
165
+ />
156
166
  </span>
157
167
  </template>
158
168
 
@@ -213,7 +223,7 @@ import RailBottom from '@/components/railBottom/RailBottom.vue';
213
223
  import ProcessmakerModelerGenericFlow from '@/components/nodes/genericFlow/genericFlow';
214
224
 
215
225
  import Selection from './Selection';
216
-
226
+ import RemoteCursor from '@/components/multiplayer/remoteCursor/RemoteCursor.vue';
217
227
 
218
228
  export default {
219
229
  components: {
@@ -225,6 +235,7 @@ export default {
225
235
  ProcessmakerModelerGenericFlow,
226
236
  Selection,
227
237
  RailBottom,
238
+ RemoteCursor,
228
239
  },
229
240
  props: {
230
241
  owner: Object,
@@ -313,6 +324,7 @@ export default {
313
324
  isSelecting: false,
314
325
  isIntoTheSelection: false,
315
326
  dragStart: null,
327
+ players: [],
316
328
  showInspectorButton: true,
317
329
  inspectorButtonRight: 65,
318
330
  };
@@ -907,7 +919,7 @@ export default {
907
919
 
908
920
  const config = definition.config ? JSON.parse(definition.config) : {};
909
921
  const type = config?.processKey || parser(definition, this.moddle);
910
-
922
+
911
923
  const unnamedElements = ['bpmn:TextAnnotation', 'bpmn:Association', 'bpmn:DataOutputAssociation', 'bpmn:DataInputAssociation'];
912
924
  const requireName = unnamedElements.indexOf(bpmnType) === -1;
913
925
  if (requireName && !definition.get('name')) {
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <div class="remote-cursor" :style="{ left: left + 'px', top: top + 'px' }">
3
+ <inline-svg :src="cursorIcon" :fill="cursorColor" />
4
+
5
+ <div class="remote-username">
6
+ {{ username }}
7
+ </div>
8
+ </div>
9
+ </template>
10
+
11
+ <script>
12
+ import InlineSvg from 'vue-inline-svg';
13
+
14
+ export default {
15
+ components: {
16
+ InlineSvg,
17
+ },
18
+ props: {
19
+ cursorColor: {
20
+ type: String,
21
+ default: '#000000',
22
+ },
23
+ username: {
24
+ type: String,
25
+ },
26
+ top: {
27
+ type: Number,
28
+ },
29
+ left: {
30
+ type: Number,
31
+ },
32
+ },
33
+ data() {
34
+ return {
35
+ cursorIcon: require('@/components/multiplayer/remoteCursor/cursor.svg'),
36
+ };
37
+ },
38
+ };
39
+ </script>
40
+
41
+ <style scoped lang="scss">
42
+ .remote {
43
+ &-cursor {
44
+ position: absolute;
45
+ display: flex;
46
+ width: auto;
47
+ height: 34px;
48
+ }
49
+
50
+ &-username {
51
+ display: flex;
52
+ justify-content: center;
53
+ align-items: center;
54
+ margin-top: 12px;
55
+ padding: 4px 10px;
56
+ gap: 10px;
57
+ border-radius: 4px;
58
+ background-color: #212529;
59
+
60
+ color: #FFFFFF;
61
+ font-size: 12px;
62
+ font-style: normal;
63
+ font-weight: 400;
64
+ line-height: normal;
65
+ }
66
+ }
67
+ </style>
@@ -0,0 +1,3 @@
1
+ <svg width="23" height="19" viewBox="0 0 23 19" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M11.5 17.5L2 1L20.5 7L13 9L11.5 17.5Z" stroke="#212529" />
3
+ </svg>
@@ -8,6 +8,7 @@
8
8
  <TopRail
9
9
  :validation-errors="validationErrors"
10
10
  :warnings="warnings"
11
+ :players="players"
11
12
  >
12
13
  <component
13
14
  :is="component.button"
@@ -129,6 +130,7 @@ export default {
129
130
  'warnings',
130
131
  'xmlManager',
131
132
  'validationBar',
133
+ 'players',
132
134
  'extraActions',
133
135
  ],
134
136
  watch: {
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <div class="top-rail-container">
3
+ <MultiplayerViewUsers :players="players"/>
3
4
  <ValidateIssue
4
5
  v-show="isOpenIssue"
5
6
  :number-of-errors="numberOfErrors"
@@ -20,12 +21,13 @@
20
21
  <script>
21
22
  import store from '@/store';
22
23
  import { ValidateButton, ValidateIssue, ValidatePanel } from '@/components/topRail/validateControl';
23
-
24
+ import MultiplayerViewUsers from '@/components/topRail/multiplayerViewUsers/MultiplayerViewUsers';
24
25
  export default {
25
26
  components: {
26
27
  ValidateButton,
27
28
  ValidateIssue,
28
29
  ValidatePanel,
30
+ MultiplayerViewUsers,
29
31
  },
30
32
  props: {
31
33
  validationErrors: {
@@ -36,6 +38,10 @@ export default {
36
38
  type: Array,
37
39
  required: true,
38
40
  },
41
+ players: {
42
+ type: Array,
43
+ required: false,
44
+ },
39
45
  },
40
46
  data() {
41
47
  return {
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <b-avatar-group class="container">
3
+ <template v-for="item in players" >
4
+ <Avatar :badgeBackgroundColor="item.color" :imgSrc= "item.imgSrc" :userName="item.name" :key="item.key"/>
5
+ </template>
6
+ </b-avatar-group>
7
+ </template>
8
+
9
+ <script>
10
+ import Avatar from '@/components/topRail/multiplayerViewUsers/avatar/Avatar';
11
+ export default {
12
+ components:{
13
+ Avatar,
14
+ },
15
+ props: {
16
+ players: {
17
+ type: Array,
18
+ required: true,
19
+ },
20
+ },
21
+ };
22
+ </script>
@@ -0,0 +1,137 @@
1
+ <template>
2
+ <span
3
+ class="b-avatar rounded-circle"
4
+ :style="{'backgroundColor': generateColorHsl(userName, saturationRange, lightnessRange)}"
5
+ >
6
+ <span v-if="imgSrc" class="b-avatar-img">
7
+ <img :src="imgSrc" :alt=userName>
8
+ </span>
9
+ <span v-else class="b-avatar-text avatar-initials">
10
+ <span>
11
+ {{ this.getInitials(userName) }}
12
+ </span>
13
+
14
+ </span>
15
+ <span class="b-avatar-badge badge-danger"
16
+ :style="{bottom: '0px', right: '0px', backgroundColor: badgeBackgroundColor}"
17
+ />
18
+ </span>
19
+ </template>
20
+
21
+ <script>
22
+
23
+ export default {
24
+ props: {
25
+ badgeBackgroundColor: {
26
+ type: String,
27
+ required: false,
28
+ },
29
+ imgSrc: {
30
+ type: String,
31
+ required: false,
32
+ },
33
+ userName: {
34
+ type: String,
35
+ required: false,
36
+ },
37
+ },
38
+ data() {
39
+ return {
40
+ saturation: 50,
41
+ lightness: 50,
42
+ range: 10,
43
+ };
44
+ },
45
+ computed: {
46
+ saturationRange() {
47
+ return this.getRange(this.saturation, this.range);
48
+ },
49
+ lightnessRange() {
50
+ return this.getRange(this.lightness, this.range);
51
+ },
52
+ },
53
+ methods: {
54
+ /**
55
+ * Get the initials from a given name.
56
+ *
57
+ * @param {string} name - The full name from which to extract initials.
58
+ * @returns {string} The initials of the first and last names.
59
+ */
60
+ getInitials(name = '') {
61
+ const nameArray = name.split(' ');
62
+ const firstNameIn = nameArray[0].charAt(0).toUpperCase();
63
+ const lastNameIn = nameArray[nameArray.length - 1].charAt(0).toUpperCase();
64
+ return `${firstNameIn}${lastNameIn}`;
65
+ },
66
+ /**
67
+ * Calculates a hash value for a given string.
68
+ *
69
+ * @param {string} str - The input string for which the hash needs to be calculated.
70
+ * @returns {number} The calculated hash value for the input string.
71
+ */
72
+ getHashOfString(str){
73
+ let hash = 0;
74
+ for (let i = 0; i < str.length; i++) {
75
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
76
+ }
77
+ hash = Math.abs(hash);
78
+ return hash;
79
+ },
80
+ /**
81
+ * Calculates a range around a given value.
82
+ *
83
+ * @param {number} value - The central value.
84
+ * @param {number} range - The range value.
85
+ * @returns {number[]} An array containing the lower and upper bounds of the range.
86
+ */
87
+ getRange(value, range) {
88
+ return [Math.max(0, value-range), Math.min(value + range, 100)];
89
+ },
90
+ /**
91
+ * Get the hash number to within our range
92
+ *
93
+ * @param {Number} hash
94
+ * @param {Number} min
95
+ * @param {Number} max
96
+ * @returns {Number}
97
+ */
98
+ normalizeHash(hash, min, max){
99
+ return Math.floor((hash % (max - min)) + min);
100
+ },
101
+ /**
102
+ *Generate Unique Color, create a string using our h,s,l values.
103
+ * @param {String} name
104
+ * @param {Array} saturationRange
105
+ * @param {Array} lightnessRange
106
+ * @returns {Number}
107
+ */
108
+ generateHSL(name, saturationRange, lightnessRange) {
109
+ const hash = this.getHashOfString(name);
110
+ const h = this.normalizeHash(hash, 0, 360);
111
+ const s = this.normalizeHash(hash, saturationRange[0], saturationRange[1]);
112
+ const l = this.normalizeHash(hash, lightnessRange[0], lightnessRange[1]);
113
+ return [h, s, l];
114
+ },
115
+ /**
116
+ * Convert HSL array to string
117
+ * @param {Array} hsl
118
+ * @returns {String}
119
+ */
120
+ HSLtoString(hsl) {
121
+ return `hsl(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%)`;
122
+ },
123
+ /**
124
+ * Generate a unique hsl value.
125
+ * @param {String} name
126
+ * @param {Array} saturationRange
127
+ * @param {Array} lightnessRange
128
+ * @returns {String}
129
+ */
130
+ generateColorHsl(id, saturationRange, lightnessRange) {
131
+ return this.HSLtoString(this.generateHSL(id, saturationRange, lightnessRange));
132
+ },
133
+ },
134
+ };
135
+
136
+ </script>
137
+ <style scoped lang="scss" src="./avatar.scss"></style>
@@ -0,0 +1,6 @@
1
+ .avatar-initials {
2
+ text-align: center;
3
+ line-height: 2.4rem;
4
+ color: #ffffff;
5
+ font-weight: bold;
6
+ }