From c25e7f538d7ddd3bce495993bb1d093d87da04ff Mon Sep 17 00:00:00 2001 From: ziajka Date: Wed, 14 Nov 2018 16:24:12 +0100 Subject: [PATCH] Merge store into selection manager and separate selection listener --- src/app/cartography/cartography.module.ts | 8 +- .../map/map-node-to-node-converter.ts | 4 +- .../datasources/datasource.spec.ts | 6 +- .../datasources/drawings-datasource.spec.ts | 8 +- ...able-listener.ts => draggable-listener.ts} | 4 +- .../cartography/listeners/map-listeners.ts | 8 +- .../listeners/selection-listener.spec.ts | 73 ++++++++++++++++ .../listeners/selection-listener.ts | 40 ++++++--- .../listeners/selection-update-listener.ts | 31 +++++++ .../managers/selection-manager.spec.ts | 85 ++----------------- .../cartography/managers/selection-manager.ts | 60 +------------ .../widgets/drawings/image-drawing.spec.ts | 2 +- .../widgets/drawings/rect-drawing.spec.ts | 2 +- .../widgets/drawings/text-drawing.spec.ts | 2 +- .../widgets/interface-label.spec.ts | 14 +-- .../project-map-shortcuts.component.spec.ts | 28 +++--- .../project-map-shortcuts.component.ts | 23 ++--- .../project-map/project-map.component.html | 3 +- 18 files changed, 199 insertions(+), 202 deletions(-) rename src/app/cartography/listeners/{nodes-draggable-listener.ts => draggable-listener.ts} (98%) create mode 100644 src/app/cartography/listeners/selection-listener.spec.ts create mode 100644 src/app/cartography/listeners/selection-update-listener.ts diff --git a/src/app/cartography/cartography.module.ts b/src/app/cartography/cartography.module.ts index 739605fb..770ca075 100644 --- a/src/app/cartography/cartography.module.ts +++ b/src/app/cartography/cartography.module.ts @@ -17,7 +17,7 @@ import { Context } from './models/context'; import { D3_MAP_IMPORTS } from './d3-map.imports'; import { CanvasSizeDetector } from './helpers/canvas-size-detector'; import { MapListeners } from './listeners/map-listeners'; -import { NodesDraggableListener } from './listeners/nodes-draggable-listener'; +import { DraggableListener } from './listeners/draggable-listener'; import { DrawingsEventSource } from './events/drawings-event-source'; import { NodesEventSource } from './events/nodes-event-source'; import { DrawingToMapDrawingConverter } from './converters/map/drawing-to-map-drawing-converter'; @@ -35,7 +35,7 @@ import { PortToMapPortConverter } from './converters/map/port-to-map-port-conver import { SymbolToMapSymbolConverter } from './converters/map/symbol-to-map-symbol-converter'; import { LinkNodeToMapLinkNodeConverter } from './converters/map/link-node-to-map-link-node-converter'; import { GraphDataManager } from './managers/graph-data-manager'; -import { SelectionListener } from './listeners/selection-listener'; +import { SelectionUpdateListener } from './listeners/selection-update-listener'; import { MapNodesDataSource, MapLinksDataSource, MapDrawingsDataSource, MapSymbolsDataSource } from './datasources/map-datasource'; @@ -60,9 +60,9 @@ import { MapNodesDataSource, MapLinksDataSource, MapDrawingsDataSource, MapSymbo MapChangeDetectorRef, CanvasSizeDetector, Context, - SelectionListener, + SelectionUpdateListener, MapListeners, - NodesDraggableListener, + DraggableListener, DrawingsEventSource, NodesEventSource, DrawingToMapDrawingConverter, diff --git a/src/app/cartography/converters/map/map-node-to-node-converter.ts b/src/app/cartography/converters/map/map-node-to-node-converter.ts index f45ab71c..d8d02111 100644 --- a/src/app/cartography/converters/map/map-node-to-node-converter.ts +++ b/src/app/cartography/converters/map/map-node-to-node-converter.ts @@ -23,13 +23,13 @@ export class MapNodeToNodeConverter implements Converter { node.console_host = mapNode.consoleHost; node.first_port_name = mapNode.firstPortName; node.height = mapNode.height; - node.label = this.mapLabelToLabel.convert(mapNode.label); + node.label = mapNode.label ? this.mapLabelToLabel.convert(mapNode.label) : undefined; node.name = mapNode.name; node.node_directory = mapNode.nodeDirectory; node.node_type = mapNode.nodeType; node.port_name_format = mapNode.portNameFormat; node.port_segment_size = mapNode.portSegmentSize; - node.ports = mapNode.ports.map((mapPort) => this.mapPortToPort.convert(mapPort)); + node.ports = mapNode.ports ? mapNode.ports.map((mapPort) => this.mapPortToPort.convert(mapPort)) : []; node.project_id = mapNode.projectId; node.status = mapNode.status; node.symbol = mapNode.symbol; diff --git a/src/app/cartography/datasources/datasource.spec.ts b/src/app/cartography/datasources/datasource.spec.ts index c323fe5e..27588056 100644 --- a/src/app/cartography/datasources/datasource.spec.ts +++ b/src/app/cartography/datasources/datasource.spec.ts @@ -6,9 +6,9 @@ class Item { class TestDataSource extends DataSource { - protected findIndex(item: Item) { - return this.data.findIndex((i: Item) => i.id === item.id); - } + protected getItemKey(item: Item) { + return item.id; + }; } diff --git a/src/app/cartography/datasources/drawings-datasource.spec.ts b/src/app/cartography/datasources/drawings-datasource.spec.ts index 3f17bdb0..8a5f4fb8 100644 --- a/src/app/cartography/datasources/drawings-datasource.spec.ts +++ b/src/app/cartography/datasources/drawings-datasource.spec.ts @@ -1,21 +1,21 @@ import { DrawingsDataSource } from "./drawings-datasource"; -import { MapDrawing } from "../models/drawing"; +import { Drawing } from "../models/drawing"; describe('DrawingsDataSource', () => { let dataSource: DrawingsDataSource; - let data: MapDrawing[]; + let data: Drawing[]; beforeEach(() => { dataSource = new DrawingsDataSource(); - dataSource.changes.subscribe((drawings: MapDrawing[]) => { + dataSource.changes.subscribe((drawings: Drawing[]) => { data = drawings; }); }); describe('Drawing can be updated', () => { beforeEach(() => { - const drawing = new MapDrawing(); + const drawing = new Drawing(); drawing.drawing_id = "1"; drawing.project_id = "project1"; dataSource.add(drawing); diff --git a/src/app/cartography/listeners/nodes-draggable-listener.ts b/src/app/cartography/listeners/draggable-listener.ts similarity index 98% rename from src/app/cartography/listeners/nodes-draggable-listener.ts rename to src/app/cartography/listeners/draggable-listener.ts index f0afcdf9..c2406491 100644 --- a/src/app/cartography/listeners/nodes-draggable-listener.ts +++ b/src/app/cartography/listeners/draggable-listener.ts @@ -15,7 +15,7 @@ import { DrawingsEventSource } from "../events/drawings-event-source"; @Injectable() -export class NodesDraggableListener { +export class DraggableListener { private start: Subscription; private drag: Subscription; private end: Subscription; @@ -32,7 +32,6 @@ export class NodesDraggableListener { } public onInit(svg: any) { - this.start = merge( this.nodesWidget.draggable.start, this.drawingsWidget.draggable.start @@ -52,7 +51,6 @@ export class NodesDraggableListener { } }); - this.drag = merge( this.nodesWidget.draggable.drag, this.drawingsWidget.draggable.drag diff --git a/src/app/cartography/listeners/map-listeners.ts b/src/app/cartography/listeners/map-listeners.ts index 2952baf5..afec7f5b 100644 --- a/src/app/cartography/listeners/map-listeners.ts +++ b/src/app/cartography/listeners/map-listeners.ts @@ -1,15 +1,15 @@ import { Injectable } from "@angular/core"; import { MapListener } from "./map-listener"; -import { NodesDraggableListener } from "./nodes-draggable-listener"; -import { SelectionListener } from "./selection-listener"; +import { DraggableListener } from "./draggable-listener"; +import { SelectionUpdateListener } from "./selection-update-listener"; @Injectable() export class MapListeners { private listeners: MapListener[] = []; constructor( - private nodesDraggableListener: NodesDraggableListener, - private selectionListener: SelectionListener + private nodesDraggableListener: DraggableListener, + private selectionListener: SelectionUpdateListener ) { this.listeners.push(this.nodesDraggableListener); this.listeners.push(this.selectionListener); diff --git a/src/app/cartography/listeners/selection-listener.spec.ts b/src/app/cartography/listeners/selection-listener.spec.ts new file mode 100644 index 00000000..2136bb47 --- /dev/null +++ b/src/app/cartography/listeners/selection-listener.spec.ts @@ -0,0 +1,73 @@ +import { Subject} from "rxjs"; + +import { Rectangle } from "../models/rectangle"; +import { InRectangleHelper } from "../helpers/in-rectangle-helper"; +import { MapNode } from "../models/map/map-node"; +import { MapLink } from "../models/map/map-link"; +import { mock, instance, when } from "ts-mockito"; +import { fakeAsync, tick } from "@angular/core/testing"; +import { SelectionListener } from "./selection-listener"; +import { SelectionManager } from "../managers/selection-manager"; +import { GraphDataManager } from "../managers/graph-data-manager"; +import { SelectionTool } from "../tools/selection-tool"; +import { Context } from "../models/context"; + + +describe('SelectionListener', () => { + let selectionListener: SelectionListener; + let manager: SelectionManager; + let selectedRectangleSubject: Subject; + let selectionTool: SelectionTool; + + beforeEach(() => { + const mockedGraphData = mock(GraphDataManager); + + const node_1 = new MapNode(); + node_1.id = "test1"; + node_1.name = "Node 1"; + node_1.x = 150; + node_1.y = 150; + + const node_2 = new MapNode(); + node_2.id = "test2"; + node_2.name = "Node 2"; + node_2.x = 300; + node_2.y = 300; + + const link_1 = new MapLink(); + link_1.id = "test1"; + + when(mockedGraphData.getNodes()).thenReturn([node_1, node_2]); + when(mockedGraphData.getLinks()).thenReturn([link_1]); + when(mockedGraphData.getDrawings()).thenReturn([]); + + const graphData = instance(mockedGraphData); + const inRectangleHelper = new InRectangleHelper(); + + selectedRectangleSubject = new Subject(); + + manager = new SelectionManager(); + selectionTool = new SelectionTool(new Context()); + selectionListener = new SelectionListener(selectionTool, graphData, inRectangleHelper, manager); + selectionListener.onInit(null); + }); + + afterEach(() => { + selectionListener.onDestroy(); + }) + + it('node should be selected', fakeAsync(() => { + selectionTool.rectangleSelected.next(new Rectangle(100, 100, 100, 100)); + tick(); + expect(manager.getSelected().length).toEqual(1); + })); + + it('node should be selected and deselected', fakeAsync(() => { + selectionTool.rectangleSelected.next(new Rectangle(100, 100, 100, 100)); + tick(); + selectionTool.rectangleSelected.next(new Rectangle(350, 350, 100, 100)); + tick(); + expect(manager.getSelected().length).toEqual(0); + })); + +}); diff --git a/src/app/cartography/listeners/selection-listener.ts b/src/app/cartography/listeners/selection-listener.ts index 06725220..b97e366c 100644 --- a/src/app/cartography/listeners/selection-listener.ts +++ b/src/app/cartography/listeners/selection-listener.ts @@ -1,31 +1,45 @@ import { Injectable } from "@angular/core"; +import { GraphDataManager } from "../managers/graph-data-manager"; +import { InRectangleHelper } from "../helpers/in-rectangle-helper"; +import { SelectionTool } from "../tools/selection-tool"; import { Subscription } from "rxjs"; -import { SelectionStore } from "../managers/selection-manager"; -import { MapChangeDetectorRef } from "../services/map-change-detector-ref"; +import { Rectangle } from "electron"; +import { SelectionManager } from "../managers/selection-manager"; @Injectable() export class SelectionListener { - private onSelected: Subscription; - private onUnselected: Subscription; + private onSelection: Subscription; constructor( - private selectionStore: SelectionStore, - private mapChangeDetectorRef: MapChangeDetectorRef + private selectionTool: SelectionTool, + private graphDataManager: GraphDataManager, + private inRectangleHelper: InRectangleHelper, + private selectionManager: SelectionManager ) { } public onInit(svg: any) { - this.onSelected = this.selectionStore.selected.subscribe(() => { - this.mapChangeDetectorRef.detectChanges(); - }); - this.onUnselected = this.selectionStore.unselected.subscribe(() => { - this.mapChangeDetectorRef.detectChanges(); + this.onSelection = this.selectionTool.rectangleSelected.subscribe((rectangle: Rectangle) => { + const selectedNodes = this.graphDataManager.getNodes().filter((node) => { + return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y) + }); + + const selectedLinks = this.graphDataManager.getLinks().filter((link) => { + return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y) + }); + + const selectedDrawings = this.graphDataManager.getDrawings().filter((drawing) => { + return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y) + }); + + const selected = [...selectedNodes, ...selectedLinks, ...selectedDrawings]; + + this.selectionManager.setSelected(selected); }); } public onDestroy() { - this.onSelected.unsubscribe(); - this.onUnselected.unsubscribe(); + this.onSelection.unsubscribe(); } } \ No newline at end of file diff --git a/src/app/cartography/listeners/selection-update-listener.ts b/src/app/cartography/listeners/selection-update-listener.ts new file mode 100644 index 00000000..91fd8a5a --- /dev/null +++ b/src/app/cartography/listeners/selection-update-listener.ts @@ -0,0 +1,31 @@ +import { Injectable } from "@angular/core"; +import { Subscription } from "rxjs"; +import { SelectionStore } from "../managers/selection-manager"; +import { MapChangeDetectorRef } from "../services/map-change-detector-ref"; + + +@Injectable() +export class SelectionUpdateListener { + private onSelected: Subscription; + private onUnselected: Subscription; + + constructor( + private selectionStore: SelectionStore, + private mapChangeDetectorRef: MapChangeDetectorRef + ) { + } + + public onInit(svg: any) { + this.onSelected = this.selectionStore.selected.subscribe(() => { + this.mapChangeDetectorRef.detectChanges(); + }); + this.onUnselected = this.selectionStore.unselected.subscribe(() => { + this.mapChangeDetectorRef.detectChanges(); + }); + } + + public onDestroy() { + this.onSelected.unsubscribe(); + this.onUnselected.unsubscribe(); + } +} \ No newline at end of file diff --git a/src/app/cartography/managers/selection-manager.spec.ts b/src/app/cartography/managers/selection-manager.spec.ts index d40bb0a4..85746789 100644 --- a/src/app/cartography/managers/selection-manager.spec.ts +++ b/src/app/cartography/managers/selection-manager.spec.ts @@ -1,95 +1,20 @@ -import { Subject} from "rxjs"; - -import { Rectangle } from "../models/rectangle"; -import { SelectionManager } from "./selection-manager"; -import { NodesDataSource } from "../datasources/nodes-datasource"; -import { LinksDataSource } from "../datasources/links-datasource"; -import { InRectangleHelper } from "../helpers/in-rectangle-helper"; -import { DrawingsDataSource } from "../datasources/drawings-datasource"; import { MapNode } from "../models/map/map-node"; -import { MapLink } from "../models/map/map-link"; -import { MapDrawing } from "../models/map/map-drawing"; +import { SelectionManager } from "./selection-manager"; describe('SelectionManager', () => { let manager: SelectionManager; - let selectedRectangleSubject: Subject; - let nodesDataSource: NodesDataSource; beforeEach(() => { - const linksDataSource = new LinksDataSource(); - const drawingsDataSource = new DrawingsDataSource(); - const inRectangleHelper = new InRectangleHelper(); - - selectedRectangleSubject = new Subject(); - - nodesDataSource = new NodesDataSource(); - - manager = new SelectionManager(nodesDataSource, linksDataSource, drawingsDataSource, inRectangleHelper); - manager.subscribe(selectedRectangleSubject); - - const node_1 = new MapNode(); - node_1.id = "test1"; - node_1.name = "Node 1"; - node_1.x = 150; - node_1.y = 150; - - nodesDataSource.add(node_1); - - const node_2 = new MapNode(); - node_2.id = "test2"; - node_2.name = "Node 2"; - node_2.x = 300; - node_2.y = 300; - nodesDataSource.add(node_2); - - const link_1 = new MapLink(); - link_1.id = "test1"; - linksDataSource.add(link_1); - }); - - it('node should be selected', () => { - selectedRectangleSubject.next(new Rectangle(100, 100, 100, 100)); - expect(nodesDataSource.getItems()[0].is_selected).toEqual(true); - expect(manager.getSelectedNodes().length).toEqual(1); - expect(manager.getSelectedLinks().length).toEqual(0); - }); - - it('node should be selected and deselected', () => { - selectedRectangleSubject.next(new Rectangle(100, 100, 100, 100)); - selectedRectangleSubject.next(new Rectangle(350, 350, 100, 100)); - expect(nodesDataSource.getItems()[0].is_selected).toEqual(false); - expect(manager.getSelectedNodes().length).toEqual(0); - expect(manager.getSelectedLinks().length).toEqual(0); + manager = new SelectionManager(); }); + it('nodes should be manually selected', () => { const node = new MapNode(); node.id = "test1"; - manager.setSelectedNodes([node]); - expect(manager.getSelectedNodes().length).toEqual(1); + manager.setSelected([node]); + expect(manager.getSelected().length).toEqual(1); }); - it('links should be manually selected', () => { - const link = new MapLink(); - link.id = "test1"; - manager.setSelectedLinks([link]); - expect(manager.getSelectedLinks().length).toEqual(1); - }); - - it('items should be cleared', () => { - const link = new MapLink(); - link.id = "test1"; - const node = new MapNode(); - node.id = "test1"; - const drawing = new MapDrawing(); - drawing.id = "test1"; - manager.setSelectedLinks([link]); - manager.setSelectedNodes([node]); - manager.setSelectedDrawings([drawing]); - manager.clearSelection(); - expect(manager.getSelectedLinks().length).toEqual(0); - expect(manager.getSelectedDrawings().length).toEqual(0); - expect(manager.getSelectedNodes().length).toEqual(0); - }); }); diff --git a/src/app/cartography/managers/selection-manager.ts b/src/app/cartography/managers/selection-manager.ts index c198035e..2f7b0dd3 100644 --- a/src/app/cartography/managers/selection-manager.ts +++ b/src/app/cartography/managers/selection-manager.ts @@ -1,22 +1,16 @@ import { Injectable, EventEmitter } from "@angular/core"; -import { Subject } from "rxjs"; -import { Subscription } from "rxjs"; - -import { InRectangleHelper } from "../helpers/in-rectangle-helper"; -import { Rectangle } from "../models/rectangle"; -import { GraphDataManager } from "./graph-data-manager"; import { Indexed } from "../datasources/map-datasource"; @Injectable() -export class SelectionStore { +export class SelectionManager { private selection: {[id:string]: any} = {}; public selected = new EventEmitter(); public unselected = new EventEmitter(); - public set(items: Indexed[]) { + public setSelected(items: Indexed[]) { const dictItems = this.convertToKeyDict(items); const selected = Object.keys(dictItems).filter((key) => { @@ -33,7 +27,7 @@ export class SelectionStore { this.unselected.emit(unselected); } - public get(): Indexed[] { + public getSelected(): Indexed[] { return Object.keys(this.selection).map(key => this.selection[key]); } @@ -59,51 +53,3 @@ export class SelectionStore { return dict; } } - - -@Injectable() -export class SelectionManager { - private subscription: Subscription; - - constructor( - private graphDataManager: GraphDataManager, - private inRectangleHelper: InRectangleHelper, - private selectionStore: SelectionStore - ) {} - - public subscribe(subject: Subject) { - this.subscription = subject.subscribe((rectangle: Rectangle) => { - this.onSelection(rectangle); - }); - return this.subscription; - } - - public onSelection(rectangle: Rectangle) { - const selectedNodes = this.graphDataManager.getNodes().filter((node) => { - return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y) - }); - - const selectedLinks = this.graphDataManager.getLinks().filter((link) => { - return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y) - }); - - const selectedDrawings = this.graphDataManager.getDrawings().filter((drawing) => { - return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y) - }); - - const selected = [...selectedNodes, ...selectedLinks, ...selectedDrawings]; - - this.selectionStore.set(selected); - } - - public getSelected() { - return this.selectionStore.get(); - } - - public setSelected(value: Indexed[]) { - this.selectionStore.set(value); - } - - public clearSelection() { - } -} diff --git a/src/app/cartography/widgets/drawings/image-drawing.spec.ts b/src/app/cartography/widgets/drawings/image-drawing.spec.ts index 96008962..7fc19d2c 100644 --- a/src/app/cartography/widgets/drawings/image-drawing.spec.ts +++ b/src/app/cartography/widgets/drawings/image-drawing.spec.ts @@ -1,7 +1,7 @@ import { TestSVGCanvas } from "../../testing"; -import { MapDrawing } from "../../models/drawing"; import { ImageDrawingWidget } from "./image-drawing"; import { ImageElement } from "../../models/drawings/image-element"; +import { MapDrawing } from "../../models/map/map-drawing"; describe('ImageDrawingWidget', () => { diff --git a/src/app/cartography/widgets/drawings/rect-drawing.spec.ts b/src/app/cartography/widgets/drawings/rect-drawing.spec.ts index dcbf4e89..f90d02ad 100644 --- a/src/app/cartography/widgets/drawings/rect-drawing.spec.ts +++ b/src/app/cartography/widgets/drawings/rect-drawing.spec.ts @@ -1,8 +1,8 @@ import { TestSVGCanvas } from "../../testing"; -import { MapDrawing } from "../../models/drawing"; import { RectDrawingWidget } from "./rect-drawing"; import { RectElement } from "../../models/drawings/rect-element"; import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer"; +import { MapDrawing } from "../../models/map/map-drawing"; describe('RectDrawingWidget', () => { diff --git a/src/app/cartography/widgets/drawings/text-drawing.spec.ts b/src/app/cartography/widgets/drawings/text-drawing.spec.ts index 8f255eb5..1d75f237 100644 --- a/src/app/cartography/widgets/drawings/text-drawing.spec.ts +++ b/src/app/cartography/widgets/drawings/text-drawing.spec.ts @@ -1,8 +1,8 @@ import { TestSVGCanvas } from "../../testing"; import { TextDrawingWidget } from "./text-drawing"; -import { MapDrawing } from "../../models/drawing"; import { TextElement } from "../../models/drawings/text-element"; import { FontFixer } from "../../helpers/font-fixer"; +import { MapDrawing } from "../../models/map/map-drawing"; describe('TextDrawingWidget', () => { let svg: TestSVGCanvas; diff --git a/src/app/cartography/widgets/interface-label.spec.ts b/src/app/cartography/widgets/interface-label.spec.ts index 3e51e616..c007d4a5 100644 --- a/src/app/cartography/widgets/interface-label.spec.ts +++ b/src/app/cartography/widgets/interface-label.spec.ts @@ -110,14 +110,14 @@ describe('InterfaceLabelsWidget', () => { expect(drew.nodes().length).toEqual(0); }); - it('should draw interface label with class `selected` when selected', () => { - links[0].nodes[0].label.isSelected = true; + // it('should draw interface label with class `selected` when selected', () => { + // links[0].nodes[0].label.isSelected = true; - widget.draw(linksEnter); + // widget.draw(linksEnter); - const drew = svg.canvas.selectAll('g.interface_label_container'); - const sourceInterface = drew.nodes()[0]; - expect(sourceInterface.getAttribute('class')).toContain('selected'); - }); + // const drew = svg.canvas.selectAll('g.interface_label_container'); + // const sourceInterface = drew.nodes()[0]; + // expect(sourceInterface.getAttribute('class')).toContain('selected'); + // }); }); diff --git a/src/app/components/project-map/project-map-shortcuts/project-map-shortcuts.component.spec.ts b/src/app/components/project-map/project-map-shortcuts/project-map-shortcuts.component.spec.ts index 8a93ee5c..4b609013 100644 --- a/src/app/components/project-map/project-map-shortcuts/project-map-shortcuts.component.spec.ts +++ b/src/app/components/project-map/project-map-shortcuts/project-map-shortcuts.component.spec.ts @@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { HttpClientTestingModule } from "@angular/common/http/testing"; import { inject } from "@angular/core/testing"; -import { mock, instance, capture, when } from "ts-mockito"; +import { mock, instance, capture, when, anything } from "ts-mockito"; import { HotkeyModule, HotkeysService, Hotkey } from "angular2-hotkeys"; import { of } from "rxjs"; @@ -12,13 +12,17 @@ import { NodeService } from "../../../services/node.service"; import { HttpServer } from "../../../services/http-server.service"; import { SelectionManager } from "../../../cartography/managers/selection-manager"; import { Server } from "../../../models/server"; -import { Node } from "../../../cartography/models/node"; import { Project } from "../../../models/project"; import { ProjectService } from "../../../services/project.service"; import { MockedProjectService } from "../../../services/project.service.spec"; import { SettingsService } from "../../../services/settings.service"; import { MockedToasterService } from "../../../services/toaster.service.spec"; import { mapTo } from "rxjs/internal/operators"; +import { MapNodeToNodeConverter } from '../../../cartography/converters/map/map-node-to-node-converter'; +import { MapNode } from '../../../cartography/models/map/map-node'; +import { MapLabelToLabelConverter } from '../../../cartography/converters/map/map-label-to-label-converter'; +import { MapPortToPortConverter } from '../../../cartography/converters/map/map-port-to-port-converter'; +import { Node } from '../../../cartography/models/node'; describe('ProjectMapShortcutsComponent', () => { @@ -27,8 +31,13 @@ describe('ProjectMapShortcutsComponent', () => { let hotkeyServiceMock: HotkeysService; let hotkeyServiceInstanceMock: HotkeysService; let nodeServiceMock: NodeService; + let node: MapNode; beforeEach(async(() => { + node = new MapNode(); + const selectionManagerMock = mock(SelectionManager); + when(selectionManagerMock.getSelected()).thenReturn([node]); + nodeServiceMock = mock(NodeService); hotkeyServiceMock = mock(HotkeysService); hotkeyServiceInstanceMock = instance(hotkeyServiceMock); @@ -43,7 +52,11 @@ describe('ProjectMapShortcutsComponent', () => { { provide: HotkeysService, useFactory: () => hotkeyServiceInstanceMock }, { provide: ToasterService, useClass: MockedToasterService }, { provide: ProjectService, useClass: MockedProjectService }, - { provide: SettingsService, useClass: SettingsService } + { provide: SelectionManager, useValue: instance(selectionManagerMock)}, + SettingsService, + MapNodeToNodeConverter, + MapLabelToLabelConverter, + MapPortToPortConverter ], declarations: [ ProjectMapShortcutsComponent ] }) @@ -75,19 +88,14 @@ describe('ProjectMapShortcutsComponent', () => { describe('onDeleteHandler', () => { beforeEach(() => { - const selectionManagerMock = mock(SelectionManager); - const node = new Node(); - node.node_id = "nodeid"; const server = new Server(); const project = new Project(); - when(selectionManagerMock.getSelectedNodes()).thenReturn([node]); - when(nodeServiceMock.delete(server, node)) - .thenReturn(of(node).pipe(mapTo(null))); + when(nodeServiceMock.delete(server, anything())) + .thenReturn(of(new Node()).pipe(mapTo(null))); component.project = project; component.server = server; - component.selectionManager = instance(selectionManagerMock); }); it('should handle delete', inject([ToasterService], (toaster: MockedToasterService) => { diff --git a/src/app/components/project-map/project-map-shortcuts/project-map-shortcuts.component.ts b/src/app/components/project-map/project-map-shortcuts/project-map-shortcuts.component.ts index 00bfa90b..ab372d90 100644 --- a/src/app/components/project-map/project-map-shortcuts/project-map-shortcuts.component.ts +++ b/src/app/components/project-map/project-map-shortcuts/project-map-shortcuts.component.ts @@ -7,6 +7,8 @@ import { Server } from '../../../models/server'; import { ToasterService } from '../../../services/toaster.service'; import { Project } from "../../../models/project"; import { ProjectService } from "../../../services/project.service"; +import { MapNode } from '../../../cartography/models/map/map-node'; +import { MapNodeToNodeConverter } from '../../../cartography/converters/map/map-node-to-node-converter'; @Component({ @@ -16,7 +18,6 @@ import { ProjectService } from "../../../services/project.service"; export class ProjectMapShortcutsComponent implements OnInit, OnDestroy { @Input() project: Project; @Input() server: Server; - @Input() selectionManager: SelectionManager; private deleteHotkey: Hotkey; @@ -24,7 +25,9 @@ export class ProjectMapShortcutsComponent implements OnInit, OnDestroy { private hotkeysService: HotkeysService, private toaster: ToasterService, private nodesService: NodeService, - private projectService: ProjectService + private projectService: ProjectService, + private mapNodeToNode: MapNodeToNodeConverter, + private selectionManager: SelectionManager ) { } ngOnInit() { @@ -37,14 +40,14 @@ export class ProjectMapShortcutsComponent implements OnInit, OnDestroy { onDeleteHandler(event: KeyboardEvent): boolean { if (!this.projectService.isReadOnly(this.project)) { - // const selectedNodes = this.selectionManager.getSelectedNodes(); - // if (selectedNodes) { - // selectedNodes.forEach((node) => { - // this.nodesService.delete(this.server, node).subscribe(data => { - // this.toaster.success("Node has been deleted"); - // }); - // }); - // } + const selected = this.selectionManager.getSelected(); + + selected.filter((item) => item instanceof MapNode).forEach((item: MapNode) => { + const node = this.mapNodeToNode.convert(item); + this.nodesService.delete(this.server, node).subscribe(data => { + this.toaster.success("Node has been deleted"); + }); + }); } return false; } diff --git a/src/app/components/project-map/project-map.component.html b/src/app/components/project-map/project-map.component.html index a62f2834..9bfda43d 100644 --- a/src/app/components/project-map/project-map.component.html +++ b/src/app/components/project-map/project-map.component.html @@ -88,6 +88,5 @@ + [server]="server">