@@ -50,7 +50,7 @@ class Topology extends Window {
5050 this . sideBar . textContent = "" ;
5151
5252 if ( this . selected ) {
53- this . selected . element . rect . classList . remove ( "topology-selected" ) ;
53+ this . selected . element . highlight . classList . remove ( "topology-selected" ) ;
5454 this . selected = null ;
5555 }
5656 } ;
@@ -171,6 +171,18 @@ class Topology extends Window {
171171 firewallImage . setAttribute ( "href" , "mono/firewall.svg?light" ) ;
172172 firewallMask . appendChild ( firewallImage ) ;
173173
174+ const l2switchMask = document . createElementNS ( "http://www.w3.org/2000/svg" , "mask" ) ;
175+ l2switchMask . setAttribute ( "id" , "l2switchMask" ) ;
176+ l2switchMask . setAttribute ( "mask-type" , "alpha" ) ;
177+ this . svg . appendChild ( l2switchMask ) ;
178+ const l2switchImage = document . createElementNS ( "http://www.w3.org/2000/svg" , "image" ) ;
179+ l2switchImage . setAttribute ( "x" , 2 ) ;
180+ l2switchImage . setAttribute ( "y" , 2 ) ;
181+ l2switchImage . setAttribute ( "width" , 44 ) ;
182+ l2switchImage . setAttribute ( "height" , 44 ) ;
183+ l2switchImage . setAttribute ( "href" , "mono/switch.svg?light" ) ;
184+ l2switchMask . appendChild ( l2switchImage ) ;
185+
174186 this . linksGroup = document . createElementNS ( "http://www.w3.org/2000/svg" , "g" ) ;
175187 this . linksGroup . setAttribute ( "stroke" , "#c0c0c0" ) ;
176188 this . linksGroup . setAttribute ( "stroke-width" , 3 ) ;
@@ -319,7 +331,7 @@ class Topology extends Window {
319331 if ( json . initial ) {
320332 let count = 0 ;
321333 for ( let i = 0 ; i < json . initial . length ; i ++ ) {
322- const element = this . CreateDevice ( {
334+ const element = this . CreateDeviceElement ( {
323335 file : json . initial [ i ] . file ,
324336 type : json . initial [ i ] . type ,
325337 name : json . initial [ i ] . hostname ,
@@ -377,15 +389,15 @@ class Topology extends Window {
377389 this . stopButton . disabled = true ;
378390 }
379391
380- CreateDevice ( options ) {
392+ CreateDeviceElement ( options ) {
381393 const g = document . createElementNS ( "http://www.w3.org/2000/svg" , "g" ) ;
382394 g . style . transform = `translate(${ options . x } px,${ options . y } px)` ;
383395 g . setAttribute ( "file" , options . file ) ;
384396 this . svg . appendChild ( g ) ;
385397
386398 const rect = document . createElementNS ( "http://www.w3.org/2000/svg" , "rect" ) ;
387- rect . setAttribute ( "rx" , 8 ) ;
388- rect . setAttribute ( "ry" , 8 ) ;
399+ rect . setAttribute ( "rx" , 16 ) ;
400+ rect . setAttribute ( "ry" , 16 ) ;
389401 rect . setAttribute ( "width" , 96 ) ;
390402 rect . setAttribute ( "height" , 96 ) ;
391403 rect . setAttribute ( "fill" , "transparent" ) ;
@@ -429,26 +441,97 @@ class Topology extends Window {
429441
430442 return {
431443 root : g ,
432- rect : rect ,
444+ highlight : rect ,
433445 icon : icon ,
434446 label : label ,
435447 x : options . x ,
436448 y : options . y
437449 } ;
438450 }
439451
452+ CreateUnmanagedSwitchElement ( options ) {
453+ const uuid = UI . GenerateUuid ( ) ;
454+
455+ const g = document . createElementNS ( "http://www.w3.org/2000/svg" , "g" ) ;
456+ g . style . transform = `translate(${ options . x } px,${ options . y } px)` ;
457+ g . setAttribute ( "file" , uuid ) ;
458+ this . svg . appendChild ( g ) ;
459+
460+ const circle = document . createElementNS ( "http://www.w3.org/2000/svg" , "circle" ) ;
461+ circle . setAttribute ( "cx" , 24 ) ;
462+ circle . setAttribute ( "cy" , 24 ) ;
463+ circle . setAttribute ( "r" , 24 ) ;
464+ circle . setAttribute ( "fill" , "transparent" ) ;
465+ g . appendChild ( circle ) ;
466+
467+ const icon = document . createElementNS ( "http://www.w3.org/2000/svg" , "rect" ) ;
468+ icon . setAttribute ( "x" , 4 ) ;
469+ icon . setAttribute ( "y" , 4 ) ;
470+ icon . setAttribute ( "width" , 40 ) ;
471+ icon . setAttribute ( "height" , 40 ) ;
472+ icon . setAttribute ( "rx" , 20 ) ;
473+ icon . setAttribute ( "ry" , 20 ) ;
474+ icon . setAttribute ( "fill" , "#c0c0c0" ) ;
475+ icon . setAttribute ( "mask" , "url(#l2switchMask)" ) ;
476+ icon . style . transition = "fill .8s" ;
477+ g . appendChild ( icon ) ;
478+
479+ g . addEventListener ( "mousedown" , event => {
480+ event . stopPropagation ( ) ;
481+ const element = this . devices [ uuid ] . element ;
482+
483+ this . offsetX = element . x ;
484+ this . offsetY = element . y ;
485+ this . x0 = event . clientX ;
486+ this . y0 = event . clientY ;
487+
488+ this . svg . appendChild ( g ) ;
489+ this . SelectDevice ( uuid ) ;
490+ } ) ;
491+
492+ this . AdjustSvgSize ( ) ;
493+
494+ const element = {
495+ root : g ,
496+ highlight : circle ,
497+ icon : icon ,
498+ x : options . x ,
499+ y : options . y
500+ } ;
501+
502+ this . devices [ uuid ] = {
503+ element : element ,
504+ initial : { type : "switch" , unmanaged : true }
505+ } ;
506+
507+ return element ;
508+ }
509+
440510 ComputeLinks ( device ) {
441511 if ( ! device . lldp ) return ;
442512
443513 device . links = { } ;
444514
515+ console . log ( device . initial . hostname ) ;
516+
445517 for ( const key in device . lldp . remoteChassisIdSubtype ) {
446518
447- if ( device . lldp . remoteChassisIdSubtype . length === 1 ) {
448- device . links [ key ] = { } ;
519+ if ( device . lldp . remoteChassisIdSubtype [ key ] . length === 1 ) {
520+ console . log (
521+ key ,
522+ device . lldp . remoteSystemName [ key ] [ 0 ] ,
523+ device . lldp . remotePortIdSubtype [ key ] [ 0 ] ,
524+ device . lldp . remotePortId [ key ] [ 0 ] ,
525+ device . lldp . remoteChassisIdSubtype [ key ] [ 0 ] ,
526+ device . lldp . remoteChassisId [ key ] [ 0 ] ) ;
527+
528+ const remoteDevice = null ;
529+ //TODO:
530+ device . links [ key ] = { device :remoteDevice , port :null } ;
449531 }
450- else if ( device . lldp . remoteChassisIdSubtype . length > 1 ) {
451- device . links [ key ] = { } ;
532+ else if ( device . lldp . remoteChassisIdSubtype [ key ] . length > 1 ) {
533+ const unmanagedDevice = this . CreateUnmanagedSwitchElement ( { x : 100 , y : 100 } ) ;
534+ device . links [ key ] = { device :unmanagedDevice , port :null } ;
452535 }
453536
454537 for ( let i = 0 ; i < device . lldp . remoteChassisIdSubtype [ key ] . length ; i ++ ) {
@@ -465,13 +548,13 @@ class Topology extends Window {
465548
466549 for ( let i = 0 ; i < device . lldp . remotePortIdSubtype [ key ] . length ; i ++ ) {
467550 switch ( device . lldp . remotePortIdSubtype [ key ] [ i ] ) {
468- case 1 : //interface alias
469- case 2 : //port component
470- case 3 : //mac address
471- case 4 : //network name
472- case 5 : //int name
473- case 6 : //agent circuit ID
474- case 7 : //local
551+ case 1 : //interface alias
552+ case 2 : //port component
553+ case 3 : //mac address
554+ case 4 : //network name
555+ case 5 : //int name
556+ case 6 : //agent circuit ID
557+ case 7 : //local
475558 }
476559 }
477560
@@ -480,17 +563,19 @@ class Topology extends Window {
480563
481564 SelectDevice ( file ) {
482565 if ( this . selected ) {
483- this . selected . element . rect . classList . remove ( "topology-selected" ) ;
566+ this . selected . element . highlight . classList . remove ( "topology-selected" ) ;
484567 }
485568
486- this . devices [ file ] . element . rect . classList . add ( "topology-selected" ) ;
569+ const device = this . devices [ file ] ;
570+
571+ device . element . highlight . classList . add ( "topology-selected" ) ;
487572
488- this . selected = this . devices [ file ] ;
489- this . dragging = this . devices [ file ] ;
573+ this . selected = device ;
574+ this . dragging = device ;
490575
491576 this . sideBar . textContent = "" ;
492577
493- const initial = this . devices [ file ] . initial ;
578+ const initial = device . initial ;
494579
495580 const grid = document . createElement ( "div" ) ;
496581 grid . className = "topology-sidebar-grid" ;
@@ -507,24 +592,24 @@ class Topology extends Window {
507592 const hostnameLabel = document . createElement ( "div" ) ;
508593 hostnameLabel . style . gridArea = "2 / 2" ;
509594 hostnameLabel . style . fontWeight = "bold" ;
510- hostnameLabel . textContent = initial . hostname ;
595+ hostnameLabel . textContent = device . initial . unmanaged ? "unmanaged" : initial . hostname ;
511596 grid . appendChild ( hostnameLabel ) ;
512597
513598 const ipLabel = document . createElement ( "div" ) ;
514599 ipLabel . style . gridArea = "3 / 2" ;
515600 ipLabel . textContent = initial . ip ;
516601 grid . appendChild ( ipLabel ) ;
517602
518- if ( file in this . devices && this . devices [ file ] . lldp ) {
519- const id = this . devices [ file ] . lldp . localChassisId ;
603+ if ( file in this . devices && device . lldp ) {
604+ const id = device . lldp . localChassisId ;
520605 const idLabel = document . createElement ( "div" ) ;
521606 if ( id && initial . hostname != id && initial . ip != id ) {
522607 idLabel . style . gridArea = "4 / 2" ;
523608 idLabel . textContent = id ;
524609 grid . appendChild ( idLabel ) ;
525610 }
526611
527- const systemName = this . devices [ file ] . lldp . localHostname ;
612+ const systemName = device . lldp . localHostname ;
528613 if ( systemName ) {
529614 hostnameLabel . textContent = systemName ;
530615 hostnameLabel . style . gridArea = "1 / 2" ;
@@ -536,27 +621,23 @@ class Topology extends Window {
536621 intList . className = "topology-interface-list" ;
537622 this . sideBar . appendChild ( intList ) ;
538623
539- for ( let i = 0 ; i < this . devices [ file ] . lldp . localPortName . length ; i ++ ) {
624+
625+
626+ for ( let i = 0 ; i < device . lldp . localPortName . length ; i ++ ) {
540627 const interfaceBox = document . createElement ( "div" ) ;
541628 const localPort = document . createElement ( "div" ) ;
542629 const remotePort = document . createElement ( "div" ) ;
543630
544- let localPortName = this . devices [ file ] . lldp . localPortName [ i ] ;
631+ let localPortName = device . lldp . localPortName [ i ] ;
545632 if ( ! localPortName || localPortName . length === 0 ) {
546633 localPortName = `(${ i + 1 } )` ;
547634 localPort . style . color = "#404040" ;
548635 localPort . style . fontStyle = "italic" ;
549636 }
550637
551638 let remotePortName = "" ;
552- if ( i in this . devices [ file ] . lldp . remoteSystemName ) {
553- const remoteName = this . devices [ file ] . lldp . remoteSystemName [ i ] ;
554- if ( remoteName . length === 1 ) {
555- remotePortName = remoteName [ 0 ] ;
556- }
557- else {
558- remotePortName = "[...]" ;
559- }
639+ if ( i in device . links && device . links [ i ] . device ) {
640+ remotePortName = device . links [ i ] . device . initial . hostname ;
560641 }
561642
562643 intList . appendChild ( interfaceBox ) ;
0 commit comments