Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 1 | /* |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 2 | * Copyright 2019-present Open Networking Foundation |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the 'License'); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an 'AS IS' BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
Sean Condon | 0c577f6 | 2018-11-18 22:40:05 +0000 | [diff] [blame] | 16 | import { |
Sean Condon | 4e55c80 | 2019-12-03 22:13:34 +0000 | [diff] [blame] | 17 | AfterViewInit, |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 18 | Component, HostListener, Inject, Input, |
Sean Condon | 0c577f6 | 2018-11-18 22:40:05 +0000 | [diff] [blame] | 19 | OnDestroy, |
Sean Condon | 021f0fa | 2018-12-06 23:31:11 -0800 | [diff] [blame] | 20 | OnInit, SimpleChange, |
Sean Condon | 0c577f6 | 2018-11-18 22:40:05 +0000 | [diff] [blame] | 21 | ViewChild |
| 22 | } from '@angular/core'; |
Sean Condon | 55c3053 | 2018-10-29 12:26:57 +0000 | [diff] [blame] | 23 | import * as d3 from 'd3'; |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 24 | import { |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 25 | FnService, |
| 26 | IconService, |
Sean Condon | 0c577f6 | 2018-11-18 22:40:05 +0000 | [diff] [blame] | 27 | KeysService, |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 28 | KeysToken, |
| 29 | LionService, |
Sean Condon | 0c577f6 | 2018-11-18 22:40:05 +0000 | [diff] [blame] | 30 | LogService, |
| 31 | PrefsService, |
| 32 | SvgUtilService, |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 33 | TopoZoomPrefs, |
Sean Condon | 0c577f6 | 2018-11-18 22:40:05 +0000 | [diff] [blame] | 34 | WebSocketService, |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 35 | ZoomUtils |
Sean Condon | a3ad779 | 2020-01-04 19:26:34 +0000 | [diff] [blame] | 36 | } from 'gui2-fw-lib/public_api'; |
Sean Condon | 0c577f6 | 2018-11-18 22:40:05 +0000 | [diff] [blame] | 37 | import {InstanceComponent} from '../panel/instance/instance.component'; |
Sean Condon | 0c577f6 | 2018-11-18 22:40:05 +0000 | [diff] [blame] | 38 | import {DetailsComponent} from '../panel/details/details.component'; |
| 39 | import {BackgroundSvgComponent} from '../layer/backgroundsvg/backgroundsvg.component'; |
| 40 | import {ForceSvgComponent} from '../layer/forcesvg/forcesvg.component'; |
Sean Condon | 4e55c80 | 2019-12-03 22:13:34 +0000 | [diff] [blame] | 41 | import {Intent, TopologyService} from '../topology.service'; |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 42 | import { |
Sean Condon | 7191054 | 2019-02-16 18:16:42 +0000 | [diff] [blame] | 43 | GridDisplayToggle, |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 44 | HostLabelToggle, |
| 45 | LabelToggle, |
| 46 | UiElement |
| 47 | } from '../layer/forcesvg/models'; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 48 | import { |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 49 | ALL_TRAFFIC, |
| 50 | BKGRND_SELECT, |
| 51 | BKGRND_TOGGLE, |
| 52 | CANCEL_TRAFFIC, |
| 53 | CYCLEGRIDDISPLAY_BTN, |
| 54 | CYCLEHOSTLABEL_BTN, |
| 55 | CYCLELABELS_BTN, |
| 56 | DETAILS_TOGGLE, |
| 57 | EQMASTER_BTN, |
| 58 | HOSTS_TOGGLE, |
| 59 | INSTANCE_TOGGLE, |
| 60 | LAYOUT_ACCESS_BTN, |
| 61 | LAYOUT_DEFAULT_BTN, |
| 62 | OFFLINE_TOGGLE, |
| 63 | PORTS_TOGGLE, |
| 64 | QUICKHELP_BTN, |
| 65 | RESETZOOM_BTN, |
Sean Condon | 590b34b | 2019-12-04 18:44:37 +0000 | [diff] [blame] | 66 | SUMMARY_TOGGLE, |
| 67 | ALARMS_TOGGLE |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 68 | } from '../panel/toolbar/toolbar.component'; |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 69 | import {TrafficService, TrafficType} from '../traffic.service'; |
Sean Condon | a3ad779 | 2020-01-04 19:26:34 +0000 | [diff] [blame] | 70 | import {ZoomableDirective} from 'gui2-fw-lib/public_api'; |
Sean Condon | 0d064ec | 2019-02-04 21:53:53 +0000 | [diff] [blame] | 71 | import {MapObject} from '../layer/maputils'; |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 72 | import {LayoutService, LayoutType} from '../layout.service'; |
Sean Condon | 64ea7d2 | 2019-04-12 19:39:13 +0100 | [diff] [blame] | 73 | import {SelectedEvent} from '../layer/forcesvg/visuals/nodevisual'; |
Sean Condon | 4e55c80 | 2019-12-03 22:13:34 +0000 | [diff] [blame] | 74 | import {ActivatedRoute} from '@angular/router'; |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 75 | |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 76 | const TOPO2_PREFS = 'topo2_prefs'; |
Sean Condon | 0d064ec | 2019-02-04 21:53:53 +0000 | [diff] [blame] | 77 | const TOPO_MAPID_PREFS = 'topo_mapid'; |
| 78 | |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 79 | const PREF_BG = 'bg'; |
| 80 | const PREF_DETAIL = 'detail'; |
| 81 | const PREF_DLBLS = 'dlbls'; |
| 82 | const PREF_HLBLS = 'hlbls'; |
Sean Condon | 7191054 | 2019-02-16 18:16:42 +0000 | [diff] [blame] | 83 | const PREF_GRID = 'grid'; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 84 | const PREF_HOSTS = 'hosts'; |
| 85 | const PREF_INSTS = 'insts'; |
| 86 | const PREF_OFFDEV = 'offdev'; |
| 87 | const PREF_PORTHL = 'porthl'; |
| 88 | const PREF_SUMMARY = 'summary'; |
| 89 | const PREF_TOOLBAR = 'toolbar'; |
Sean Condon | 9de2135 | 2019-04-06 19:22:27 +0100 | [diff] [blame] | 90 | const PREF_PINNED = 'pinned'; |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 91 | const PREF_TRAFFIC = 'traffic'; |
Sean Condon | 590b34b | 2019-12-04 18:44:37 +0000 | [diff] [blame] | 92 | const PREF_ALARMS = 'alarms'; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 93 | |
Sean Condon | 64ea7d2 | 2019-04-12 19:39:13 +0100 | [diff] [blame] | 94 | const BACKGROUND_ELEMENTS = [ |
| 95 | 'svg topo2', |
| 96 | 'path bgmap' |
| 97 | ]; |
| 98 | |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 99 | /** |
Sean Condon | 0d064ec | 2019-02-04 21:53:53 +0000 | [diff] [blame] | 100 | * Model of the topo2_prefs object - this is a subset of the overall Prefs returned |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 101 | * by the server |
| 102 | */ |
| 103 | export interface Topo2Prefs { |
| 104 | bg: number; |
| 105 | detail: number; |
| 106 | dlbls: number; |
| 107 | hlbls: number; |
| 108 | hosts: number; |
| 109 | insts: number; |
| 110 | offdev: number; |
| 111 | porthl: number; |
| 112 | spr: number; |
| 113 | ovid: string; |
| 114 | summary: number; |
| 115 | toolbar: number; |
Sean Condon | 7191054 | 2019-02-16 18:16:42 +0000 | [diff] [blame] | 116 | grid: number; |
Sean Condon | 9de2135 | 2019-04-06 19:22:27 +0100 | [diff] [blame] | 117 | pinned: number; |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 118 | traffic: number; |
Sean Condon | 590b34b | 2019-12-04 18:44:37 +0000 | [diff] [blame] | 119 | alarms: number; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 120 | } |
| 121 | |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 122 | /** |
| 123 | * ONOS GUI Topology View |
| 124 | * |
| 125 | * This Topology View component is the top level component in a hierarchy that |
| 126 | * comprises the whole Topology View |
| 127 | * |
| 128 | * There are three main parts (panels, graphical and breadcrumbs) |
| 129 | * The panel hierarchy |
| 130 | * |-- Instances Panel (shows ONOS instances) |
| 131 | * |-- Summary Panel (summary of ONOS) |
| 132 | * |-- Toolbar Panel (the toolbar) |
| 133 | * |-- Details Panel (when a node is selected in the Force graphical view (see below)) |
| 134 | * |
| 135 | * The graphical hierarchy contains |
| 136 | * Topology (this) |
| 137 | * |-- No Devices Connected (only of there are no nodes to show) |
| 138 | * |-- Zoom Layer (everything beneath this can be zoomed and panned) |
| 139 | * |-- Background (container for any backgrounds - can be toggled on and off) |
| 140 | * |-- Map |
| 141 | * |-- Forces (all of the nodes and links laid out by a d3.force simulation) |
| 142 | * |
| 143 | * The breadcrumbs |
| 144 | * |-- Breadcrumb (in region view a way of navigating back up through regions) |
| 145 | */ |
| 146 | @Component({ |
| 147 | selector: 'onos-topology', |
| 148 | templateUrl: './topology.component.html', |
| 149 | styleUrls: ['./topology.component.css'] |
| 150 | }) |
Sean Condon | 4e55c80 | 2019-12-03 22:13:34 +0000 | [diff] [blame] | 151 | export class TopologyComponent implements OnInit, OnDestroy, AfterViewInit { |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 152 | @Input() bannerHeight: number = 48; |
Sean Condon | aa4366d | 2018-11-02 14:29:01 +0000 | [diff] [blame] | 153 | // These are references to the components inserted in the template |
Sean Condon | 0a884ad | 2019-10-28 17:57:21 +0000 | [diff] [blame] | 154 | @ViewChild(InstanceComponent, {static: true}) instance: InstanceComponent; |
| 155 | @ViewChild(DetailsComponent, {static: true}) details: DetailsComponent; |
| 156 | @ViewChild(BackgroundSvgComponent, {static: true}) background: BackgroundSvgComponent; |
| 157 | @ViewChild(ForceSvgComponent, {static: true}) force: ForceSvgComponent; |
| 158 | @ViewChild(ZoomableDirective, {static: true}) zoomDirective: ZoomableDirective; |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 159 | |
| 160 | flashMsg: string = ''; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 161 | // These are used as defaults if nothing is set on the server |
| 162 | prefsState: Topo2Prefs = <Topo2Prefs>{ |
| 163 | bg: 0, |
| 164 | detail: 1, |
| 165 | dlbls: 0, |
| 166 | hlbls: 2, |
| 167 | hosts: 0, |
| 168 | insts: 1, |
| 169 | offdev: 1, |
| 170 | ovid: 'traffic', // default to traffic overlay |
| 171 | porthl: 1, |
| 172 | spr: 0, |
| 173 | summary: 1, |
| 174 | toolbar: 0, |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 175 | grid: 0, |
| 176 | pinned: 0, |
Sean Condon | 590b34b | 2019-12-04 18:44:37 +0000 | [diff] [blame] | 177 | traffic: 2, // default to PORTSTATSPKTSEC, as it will iterate over to 0 on init |
| 178 | alarms: 1, |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 179 | }; |
Sean Condon | 0d064ec | 2019-02-04 21:53:53 +0000 | [diff] [blame] | 180 | |
| 181 | mapIdState: MapObject = <MapObject>{ |
| 182 | id: undefined, |
| 183 | scale: 1.0 |
| 184 | }; |
| 185 | mapSelShown: boolean = false; |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 186 | lionFn; // Function |
Sean Condon | 55c3053 | 2018-10-29 12:26:57 +0000 | [diff] [blame] | 187 | |
Sean Condon | 7191054 | 2019-02-16 18:16:42 +0000 | [diff] [blame] | 188 | gridShown: boolean = true; |
| 189 | geoGridShown: boolean = true; |
| 190 | |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 191 | constructor( |
| 192 | protected log: LogService, |
| 193 | protected fs: FnService, |
| 194 | protected ks: KeysService, |
| 195 | protected sus: SvgUtilService, |
| 196 | protected ps: PrefsService, |
Sean Condon | 55c3053 | 2018-10-29 12:26:57 +0000 | [diff] [blame] | 197 | protected wss: WebSocketService, |
Sean Condon | aa4366d | 2018-11-02 14:29:01 +0000 | [diff] [blame] | 198 | protected ts: TopologyService, |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 199 | protected trs: TrafficService, |
| 200 | protected is: IconService, |
| 201 | private lion: LionService, |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 202 | private layout: LayoutService, |
Sean Condon | 4e55c80 | 2019-12-03 22:13:34 +0000 | [diff] [blame] | 203 | protected ar: ActivatedRoute, |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 204 | @Inject('Window') public window: any, |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 205 | ) { |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 206 | if (this.lion.ubercache.length === 0) { |
| 207 | this.lionFn = this.dummyLion; |
| 208 | this.lion.loadCbs.set('topo-toolbar', () => this.doLion()); |
| 209 | } else { |
| 210 | this.doLion(); |
| 211 | } |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 212 | |
Sean Condon | 0a884ad | 2019-10-28 17:57:21 +0000 | [diff] [blame] | 213 | this.log.warn('Constructor', this.zoomDirective); |
| 214 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 215 | this.is.loadIconDef('active'); |
Sean Condon | 4747ece | 2019-05-04 20:17:02 +0100 | [diff] [blame] | 216 | this.is.loadIconDef('bgpSpeaker'); |
| 217 | this.is.loadIconDef('bird'); |
| 218 | this.is.loadIconDef('deviceTable'); |
| 219 | this.is.loadIconDef('fiber_switch'); |
| 220 | this.is.loadIconDef('flowTable'); |
| 221 | this.is.loadIconDef('groupTable'); |
| 222 | this.is.loadIconDef('m_allTraffic'); |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 223 | this.is.loadIconDef('m_cycleLabels'); |
Sean Condon | 7191054 | 2019-02-16 18:16:42 +0000 | [diff] [blame] | 224 | this.is.loadIconDef('m_cycleGridDisplay'); |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 225 | this.is.loadIconDef('m_disjointPaths'); |
Sean Condon | 4747ece | 2019-05-04 20:17:02 +0100 | [diff] [blame] | 226 | this.is.loadIconDef('m_details'); |
| 227 | this.is.loadIconDef('m_endstation'); |
| 228 | this.is.loadIconDef('m_eqMaster'); |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 229 | this.is.loadIconDef('m_fiberSwitch'); |
Sean Condon | 4747ece | 2019-05-04 20:17:02 +0100 | [diff] [blame] | 230 | this.is.loadIconDef('m_firewall'); |
| 231 | this.is.loadIconDef('m_map'); |
| 232 | this.is.loadIconDef('m_microwave'); |
| 233 | this.is.loadIconDef('m_ols'); |
| 234 | this.is.loadIconDef('m_otn'); |
| 235 | this.is.loadIconDef('m_ports'); |
| 236 | this.is.loadIconDef('m_resetZoom'); |
| 237 | this.is.loadIconDef('m_roadm'); |
| 238 | this.is.loadIconDef('m_roadm_otn'); |
| 239 | this.is.loadIconDef('m_router'); |
| 240 | this.is.loadIconDef('m_selectMap'); |
| 241 | this.is.loadIconDef('m_summary'); |
| 242 | this.is.loadIconDef('m_switch'); |
| 243 | this.is.loadIconDef('m_terminal_device'); |
| 244 | this.is.loadIconDef('m_uiAttached'); |
| 245 | this.is.loadIconDef('m_unknown'); |
| 246 | this.is.loadIconDef('meterTable'); |
| 247 | this.is.loadIconDef('microwave'); |
| 248 | this.is.loadIconDef('otn'); |
| 249 | this.is.loadIconDef('portTable'); |
| 250 | this.is.loadIconDef('roadm_otn'); |
| 251 | this.is.loadIconDef('triangleUp'); |
| 252 | this.is.loadIconDef('uiAttached'); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 253 | } |
| 254 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 255 | /** |
| 256 | * Static functions must come before member variables |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 257 | * @param index Corresponds to LabelToggle.Enum index |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 258 | */ |
Sean Condon | 021f0fa | 2018-12-06 23:31:11 -0800 | [diff] [blame] | 259 | private static deviceLabelFlashMessage(index: number): string { |
| 260 | switch (index) { |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 261 | case 0: return 'fl_device_labels_hide'; |
| 262 | case 1: return 'fl_device_labels_show_friendly'; |
| 263 | case 2: return 'fl_device_labels_show_id'; |
Sean Condon | 021f0fa | 2018-12-06 23:31:11 -0800 | [diff] [blame] | 264 | } |
| 265 | } |
| 266 | |
| 267 | private static hostLabelFlashMessage(index: number): string { |
| 268 | switch (index) { |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 269 | case 0: return 'fl_host_labels_hide'; |
| 270 | case 1: return 'fl_host_labels_show_friendly'; |
| 271 | case 2: return 'fl_host_labels_show_ip'; |
| 272 | case 3: return 'fl_host_labels_show_mac'; |
Sean Condon | 021f0fa | 2018-12-06 23:31:11 -0800 | [diff] [blame] | 273 | } |
| 274 | } |
| 275 | |
Sean Condon | 7191054 | 2019-02-16 18:16:42 +0000 | [diff] [blame] | 276 | private static gridDisplayFlashMessage(index: number): string { |
| 277 | switch (index) { |
| 278 | case 0: return 'fl_grid_display_hide'; |
| 279 | case 1: return 'fl_grid_display_1000'; |
| 280 | case 2: return 'fl_grid_display_geo'; |
| 281 | case 3: return 'fl_grid_display_both'; |
| 282 | } |
| 283 | } |
| 284 | |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 285 | private static trafficTypeFlashMessage(index: number): string { |
| 286 | switch (index) { |
| 287 | case 0: return 'tr_fl_fstats_bytes'; |
| 288 | case 1: return 'tr_fl_pstats_bits'; |
| 289 | case 2: return 'tr_fl_pstats_pkts'; |
| 290 | } |
| 291 | } |
| 292 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 293 | /** |
| 294 | * Pass the list of Key Commands to the KeyService, and initialize the Topology |
| 295 | * Service - which communicates with through the WebSocket to the ONOS server |
| 296 | * to get the nodes and links. |
| 297 | */ |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 298 | ngOnInit() { |
| 299 | this.bindCommands(); |
Sean Condon | 0a884ad | 2019-10-28 17:57:21 +0000 | [diff] [blame] | 300 | |
Sean Condon | aa4366d | 2018-11-02 14:29:01 +0000 | [diff] [blame] | 301 | // The components from the template are handed over to TopologyService here |
| 302 | // so that WebSocket responses can be passed back in to them |
| 303 | // The handling of the WebSocket call is delegated out to the Topology |
| 304 | // Service just to compartmentalize things a bit |
| 305 | this.ts.init(this.instance, this.background, this.force); |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 306 | |
Sean Condon | b0a196a | 2019-04-19 09:50:44 +0100 | [diff] [blame] | 307 | // For the 2.1 release to not listen to updates of prefs as they are |
| 308 | // only the echo of what we have sent down and the event mechanism |
| 309 | // does not discern between users. Can get confused if multiple windows open |
| 310 | // this.ps.addListener((data) => this.prefsUpdateHandler(data)); |
| 311 | |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 312 | this.prefsState = this.ps.getPrefs(TOPO2_PREFS, this.prefsState); |
Sean Condon | 0d064ec | 2019-02-04 21:53:53 +0000 | [diff] [blame] | 313 | this.mapIdState = this.ps.getPrefs(TOPO_MAPID_PREFS, this.mapIdState); |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 314 | this.trs.init(this.force); |
Sean Condon | 4e55c80 | 2019-12-03 22:13:34 +0000 | [diff] [blame] | 315 | |
| 316 | // Scale the window initially - then after resize |
| 317 | const zoomMapExtents = ZoomUtils.zoomToWindowSize( |
| 318 | this.bannerHeight, this.window.innerWidth, this.window.innerHeight); |
| 319 | this.zoomDirective.changeZoomLevel(zoomMapExtents, true); |
| 320 | |
| 321 | // TODO find out why the following is never printed |
| 322 | this.log.debug('TopologyComponent initialized,', |
| 323 | this.bannerHeight, this.window.innerWidth, this.window.innerHeight, |
| 324 | zoomMapExtents); |
| 325 | } |
| 326 | |
| 327 | ngAfterViewInit(): void { |
| 328 | this.ar.queryParams.subscribe(params => { |
| 329 | const intentId = params['intentId']; |
| 330 | const intentType = params['intentType']; |
| 331 | const appId = params['appId']; |
| 332 | const appName = params['appName']; |
| 333 | |
| 334 | if (intentId && intentType && appId) { |
| 335 | const selectedIntent = <Intent>{ |
| 336 | key: intentId, |
| 337 | type: intentType, |
| 338 | appId: appId, |
| 339 | appName: appName, |
| 340 | }; |
| 341 | this.ts.setSelectedIntent(selectedIntent); |
| 342 | |
| 343 | this.log.warn('TopologyComponent init with Intent: ', selectedIntent, params); |
| 344 | } |
| 345 | }); |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 346 | } |
| 347 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 348 | /** |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 349 | * Callback function that's called whenever new Prefs are received from WebSocket |
| 350 | * |
| 351 | * Note: At present the backend server does not filter updated by logged in user, |
| 352 | * so you might get updates pertaining to a different user |
| 353 | */ |
| 354 | prefsUpdateHandler(data: any): void { |
| 355 | // Extract the TOPO2 prefs from it |
Sean Condon | 0d064ec | 2019-02-04 21:53:53 +0000 | [diff] [blame] | 356 | if (data[TOPO2_PREFS]) { |
| 357 | this.prefsState = data[TOPO2_PREFS]; |
| 358 | } |
Sean Condon | 0d064ec | 2019-02-04 21:53:53 +0000 | [diff] [blame] | 359 | this.log.debug('Updated topo2 prefs', this.prefsState, this.mapIdState); |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 360 | } |
| 361 | |
| 362 | /** |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 363 | * When this component is being stopped, disconnect the TopologyService from |
| 364 | * the WebSocket |
| 365 | */ |
Sean Condon | aa4366d | 2018-11-02 14:29:01 +0000 | [diff] [blame] | 366 | ngOnDestroy() { |
| 367 | this.ts.destroy(); |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 368 | this.ps.removeListener((data) => this.prefsUpdateHandler(data)); |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 369 | this.trs.destroy(); |
Sean Condon | aa4366d | 2018-11-02 14:29:01 +0000 | [diff] [blame] | 370 | this.log.debug('Topology component destroyed'); |
| 371 | } |
| 372 | |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 373 | @HostListener('window:resize', ['$event']) |
| 374 | onResize(event) { |
| 375 | const zoomMapExtents = ZoomUtils.zoomToWindowSize( |
| 376 | this.bannerHeight, event.target.innerWidth, event.target.innerHeight); |
| 377 | this.zoomDirective.changeZoomLevel(zoomMapExtents, true); |
| 378 | this.log.debug('Topology window resize', |
| 379 | event.target.innerWidth, event.target.innerHeight, this.bannerHeight, zoomMapExtents); |
| 380 | } |
| 381 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 382 | /** |
| 383 | * When ever a toolbar button is clicked, an event is sent up from toolbar |
| 384 | * component which is caught and passed on to here. |
| 385 | * @param name The name of the button that was clicked |
| 386 | */ |
| 387 | toolbarButtonClicked(name: string) { |
| 388 | switch (name) { |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 389 | case INSTANCE_TOGGLE: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 390 | this.toggleInstancePanel(); |
| 391 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 392 | case SUMMARY_TOGGLE: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 393 | this.toggleSummary(); |
| 394 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 395 | case DETAILS_TOGGLE: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 396 | this.toggleDetails(); |
| 397 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 398 | case HOSTS_TOGGLE: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 399 | this.toggleHosts(); |
| 400 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 401 | case OFFLINE_TOGGLE: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 402 | this.toggleOfflineDevices(); |
| 403 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 404 | case PORTS_TOGGLE: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 405 | this.togglePorts(); |
| 406 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 407 | case BKGRND_TOGGLE: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 408 | this.toggleBackground(); |
| 409 | break; |
Sean Condon | 0d064ec | 2019-02-04 21:53:53 +0000 | [diff] [blame] | 410 | case BKGRND_SELECT: |
| 411 | this.mapSelShown = !this.mapSelShown; |
| 412 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 413 | case CYCLELABELS_BTN: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 414 | this.cycleDeviceLabels(); |
| 415 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 416 | case CYCLEHOSTLABEL_BTN: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 417 | this.cycleHostLabels(); |
| 418 | break; |
Sean Condon | 7191054 | 2019-02-16 18:16:42 +0000 | [diff] [blame] | 419 | case CYCLEGRIDDISPLAY_BTN: |
| 420 | this.cycleGridDisplay(); |
| 421 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 422 | case RESETZOOM_BTN: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 423 | this.resetZoom(); |
| 424 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 425 | case EQMASTER_BTN: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 426 | this.equalizeMasters(); |
| 427 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 428 | case CANCEL_TRAFFIC: |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 429 | this.cancelTraffic(); |
| 430 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 431 | case ALL_TRAFFIC: |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 432 | this.cycleTrafficTypeDisplay(); |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 433 | break; |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 434 | case QUICKHELP_BTN: |
| 435 | this.ks.quickHelpShown = true; |
| 436 | break; |
Sean Condon | 2888433 | 2019-03-21 14:07:00 +0000 | [diff] [blame] | 437 | case LAYOUT_DEFAULT_BTN: |
| 438 | this.layout.changeLayout(LayoutType.LAYOUT_DEFAULT); |
| 439 | break; |
| 440 | case LAYOUT_ACCESS_BTN: |
| 441 | this.layout.changeLayout(LayoutType.LAYOUT_ACCESS); |
| 442 | break; |
Sean Condon | 590b34b | 2019-12-04 18:44:37 +0000 | [diff] [blame] | 443 | case ALARMS_TOGGLE: |
| 444 | this.toggleAlarms(); |
| 445 | break; |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 446 | default: |
| 447 | this.log.warn('Unhandled Toolbar action', name); |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | /** |
| 452 | * The list of key strokes that will be active in the Topology View. |
| 453 | * |
| 454 | * This action map is passed to the KeyService through the bindCommands() |
| 455 | * when this component is being initialized |
Sean Condon | bed2e03 | 2019-04-17 22:22:49 +0100 | [diff] [blame] | 456 | * |
| 457 | * TODO - Replace this doggy doo doo (copied over from GUI-1) |
| 458 | * with something more structured |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 459 | */ |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 460 | actionMap() { |
| 461 | return { |
Sean Condon | bed2e03 | 2019-04-17 22:22:49 +0100 | [diff] [blame] | 462 | A: [() => {this.cycleTrafficTypeDisplay(); }, this.lionFn('tr_btn_monitor_all')], |
| 463 | B: [(token) => {this.toggleBackground(token); }, this.lionFn('tbtt_tog_map')], |
| 464 | D: [(token) => {this.toggleDetails(token); }, this.lionFn('tbtt_tog_use_detail')], |
| 465 | E: [() => {this.equalizeMasters(); }, this.lionFn('tbtt_eq_master')], |
| 466 | H: [() => {this.toggleHosts(); }, this.lionFn('tbtt_tog_host')], |
| 467 | I: [(token) => {this.toggleInstancePanel(token); }, this.lionFn('tbtt_tog_instances')], |
| 468 | G: [() => {this.mapSelShown = !this.mapSelShown; }, this.lionFn('tbtt_sel_map')], |
| 469 | L: [() => {this.cycleDeviceLabels(); }, this.lionFn('tbtt_cyc_dev_labs')], |
| 470 | M: [() => {this.toggleOfflineDevices(); }, this.lionFn('tbtt_tog_offline')], |
| 471 | O: [() => {this.toggleSummary(); }, this.lionFn('tbtt_tog_summary')], |
| 472 | P: [(token) => {this.togglePorts(token); }, this.lionFn('tbtt_tog_porthi')], |
| 473 | Q: [() => {this.cycleGridDisplay(); }, this.lionFn('tbtt_cyc_grid_display')], |
| 474 | R: [() => {this.resetZoom(); }, this.lionFn('tbtt_reset_zoom')], |
| 475 | U: [() => {this.unpinOrFreezeNodes(); }, this.lionFn('tbtt_unpin_node')], |
| 476 | X: [() => {this.resetNodeLocation(); }, this.lionFn('tbtt_reset_loc')], |
| 477 | dot: [() => {this.toggleToolbar(); }, this.lionFn('tbtt_tog_toolbar')], |
| 478 | 0: [() => {this.cancelTraffic(); }, this.lionFn('tr_btn_cancel_monitoring')], |
| 479 | 'shift-L': [() => {this.cycleHostLabels(); }, this.lionFn('tbtt_cyc_host_labs')], |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 480 | |
| 481 | // -- instance color palette debug |
Sean Condon | 55c3053 | 2018-10-29 12:26:57 +0000 | [diff] [blame] | 482 | 9: () => { |
| 483 | this.sus.cat7().testCard(d3.select('svg#topo2')); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 484 | }, |
| 485 | |
Sean Condon | bed2e03 | 2019-04-17 22:22:49 +0100 | [diff] [blame] | 486 | esc: [() => {this.handleEscape(); }, this.lionFn('qh_hint_esc')], |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 487 | |
| 488 | // TODO update after adding in Background Service |
| 489 | // topology overlay selections |
| 490 | // F1: function () { t2tbs.fnKey(0); }, |
| 491 | // F2: function () { t2tbs.fnKey(1); }, |
| 492 | // F3: function () { t2tbs.fnKey(2); }, |
| 493 | // F4: function () { t2tbs.fnKey(3); }, |
| 494 | // F5: function () { t2tbs.fnKey(4); }, |
| 495 | // |
| 496 | // _keyListener: t2tbs.keyListener.bind(t2tbs), |
| 497 | |
| 498 | _helpFormat: [ |
| 499 | ['I', 'O', 'D', 'H', 'M', 'P', 'dash', 'B'], |
| 500 | ['X', 'Z', 'N', 'L', 'shift-L', 'U', 'R', 'E', 'dot'], |
| 501 | [], // this column reserved for overlay actions |
| 502 | ], |
| 503 | }; |
| 504 | } |
| 505 | |
| 506 | |
| 507 | bindCommands(additional?: any) { |
| 508 | |
| 509 | const am = this.actionMap(); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 510 | this.ks.keyBindings(am); |
| 511 | |
| 512 | this.ks.gestureNotes([ |
| 513 | ['click', 'Select the item and show details'], |
| 514 | ['shift-click', 'Toggle selection state'], |
| 515 | ['drag', 'Reposition (and pin) device / host'], |
| 516 | ['cmd-scroll', 'Zoom in / out'], |
| 517 | ['cmd-drag', 'Pan'], |
| 518 | ]); |
| 519 | } |
| 520 | |
| 521 | handleEscape() { |
| 522 | |
| 523 | if (false) { |
| 524 | // TODO: Cancel show mastership |
| 525 | // TODO: Cancel Active overlay |
| 526 | // TODO: Reinstate with components |
| 527 | } else { |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 528 | this.nodeSelected(undefined); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 529 | this.log.debug('Handling escape'); |
| 530 | // } else if (t2rs.deselectAllNodes()) { |
| 531 | // // else if we have node selections, deselect them all |
| 532 | // // (work already done) |
| 533 | // } else if (t2rs.deselectLink()) { |
| 534 | // // else if we have a link selection, deselect it |
| 535 | // // (work already done) |
| 536 | // } else if (t2is.isVisible()) { |
| 537 | // // If the instance panel is visible, close it |
| 538 | // t2is.toggle(); |
| 539 | // } else if (t2sp.isVisible()) { |
| 540 | // // If the summary panel is visible, close it |
| 541 | // t2sp.toggle(); |
| 542 | } |
| 543 | } |
| 544 | |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 545 | /** |
| 546 | * Updates the cache of preferences locally and onwards to the PrefsService |
| 547 | * @param what The attribute of the local topo2-prefs cache to update |
| 548 | * @param b the value to update it with |
| 549 | */ |
| 550 | updatePrefsState(what: string, b: number) { |
| 551 | this.prefsState[what] = b; |
| 552 | this.ps.setPrefs(TOPO2_PREFS, this.prefsState); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 553 | } |
| 554 | |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 555 | /** |
| 556 | * When the button is clicked on the toolbar or the L key is pressed |
| 557 | * 1) cycle through options |
| 558 | * 2) flash up a message |
| 559 | * 3a) Update the local prefs cache |
| 560 | * 3b) And passes on to the global prefs service which sends back to the server |
| 561 | * 3c) It also has a knock on effect of passing it on to ForceSvgComponent |
| 562 | * because prefsState.dlbls is given as an input to it |
| 563 | * 3d) This will in turn pass it down to the DeviceSvgComponent which |
| 564 | * displays the label |
| 565 | */ |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 566 | protected cycleDeviceLabels() { |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 567 | const old: LabelToggle.Enum = this.prefsState.dlbls; |
Sean Condon | 021f0fa | 2018-12-06 23:31:11 -0800 | [diff] [blame] | 568 | const next = LabelToggle.next(old); |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 569 | this.flashMsg = this.lionFn(TopologyComponent.deviceLabelFlashMessage(next)); |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 570 | this.updatePrefsState(PREF_DLBLS, next); |
Sean Condon | 021f0fa | 2018-12-06 23:31:11 -0800 | [diff] [blame] | 571 | this.log.debug('Cycling device labels', old, next); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 572 | } |
| 573 | |
| 574 | protected cycleHostLabels() { |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 575 | const old: HostLabelToggle.Enum = this.prefsState.hlbls; |
Sean Condon | 021f0fa | 2018-12-06 23:31:11 -0800 | [diff] [blame] | 576 | const next = HostLabelToggle.next(old); |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 577 | this.flashMsg = this.lionFn(TopologyComponent.hostLabelFlashMessage(next)); |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 578 | this.updatePrefsState(PREF_HLBLS, next); |
Sean Condon | 021f0fa | 2018-12-06 23:31:11 -0800 | [diff] [blame] | 579 | this.log.debug('Cycling host labels', old, next); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 580 | } |
| 581 | |
Sean Condon | 7191054 | 2019-02-16 18:16:42 +0000 | [diff] [blame] | 582 | protected cycleGridDisplay() { |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 583 | const old: GridDisplayToggle.Enum = this.prefsState.grid; |
Sean Condon | 7191054 | 2019-02-16 18:16:42 +0000 | [diff] [blame] | 584 | const next = GridDisplayToggle.next(old); |
| 585 | this.flashMsg = this.lionFn(TopologyComponent.gridDisplayFlashMessage(next)); |
| 586 | this.updatePrefsState(PREF_GRID, next); |
| 587 | this.log.debug('Cycling grid display', old, next); |
| 588 | } |
| 589 | |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 590 | protected cycleTrafficTypeDisplay() { |
| 591 | const old: TrafficType.Enum = this.prefsState.traffic; // by number |
| 592 | const next = TrafficType.next(old); |
| 593 | this.flashMsg = this.lionFn(TopologyComponent.trafficTypeFlashMessage(next)); |
| 594 | this.updatePrefsState(PREF_TRAFFIC, next); |
| 595 | this.trs.requestTraffic(next); |
| 596 | this.log.debug('Cycling traffic display', old, next); |
| 597 | } |
| 598 | |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 599 | /** |
| 600 | * When the button is clicked on the toolbar or the B key is pressed |
| 601 | * 1) Find the inverse of the current state (held as 1 or 0) |
| 602 | * 2) Flash up a message on screen |
| 603 | * 3b) And passes on to the global prefs service which sends back to the server |
| 604 | * 3c) It also has a knock on effect of passing it on to ToolbarComponent |
| 605 | * because prefsState.bg is given as an input to it |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 606 | * @param token not currently used |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 607 | */ |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 608 | protected toggleBackground(token?: KeysToken) { |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 609 | const bg: boolean = !Boolean(this.prefsState.bg); |
| 610 | this.flashMsg = this.lionFn(bg ? 'show' : 'hide') + |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 611 | ' ' + this.lionFn('fl_background_map'); |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 612 | this.updatePrefsState(PREF_BG, bg ? 1 : 0); |
| 613 | this.log.debug('Toggling background', token, bg ? 'shown' : 'hidden'); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 614 | } |
| 615 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 616 | protected toggleDetails(token?: KeysToken) { |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 617 | const on: boolean = !Boolean(this.prefsState.detail); |
| 618 | this.flashMsg = this.lionFn(on ? 'show' : 'hide') + |
| 619 | ' ' + this.lionFn('fl_panel_details'); |
| 620 | this.updatePrefsState(PREF_DETAIL, on ? 1 : 0); |
| 621 | this.log.debug('Toggling details', token); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 622 | } |
| 623 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 624 | protected toggleInstancePanel(token?: KeysToken) { |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 625 | const on: boolean = !Boolean(this.prefsState.insts); |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 626 | this.flashMsg = this.lionFn(on ? 'show' : 'hide') + |
| 627 | ' ' + this.lionFn('fl_panel_instances'); |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 628 | this.updatePrefsState(PREF_INSTS, on ? 1 : 0); |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 629 | this.log.debug('Toggling instances', token, on); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 630 | } |
| 631 | |
| 632 | protected toggleSummary() { |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 633 | const on: boolean = !Boolean(this.prefsState.summary); |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 634 | this.flashMsg = this.lionFn(on ? 'show' : 'hide') + |
| 635 | ' ' + this.lionFn('fl_panel_summary'); |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 636 | this.updatePrefsState(PREF_SUMMARY, on ? 1 : 0); |
| 637 | } |
| 638 | |
| 639 | protected togglePorts(token?: KeysToken) { |
| 640 | const current: boolean = !Boolean(this.prefsState.porthl); |
| 641 | this.flashMsg = this.lionFn(current ? 'enable' : 'disable') + |
| 642 | ' ' + this.lionFn('fl_port_highlighting'); |
| 643 | this.updatePrefsState(PREF_PORTHL, current ? 1 : 0); |
| 644 | this.log.debug(current ? 'Enable' : 'Disable', 'port highlighting'); |
| 645 | } |
| 646 | |
| 647 | protected toggleToolbar() { |
| 648 | const on: boolean = !Boolean(this.prefsState.toolbar); |
| 649 | this.updatePrefsState(PREF_TOOLBAR, on ? 1 : 0); |
| 650 | this.log.debug('toggling toolbar', on ? 'shown' : 'hidden'); |
| 651 | } |
| 652 | |
| 653 | protected toggleHosts() { |
| 654 | const current: boolean = !Boolean(this.prefsState.hosts); |
| 655 | this.flashMsg = this.lionFn('hosts') + ' ' + |
Sean Condon | b0a196a | 2019-04-19 09:50:44 +0100 | [diff] [blame] | 656 | this.lionFn(current ? 'visible' : 'hidden'); |
Sean Condon | b2c483c | 2019-01-16 20:28:55 +0000 | [diff] [blame] | 657 | this.updatePrefsState(PREF_HOSTS, current ? 1 : 0); |
| 658 | this.log.debug('toggling hosts: ', this.prefsState.hosts ? 'Show' : 'Hide'); |
| 659 | } |
| 660 | |
| 661 | protected toggleOfflineDevices() { |
| 662 | const on: boolean = !Boolean(this.prefsState.offdev); |
| 663 | this.flashMsg = this.lionFn(on ? 'show' : 'hide') + |
| 664 | ' ' + this.lionFn('fl_offline_devices'); |
| 665 | this.updatePrefsState(PREF_OFFDEV, on ? 1 : 0); |
| 666 | this.log.debug('toggling offline devices', this.prefsState.offdev); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 667 | } |
| 668 | |
Sean Condon | 590b34b | 2019-12-04 18:44:37 +0000 | [diff] [blame] | 669 | |
| 670 | protected toggleAlarms() { |
| 671 | const on: boolean = !Boolean(this.prefsState.alarms); |
| 672 | this.flashMsg = this.lionFn(on ? 'show' : 'hide') + ' Alarms'; |
| 673 | this.updatePrefsState(PREF_ALARMS, on ? 1 : 0); |
| 674 | this.log.debug('Alarms toggled', on); |
| 675 | } |
| 676 | |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 677 | protected resetZoom() { |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 678 | const zoomMapExtents = ZoomUtils.zoomToWindowSize( |
| 679 | this.bannerHeight, this.window.innerWidth, this.window.innerHeight); |
| 680 | this.zoomDirective.changeZoomLevel(zoomMapExtents, false); |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 681 | this.flashMsg = this.lionFn('fl_pan_zoom_reset'); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 682 | } |
| 683 | |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 684 | protected equalizeMasters() { |
Sean Condon | 64ea7d2 | 2019-04-12 19:39:13 +0100 | [diff] [blame] | 685 | this.wss.sendEvent('equalizeMasters', {}); |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 686 | this.flashMsg = this.lionFn('fl_eq_masters'); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 687 | this.log.debug('equalizing masters'); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 688 | } |
| 689 | |
Sean Condon | 9de2135 | 2019-04-06 19:22:27 +0100 | [diff] [blame] | 690 | /** |
| 691 | * If any nodes with fixed positions had been dragged out of place |
| 692 | * then put back where they belong |
| 693 | * If there are some devices selected reset only these |
| 694 | */ |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 695 | protected resetNodeLocation() { |
Sean Condon | 9de2135 | 2019-04-06 19:22:27 +0100 | [diff] [blame] | 696 | const numNodes = this.force.resetNodeLocations(); |
| 697 | this.flashMsg = this.lionFn('fl_reset_node_locations') + |
| 698 | '(' + String(numNodes) + ')'; |
| 699 | this.log.debug('resetting ', numNodes, 'node(s) location'); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 700 | } |
| 701 | |
Sean Condon | 9de2135 | 2019-04-06 19:22:27 +0100 | [diff] [blame] | 702 | /** |
| 703 | * Toggle floating nodes between pinned and frozen |
| 704 | * If there are floating nodes selected toggle only these |
| 705 | */ |
| 706 | protected unpinOrFreezeNodes() { |
| 707 | const pinned: boolean = !Boolean(this.prefsState.pinned); |
| 708 | const numNodes = this.force.unpinOrFreezeNodes(pinned); |
| 709 | this.flashMsg = this.lionFn(pinned ? |
| 710 | 'fl_pinned_floating_nodes' : 'fl_unpinned_floating_nodes') + |
| 711 | '(' + String(numNodes) + ')'; |
| 712 | this.updatePrefsState(PREF_PINNED, pinned ? 1 : 0); |
| 713 | this.log.debug('Toggling pinning for floating ', numNodes, 'nodes', pinned); |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 714 | } |
| 715 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 716 | /** |
| 717 | * Check to see if this is needed anymore |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 718 | * @param what - a key stroke |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 719 | */ |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 720 | protected notValid(what) { |
| 721 | this.log.warn('topo.js getActionEntry(): Not a valid ' + what); |
| 722 | } |
| 723 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 724 | /** |
| 725 | * Check to see if this is needed anymore |
Sean Condon | ff85fbe | 2019-03-16 14:28:46 +0000 | [diff] [blame] | 726 | * @param key - a key stroke |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 727 | */ |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 728 | getActionEntry(key) { |
| 729 | let entry; |
| 730 | |
| 731 | if (!key) { |
| 732 | this.notValid('key'); |
| 733 | return null; |
| 734 | } |
| 735 | |
| 736 | entry = this.actionMap()[key]; |
| 737 | |
| 738 | if (!entry) { |
| 739 | this.notValid('actionMap (' + key + ') entry'); |
| 740 | return null; |
| 741 | } |
| 742 | return this.fs.isA(entry) || [entry, '']; |
| 743 | } |
| 744 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 745 | /** |
| 746 | * An event handler that updates the details panel as items are |
| 747 | * selected in the forcesvg layer |
Sean Condon | d88f366 | 2019-04-03 16:35:30 +0100 | [diff] [blame] | 748 | * |
| 749 | * @param nodesOrLink the item(s) to display details of |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 750 | */ |
Sean Condon | d88f366 | 2019-04-03 16:35:30 +0100 | [diff] [blame] | 751 | nodeSelected(nodesOrLink: UiElement[]) { |
| 752 | this.details.ngOnChanges({'selectedNodes': |
| 753 | new SimpleChange(undefined, nodesOrLink, true)}); |
Sean Condon | 50855cf | 2018-12-23 15:37:42 +0000 | [diff] [blame] | 754 | } |
| 755 | |
| 756 | /** |
| 757 | * Cancel traffic monitoring |
| 758 | */ |
| 759 | cancelTraffic() { |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 760 | this.flashMsg = this.lionFn('fl_monitoring_canceled'); |
Sean Condon | 19e8367 | 2019-04-13 16:21:52 +0100 | [diff] [blame] | 761 | this.trs.cancelTraffic(); |
Sean Condon | 50855cf | 2018-12-23 15:37:42 +0000 | [diff] [blame] | 762 | } |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 763 | |
Sean Condon | 0d064ec | 2019-02-04 21:53:53 +0000 | [diff] [blame] | 764 | changeMap(map: MapObject) { |
| 765 | this.mapSelShown = false; // Hide the MapSelector component |
| 766 | this.mapIdState = map; |
| 767 | this.ps.setPrefs(TOPO_MAPID_PREFS, this.mapIdState); |
| 768 | this.log.debug('Map has been changed to ', map); |
| 769 | } |
| 770 | |
Sean Condon | 1ae1580 | 2019-03-02 09:07:18 +0000 | [diff] [blame] | 771 | mapExtentsZoom(zoomMapExtents: TopoZoomPrefs) { |
| 772 | // this.zoomDirective.updateZoomState(zoomPrefs.tx, zoomPrefs.ty, zoomPrefs.sc); |
| 773 | this.zoomDirective.changeZoomLevel(zoomMapExtents); |
| 774 | this.log.debug('Map zoom prefs updated', zoomMapExtents); |
| 775 | } |
| 776 | |
Sean Condon | 64ea7d2 | 2019-04-12 19:39:13 +0100 | [diff] [blame] | 777 | backgroundClicked(event: MouseEvent) { |
| 778 | const elemTagName = event.target['tagName'] + ' ' + event.target['id']; |
| 779 | if (BACKGROUND_ELEMENTS.includes(elemTagName)) { |
| 780 | this.force.updateSelected( |
| 781 | <SelectedEvent>{ |
| 782 | uiElement: undefined, |
| 783 | deselecting: true |
| 784 | } |
| 785 | ); |
| 786 | } |
Sean Condon | 4e55c80 | 2019-12-03 22:13:34 +0000 | [diff] [blame] | 787 | this.ts.cancelHighlights(); |
| 788 | this.force.cancelAllLinkHighlightsNow(); |
Sean Condon | 64ea7d2 | 2019-04-12 19:39:13 +0100 | [diff] [blame] | 789 | } |
| 790 | |
Sean Condon | 9148182 | 2019-01-01 13:56:14 +0000 | [diff] [blame] | 791 | /** |
| 792 | * Read the LION bundle for Toolbar and set up the lionFn |
| 793 | */ |
| 794 | doLion() { |
| 795 | this.lionFn = this.lion.bundle('core.view.Topo'); |
| 796 | } |
| 797 | |
| 798 | /** |
| 799 | * A dummy implementation of the lionFn until the response is received and the LION |
| 800 | * bundle is received from the WebSocket |
| 801 | */ |
| 802 | dummyLion(key: string): string { |
| 803 | return '%' + key + '%'; |
| 804 | } |
Sean Condon | f4f54a1 | 2018-10-10 23:25:46 +0100 | [diff] [blame] | 805 | } |