Move link creation to cartography

This commit is contained in:
ziajka 2018-11-06 08:23:39 +01:00
parent 9106e8bf88
commit d0ecd3b2ef
18 changed files with 134 additions and 51 deletions

View File

@ -39,7 +39,6 @@ import { StartNodeActionComponent } from './components/project-map/node-context-
import { StopNodeActionComponent } from './components/project-map/node-context-menu/actions/stop-node-action/stop-node-action.component'; import { StopNodeActionComponent } from './components/project-map/node-context-menu/actions/stop-node-action/stop-node-action.component';
import { ApplianceComponent } from './components/appliance/appliance.component'; import { ApplianceComponent } from './components/appliance/appliance.component';
import { ApplianceListDialogComponent } from './components/appliance/appliance-list-dialog/appliance-list-dialog.component'; import { ApplianceListDialogComponent } from './components/appliance/appliance-list-dialog/appliance-list-dialog.component';
import { NodeSelectInterfaceComponent } from './components/project-map/node-select-interface/node-select-interface.component';
import { CartographyModule } from './cartography/cartography.module'; import { CartographyModule } from './cartography/cartography.module';
import { ToasterService } from './services/toaster.service'; import { ToasterService } from './services/toaster.service';
import { ProjectWebServiceHandler } from "./handlers/project-web-service-handler"; import { ProjectWebServiceHandler } from "./handlers/project-web-service-handler";
@ -99,7 +98,6 @@ if (environment.production) {
StopNodeActionComponent, StopNodeActionComponent,
ApplianceComponent, ApplianceComponent,
ApplianceListDialogComponent, ApplianceListDialogComponent,
NodeSelectInterfaceComponent,
MoveLayerDownActionComponent, MoveLayerDownActionComponent,
MoveLayerUpActionComponent, MoveLayerUpActionComponent,
ProjectMapShortcutsComponent, ProjectMapShortcutsComponent,

View File

@ -25,13 +25,20 @@ import { RectDrawingWidget } from './widgets/drawings/rect-drawing';
import { TextDrawingWidget } from './widgets/drawings/text-drawing'; import { TextDrawingWidget } from './widgets/drawings/text-drawing';
import { LineDrawingWidget } from './widgets/drawings/line-drawing'; import { LineDrawingWidget } from './widgets/drawings/line-drawing';
import { Context } from './models/context'; import { Context } from './models/context';
import { DrawLinkToolComponent } from './components/draw-link-tool/draw-link-tool.component';
import { NodeSelectInterfaceComponent } from './components/node-select-interface/node-select-interface.component';
import { MatMenuModule, MatIconModule } from '@angular/material';
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule CommonModule,
MatMenuModule,
MatIconModule
], ],
declarations: [ declarations: [
MapComponent, MapComponent,
DrawLinkToolComponent,
NodeSelectInterfaceComponent
], ],
providers: [ providers: [
CssFixer, CssFixer,
@ -57,7 +64,7 @@ import { Context } from './models/context';
LineDrawingWidget, LineDrawingWidget,
RectDrawingWidget, RectDrawingWidget,
TextDrawingWidget, TextDrawingWidget,
Context Context,
], ],
exports: [MapComponent] exports: [MapComponent]
}) })

View File

@ -0,0 +1 @@
<app-node-select-interface (onChooseInterface)="onChooseInterface($event)"></app-node-select-interface>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DrawLinkToolComponent } from './draw-link-tool.component';
describe('DrawLinkToolComponent', () => {
let component: DrawLinkToolComponent;
let fixture: ComponentFixture<DrawLinkToolComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DrawLinkToolComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DrawLinkToolComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,70 @@
import { Component, OnInit, Output, EventEmitter, OnDestroy, ViewChild } from '@angular/core';
import { Port } from '../../../models/port';
import { DrawingLineWidget } from '../../widgets/drawing-line';
import { Node } from '../../models/node';
import { NodesWidget, NodeEvent } from '../../widgets/nodes';
import { Subscription } from 'rxjs';
import { NodeSelectInterfaceComponent } from '../node-select-interface/node-select-interface.component';
export class LinkCreated {
constructor(
public sourceNode: Node,
public sourcePort: Port,
public targetNode: Node,
public targetPort: Port
){}
}
@Component({
selector: 'app-draw-link-tool',
templateUrl: './draw-link-tool.component.html',
styleUrls: ['./draw-link-tool.component.scss']
})
export class DrawLinkToolComponent implements OnInit, OnDestroy {
@ViewChild(NodeSelectInterfaceComponent) nodeSelectInterfaceMenu: NodeSelectInterfaceComponent;
@Output('linkCreated') linkCreated = new EventEmitter<LinkCreated>();
private onNodeClicked: Subscription;
constructor(
private drawingLineTool: DrawingLineWidget,
private nodesWidget: NodesWidget
) { }
ngOnInit() {
this.onNodeClicked = this.nodesWidget.onNodeClicked.subscribe((eventNode: NodeEvent) => {
this.nodeSelectInterfaceMenu.open(eventNode.node, eventNode.event.clientY, eventNode.event.clientX);
});
}
ngOnDestroy() {
if(this.drawingLineTool.isDrawing()) {
this.drawingLineTool.stop();
}
this.onNodeClicked.unsubscribe();
}
// public toggleDrawLineMode() {
// this.drawLineMode = !this.drawLineMode;
// if (!this.drawLineMode) {
// this.mapChild.graphLayout.getDrawingLineTool().stop();
// }
// }
public onChooseInterface(event) {
const node: Node = event.node;
const port: Port = event.port;
// const drawingLineTool = this.mapChild.graphLayout.getDrawingLineTool();
if (this.drawingLineTool.isDrawing()) {
const data = this.drawingLineTool.stop();
this.linkCreated.emit(new LinkCreated(data['node'], data['port'], node, port));
} else {
this.drawingLineTool.start(node.x + node.width / 2., node.y + node.height / 2., {
'node': node,
'port': port
});
}
}
}

View File

@ -2,3 +2,5 @@
class="map" class="map"
preserveAspectRatio="none" preserveAspectRatio="none"
></svg> ></svg>
<app-draw-link-tool *ngIf="drawLinkTool" (linkCreated)="linkCreated($event)"></app-draw-link-tool>

Before

Width:  |  Height:  |  Size: 60 B

After

Width:  |  Height:  |  Size: 159 B

View File

@ -18,6 +18,7 @@ import { SelectionTool } from '../../tools/selection-tool';
import { MovingTool } from '../../tools/moving-tool'; import { MovingTool } from '../../tools/moving-tool';
import { LinksWidget } from '../../widgets/links'; import { LinksWidget } from '../../widgets/links';
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref'; import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
import { LinkCreated } from '../draw-link-tool/draw-link-tool.component';
@Component({ @Component({
@ -35,6 +36,7 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
@Input() height = 600; @Input() height = 600;
@Output() onNodeDragged: EventEmitter<NodeEvent>; @Output() onNodeDragged: EventEmitter<NodeEvent>;
@Output() onLinkCreated = new EventEmitter<LinkCreated>();
private d3: D3; private d3: D3;
private parentNativeElement: any; private parentNativeElement: any;
@ -85,6 +87,8 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
this.mapChangeDetectorRef.detectChanges(); this.mapChangeDetectorRef.detectChanges();
} }
@Input('draw-link-tool') drawLinkTool: boolean;
ngOnChanges(changes: { [propKey: string]: SimpleChange }) { ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
if ( if (
(changes['width'] && !changes['width'].isFirstChange()) || (changes['width'] && !changes['width'].isFirstChange()) ||
@ -156,6 +160,10 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
return new Size(width, height); return new Size(width, height);
} }
protected linkCreated(evt) {
this.onLinkCreated.emit(evt);
}
private changeLayout() { private changeLayout() {
if (this.parentNativeElement != null) { if (this.parentNativeElement != null) {
this.context.size = this.getSize(); this.context.size = this.getSize();
@ -208,6 +216,10 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
this.redraw(); this.redraw();
} }
protected onLinkdddCreated(evt) {
}
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event) { onResize(event) {
this.changeLayout(); this.changeLayout();

View File

@ -1,8 +1,9 @@
import {ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core'; import {ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild, OnDestroy} from '@angular/core';
import {MatMenuTrigger} from "@angular/material"; import {MatMenuTrigger} from "@angular/material";
import {DomSanitizer} from "@angular/platform-browser"; import {DomSanitizer} from "@angular/platform-browser";
import {Node} from "../../../cartography/models/node"; import {Node} from "../../../cartography/models/node";
import {Port} from "../../../models/port"; import {Port} from "../../../models/port";
import { Subscription } from 'rxjs';
@Component({ @Component({
@ -17,11 +18,13 @@ export class NodeSelectInterfaceComponent implements OnInit {
protected topPosition; protected topPosition;
protected leftPosition; protected leftPosition;
public node: Node; public node: Node;
constructor( constructor(
private sanitizer: DomSanitizer, private sanitizer: DomSanitizer,
private changeDetector: ChangeDetectorRef) {} private changeDetector: ChangeDetectorRef,
) {}
ngOnInit() { ngOnInit() {
this.setPosition(0, 0); this.setPosition(0, 0);

View File

@ -9,8 +9,6 @@ import { Context} from "../models/context";
@Injectable() @Injectable()
export class MovingTool { export class MovingTool {
// private selection: SVGSelection;
private zoom: ZoomBehavior<SVGSVGElement, any>; private zoom: ZoomBehavior<SVGSVGElement, any>;
private enabled = false; private enabled = false;
private needsDeactivate = false; private needsDeactivate = false;

View File

@ -9,9 +9,10 @@
[show-interface-labels]="project.show_interface_labels" [show-interface-labels]="project.show_interface_labels"
[selection-tool]="tools.selection" [selection-tool]="tools.selection"
[moving-tool]="tools.moving" [moving-tool]="tools.moving"
[draw-link-tool]="tools.draw_link"
(onNodeDragged)="onNodeDragged($event)" (onNodeDragged)="onNodeDragged($event)"
(onLinkCreated)="onLinkCreated($event)"
></app-map> ></app-map>
<div class="project-toolbar"> <div class="project-toolbar">
<mat-toolbar color="primary" class="project-toolbar"> <mat-toolbar color="primary" class="project-toolbar">
@ -49,7 +50,7 @@
</mat-menu> </mat-menu>
<mat-toolbar-row *ngIf="!readonly"> <mat-toolbar-row *ngIf="!readonly">
<button mat-icon-button [color]="drawLineMode ? 'primary': 'basic'" (click)="toggleDrawLineMode()"> <button mat-icon-button [color]="tools.draw_link ? 'primary': 'basic'" (click)="toggleDrawLineMode()">
<mat-icon>timeline</mat-icon> <mat-icon>timeline</mat-icon>
</button> </button>
</mat-toolbar-row> </mat-toolbar-row>
@ -78,7 +79,6 @@
</div> </div>
<app-node-context-menu [project]="project" [server]="server"></app-node-context-menu> <app-node-context-menu [project]="project" [server]="server"></app-node-context-menu>
<app-node-select-interface (onChooseInterface)="onChooseInterface($event)"></app-node-select-interface>
</div> </div>
<app-progress></app-progress> <app-progress></app-progress>

View File

@ -18,8 +18,6 @@ import { NodeContextMenuComponent } from "./node-context-menu/node-context-menu.
import { Appliance } from "../../models/appliance"; import { Appliance } from "../../models/appliance";
import { NodeService } from "../../services/node.service"; import { NodeService } from "../../services/node.service";
import { Symbol } from "../../models/symbol"; import { Symbol } from "../../models/symbol";
import { NodeSelectInterfaceComponent } from "./node-select-interface/node-select-interface.component";
import { Port } from "../../models/port";
import { LinkService } from "../../services/link.service"; import { LinkService } from "../../services/link.service";
import { NodesDataSource } from "../../cartography/datasources/nodes-datasource"; import { NodesDataSource } from "../../cartography/datasources/nodes-datasource";
import { LinksDataSource } from "../../cartography/datasources/links-datasource"; import { LinksDataSource } from "../../cartography/datasources/links-datasource";
@ -30,6 +28,7 @@ import { DrawingsDataSource } from "../../cartography/datasources/drawings-datas
import { ProgressService } from "../../common/progress/progress.service"; import { ProgressService } from "../../common/progress/progress.service";
import { NodeEvent } from '../../cartography/widgets/nodes'; import { NodeEvent } from '../../cartography/widgets/nodes';
import { MapChangeDetectorRef } from '../../cartography/services/map-change-detector-ref'; import { MapChangeDetectorRef } from '../../cartography/services/map-change-detector-ref';
import { LinkCreated } from '../../cartography/components/draw-link-tool/draw-link-tool.component';
@Component({ @Component({
@ -48,11 +47,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
public server: Server; public server: Server;
private ws: Subject<any>; private ws: Subject<any>;
private drawLineMode = false;
protected tools = { protected tools = {
'selection': true, 'selection': true,
'moving': false 'moving': false,
'draw_link': false
}; };
private inReadOnlyMode = false; private inReadOnlyMode = false;
@ -62,7 +61,6 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
@ViewChild(MapComponent) mapChild: MapComponent; @ViewChild(MapComponent) mapChild: MapComponent;
@ViewChild(NodeContextMenuComponent) nodeContextMenu: NodeContextMenuComponent; @ViewChild(NodeContextMenuComponent) nodeContextMenu: NodeContextMenuComponent;
@ViewChild(NodeSelectInterfaceComponent) nodeSelectInterfaceMenu: NodeSelectInterfaceComponent;
private subscriptions: Subscription[]; private subscriptions: Subscription[];
@ -198,16 +196,6 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
this.subscriptions.push(onContextMenu); this.subscriptions.push(onContextMenu);
const onNodeClicked = this.mapChild.graphLayout.getNodesWidget().onNodeClicked.subscribe((eventNode: NodeEvent) => {
this.selectionManager.clearSelection();
this.selectionManager.setSelectedNodes([eventNode.node]);
if (this.drawLineMode) {
this.nodeSelectInterfaceMenu.open(eventNode.node, eventNode.event.clientY, eventNode.event.clientX);
}
});
this.subscriptions.push(onNodeClicked);
this.subscriptions.push( this.subscriptions.push(
this.selectionManager.subscribe( this.selectionManager.subscribe(
this.mapChild.graphLayout.getSelectionTool().rectangleSelected) this.mapChild.graphLayout.getSelectionTool().rectangleSelected)
@ -259,30 +247,12 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
} }
public toggleDrawLineMode() { public toggleDrawLineMode() {
this.drawLineMode = !this.drawLineMode; this.tools.draw_link = !this.tools.draw_link;
if (!this.drawLineMode) {
this.mapChild.graphLayout.getDrawingLineTool().stop();
}
} }
public onChooseInterface(event) { public onLinkCreated(linkCreated: LinkCreated) {
const node: Node = event.node;
const port: Port = event.port;
const drawingLineTool = this.mapChild.graphLayout.getDrawingLineTool();
if (drawingLineTool.isDrawing()) {
const data = drawingLineTool.stop();
this.onLineCreation(data['node'], data['port'], node, port);
} else {
drawingLineTool.start(node.x + node.width / 2., node.y + node.height / 2., {
'node': node,
'port': port
});
}
}
public onLineCreation(source_node: Node, source_port: Port, target_node: Node, target_port: Port) {
this.linkService this.linkService
.createLink(this.server, source_node, source_port, target_node, target_port) .createLink(this.server, linkCreated.sourceNode, linkCreated.sourcePort, linkCreated.targetNode, linkCreated.targetPort)
.subscribe(() => { .subscribe(() => {
this.projectService.links(this.server, this.project.project_id).subscribe((links: Link[]) => { this.projectService.links(this.server, this.project.project_id).subscribe((links: Link[]) => {
this.linksDataSource.set(links); this.linksDataSource.set(links);

View File

@ -5,8 +5,6 @@ import { Server } from "../models/server";
import { IndexedDbService } from "./indexed-db.service"; import { IndexedDbService } from "./indexed-db.service";
import { AngularIndexedDB } from "angular2-indexeddb"; import { AngularIndexedDB } from "angular2-indexeddb";
import Spy = jasmine.Spy; import Spy = jasmine.Spy;
import { resolve } from 'path';
import { reject } from 'q';
export class MockedServerService { export class MockedServerService {

View File

@ -2,7 +2,6 @@ import { TestBed, inject } from '@angular/core/testing';
import { PersistenceService, StorageType } from "angular-persistence"; import { PersistenceService, StorageType } from "angular-persistence";
import { Settings, SettingsService } from './settings.service'; import { Settings, SettingsService } from './settings.service';
import createSpyObj = jasmine.createSpyObj;
export class MockedSettingsService { export class MockedSettingsService {