@abi-software/map-utilities 0.0.0-beta.6 → 1.0.0-beta.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.
@@ -1,350 +1,418 @@
1
- <template>
2
- <div class="selections-container">
3
- <el-row v-if="title">
4
- <el-col :span="12">
5
- <div class="title-text">
6
- {{ title }}
7
- </div>
8
- </el-col>
9
- </el-row>
10
- <div class="tree-container">
11
- <el-tree
12
- ref="regionTree"
13
- v-loading="!isReady"
14
- element-loading-background="rgba(0, 0, 0, 0.3)"
15
- show-checkbox
16
- :node-key="nodeKey"
17
- :data="treeData"
18
- :check-strictly="false"
19
- :expand-on-click-node="false"
20
- :render-after-expand="false"
21
- :default-expanded-keys="expandedKeys"
22
- @check="checkChanged"
23
- >
24
- <template #default="{ node, data }">
25
- <span
26
- v-if="mapType === 'flatmap'"
27
- class="region-tree-node"
28
- :class="{
29
- activeItem: nodeIsActive(data),
30
- hoverItem: nodeIsHover(data),
31
- }"
32
- @click="changeActiveByNode(data)"
33
- @mouseover="changeHoverByNode(data)"
34
- >
35
- <div :style="getBackgroundStyles(data)">
36
- {{ node.label }}
37
- </div>
38
- </span>
39
- <span
40
- v-else-if="mapType === 'scaffold'"
41
- class="region-tree-node"
42
- :class="{
43
- activeItem: active.includes(data.id),
44
- hoverItem: hover.includes(data.id),
45
- }"
46
- @click="changeActiveByNode(data, true)"
47
- @mouseover="changeHoverByNode(data, true)"
48
- >
49
- <el-color-picker
50
- v-if="data.isPrimitives"
51
- :class="{ 'show-picker': showColourPicker }"
52
- v-model="data.activeColour"
53
- size="small"
54
- :popper-class="myPopperClass"
55
- @change="setColour(data, $event)"
56
- />
57
- <span>{{ node.label }}</span>
58
- <span v-if="data.isTextureSlides" class="node-options">
59
- (Texture)
60
- </span>
61
- </span>
62
- </template>
63
- </el-tree>
64
- </div>
65
- </div>
66
- </template>
67
-
68
- <script>
69
- export default {
70
- name: "TreeControls",
71
- props: {
72
- /**
73
- * The type of map that the TreeControls is used. Either "flatmap" or "scaffold".
74
- */
75
- mapType: {
76
- type: String,
77
- required: true,
78
- },
79
- isReady: {
80
- type: Boolean,
81
- default: true,
82
- },
83
- /**
84
- * The title of the TreeControls.
85
- */
86
- title: {
87
- type: String,
88
- },
89
- /**
90
- * The data of the tree.
91
- */
92
- treeData: {
93
- type: Array,
94
- default: function () {
95
- return [];
96
- },
97
- },
98
- showColourPicker: {
99
- type: Boolean,
100
- default: false,
101
- },
102
- /**
103
- * The active node of the tree.
104
- */
105
- active: {
106
- type: [String, Array],
107
- required: true,
108
- },
109
- /**
110
- * The hover node of the tree.
111
- */
112
- hover: {
113
- type: [String, Array],
114
- required: true,
115
- },
116
- },
117
- data: function () {
118
- return {
119
- defaultExpandedKeys: ["All"],
120
- myPopperClass: "hide-scaffold-colour-popup",
121
- };
122
- },
123
- computed: {
124
- isFlatmap: function () {
125
- return this.mapType === "flatmap";
126
- },
127
- isScaffold: function () {
128
- return this.mapType === "scaffold";
129
- },
130
- nodeKey: function () {
131
- if (this.isFlatmap) {
132
- return "key";
133
- } else if (this.isScaffold) {
134
- return "id";
135
- }
136
- },
137
- expandedKeys: function () {
138
- if (this.isFlatmap) {
139
- return this.defaultExpandedKeys;
140
- } else if (this.isScaffold) {
141
- return [];
142
- }
143
- },
144
- },
145
- watch: {
146
- showColourPicker: {
147
- immediate: true,
148
- handler: function () {
149
- if (this.showColourPicker) this.myPopperClass = "showPicker";
150
- else this.myPopperClass = "hide-scaffold-colour-popup";
151
- },
152
- },
153
- },
154
- methods: {
155
- setColour: function (nodeData, value) {
156
- this.$emit("setColour", nodeData, value);
157
- },
158
- getBackgroundStyles: function (node) {
159
- if ("colour" in node) {
160
- return { background: node.colour };
161
- }
162
- return {};
163
- },
164
- nodeIsActive: function (data) {
165
- return this.active === data.models;
166
- },
167
- nodeIsHover: function (data) {
168
- return this.hover === data.models;
169
- },
170
- changeActiveByNode: function (data, propagate = false) {
171
- if (this.isFlatmap) {
172
- if (data.models) {
173
- this.$emit("changeActive", data.models);
174
- }
175
- } else if (this.isScaffold) {
176
- if (data.isPrimitives || data.isRegion) {
177
- this.$emit("changeActive", data, propagate);
178
- }
179
- }
180
- },
181
- changeHoverByNode: function (data, propagate = false) {
182
- if (this.isFlatmap) {
183
- if (data.models) {
184
- this.$emit("changeHover", data.models);
185
- }
186
- } else if (this.isScaffold) {
187
- if (data.isPrimitives) {
188
- this.$emit("changeHover", data, propagate);
189
- }
190
- }
191
- },
192
- checkChanged: function (node, data) {
193
- if (this.isFlatmap) {
194
- const isChecked = data.checkedKeys.includes(node.key);
195
- if (node.key === "All") {
196
- this.$emit("checkAll", isChecked);
197
- } else {
198
- this.$emit("checkChanged", { key: node.key, value: isChecked });
199
- }
200
- } else if (this.isScaffold) {
201
- this.$emit("checkChanged", node, data);
202
- }
203
- },
204
- },
205
- unmounted: function () {
206
- this.sortedPrimitiveGroups = undefined;
207
- },
208
- };
209
- </script>
210
-
211
- <style lang="scss" scoped>
212
- :deep(.el-loading-spinner) {
213
- .path {
214
- stroke: $app-primary-color;
215
- }
216
-
217
- .el-loading-text {
218
- color: $app-primary-color;
219
- }
220
- }
221
-
222
- .selections-container {
223
- padding-top: 5px;
224
- }
225
-
226
- .title-text {
227
- width: 59px;
228
- height: 20px;
229
- color: rgb(48, 49, 51);
230
- font-size: 14px;
231
- font-weight: normal;
232
- line-height: 20px;
233
- margin-left: 8px;
234
- }
235
-
236
- .tree-container {
237
- width: 260px;
238
- border: 1px solid rgb(144, 147, 153);
239
- border-radius: 4px;
240
- background: #ffffff;
241
- margin-top: 6px;
242
- scrollbar-width: thin;
243
- overflow: hidden;
244
-
245
- :deep(.el-tree) {
246
- max-height: 240px;
247
- min-height: 130px;
248
- overflow: auto;
249
-
250
- &::-webkit-scrollbar {
251
- width: 4px;
252
- }
253
-
254
- &::-webkit-scrollbar-thumb {
255
- border-radius: 10px;
256
- box-shadow: inset 0 0 6px #c0c4cc;
257
- }
258
- }
259
-
260
- :deep(.el-tree-node__content) {
261
- height: 22px;
262
- }
263
- }
264
-
265
- :deep(.el-checkbox__input) {
266
- &.is-indeterminate,
267
- &.is-checked {
268
- .el-checkbox__inner {
269
- background-color: $app-primary-color;
270
- border-color: $app-primary-color;
271
- }
272
- }
273
- }
274
-
275
- :deep(
276
- .el-tree-node__children
277
- .el-tree-node__children
278
- .el-tree-node__content
279
- > label.el-checkbox
280
- ) {
281
- display: none;
282
- }
283
-
284
- :deep(.el-checkbox__label) {
285
- padding-left: 5px;
286
- color: $app-primary-color !important;
287
- font-size: 12px;
288
- font-weight: 500;
289
- letter-spacing: 0px;
290
- line-height: 14px;
291
- }
292
-
293
- .activeItem {
294
- background-color: #bbb !important;
295
- }
296
-
297
- .hoverItem {
298
- background-color: #eee !important;
299
- }
300
-
301
- .region-tree-node {
302
- flex: 1;
303
- color: $app-primary-color !important;
304
- display: flex;
305
- font-size: 12px;
306
- line-height: 14px;
307
- padding-left: 0px;
308
- background-color: #fff;
309
- width: 100%;
310
-
311
- :deep(.el-color-picker) {
312
- height: 14px !important;
313
- }
314
-
315
- :deep(.el-color-picker__trigger) {
316
- margin-left: 8px;
317
- margin-right: 8px;
318
- padding: 0px;
319
- height: 14px;
320
- width: 14px;
321
- border: 0px;
322
- }
323
- }
324
-
325
- :deep(.el-color-picker__color) {
326
- border: 1px solid $app-primary-color;
327
- }
328
-
329
- :deep(.el-color-picker__icon) {
330
- &.el-icon-arrow-down {
331
- display: none;
332
- }
333
- }
334
-
335
- :deep(.show-picker) {
336
- .el-color-picker__icon {
337
- &.el-icon-arrow-down {
338
- display: block;
339
- }
340
- }
341
- }
342
-
343
- .hide-scaffold-colour-popup {
344
- display: none;
345
- }
346
-
347
- .node-options {
348
- text-align: right;
349
- }
350
- </style>
1
+ <template>
2
+ <div class="selections-container">
3
+ <el-row v-if="title">
4
+ <el-col :span="12">
5
+ <div class="title-text">
6
+ {{ title }}
7
+ </div>
8
+ </el-col>
9
+ </el-row>
10
+ <div class="tree-container" ref="treeContainer">
11
+ <div :class="['tree-tooltip', tooltipAtBottom ? 'bottom' : '']" >
12
+ <el-popover
13
+ ref="tooltip"
14
+ :visible="tooltipVisible"
15
+ placement="top"
16
+ :show-arrow="false"
17
+ :teleported="false"
18
+ trigger="manual"
19
+ popper-class="tree-tooltip-popper"
20
+ virtual-triggering
21
+ :width="260"
22
+ >
23
+ <template #default>
24
+ <div class="tooltip-text">{{ tooltipLabel }}</div>
25
+ </template>
26
+ </el-popover>
27
+ </div>
28
+ <el-tree
29
+ ref="regionTree"
30
+ v-loading="!isReady"
31
+ element-loading-background="rgba(0, 0, 0, 0.3)"
32
+ show-checkbox
33
+ :node-key="nodeKey"
34
+ :data="treeData"
35
+ :check-strictly="false"
36
+ :expand-on-click-node="false"
37
+ :render-after-expand="false"
38
+ :default-expanded-keys="expandedKeys"
39
+ @check="checkChanged"
40
+ :indent="8"
41
+ :class="[mapType === 'flatmap' ? 'hide_grandchildren_checkbox': '']"
42
+ >
43
+ <template #default="{ node, data }">
44
+ <span
45
+ v-if="mapType === 'flatmap'"
46
+ class="region-tree-node"
47
+ :class="{
48
+ activeItem: nodeIsActive(data),
49
+ hoverItem: nodeIsHover(data),
50
+ }"
51
+ @click="changeActiveByNode(data)"
52
+ @mouseover="changeHoverByNode(data, false)"
53
+ @mouseenter="displayTooltip(node.label, true, $event)"
54
+ @mouseleave="displayTooltip('', false, $event)"
55
+ >
56
+ <div :style="getBackgroundStyles(data)" class="lastChildInItem">
57
+ {{ node.label }}
58
+ </div>
59
+ </span>
60
+ <span
61
+ v-else-if="mapType === 'scaffold'"
62
+ class="region-tree-node"
63
+ :class="{
64
+ activeItem: active.includes(data.id),
65
+ hoverItem: hover.includes(data.id),
66
+ }"
67
+ @click="changeActiveByNode(data, true)"
68
+ @mouseover="changeHoverByNode(data, true, $event)"
69
+ @mouseenter="displayTooltip(node.label, true, $event)"
70
+ @mouseleave="displayTooltip('', false, $event)"
71
+ >
72
+ <el-color-picker
73
+ v-if="data.isPrimitives"
74
+ :class="{ 'show-picker': showColourPicker }"
75
+ v-model="data.activeColour"
76
+ size="small"
77
+ :popper-class="myPopperClass"
78
+ @change="setColour(data, $event)"
79
+ />
80
+ <div class="lastChildInItem">
81
+ <span>{{ node.label }}</span>
82
+ <span v-if="data.isTextureSlides" class="node-options">
83
+ (Texture)
84
+ </span>
85
+ </div>
86
+ </span>
87
+ </template>
88
+ </el-tree>
89
+ </div>
90
+ </div>
91
+ </template>
92
+
93
+ <script>
94
+ export default {
95
+ name: "TreeControls",
96
+ props: {
97
+ /**
98
+ * The type of map that the TreeControls is used. Either "flatmap" or "scaffold".
99
+ */
100
+ mapType: {
101
+ type: String,
102
+ required: true,
103
+ },
104
+ isReady: {
105
+ type: Boolean,
106
+ default: true,
107
+ },
108
+ /**
109
+ * The title of the TreeControls.
110
+ */
111
+ title: {
112
+ type: String,
113
+ },
114
+ /**
115
+ * The data of the tree.
116
+ */
117
+ treeData: {
118
+ type: Array,
119
+ default: function () {
120
+ return [];
121
+ },
122
+ },
123
+ showColourPicker: {
124
+ type: Boolean,
125
+ default: false,
126
+ },
127
+ /**
128
+ * The active node of the tree.
129
+ */
130
+ active: {
131
+ type: [String, Array],
132
+ required: true,
133
+ },
134
+ /**
135
+ * The hover node of the tree.
136
+ */
137
+ hover: {
138
+ type: [String, Array],
139
+ required: true,
140
+ },
141
+ },
142
+ data: function () {
143
+ return {
144
+ defaultExpandedKeys: ["All"],
145
+ myPopperClass: "hide-scaffold-colour-popup",
146
+ tooltipVisible: false,
147
+ tooltipLabel: "",
148
+ tooltipAtBottom: false,
149
+ };
150
+ },
151
+ computed: {
152
+ isFlatmap: function () {
153
+ return this.mapType === "flatmap";
154
+ },
155
+ isScaffold: function () {
156
+ return this.mapType === "scaffold";
157
+ },
158
+ nodeKey: function () {
159
+ if (this.isFlatmap) {
160
+ return "key";
161
+ } else if (this.isScaffold) {
162
+ return "id";
163
+ }
164
+ },
165
+ expandedKeys: function () {
166
+ if (this.isFlatmap) {
167
+ return this.defaultExpandedKeys;
168
+ } else if (this.isScaffold) {
169
+ return [];
170
+ }
171
+ },
172
+ },
173
+ watch: {
174
+ showColourPicker: {
175
+ immediate: true,
176
+ handler: function () {
177
+ if (this.showColourPicker) this.myPopperClass = "showPicker";
178
+ else this.myPopperClass = "hide-scaffold-colour-popup";
179
+ },
180
+ },
181
+ },
182
+ methods: {
183
+ setColour: function (nodeData, value) {
184
+ this.$emit("setColour", nodeData, value);
185
+ },
186
+ getBackgroundStyles: function (node) {
187
+ if ("colour" in node) {
188
+ return { background: node.colour };
189
+ }
190
+ return {};
191
+ },
192
+ nodeIsActive: function (data) {
193
+ return this.active === data.models;
194
+ },
195
+ nodeIsHover: function (data) {
196
+ return this.hover === data.models;
197
+ },
198
+ changeActiveByNode: function (data, propagate = false) {
199
+ if (this.isFlatmap) {
200
+ if (data.models) {
201
+ this.$emit("changeActive", data.models);
202
+ }
203
+ } else if (this.isScaffold) {
204
+ if (data.isPrimitives || data.isRegion) {
205
+ this.$emit("changeActive", data, propagate);
206
+ }
207
+ }
208
+ },
209
+ changeHoverByNode: function (data, propagate = false) {
210
+ if (this.isFlatmap) {
211
+ if (data.models) {
212
+ this.$emit("changeHover", data.models);
213
+ }
214
+ } else if (this.isScaffold) {
215
+ if (data.isPrimitives) {
216
+ this.$emit("changeHover", data, propagate);
217
+ }
218
+ }
219
+ },
220
+ checkChanged: function (node, data) {
221
+ if (this.isFlatmap) {
222
+ const isChecked = data.checkedKeys.includes(node.key);
223
+ if (node.key === "All") {
224
+ this.$emit("checkAll", isChecked);
225
+ } else {
226
+ this.$emit("checkChanged", { key: node.key, value: isChecked });
227
+ }
228
+ } else if (this.isScaffold) {
229
+ this.$emit("checkChanged", node, data);
230
+ }
231
+ },
232
+ displayTooltip: function (tooltipLabel, visible, e) {
233
+ const hoverItem = e.target;
234
+ const containerItem = hoverItem.closest('.el-tree-node__content');
235
+ const containerItemWidth = containerItem.clientWidth;
236
+ const xOffset = containerItem.getBoundingClientRect().x;
237
+ const lastElement = containerItem.querySelector('.lastChildInItem');
238
+ let childrenWidth = 0;
239
+ if (lastElement) {
240
+ const rect = lastElement.getBoundingClientRect();
241
+ childrenWidth = rect.x + rect.width - xOffset;
242
+ }
243
+ const longLabel = childrenWidth > containerItemWidth;
244
+ this.tooltipVisible = longLabel && visible;
245
+ this.tooltipLabel = tooltipLabel;
246
+ this.tooltipAtBottom =
247
+ 0.5 > (e.layerY / this.$refs.treeContainer.clientHeight) ? true : false;
248
+ }
249
+ },
250
+ unmounted: function () {
251
+ this.sortedPrimitiveGroups = undefined;
252
+ },
253
+ };
254
+ </script>
255
+
256
+ <style lang="scss" scoped>
257
+ :deep(.el-loading-spinner) {
258
+ .path {
259
+ stroke: $app-primary-color;
260
+ }
261
+
262
+ .el-loading-text {
263
+ color: $app-primary-color;
264
+ }
265
+ }
266
+
267
+ .selections-container {
268
+ padding-top: 5px;
269
+ }
270
+
271
+ .title-text {
272
+ width: 59px;
273
+ height: 20px;
274
+ color: rgb(48, 49, 51);
275
+ font-size: 14px;
276
+ font-weight: normal;
277
+ line-height: 20px;
278
+ margin-left: 8px;
279
+ }
280
+
281
+ .tree-container {
282
+ width: 260px;
283
+ border: 1px solid rgb(144, 147, 153);
284
+ border-radius: 4px;
285
+ background: #ffffff;
286
+ margin-top: 6px;
287
+ scrollbar-width: thin;
288
+ overflow: hidden;
289
+ position:relative;
290
+
291
+ :deep(.el-tree) {
292
+ max-height: 240px;
293
+ min-height: 130px;
294
+ overflow: auto;
295
+
296
+ &::-webkit-scrollbar {
297
+ width: 4px;
298
+ }
299
+
300
+ &::-webkit-scrollbar-thumb {
301
+ border-radius: 10px;
302
+ box-shadow: inset 0 0 6px #c0c4cc;
303
+ }
304
+ }
305
+
306
+ :deep(.el-tree-node__content) {
307
+ height: 22px;
308
+ }
309
+ }
310
+
311
+ :deep(.el-checkbox__input) {
312
+ &.is-indeterminate,
313
+ &.is-checked {
314
+ .el-checkbox__inner {
315
+ background-color: $app-primary-color;
316
+ border-color: $app-primary-color;
317
+ }
318
+ }
319
+ }
320
+
321
+ .hide_grandchildren_checkbox {
322
+ :deep(
323
+ .el-tree-node__children
324
+ .el-tree-node__children
325
+ .el-tree-node__content
326
+ > label.el-checkbox
327
+ ) {
328
+ display: none;
329
+ }
330
+ }
331
+
332
+ :deep(.el-checkbox__label) {
333
+ padding-left: 5px;
334
+ color: $app-primary-color !important;
335
+ font-size: 12px;
336
+ font-weight: 500;
337
+ letter-spacing: 0px;
338
+ line-height: 14px;
339
+ }
340
+
341
+ .activeItem {
342
+ background-color: #bbb !important;
343
+ }
344
+
345
+ .hoverItem {
346
+ background-color: #eee !important;
347
+ }
348
+
349
+ .region-tree-node {
350
+ flex: 1;
351
+ color: $app-primary-color !important;
352
+ display: flex;
353
+ font-size: 12px;
354
+ line-height: 14px;
355
+ padding-left: 0px;
356
+ background-color: #fff;
357
+ width: 100%;
358
+
359
+ :deep(.el-color-picker) {
360
+ height: 14px !important;
361
+ }
362
+
363
+ :deep(.el-color-picker__trigger) {
364
+ margin-left: 8px;
365
+ margin-right: 8px;
366
+ padding: 0px;
367
+ height: 14px;
368
+ width: 14px;
369
+ border: 0px;
370
+ }
371
+ }
372
+
373
+ :deep(.el-color-picker__color) {
374
+ border: 1px solid $app-primary-color;
375
+ }
376
+
377
+ :deep(.el-color-picker__icon) {
378
+ &.el-icon-arrow-down {
379
+ display: none;
380
+ }
381
+ }
382
+
383
+ :deep(.show-picker) {
384
+ .el-color-picker__icon {
385
+ &.el-icon-arrow-down {
386
+ display: block;
387
+ }
388
+ }
389
+ }
390
+
391
+ .hide-scaffold-colour-popup {
392
+ display: none;
393
+ }
394
+
395
+ .node-options {
396
+ text-align: right;
397
+ }
398
+
399
+ :deep(.tree-tooltip-popper.el-popover) {
400
+ text-transform: none !important; // need to overide the tooltip text transform
401
+ border: 1px solid $app-primary-color;
402
+ padding: 4px;
403
+ font-size: 12px;
404
+ .el-popper__arrow {
405
+ &:before {
406
+ border-color: $app-primary-color;
407
+ background-color: #ffffff;
408
+ }
409
+ }
410
+ }
411
+
412
+ .tree-tooltip {
413
+ position:absolute;
414
+ &.bottom {
415
+ top: 70% ;
416
+ }
417
+ }
418
+ </style>