diff --git a/src/app/project-map/project-map-shortcuts/project-map-shortcuts.component.spec.ts b/src/app/project-map/project-map-shortcuts/project-map-shortcuts.component.spec.ts index b3d0e43c..2b611a23 100644 --- a/src/app/project-map/project-map-shortcuts/project-map-shortcuts.component.spec.ts +++ b/src/app/project-map/project-map-shortcuts/project-map-shortcuts.component.spec.ts @@ -17,6 +17,9 @@ import { SelectionManager } from "../../cartography/shared/managers/selection-ma import { Server } from "../../shared/models/server"; import { Node } from "../../cartography/shared/models/node"; import { Project } from "../../shared/models/project"; +import { ProjectService } from "../../shared/services/project.service"; +import { MockedProjectService } from "../../shared/services/project.service.spec"; +import { SettingsService } from "../../shared/services/settings.service"; describe('ProjectMapShortcutsComponent', () => { @@ -37,9 +40,11 @@ describe('ProjectMapShortcutsComponent', () => { ], providers: [ HttpServer, - { provide: NodeService, useFactory: () => instance(nodeServiceMock)}, - { provide: HotkeysService, useFactory: () => hotkeyServiceInstanceMock}, - { provide: ToasterService, useClass: MockedToasterService}, + { provide: NodeService, useFactory: () => instance(nodeServiceMock) }, + { provide: HotkeysService, useFactory: () => hotkeyServiceInstanceMock }, + { provide: ToasterService, useClass: MockedToasterService }, + { provide: ProjectService, useClass: MockedProjectService }, + { provide: SettingsService, useClass: SettingsService } ], declarations: [ ProjectMapShortcutsComponent ] }) diff --git a/src/app/project-map/project-map-shortcuts/project-map-shortcuts.component.ts b/src/app/project-map/project-map-shortcuts/project-map-shortcuts.component.ts index 6b64476e..493de4c2 100644 --- a/src/app/project-map/project-map-shortcuts/project-map-shortcuts.component.ts +++ b/src/app/project-map/project-map-shortcuts/project-map-shortcuts.component.ts @@ -6,6 +6,7 @@ import { NodeService } from '../../shared/services/node.service'; import { Server } from '../../shared/models/server'; import { ToasterService } from '../../shared/services/toaster.service'; import { Project } from "../../shared/models/project"; +import { ProjectService } from "../../shared/services/project.service"; @Component({ @@ -23,6 +24,7 @@ export class ProjectMapShortcutsComponent implements OnInit, OnDestroy { private hotkeysService: HotkeysService, private toaster: ToasterService, private nodesService: NodeService, + private projectService: ProjectService ) { } ngOnInit() { @@ -30,8 +32,8 @@ export class ProjectMapShortcutsComponent implements OnInit, OnDestroy { this.hotkeysService.add(this.deleteHotkey); } - onDeleteHandler(event: KeyboardEvent):boolean { - if (!this.project.readonly) { + onDeleteHandler(event: KeyboardEvent): boolean { + if (!this.projectService.isReadOnly(this.project)) { const selectedNodes = this.selectionManager.getSelectedNodes(); if (selectedNodes) { selectedNodes.forEach((node) => { diff --git a/src/app/project-map/project-map.component.html b/src/app/project-map/project-map.component.html index 067bff29..63962683 100644 --- a/src/app/project-map/project-map.component.html +++ b/src/app/project-map/project-map.component.html @@ -33,7 +33,7 @@ - + @@ -45,13 +45,13 @@ - + - + diff --git a/src/app/project-map/project-map.component.ts b/src/app/project-map/project-map.component.ts index c759754d..ead5949d 100644 --- a/src/app/project-map/project-map.component.ts +++ b/src/app/project-map/project-map.component.ts @@ -40,7 +40,7 @@ import { SelectionManager } from "../cartography/shared/managers/selection-manag import { InRectangleHelper } from "../cartography/map/helpers/in-rectangle-helper"; import { DrawingsDataSource } from "../cartography/shared/datasources/drawings-datasource"; import { Subscription } from "rxjs/Subscription"; - +import { SettingsService } from "../shared/services/settings.service"; @Component({ @@ -61,6 +61,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy { private ws: Subject; private drawLineMode = false; private movingMode = false; + private readonly = false; protected selectionManager: SelectionManager; @@ -85,6 +86,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy { private progressDialogService: ProgressDialogService, private toaster: ToasterService, private projectWebServiceHandler: ProjectWebServiceHandler, + private settingsService: SettingsService, protected nodesDataSource: NodesDataSource, protected linksDataSource: LinksDataSource, protected drawingsDataSource: DrawingsDataSource, @@ -104,7 +106,6 @@ export class ProjectMapComponent implements OnInit, OnDestroy { .flatMap((server: Server) => { this.server = server; return this.projectService.get(server, paramMap.get('project_id')).map((project) => { - project.readonly = true; return project; }); }) @@ -162,6 +163,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy { } onProjectLoad(project: Project) { + this.readonly = this.projectService.isReadOnly(project); + const subscription = this.symbolService .load(this.server) .flatMap(() => { @@ -195,10 +198,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy { } setUpMapCallbacks(project: Project) { - if (this.project.readonly) { + if (this.readonly) { this.mapChild.graphLayout.getSelectionTool().deactivate(); } - this.mapChild.graphLayout.getNodesWidget().setDraggingEnabled(!this.project.readonly); + + this.mapChild.graphLayout.getNodesWidget().setDraggingEnabled(!this.readonly); this.mapChild.graphLayout.getNodesWidget().setOnContextMenuCallback((event: any, node: Node) => { this.nodeContextMenu.open(node, event.clientY, event.clientX); @@ -280,18 +284,19 @@ export class ProjectMapComponent implements OnInit, OnDestroy { public toggleMovingMode() { this.movingMode = !this.movingMode; if (this.movingMode) { - if (!this.project.readonly) { + if (!this.readonly) { this.mapChild.graphLayout.getSelectionTool().deactivate(); } this.mapChild.graphLayout.getMovingTool().activate(); } else { this.mapChild.graphLayout.getMovingTool().deactivate(); - if (!this.project.readonly) { + if (!this.readonly) { this.mapChild.graphLayout.getSelectionTool().activate(); } } } + public onChooseInterface(event) { const node: Node = event.node; const port: Port = event.port; diff --git a/src/app/settings/settings.component.spec.ts b/src/app/settings/settings.component.spec.ts index c5a151e6..feaf3b22 100644 --- a/src/app/settings/settings.component.spec.ts +++ b/src/app/settings/settings.component.spec.ts @@ -6,6 +6,7 @@ import { FormsModule } from "@angular/forms"; import { SettingsService } from "../shared/services/settings.service"; import { PersistenceModule } from "angular-persistence"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { MockedToasterService, ToasterService } from "../shared/services/toaster.service"; describe('SettingsComponent', () => { let component: SettingsComponent; @@ -17,7 +18,10 @@ describe('SettingsComponent', () => { imports: [ MatExpansionModule, MatCheckboxModule, FormsModule, PersistenceModule, BrowserAnimationsModule ], - providers: [ SettingsService ], + providers: [ + SettingsService, + { provide: ToasterService, useClass: MockedToasterService } + ], declarations: [ SettingsComponent ] }) .compileComponents(); @@ -37,7 +41,8 @@ describe('SettingsComponent', () => { it('should get and save new settings', () => { const settings = { - 'crash_reports': true + 'crash_reports': true, + 'experimental_features': true }; const getAll = spyOn(settingsService, 'getAll').and.returnValue(settings); const setAll = spyOn(settingsService, 'setAll'); diff --git a/src/app/shared/node-context-menu/node-context-menu.component.html b/src/app/shared/node-context-menu/node-context-menu.component.html index bd0a086b..cd50b5f6 100644 --- a/src/app/shared/node-context-menu/node-context-menu.component.html +++ b/src/app/shared/node-context-menu/node-context-menu.component.html @@ -3,7 +3,7 @@ - - + + diff --git a/src/app/shared/node-context-menu/node-context-menu.component.ts b/src/app/shared/node-context-menu/node-context-menu.component.ts index 1fda55c5..4f4ad8ea 100644 --- a/src/app/shared/node-context-menu/node-context-menu.component.ts +++ b/src/app/shared/node-context-menu/node-context-menu.component.ts @@ -4,6 +4,7 @@ import { DomSanitizer } from "@angular/platform-browser"; import { Node } from "../../cartography/shared/models/node"; import { Server } from "../models/server"; import { Project } from "../models/project"; +import { ProjectService } from "../services/project.service"; @Component({ @@ -23,7 +24,8 @@ export class NodeContextMenuComponent implements OnInit { constructor( private sanitizer: DomSanitizer, - private changeDetector: ChangeDetectorRef) {} + private changeDetector: ChangeDetectorRef, + protected projectService: ProjectService) {} ngOnInit() { this.setPosition(0, 0); diff --git a/src/app/shared/services/project.service.spec.ts b/src/app/shared/services/project.service.spec.ts index 60f47ffd..32ad72c5 100644 --- a/src/app/shared/services/project.service.spec.ts +++ b/src/app/shared/services/project.service.spec.ts @@ -4,12 +4,21 @@ import { HttpClient } from '@angular/common/http'; import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing'; import { HttpServer } from './http-server.service'; import { Server } from '../models/server'; -import { Node } from '../../cartography/shared/models/node'; -import { Port } from '../models/port'; import { getTestServer } from './testing'; -import { Appliance } from '../models/appliance'; -import { Project } from '../models/project'; import { ProjectService } from './project.service'; +import { SettingsService } from "./settings.service"; +import { MockedSettingsService } from "./settings.service.spec"; + + +/** + * Mocks ProjectsService so it's not based on settings + */ +export class MockedProjectService { + isReadOnly(project) { + return project.readonly; + } +} + describe('ProjectService', () => { let httpClient: HttpClient; @@ -25,7 +34,8 @@ describe('ProjectService', () => { ], providers: [ HttpServer, - ProjectService + ProjectService, + { provide: SettingsService, useClass: MockedSettingsService } ] }); diff --git a/src/app/shared/services/project.service.ts b/src/app/shared/services/project.service.ts index c8f83440..c3ef1f0c 100644 --- a/src/app/shared/services/project.service.ts +++ b/src/app/shared/services/project.service.ts @@ -8,11 +8,13 @@ import { Link } from "../../cartography/shared/models/link"; import { Server } from "../models/server"; import { HttpServer } from "./http-server.service"; import {Drawing} from "../../cartography/shared/models/drawing"; +import { SettingsService } from "./settings.service"; @Injectable() export class ProjectService { - constructor(private httpServer: HttpServer) { } + constructor(private httpServer: HttpServer, + private settingsService: SettingsService) { } get(server: Server, project_id: string) { return this.httpServer @@ -52,4 +54,11 @@ export class ProjectService { notificationsPath(server: Server, project_id: string): string { return `ws://${server.ip}:${server.port}/v2/projects/${project_id}/notifications/ws`; } + + isReadOnly(project: Project) { + if (project.readonly) { + return project.readonly; + } + return !this.settingsService.isExperimentalEnabled(); + } } diff --git a/src/app/shared/services/settings.service.spec.ts b/src/app/shared/services/settings.service.spec.ts index 6a32066c..7f5650cf 100644 --- a/src/app/shared/services/settings.service.spec.ts +++ b/src/app/shared/services/settings.service.spec.ts @@ -5,6 +5,13 @@ import { Settings, SettingsService } from './settings.service'; import createSpyObj = jasmine.createSpyObj; +export class MockedSettingsService { + isExperimentalEnabled() { + return true; + } +} + + describe('SettingsService', () => { let persistenceService: PersistenceService; @@ -45,7 +52,8 @@ describe('SettingsService', () => { it('should get all values', inject([SettingsService], (service: SettingsService) => { expect(service.getAll()).toEqual({ - 'crash_reports': true + 'crash_reports': true, + 'experimental_features': false }); })); @@ -53,10 +61,11 @@ describe('SettingsService', () => { const settings = { 'crash_reports': false }; - service.setAll(settings) + service.setAll(settings); expect(service.getAll()).toEqual({ - 'crash_reports': false + 'crash_reports': false, + 'experimental_features': false }); }));