From d94f6d3d7d91547d00d24a0e435edafdcb0407bd Mon Sep 17 00:00:00 2001 From: Piotr Pekala Date: Thu, 1 Aug 2019 09:10:51 -0700 Subject: [PATCH 1/3] Keyboard shortcuts added --- .../progress/progress.component.spec.ts | 2 +- src/app/components/help/help.component.html | 13 +++++++ .../project-map/project-map.component.spec.ts | 11 +++++- .../project-map/project-map.component.ts | 38 +++++++++++++++++-- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/app/common/progress/progress.component.spec.ts b/src/app/common/progress/progress.component.spec.ts index e5c8f4bb..735354d2 100644 --- a/src/app/common/progress/progress.component.spec.ts +++ b/src/app/common/progress/progress.component.spec.ts @@ -7,7 +7,7 @@ import { RouterTestingModule } from '@angular/router/testing'; import { Router } from '@angular/router'; import { BehaviorSubject, Observable } from 'rxjs'; -class MockedRouter { +export class MockedRouter { events: BehaviorSubject; constructor() { diff --git a/src/app/components/help/help.component.html b/src/app/components/help/help.component.html index 0eda8204..eab6611f 100644 --- a/src/app/components/help/help.component.html +++ b/src/app/components/help/help.component.html @@ -3,6 +3,19 @@
+ + + Useful shortcuts + + + ctrl + + to zoom in + ctrl + - to zoom out + ctrl + 0 to reset zoom + ctrl + a to select all items on map + ctrl + shift + a to deselect all items on map + ctrl + shift + s to go to preferences + + Third party components diff --git a/src/app/components/project-map/project-map.component.spec.ts b/src/app/components/project-map/project-map.component.spec.ts index 8daeda92..dd45a04d 100644 --- a/src/app/components/project-map/project-map.component.spec.ts +++ b/src/app/components/project-map/project-map.component.spec.ts @@ -2,6 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ProjectMapComponent } from './project-map.component'; import { MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule } from '@angular/material'; +import { Router } from '@angular/router'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ServerService } from '../../services/server.service'; import { ProjectService } from '../../services/project.service'; @@ -52,6 +53,8 @@ import { MapSettingService } from '../../services/mapsettings.service'; import { ProjectMapMenuComponent } from './project-map-menu/project-map-menu.component'; import { MockedToasterService } from '../../services/toaster.service.spec'; import { ToasterService } from '../../services/toaster.service'; +import { MapNodesDataSource, MapLinksDataSource, MapDrawingsDataSource, MapSymbolsDataSource } from '../../cartography/datasources/map-datasource'; +import { MockedRouter } from '../../common/progress/progress.component.spec'; export class MockedProgressService { public activate() {} @@ -201,6 +204,7 @@ describe('ProjectMapComponent', () => { let nodesDataSource = new MockedNodesDataSource(); let linksDataSource = new MockedLinksDataSource(); let mockedToasterService = new MockedToasterService(); + let router = new MockedRouter(); let nodeCreatedLabelStylesFixer; beforeEach(async(() => { @@ -245,7 +249,12 @@ describe('ProjectMapComponent', () => { { provide: NodeCreatedLabelStylesFixer, useValue: nodeCreatedLabelStylesFixer}, { provide: MapScaleService }, { provide: NodeCreatedLabelStylesFixer, useValue: nodeCreatedLabelStylesFixer}, - { provide: ToasterService, useValue: mockedToasterService } + { provide: ToasterService, useValue: mockedToasterService }, + { provide: MapNodesDataSource, useClass: MapNodesDataSource }, + { provide: MapLinksDataSource, useClass: LinksDataSource }, + { provide: MapDrawingsDataSource, useClass: MapDrawingsDataSource }, + { provide: MapSymbolsDataSource, useClass: MapSymbolsDataSource }, + { provide: Router, useValue: router} ], declarations: [ProjectMapComponent, ProjectMapMenuComponent, D3MapComponent, ...ANGULAR_MAP_DECLARATIONS], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/components/project-map/project-map.component.ts b/src/app/components/project-map/project-map.component.ts index 002d167b..247c795a 100644 --- a/src/app/components/project-map/project-map.component.ts +++ b/src/app/components/project-map/project-map.component.ts @@ -1,5 +1,5 @@ import { Component, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { ActivatedRoute, ParamMap, Router } from '@angular/router'; import { Observable, Subject, Subscription, from } from 'rxjs'; import { webSocket } from 'rxjs/webSocket'; @@ -51,6 +51,7 @@ import { LabelWidget } from '../../cartography/widgets/label'; import { MapLinkNodeToLinkNodeConverter } from '../../cartography/converters/map/map-link-node-to-link-node-converter'; import { ProjectMapMenuComponent } from './project-map-menu/project-map-menu.component'; import { ToasterService } from '../../services/toaster.service'; +import { MapNodesDataSource, MapLinksDataSource, MapDrawingsDataSource, MapSymbolsDataSource, Indexed } from '../../cartography/datasources/map-datasource'; @Component({ @@ -115,7 +116,12 @@ export class ProjectMapComponent implements OnInit, OnDestroy { private movingEventSource: MovingEventSource, private mapScaleService: MapScaleService, private nodeCreatedLabelStylesFixer: NodeCreatedLabelStylesFixer, - private toasterService: ToasterService + private toasterService: ToasterService, + private mapNodesDataSource: MapNodesDataSource, + private mapLinksDataSource: MapLinksDataSource, + private mapDrawingsDataSource: MapDrawingsDataSource, + private mapSymbolsDataSource: MapSymbolsDataSource, + private router: Router ) {} ngOnInit() { @@ -196,11 +202,37 @@ export class ProjectMapComponent implements OnInit, OnDestroy { addKeyboardListeners() { Mousetrap.bind('ctrl++', (event: Event) => { event.preventDefault(); + this.zoomIn(); }); Mousetrap.bind('ctrl+-', (event: Event) => { event.preventDefault(); - });; + this.zoomOut(); + }); + + Mousetrap.bind('ctrl+0', (event: Event) => { + event.preventDefault(); + this.resetZoom(); + }); + + Mousetrap.bind('ctrl+a', (event: Event) => { + event.preventDefault(); + let allNodes: Indexed[] = this.mapNodesDataSource.getItems(); + let allDrawings: Indexed[] = this.mapDrawingsDataSource.getItems(); + let allLinks: Indexed[] = this.mapLinksDataSource.getItems(); + let allSymbols: Indexed[] = this.mapSymbolsDataSource.getItems(); + this.selectionManager.setSelected(allNodes.concat(allDrawings).concat(allLinks).concat(allSymbols)); + }); + + Mousetrap.bind('ctrl+shift+a', (event: Event) => { + event.preventDefault(); + this.selectionManager.setSelected([]); + }); + + Mousetrap.bind('ctrl+shift+s', (event: Event) => { + event.preventDefault(); + this.router.navigate(['/server', this.server.id, 'preferences']); + }); } onProjectLoad(project: Project) { From 528842b713091e08724fafa526b3fb2f1c227f52 Mon Sep 17 00:00:00 2001 From: Piotr Pekala Date: Mon, 12 Aug 2019 04:05:04 -0700 Subject: [PATCH 2/3] Action created --- src/app/app.module.ts | 4 +- .../bring-to-front-action.component.html | 4 ++ .../bring-to-front-action.component.spec.ts | 0 .../bring-to-front-action.component.ts | 43 +++++++++++++++++++ .../context-menu/context-menu.component.html | 6 +++ 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.html create mode 100644 src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.spec.ts create mode 100644 src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4242bce2..cbe37e82 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -191,6 +191,7 @@ import { DuplicateActionComponent } from './components/project-map/context-menu/ import { MapSettingService } from './services/mapsettings.service'; import { ProjectMapMenuComponent } from './components/project-map/project-map-menu/project-map-menu.component'; import { HelpComponent } from './components/help/help.component'; +import { BringToFrontActionComponent } from './components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component'; if (environment.production) { Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', { @@ -312,7 +313,8 @@ if (environment.production) { ConsoleComponent, NodesMenuComponent, ProjectMapMenuComponent, - HelpComponent + HelpComponent, + BringToFrontActionComponent ], imports: [ BrowserModule, diff --git a/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.html b/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.html new file mode 100644 index 00000000..2a3518ab --- /dev/null +++ b/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.html @@ -0,0 +1,4 @@ + diff --git a/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.spec.ts b/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.ts b/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.ts new file mode 100644 index 00000000..b72848fb --- /dev/null +++ b/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { Server } from '../../../../../models/server'; +import { Node } from '../../../../../cartography/models/node'; +import { NodesDataSource } from '../../../../../cartography/datasources/nodes-datasource'; +import { NodeService } from '../../../../../services/node.service'; +import { Drawing } from '../../../../../cartography/models/drawing'; +import { DrawingsDataSource } from '../../../../../cartography/datasources/drawings-datasource'; +import { DrawingService } from '../../../../../services/drawing.service'; + +@Component({ + selector: 'app-bring-to-front-action', + templateUrl: './bring-to-front-action.component.html' +}) +export class BringToFrontActionComponent implements OnInit { + @Input() server: Server; + @Input() nodes: Node[]; + @Input() drawings: Drawing[]; + + constructor( + private nodesDataSource: NodesDataSource, + private drawingsDataSource: DrawingsDataSource, + private nodeService: NodeService, + private drawingService: DrawingService + ) {} + + ngOnInit() {} + + bringToFront() { + this.nodes.forEach((node) => { + node.z = 100; + this.nodesDataSource.update(node); + + this.nodeService.update(this.server, node).subscribe((node: Node) => {}); + }); + + this.drawings.forEach((drawing) => { + drawing.z = 100; + this.drawingsDataSource.update(drawing); + + this.drawingService.update(this.server, drawing).subscribe((drawing: Drawing) => {}); + }); + } +} diff --git a/src/app/components/project-map/context-menu/context-menu.component.html b/src/app/components/project-map/context-menu/context-menu.component.html index 2ebfeb6a..1824f2ad 100644 --- a/src/app/components/project-map/context-menu/context-menu.component.html +++ b/src/app/components/project-map/context-menu/context-menu.component.html @@ -44,6 +44,12 @@ [nodes]="nodes" [drawings]="drawings" > + Date: Mon, 12 Aug 2019 05:40:40 -0700 Subject: [PATCH 3/3] Unit tests added --- .../bring-to-front-action.component.spec.ts | 66 +++++++++++++++++++ .../project-map/project-map.component.spec.ts | 4 ++ 2 files changed, 70 insertions(+) diff --git a/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.spec.ts b/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.spec.ts index e69de29b..74a264f5 100644 --- a/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.spec.ts +++ b/src/app/components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component.spec.ts @@ -0,0 +1,66 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { BringToFrontActionComponent } from './bring-to-front-action.component'; +import { MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule } from '@angular/material'; +import { CommonModule } from '@angular/common'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MockedDrawingService, MockedDrawingsDataSource, MockedNodesDataSource, MockedNodeService } from '../../../project-map.component.spec'; +import { DrawingService } from '../../../../../services/drawing.service'; +import { NodesDataSource } from '../../../../../cartography/datasources/nodes-datasource'; +import { DrawingsDataSource } from '../../../../../cartography/datasources/drawings-datasource'; +import { NodeService } from '../../../../../services/node.service'; +import { Node } from '../../../../../cartography/models/node'; +import { of } from 'rxjs'; +import { ComponentFactoryResolver } from '@angular/core'; +import { Drawing } from '../../../../../cartography/models/drawing'; + +describe('BringToFrontActionComponent', () => { + let component: BringToFrontActionComponent; + let fixture: ComponentFixture; + let drawingService = new MockedDrawingService(); + let drawingsDataSource = new MockedDrawingsDataSource(); + let nodeService = new MockedNodeService(); + let nodesDataSource = new MockedNodesDataSource(); + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule], + providers: [ + { provide: DrawingService, useValue: drawingService }, + { provide: DrawingsDataSource, useValue: drawingsDataSource }, + { provide: NodeService, useValue: nodeService }, + { provide: NodesDataSource, useValue: nodesDataSource }, + ], + declarations: [BringToFrontActionComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BringToFrontActionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should call node service when bring to front action called', () => { + spyOn(nodeService, 'update').and.returnValue(of()); + component.nodes = [{z: 0} as Node]; + component.drawings = []; + + component.bringToFront(); + + expect(nodeService.update).toHaveBeenCalled(); + }); + + it('should call drawing service when bring to front action called', () => { + spyOn(drawingService, 'update').and.returnValue(of()); + component.nodes = []; + component.drawings = [{z: 0} as Drawing]; + + component.bringToFront(); + + expect(drawingService.update).toHaveBeenCalled(); + }); +}); diff --git a/src/app/components/project-map/project-map.component.spec.ts b/src/app/components/project-map/project-map.component.spec.ts index 8daeda92..5d926762 100644 --- a/src/app/components/project-map/project-map.component.spec.ts +++ b/src/app/components/project-map/project-map.component.spec.ts @@ -94,6 +94,10 @@ export class MockedNodeService { duplicate(server: Server, node: Node) { return of(node); } + + update(server: Server, node: Node) { + return of(node); + } } export class MockedDrawingService {