@@ -52,7 +52,11 @@ export class TopologyTreeComponent {
52
52
subscriptionContextMenu = input < SbbMenuItem < SubscriptionWithMetaData > [ ] > ( ) ;
53
53
subscriptionRuleContextMenu = input < SbbMenuItem < SubscriptionRule > [ ] > ( ) ;
54
54
55
- selectionMode = signal < 'single' | 'multiple' > ( 'single' ) ;
55
+ ctrlSelected = signal < boolean > ( false ) ;
56
+ shiftSelected = signal < boolean > ( false ) ;
57
+ selectionMode = computed < 'single' | 'multiple' > ( ( ) => {
58
+ return this . ctrlSelected ( ) || this . shiftSelected ( ) ? 'multiple' : 'single' ;
59
+ } ) ;
56
60
57
61
connectionsFilter = input < string [ ] > ( ) ;
58
62
@@ -150,6 +154,15 @@ export class TopologyTreeComponent {
150
154
return node ;
151
155
} ) ;
152
156
} ) ;
157
+ flatNodes = computed < TreeNode [ ] > ( ( ) => {
158
+ const flatten = ( nodes : TreeNode [ ] ) : TreeNode [ ] => {
159
+ return nodes . flatMap ( ( node ) => {
160
+ return [ node , ...( node . children ? flatten ( node . children ) : [ ] ) ] ;
161
+ } ) ;
162
+ } ;
163
+
164
+ return flatten ( this . nodes ( ) ) ;
165
+ } ) ;
153
166
contextMenu = computed ( ( ) => {
154
167
const selection = this . selection ( ) ;
155
168
const nodeType = selection ?. [ 0 ] ?. type ;
@@ -231,20 +244,38 @@ export class TopologyTreeComponent {
231
244
if ( ! ( event instanceof Array ) && event ) {
232
245
event = [ event ] ;
233
246
}
247
+
248
+ if ( this . shiftSelected ( ) ) {
249
+ const flatNodes = this . flatNodes ( ) ;
250
+ const newestSelected = event [ event . length - 1 ] ;
251
+ const oneBefore = event [ event . length - 2 ] ;
252
+ const nodeType = newestSelected . type ;
253
+
254
+ const newestSelectedIndex = flatNodes . findIndex ( ( node ) => node . key === newestSelected . key ) ;
255
+ const oneBeforeIndex = flatNodes . findIndex ( ( node ) => node . key === oneBefore . key ) ;
256
+
257
+ const inbetweenNodes = flatNodes . slice (
258
+ Math . min ( oneBeforeIndex , newestSelectedIndex ) ,
259
+ Math . max ( oneBeforeIndex , newestSelectedIndex ) + 1
260
+ ) . filter ( ( node ) => node . type === nodeType ) ;
261
+
262
+ event = [
263
+ ...event . filter ( ( node ) => ! inbetweenNodes . includes ( node ) ) ,
264
+ ...inbetweenNodes ,
265
+ ] ;
266
+ }
267
+
234
268
this . selection . set ( event as TreeNode [ ] ) ;
235
269
this . onMultipleSelectionChange ( event ?? [ ] ) ;
236
270
return ;
237
271
}
238
272
239
273
if ( event instanceof Array ) {
240
- console . log ( event ) ;
241
274
event = event [ event . length - 1 ] ;
242
275
}
243
276
244
- console . log ( 'single selection' , event ) ;
245
277
this . selection . set ( [ event ] ) ;
246
278
247
-
248
279
switch ( event . type ) {
249
280
case 'namespace' :
250
281
this . onNamespaceSelected ( event . data ) ;
@@ -363,13 +394,19 @@ export class TopologyTreeComponent {
363
394
364
395
onKeyDown ( event : KeyboardEvent ) {
365
396
if ( event . key === 'Shift' ) {
366
- this . selectionMode . set ( 'multiple' ) ;
397
+ this . shiftSelected . set ( true ) ;
398
+ }
399
+ if ( event . key === 'Control' ) {
400
+ this . ctrlSelected . set ( true ) ;
367
401
}
368
402
}
369
403
370
404
onKeyUp ( event : KeyboardEvent ) {
371
405
if ( event . key === 'Shift' ) {
372
- this . selectionMode . set ( 'single' ) ;
406
+ this . shiftSelected . set ( false ) ;
407
+ }
408
+ if ( event . key === 'Control' ) {
409
+ this . ctrlSelected . set ( false ) ;
373
410
}
374
411
}
375
412
0 commit comments