Code cleaned up

This commit is contained in:
Piotr Pekala 2019-03-20 08:23:30 -07:00
parent 69e18494bb
commit ce5c46df1a
6 changed files with 53 additions and 9 deletions

View File

@ -1,5 +1,6 @@
import { TextElement } from '../models/drawings/text-element'; import { TextElement } from '../models/drawings/text-element';
import { MapDrawing } from '../models/map/map-drawing'; import { MapDrawing } from '../models/map/map-drawing';
import { MapLink } from '../models/map/map-link';
export class DataEventSource<T> { export class DataEventSource<T> {
constructor(public datum: T, public dx: number, public dy: number) {} constructor(public datum: T, public dx: number, public dy: number) {}
@ -30,3 +31,7 @@ export class TextEditedDataEvent {
export class DrawingContextMenu { export class DrawingContextMenu {
constructor(public event: any, public drawing: MapDrawing) {} constructor(public event: any, public drawing: MapDrawing) {}
} }
export class LinkContextMenu {
constructor(public event:any, public link: MapLink) {}
}

View File

@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, EventEmitter } from '@angular/core';
import { Widget } from './widget'; import { Widget } from './widget';
import { SVGSelection } from '../models/types'; import { SVGSelection } from '../models/types';
@ -9,9 +9,12 @@ import { InterfaceLabelWidget } from './interface-label';
import { InterfaceStatusWidget } from './interface-status'; import { InterfaceStatusWidget } from './interface-status';
import { MapLink } from '../models/map/map-link'; import { MapLink } from '../models/map/map-link';
import { SelectionManager } from '../managers/selection-manager'; import { SelectionManager } from '../managers/selection-manager';
import { LinkContextMenu } from '../events/event-source';
@Injectable() @Injectable()
export class LinkWidget implements Widget { export class LinkWidget implements Widget {
public onContextMenu = new EventEmitter<LinkContextMenu>();
constructor( constructor(
private multiLinkCalculatorHelper: MultiLinkCalculatorHelper, private multiLinkCalculatorHelper: MultiLinkCalculatorHelper,
private interfaceLabelWidget: InterfaceLabelWidget, private interfaceLabelWidget: InterfaceLabelWidget,
@ -36,6 +39,10 @@ export class LinkWidget implements Widget {
link_body link_body
.filter(l => { return l.capturing && !(l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)}) .filter(l => { return l.capturing && !(l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)})
.append<SVGGElement>('g') .append<SVGGElement>('g')
.on('contextmenu', (datum: MapLink) => {
event.preventDefault();
this.onContextMenu.emit(new LinkContextMenu(event, datum));
})
.attr('class', 'capture-icon') .attr('class', 'capture-icon')
.attr('transform', link => { .attr('transform', link => {
return `translate (${(link.source.x + link.target.x)/2}, ${(link.source.y + link.target.y)/2}) scale(0.5)` return `translate (${(link.source.x + link.target.x)/2}, ${(link.source.y + link.target.y)/2}) scale(0.5)`
@ -48,6 +55,10 @@ export class LinkWidget implements Widget {
link_body link_body
.filter(l => { return l.capturing && (l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)}) .filter(l => { return l.capturing && (l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)})
.append<SVGGElement>('g') .append<SVGGElement>('g')
.on('contextmenu', (datum: MapLink) => {
event.preventDefault();
this.onContextMenu.emit(new LinkContextMenu(event, datum));
})
.attr('class', 'filter-capture-icon') .attr('class', 'filter-capture-icon')
.attr('transform', link => { .attr('transform', link => {
return `translate (${(link.source.x + link.target.x)/2}, ${(link.source.y + link.target.y)/2}) scale(0.5)` return `translate (${(link.source.x + link.target.x)/2}, ${(link.source.y + link.target.y)/2}) scale(0.5)`
@ -60,6 +71,10 @@ export class LinkWidget implements Widget {
link_body link_body
.filter(l => { return !l.capturing && (l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)}) .filter(l => { return !l.capturing && (l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)})
.append<SVGGElement>('g') .append<SVGGElement>('g')
.on('contextmenu', (datum: MapLink) => {
event.preventDefault();
this.onContextMenu.emit(new LinkContextMenu(event, datum));
})
.attr('class', 'filter-icon') .attr('class', 'filter-icon')
.attr('transform', link => { .attr('transform', link => {
return `translate (${(link.source.x + link.target.x)/2}, ${(link.source.y + link.target.y)/2}) scale(0.5)` return `translate (${(link.source.x + link.target.x)/2}, ${(link.source.y + link.target.y)/2}) scale(0.5)`

View File

@ -8,9 +8,10 @@ import { ToasterService } from '../../../../services/toaster.service';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { MockedToasterService } from '../../../../services/toaster.service.spec';
import { LinkService } from '../../../../services/link.service'; import { LinkService } from '../../../../services/link.service';
import { MockedLinkService } from '../../project-map.component.spec'; import { MockedLinkService, MockedNodesDataSource } from '../../project-map.component.spec';
import { Link } from '../../../../models/link'; import { Link } from '../../../../models/link';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { NodesDataSource } from '../../../../cartography/datasources/nodes-datasource';
describe('StartCaptureDialogComponent', () => { describe('StartCaptureDialogComponent', () => {
let component: StartCaptureDialogComponent; let component: StartCaptureDialogComponent;
@ -18,6 +19,7 @@ describe('StartCaptureDialogComponent', () => {
let mockedToasterService = new MockedToasterService; let mockedToasterService = new MockedToasterService;
let mockedLinkService = new MockedLinkService; let mockedLinkService = new MockedLinkService;
let mockedNodesDataSource = new MockedNodesDataSource;
let dialogRef = { let dialogRef = {
close: jasmine.createSpy('close') close: jasmine.createSpy('close')
}; };
@ -29,7 +31,8 @@ describe('StartCaptureDialogComponent', () => {
{ provide: MatDialogRef, useValue: dialogRef }, { provide: MatDialogRef, useValue: dialogRef },
{ provide: MAT_DIALOG_DATA, useValue: [] }, { provide: MAT_DIALOG_DATA, useValue: [] },
{ provide: ToasterService, useValue: mockedToasterService }, { provide: ToasterService, useValue: mockedToasterService },
{ provide: LinkService, useValue: mockedLinkService } { provide: LinkService, useValue: mockedLinkService },
{ provide: NodesDataSource, useValue: mockedNodesDataSource }
], ],
declarations: [ declarations: [
StartCaptureDialogComponent StartCaptureDialogComponent
@ -41,7 +44,7 @@ describe('StartCaptureDialogComponent', () => {
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(StartCaptureDialogComponent); fixture = TestBed.createComponent(StartCaptureDialogComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
component.link = {link_type: 'ethernet'} as Link; component.link = {link_type: 'ethernet', nodes: [{node_id: '1'}]} as Link;
fixture.detectChanges(); fixture.detectChanges();
}); });
@ -68,7 +71,7 @@ describe('StartCaptureDialogComponent', () => {
expect(mockedLinkService.startCaptureOnLink).not.toHaveBeenCalled(); expect(mockedLinkService.startCaptureOnLink).not.toHaveBeenCalled();
}); });
it('should call link service when filename is empty', () => { it('should not call link service when filename is empty', () => {
component.inputForm.controls['linkType'].setValue('Ethernet'); component.inputForm.controls['linkType'].setValue('Ethernet');
component.inputForm.controls['fileName'].setValue(''); component.inputForm.controls['fileName'].setValue('');
spyOn(mockedLinkService, 'startCaptureOnLink').and.returnValue(of({})); spyOn(mockedLinkService, 'startCaptureOnLink').and.returnValue(of({}));

View File

@ -7,6 +7,8 @@ import { LinkService } from '../../../../services/link.service';
import { CapturingSettings } from '../../../../models/capturingSettings'; import { CapturingSettings } from '../../../../models/capturingSettings';
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
import { ToasterService } from '../../../../services/toaster.service'; import { ToasterService } from '../../../../services/toaster.service';
import { LinkNode } from '../../../../models/link-node';
import { NodesDataSource } from '../../../../cartography/datasources/nodes-datasource';
@Component({ @Component({
selector: 'app-start-capture', selector: 'app-start-capture',
@ -23,7 +25,8 @@ export class StartCaptureDialogComponent implements OnInit {
private dialogRef: MatDialogRef<PacketFiltersDialogComponent>, private dialogRef: MatDialogRef<PacketFiltersDialogComponent>,
private linkService: LinkService, private linkService: LinkService,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private toasterService: ToasterService private toasterService: ToasterService,
private nodesDataSource: NodesDataSource
) { ) {
this.inputForm = this.formBuilder.group({ this.inputForm = this.formBuilder.group({
linkType: new FormControl('', Validators.required), linkType: new FormControl('', Validators.required),
@ -47,7 +50,15 @@ export class StartCaptureDialogComponent implements OnInit {
} }
onYesClick() { onYesClick() {
if (this.inputForm.invalid) { let isAnyRunningDevice = false;
this.link.nodes.forEach((linkNode: LinkNode) => {
let node = this.nodesDataSource.get(linkNode.node_id);
if (node.status === 'started') isAnyRunningDevice = true;
});
if (!isAnyRunningDevice) {
this.toasterService.error(`Cannot capture because there is no running device on this link`);
} else if (this.inputForm.invalid) {
this.toasterService.error(`Fill all required fields`); this.toasterService.error(`Fill all required fields`);
} else { } else {
let captureSettings: CapturingSettings = { let captureSettings: CapturingSettings = {

View File

@ -41,6 +41,7 @@ import { MapLinkToLinkConverter } from '../../cartography/converters/map/map-lin
import { Link } from '../../models/link'; import { Link } from '../../models/link';
import { Project } from '../../models/project'; import { Project } from '../../models/project';
import { CapturingSettings } from '../../models/capturingSettings'; import { CapturingSettings } from '../../models/capturingSettings';
import { LinkWidget } from '../../cartography/widgets/link';
export class MockedProgressService { export class MockedProgressService {
public activate() {} public activate() {}
@ -160,7 +161,7 @@ export class MockedNodesDataSource {
clear() {} clear() {}
get() { get() {
return of({}); return {status: 'started'};
} }
update() { update() {
@ -194,6 +195,7 @@ describe('ProjectMapComponent', () => {
{ provide: ProjectWebServiceHandler }, { provide: ProjectWebServiceHandler },
{ provide: MapChangeDetectorRef }, { provide: MapChangeDetectorRef },
{ provide: NodeWidget }, { provide: NodeWidget },
{ provide: LinkWidget },
{ provide: DrawingsWidget }, { provide: DrawingsWidget },
{ provide: MapNodeToNodeConverter }, { provide: MapNodeToNodeConverter },
{ provide: MapDrawingToDrawingConverter }, { provide: MapDrawingToDrawingConverter },

View File

@ -30,7 +30,7 @@ import { MapNodeToNodeConverter } from '../../cartography/converters/map/map-nod
import { SettingsService, Settings } from '../../services/settings.service'; import { SettingsService, Settings } from '../../services/settings.service';
import { D3MapComponent } from '../../cartography/components/d3-map/d3-map.component'; import { D3MapComponent } from '../../cartography/components/d3-map/d3-map.component';
import { ToolsService } from '../../services/tools.service'; import { ToolsService } from '../../services/tools.service';
import { DrawingContextMenu } from '../../cartography/events/event-source'; import { DrawingContextMenu, LinkContextMenu } from '../../cartography/events/event-source';
import { MapDrawingToDrawingConverter } from '../../cartography/converters/map/map-drawing-to-drawing-converter'; import { MapDrawingToDrawingConverter } from '../../cartography/converters/map/map-drawing-to-drawing-converter';
import { SelectionManager } from '../../cartography/managers/selection-manager'; import { SelectionManager } from '../../cartography/managers/selection-manager';
import { SelectionTool } from '../../cartography/tools/selection-tool'; import { SelectionTool } from '../../cartography/tools/selection-tool';
@ -42,6 +42,7 @@ import { MapLabelToLabelConverter } from '../../cartography/converters/map/map-l
import { RecentlyOpenedProjectService } from '../../services/recentlyOpenedProject.service'; import { RecentlyOpenedProjectService } from '../../services/recentlyOpenedProject.service';
import { MapLink } from '../../cartography/models/map/map-link'; import { MapLink } from '../../cartography/models/map/map-link';
import { MapLinkToLinkConverter } from '../../cartography/converters/map/map-link-to-link-converter'; import { MapLinkToLinkConverter } from '../../cartography/converters/map/map-link-to-link-converter';
import { LinkWidget } from '../../cartography/widgets/link';
@Component({ @Component({
@ -95,6 +96,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
private mapChangeDetectorRef: MapChangeDetectorRef, private mapChangeDetectorRef: MapChangeDetectorRef,
private nodeWidget: NodeWidget, private nodeWidget: NodeWidget,
private drawingsWidget: DrawingsWidget, private drawingsWidget: DrawingsWidget,
private linkWidget: LinkWidget,
private mapNodeToNode: MapNodeToNodeConverter, private mapNodeToNode: MapNodeToNodeConverter,
private mapDrawingToDrawing: MapDrawingToDrawingConverter, private mapDrawingToDrawing: MapDrawingToDrawingConverter,
private mapLabelToLabel: MapLabelToLabelConverter, private mapLabelToLabel: MapLabelToLabelConverter,
@ -219,6 +221,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
this.toolsService.selectionToolActivation(true); this.toolsService.selectionToolActivation(true);
} }
const onLinkContextMenu = this.linkWidget.onContextMenu.subscribe((eventLink: LinkContextMenu) => {
const link = this.mapLinkToLink.convert(eventLink.link);
this.contextMenu.openMenuForListOfElements([], [], [], [link], eventLink.event.pageY, eventLink.event.pageX);
});
const onNodeContextMenu = this.nodeWidget.onContextMenu.subscribe((eventNode: NodeContextMenu) => { const onNodeContextMenu = this.nodeWidget.onContextMenu.subscribe((eventNode: NodeContextMenu) => {
const node = this.mapNodeToNode.convert(eventNode.node); const node = this.mapNodeToNode.convert(eventNode.node);
this.contextMenu.openMenuForNode(node, eventNode.event.pageY, eventNode.event.pageX); this.contextMenu.openMenuForNode(node, eventNode.event.pageY, eventNode.event.pageX);
@ -253,6 +260,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
this.contextMenu.openMenuForListOfElements(drawings, nodes, labels, links, event.pageY, event.pageX); this.contextMenu.openMenuForListOfElements(drawings, nodes, labels, links, event.pageY, event.pageX);
}); });
this.subscriptions.push(onLinkContextMenu);
this.subscriptions.push(onNodeContextMenu); this.subscriptions.push(onNodeContextMenu);
this.subscriptions.push(onDrawingContextMenu); this.subscriptions.push(onDrawingContextMenu);
this.subscriptions.push(onContextMenu); this.subscriptions.push(onContextMenu);