import { Component, Input, OnChanges, SimpleChanges, OnInit, ViewChild } from '@angular/core'; import { Infra } from '@overflow/commons-typescript/model/infra'; import { InfraHost as InfraTypeHost } from '@overflow/commons-typescript/model/infra'; import { InfraService as InfraTypeService } from '@overflow/commons-typescript/model/infra'; import { Observable, of } from 'rxjs'; import { catchError, exhaustMap, map, tap, take } from 'rxjs/operators'; import { TreeNode, MenuItem, ContextMenu } from 'primeng/primeng'; import { PageParams, Page } from '@overflow/commons-typescript/core/model'; import { ProbeHost } from '@overflow/commons-typescript'; import { InfraService } from '../service/infra.service'; @Component({ selector: 'of-infra-tree', templateUrl: './infra-tree.component.html', }) export class InfraTreeComponent implements OnInit, OnChanges { @Input() probeHost: ProbeHost; infras: Infra[]; pending$: Observable; error$: Observable; zoneNode: TreeNode[]; hostNode: TreeNode[]; contextMenuZone: MenuItem[]; contextMenuHost: MenuItem[]; contextMenuService: MenuItem[]; selectedNode: TreeNode; @ViewChild('cmZone') cmZone: ContextMenu; @ViewChild('cmHost') cmHost: ContextMenu; @ViewChild('cmService') cmService: ContextMenu; constructor( private infraService: InfraService, ) { } ngOnInit(): void { this.zoneNode.push({ label: this.probeHost.probe.cidr, type: 'ZONE', data: { }, children: this.hostNode, expanded: true }); this.initContextMenu(); } initContextMenu() { this.contextMenuZone = [ { label: 'Zone Menu', command: (event) => this.cmZone.hide() }, { separator: true }, { label: 'Discovery', icon: 'fa-plus', command: (event) => alert('Discovery') }, ]; this.contextMenuHost = [ { label: 'Host Menu', command: (event) => this.cmHost.hide() }, { separator: true }, { label: 'Add sensor', icon: 'fa-plus', command: (event) => alert('Add sensor') }, { label: 'Traceroute', icon: 'fa-plus' }, { label: 'ARP Test', icon: 'fa-plus' }, ]; this.contextMenuService = [ { label: 'Service Menu', command: (event) => this.cmService.hide() }, { separator: true }, { label: 'Add sensor', icon: 'fa-plus', command: (event) => alert('Add sensor') }, ]; } ngOnChanges(changes: SimpleChanges): void { console.log(changes); if (changes['probeHost'].isFirstChange ) { this.zoneNode = []; this.hostNode = []; this.getInfras(); } } getInfras() { const pageParams: PageParams = { pageNo: 0, countPerPage: 99999, sortCol: 'id', sortDirection: 'descending' }; this.infraService.readAllByProbeID(this.probeHost.probe.id, pageParams) .pipe( tap(() => { this.pending$ = of(true); }), map((infraPage: Page) => { this.infras = infraPage.content; console.log(this.infras); this.generateTreeData(this.infras); }), catchError(error => { this.error$ = of(error); return of(); }), tap(() => { this.pending$ = of(false); }), take(1), ).subscribe(); } generateTreeData(infras: Infra[]) { infras.forEach(infra => { switch (infra.metaInfraType.id) { // TODO: fix to enum case 2: // InfraHost this.addHost(infra); break; case 7: // InfraService this.addService(infra); break; default: break; } }); } addHost(infraHost: InfraTypeHost) { this.hostNode.push({ type: 'HOST', label: infraHost.infraHostIPs[0].address, data: { target: infraHost }, expanded: true, children: [] }); } addService(infraService: InfraTypeService) { const idx = this.findHostIndex(infraService); if (idx === -1) { // this.addHost(infraService.infraHost); // this.addService(infraService); return; } this.hostNode[idx].children.push({ type: 'SERVICE', label: 'TODO', data: { target: infraService }, }); } findHostIndex(infraService: InfraTypeService): number { const idx = -1; this.hostNode.forEach((node, index) => { // if (node.data.target.id === infraService.infraHost.id) { // idx = index; // return; // } }); return idx; } showContextMenu(event: MouseEvent, node: any) { this.selectedNode = node; this.cmZone.hide(); this.cmHost.hide(); this.cmService.hide(); if (node.type === 'ZONE') { this.cmZone.show(event); } else if (node.type === 'HOST') { this.cmHost.show(event); } else if (node.type === 'SERVICE') { this.cmService.show(event); } return false; } }