mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-22 14:22:21 +00:00
Merge pull request #147 from GNS3/local-server
Local server support and limit experimental features
This commit is contained in:
commit
5bb5374b65
@ -8,6 +8,7 @@ import { ServersComponent } from "./servers/servers.component";
|
|||||||
import { ProjectsComponent } from "./projects/projects.component";
|
import { ProjectsComponent } from "./projects/projects.component";
|
||||||
import { DefaultLayoutComponent } from "./default-layout/default-layout.component";
|
import { DefaultLayoutComponent } from "./default-layout/default-layout.component";
|
||||||
import { SettingsComponent } from "./settings/settings.component";
|
import { SettingsComponent } from "./settings/settings.component";
|
||||||
|
import { LocalServerComponent } from "./local-server/local-server.component";
|
||||||
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
@ -15,6 +16,7 @@ const routes: Routes = [
|
|||||||
children: [
|
children: [
|
||||||
{ path: '', redirectTo: 'servers', pathMatch: 'full'},
|
{ path: '', redirectTo: 'servers', pathMatch: 'full'},
|
||||||
{ path: 'servers', component: ServersComponent },
|
{ path: 'servers', component: ServersComponent },
|
||||||
|
{ path: 'local', component: LocalServerComponent },
|
||||||
{ path: 'server/:server_id/projects', component: ProjectsComponent },
|
{ path: 'server/:server_id/projects', component: ProjectsComponent },
|
||||||
{ path: 'settings', component: SettingsComponent },
|
{ path: 'settings', component: SettingsComponent },
|
||||||
]
|
]
|
||||||
|
@ -75,6 +75,7 @@ import { SettingsComponent } from './settings/settings.component';
|
|||||||
import { SettingsService } from "./shared/services/settings.service";
|
import { SettingsService } from "./shared/services/settings.service";
|
||||||
|
|
||||||
import { RavenErrorHandler } from "./raven-error-handler";
|
import { RavenErrorHandler } from "./raven-error-handler";
|
||||||
|
import { LocalServerComponent } from './local-server/local-server.component';
|
||||||
|
|
||||||
Raven
|
Raven
|
||||||
.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726')
|
.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726')
|
||||||
@ -102,6 +103,7 @@ Raven
|
|||||||
MoveLayerUpActionComponent,
|
MoveLayerUpActionComponent,
|
||||||
ProjectMapShortcutsComponent,
|
ProjectMapShortcutsComponent,
|
||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
|
LocalServerComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
NgbModule.forRoot(),
|
NgbModule.forRoot(),
|
||||||
|
0
src/app/local-server/local-server.component.html
Normal file
0
src/app/local-server/local-server.component.html
Normal file
0
src/app/local-server/local-server.component.scss
Normal file
0
src/app/local-server/local-server.component.scss
Normal file
25
src/app/local-server/local-server.component.spec.ts
Normal file
25
src/app/local-server/local-server.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LocalServerComponent } from './local-server.component';
|
||||||
|
|
||||||
|
describe('LocalServerComponent', () => {
|
||||||
|
let component: LocalServerComponent;
|
||||||
|
let fixture: ComponentFixture<LocalServerComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ LocalServerComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LocalServerComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
27
src/app/local-server/local-server.component.ts
Normal file
27
src/app/local-server/local-server.component.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Location } from "@angular/common";
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
|
||||||
|
import { ServerService } from "../shared/services/server.service";
|
||||||
|
import { Server } from "../shared/models/server";
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-local-server',
|
||||||
|
templateUrl: './local-server.component.html',
|
||||||
|
styleUrls: ['./local-server.component.scss']
|
||||||
|
})
|
||||||
|
export class LocalServerComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor(private location: Location,
|
||||||
|
private router: Router,
|
||||||
|
private serverService: ServerService) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.serverService.getLocalServer(location.hostname, parseInt(location.port, 10))
|
||||||
|
.then((server: Server) => {
|
||||||
|
this.router.navigate(['/server', server.id, 'projects']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -17,6 +17,9 @@ import { SelectionManager } from "../../cartography/shared/managers/selection-ma
|
|||||||
import { Server } from "../../shared/models/server";
|
import { Server } from "../../shared/models/server";
|
||||||
import { Node } from "../../cartography/shared/models/node";
|
import { Node } from "../../cartography/shared/models/node";
|
||||||
import { Project } from "../../shared/models/project";
|
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', () => {
|
describe('ProjectMapShortcutsComponent', () => {
|
||||||
@ -37,9 +40,11 @@ describe('ProjectMapShortcutsComponent', () => {
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
HttpServer,
|
HttpServer,
|
||||||
{ provide: NodeService, useFactory: () => instance(nodeServiceMock)},
|
{ provide: NodeService, useFactory: () => instance(nodeServiceMock) },
|
||||||
{ provide: HotkeysService, useFactory: () => hotkeyServiceInstanceMock},
|
{ provide: HotkeysService, useFactory: () => hotkeyServiceInstanceMock },
|
||||||
{ provide: ToasterService, useClass: MockedToasterService},
|
{ provide: ToasterService, useClass: MockedToasterService },
|
||||||
|
{ provide: ProjectService, useClass: MockedProjectService },
|
||||||
|
{ provide: SettingsService, useClass: SettingsService }
|
||||||
],
|
],
|
||||||
declarations: [ ProjectMapShortcutsComponent ]
|
declarations: [ ProjectMapShortcutsComponent ]
|
||||||
})
|
})
|
||||||
|
@ -6,6 +6,7 @@ import { NodeService } from '../../shared/services/node.service';
|
|||||||
import { Server } from '../../shared/models/server';
|
import { Server } from '../../shared/models/server';
|
||||||
import { ToasterService } from '../../shared/services/toaster.service';
|
import { ToasterService } from '../../shared/services/toaster.service';
|
||||||
import { Project } from "../../shared/models/project";
|
import { Project } from "../../shared/models/project";
|
||||||
|
import { ProjectService } from "../../shared/services/project.service";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -23,6 +24,7 @@ export class ProjectMapShortcutsComponent implements OnInit, OnDestroy {
|
|||||||
private hotkeysService: HotkeysService,
|
private hotkeysService: HotkeysService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private nodesService: NodeService,
|
private nodesService: NodeService,
|
||||||
|
private projectService: ProjectService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -30,8 +32,8 @@ export class ProjectMapShortcutsComponent implements OnInit, OnDestroy {
|
|||||||
this.hotkeysService.add(this.deleteHotkey);
|
this.hotkeysService.add(this.deleteHotkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDeleteHandler(event: KeyboardEvent):boolean {
|
onDeleteHandler(event: KeyboardEvent): boolean {
|
||||||
if (!this.project.readonly) {
|
if (!this.projectService.isReadOnly(this.project)) {
|
||||||
const selectedNodes = this.selectionManager.getSelectedNodes();
|
const selectedNodes = this.selectionManager.getSelectedNodes();
|
||||||
if (selectedNodes) {
|
if (selectedNodes) {
|
||||||
selectedNodes.forEach((node) => {
|
selectedNodes.forEach((node) => {
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
<mat-toolbar-row *ngIf="!project.readonly">
|
<mat-toolbar-row *ngIf="!readonly">
|
||||||
<button mat-icon-button [color]="drawLineMode ? 'primary': 'basic'" (click)="toggleDrawLineMode()">
|
<button mat-icon-button [color]="drawLineMode ? 'primary': 'basic'" (click)="toggleDrawLineMode()">
|
||||||
<mat-icon>timeline</mat-icon>
|
<mat-icon>timeline</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
@ -45,13 +45,13 @@
|
|||||||
</button>
|
</button>
|
||||||
</mat-toolbar-row>
|
</mat-toolbar-row>
|
||||||
|
|
||||||
<mat-toolbar-row *ngIf="!project.readonly" >
|
<mat-toolbar-row *ngIf="!readonly" >
|
||||||
<button mat-icon-button (click)="createSnapshotModal()">
|
<button mat-icon-button (click)="createSnapshotModal()">
|
||||||
<mat-icon>snooze</mat-icon>
|
<mat-icon>snooze</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar-row>
|
</mat-toolbar-row>
|
||||||
|
|
||||||
<mat-toolbar-row *ngIf="!project.readonly" >
|
<mat-toolbar-row *ngIf="!readonly" >
|
||||||
<app-appliance [server]="server" (onNodeCreation)="onNodeCreation($event)"></app-appliance>
|
<app-appliance [server]="server" (onNodeCreation)="onNodeCreation($event)"></app-appliance>
|
||||||
</mat-toolbar-row>
|
</mat-toolbar-row>
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ import { SelectionManager } from "../cartography/shared/managers/selection-manag
|
|||||||
import { InRectangleHelper } from "../cartography/map/helpers/in-rectangle-helper";
|
import { InRectangleHelper } from "../cartography/map/helpers/in-rectangle-helper";
|
||||||
import { DrawingsDataSource } from "../cartography/shared/datasources/drawings-datasource";
|
import { DrawingsDataSource } from "../cartography/shared/datasources/drawings-datasource";
|
||||||
import { Subscription } from "rxjs/Subscription";
|
import { Subscription } from "rxjs/Subscription";
|
||||||
|
import { SettingsService } from "../shared/services/settings.service";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -61,6 +61,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
private ws: Subject<any>;
|
private ws: Subject<any>;
|
||||||
private drawLineMode = false;
|
private drawLineMode = false;
|
||||||
private movingMode = false;
|
private movingMode = false;
|
||||||
|
private readonly = false;
|
||||||
|
|
||||||
protected selectionManager: SelectionManager;
|
protected selectionManager: SelectionManager;
|
||||||
|
|
||||||
@ -85,6 +86,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
private progressDialogService: ProgressDialogService,
|
private progressDialogService: ProgressDialogService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private projectWebServiceHandler: ProjectWebServiceHandler,
|
private projectWebServiceHandler: ProjectWebServiceHandler,
|
||||||
|
private settingsService: SettingsService,
|
||||||
protected nodesDataSource: NodesDataSource,
|
protected nodesDataSource: NodesDataSource,
|
||||||
protected linksDataSource: LinksDataSource,
|
protected linksDataSource: LinksDataSource,
|
||||||
protected drawingsDataSource: DrawingsDataSource,
|
protected drawingsDataSource: DrawingsDataSource,
|
||||||
@ -104,7 +106,6 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
.flatMap((server: Server) => {
|
.flatMap((server: Server) => {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
return this.projectService.get(server, paramMap.get('project_id')).map((project) => {
|
return this.projectService.get(server, paramMap.get('project_id')).map((project) => {
|
||||||
project.readonly = true;
|
|
||||||
return project;
|
return project;
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -162,6 +163,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onProjectLoad(project: Project) {
|
onProjectLoad(project: Project) {
|
||||||
|
this.readonly = this.projectService.isReadOnly(project);
|
||||||
|
|
||||||
const subscription = this.symbolService
|
const subscription = this.symbolService
|
||||||
.load(this.server)
|
.load(this.server)
|
||||||
.flatMap(() => {
|
.flatMap(() => {
|
||||||
@ -195,10 +198,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setUpMapCallbacks(project: Project) {
|
setUpMapCallbacks(project: Project) {
|
||||||
if (this.project.readonly) {
|
if (this.readonly) {
|
||||||
this.mapChild.graphLayout.getSelectionTool().deactivate();
|
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.mapChild.graphLayout.getNodesWidget().setOnContextMenuCallback((event: any, node: Node) => {
|
||||||
this.nodeContextMenu.open(node, event.clientY, event.clientX);
|
this.nodeContextMenu.open(node, event.clientY, event.clientX);
|
||||||
@ -280,18 +284,19 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
public toggleMovingMode() {
|
public toggleMovingMode() {
|
||||||
this.movingMode = !this.movingMode;
|
this.movingMode = !this.movingMode;
|
||||||
if (this.movingMode) {
|
if (this.movingMode) {
|
||||||
if (!this.project.readonly) {
|
if (!this.readonly) {
|
||||||
this.mapChild.graphLayout.getSelectionTool().deactivate();
|
this.mapChild.graphLayout.getSelectionTool().deactivate();
|
||||||
}
|
}
|
||||||
this.mapChild.graphLayout.getMovingTool().activate();
|
this.mapChild.graphLayout.getMovingTool().activate();
|
||||||
} else {
|
} else {
|
||||||
this.mapChild.graphLayout.getMovingTool().deactivate();
|
this.mapChild.graphLayout.getMovingTool().deactivate();
|
||||||
if (!this.project.readonly) {
|
if (!this.readonly) {
|
||||||
this.mapChild.graphLayout.getSelectionTool().activate();
|
this.mapChild.graphLayout.getSelectionTool().activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public onChooseInterface(event) {
|
public onChooseInterface(event) {
|
||||||
const node: Node = event.node;
|
const node: Node = event.node;
|
||||||
const port: Port = event.port;
|
const port: Port = event.port;
|
||||||
|
@ -46,7 +46,7 @@ export class ProjectsComponent implements OnInit {
|
|||||||
this.route.paramMap
|
this.route.paramMap
|
||||||
.switchMap((params: ParamMap) => {
|
.switchMap((params: ParamMap) => {
|
||||||
const server_id = params.get('server_id');
|
const server_id = params.get('server_id');
|
||||||
return this.serverService.getLocalOrRemote(server_id);
|
return this.serverService.get(parseInt(server_id, 10));
|
||||||
})
|
})
|
||||||
.subscribe((server: Server) => {
|
.subscribe((server: Server) => {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
|
@ -6,6 +6,7 @@ import { FormsModule } from "@angular/forms";
|
|||||||
import { SettingsService } from "../shared/services/settings.service";
|
import { SettingsService } from "../shared/services/settings.service";
|
||||||
import { PersistenceModule } from "angular-persistence";
|
import { PersistenceModule } from "angular-persistence";
|
||||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
|
import { MockedToasterService, ToasterService } from "../shared/services/toaster.service";
|
||||||
|
|
||||||
describe('SettingsComponent', () => {
|
describe('SettingsComponent', () => {
|
||||||
let component: SettingsComponent;
|
let component: SettingsComponent;
|
||||||
@ -17,7 +18,10 @@ describe('SettingsComponent', () => {
|
|||||||
imports: [
|
imports: [
|
||||||
MatExpansionModule, MatCheckboxModule, FormsModule,
|
MatExpansionModule, MatCheckboxModule, FormsModule,
|
||||||
PersistenceModule, BrowserAnimationsModule ],
|
PersistenceModule, BrowserAnimationsModule ],
|
||||||
providers: [ SettingsService ],
|
providers: [
|
||||||
|
SettingsService,
|
||||||
|
{ provide: ToasterService, useClass: MockedToasterService }
|
||||||
|
],
|
||||||
declarations: [ SettingsComponent ]
|
declarations: [ SettingsComponent ]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
@ -37,7 +41,8 @@ describe('SettingsComponent', () => {
|
|||||||
|
|
||||||
it('should get and save new settings', () => {
|
it('should get and save new settings', () => {
|
||||||
const settings = {
|
const settings = {
|
||||||
'crash_reports': true
|
'crash_reports': true,
|
||||||
|
'experimental_features': true
|
||||||
};
|
};
|
||||||
const getAll = spyOn(settingsService, 'getAll').and.returnValue(settings);
|
const getAll = spyOn(settingsService, 'getAll').and.returnValue(settings);
|
||||||
const setAll = spyOn(settingsService, 'setAll');
|
const setAll = spyOn(settingsService, 'setAll');
|
||||||
|
@ -8,4 +8,5 @@ export class Server {
|
|||||||
authorization: ServerAuthorization;
|
authorization: ServerAuthorization;
|
||||||
login: string;
|
login: string;
|
||||||
password: string;
|
password: string;
|
||||||
|
is_local: boolean;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<mat-menu #contextMenu="matMenu">
|
<mat-menu #contextMenu="matMenu">
|
||||||
<app-start-node-action [server]="server" [node]="node"></app-start-node-action>
|
<app-start-node-action [server]="server" [node]="node"></app-start-node-action>
|
||||||
<app-stop-node-action [server]="server" [node]="node"></app-stop-node-action>
|
<app-stop-node-action [server]="server" [node]="node"></app-stop-node-action>
|
||||||
<app-move-layer-up-action *ngIf="!project.readonly" [server]="server" [node]="node"></app-move-layer-up-action>
|
<app-move-layer-up-action *ngIf="!projectService.isReadOnly(project)" [server]="server" [node]="node"></app-move-layer-up-action>
|
||||||
<app-move-layer-down-action *ngIf="!project.readonly" [server]="server" [node]="node"></app-move-layer-down-action>
|
<app-move-layer-down-action *ngIf="!projectService.isReadOnly(project)" [server]="server" [node]="node"></app-move-layer-down-action>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,6 +4,7 @@ import { DomSanitizer } from "@angular/platform-browser";
|
|||||||
import { Node } from "../../cartography/shared/models/node";
|
import { Node } from "../../cartography/shared/models/node";
|
||||||
import { Server } from "../models/server";
|
import { Server } from "../models/server";
|
||||||
import { Project } from "../models/project";
|
import { Project } from "../models/project";
|
||||||
|
import { ProjectService } from "../services/project.service";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -23,7 +24,8 @@ export class NodeContextMenuComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
private changeDetector: ChangeDetectorRef) {}
|
private changeDetector: ChangeDetectorRef,
|
||||||
|
protected projectService: ProjectService) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.setPosition(0, 0);
|
this.setPosition(0, 0);
|
||||||
|
@ -176,4 +176,17 @@ describe('HttpServer', () => {
|
|||||||
expect(req.request.headers.get('Authorization')).toEqual('Basic bG9naW46cGFzc3dvcmQ=');
|
expect(req.request.headers.get('Authorization')).toEqual('Basic bG9naW46cGFzc3dvcmQ=');
|
||||||
expect(req.request.headers.get('CustomHeader')).toEqual('value');
|
expect(req.request.headers.get('CustomHeader')).toEqual('value');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should make local call when ip and port is not defined', () => {
|
||||||
|
server.ip = null;
|
||||||
|
server.port = null;
|
||||||
|
|
||||||
|
service.get(server, '/test', {
|
||||||
|
headers: {
|
||||||
|
'CustomHeader': 'value'
|
||||||
|
}
|
||||||
|
}).subscribe();
|
||||||
|
|
||||||
|
const req = httpTestingController.expectOne('/v2/test');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -112,7 +112,11 @@ export class HttpServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getOptionsForServer<T extends HeadersOptions>(server: Server, url: string, options: T) {
|
private getOptionsForServer<T extends HeadersOptions>(server: Server, url: string, options: T) {
|
||||||
|
if (server.ip && server.port) {
|
||||||
url = `http://${server.ip}:${server.port}/v2${url}`;
|
url = `http://${server.ip}:${server.port}/v2${url}`;
|
||||||
|
} else {
|
||||||
|
url = `/v2${url}`;
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.headers) {
|
if (!options.headers) {
|
||||||
options.headers = {};
|
options.headers = {};
|
||||||
|
@ -4,12 +4,21 @@ import { HttpClient } from '@angular/common/http';
|
|||||||
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';
|
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';
|
||||||
import { HttpServer } from './http-server.service';
|
import { HttpServer } from './http-server.service';
|
||||||
import { Server } from '../models/server';
|
import { Server } from '../models/server';
|
||||||
import { Node } from '../../cartography/shared/models/node';
|
|
||||||
import { Port } from '../models/port';
|
|
||||||
import { getTestServer } from './testing';
|
import { getTestServer } from './testing';
|
||||||
import { Appliance } from '../models/appliance';
|
|
||||||
import { Project } from '../models/project';
|
|
||||||
import { ProjectService } from './project.service';
|
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', () => {
|
describe('ProjectService', () => {
|
||||||
let httpClient: HttpClient;
|
let httpClient: HttpClient;
|
||||||
@ -25,7 +34,8 @@ describe('ProjectService', () => {
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
HttpServer,
|
HttpServer,
|
||||||
ProjectService
|
ProjectService,
|
||||||
|
{ provide: SettingsService, useClass: MockedSettingsService }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -105,4 +115,5 @@ describe('ProjectService', () => {
|
|||||||
const path = service.notificationsPath(server, "myproject");
|
const path = service.notificationsPath(server, "myproject");
|
||||||
expect(path).toEqual('ws://127.0.0.1:3080/v2/projects/myproject/notifications/ws')
|
expect(path).toEqual('ws://127.0.0.1:3080/v2/projects/myproject/notifications/ws')
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -8,11 +8,13 @@ import { Link } from "../../cartography/shared/models/link";
|
|||||||
import { Server } from "../models/server";
|
import { Server } from "../models/server";
|
||||||
import { HttpServer } from "./http-server.service";
|
import { HttpServer } from "./http-server.service";
|
||||||
import {Drawing} from "../../cartography/shared/models/drawing";
|
import {Drawing} from "../../cartography/shared/models/drawing";
|
||||||
|
import { SettingsService } from "./settings.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProjectService {
|
export class ProjectService {
|
||||||
|
|
||||||
constructor(private httpServer: HttpServer) { }
|
constructor(private httpServer: HttpServer,
|
||||||
|
private settingsService: SettingsService) { }
|
||||||
|
|
||||||
get(server: Server, project_id: string) {
|
get(server: Server, project_id: string) {
|
||||||
return this.httpServer
|
return this.httpServer
|
||||||
@ -52,4 +54,11 @@ export class ProjectService {
|
|||||||
notificationsPath(server: Server, project_id: string): string {
|
notificationsPath(server: Server, project_id: string): string {
|
||||||
return `ws://${server.ip}:${server.port}/v2/projects/${project_id}/notifications/ws`;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
|||||||
|
|
||||||
import {IndexedDbService} from "./indexed-db.service";
|
import {IndexedDbService} from "./indexed-db.service";
|
||||||
import {Server} from "../models/server";
|
import {Server} from "../models/server";
|
||||||
|
import { Observable } from "rxjs/Observable";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -21,13 +22,6 @@ export class ServerService {
|
|||||||
this.indexedDbService.get().getByKey(this.tablename, id));
|
this.indexedDbService.get().getByKey(this.tablename, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getLocalOrRemote(id: string) {
|
|
||||||
if (id === 'local') {
|
|
||||||
|
|
||||||
}
|
|
||||||
return this.get(parseInt(id, 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
public create(server: Server) {
|
public create(server: Server) {
|
||||||
return this.onReady(() => {
|
return this.onReady(() => {
|
||||||
const promise = new Promise((resolve, reject) => {
|
const promise = new Promise((resolve, reject) => {
|
||||||
@ -40,6 +34,17 @@ export class ServerService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public update(server: Server) {
|
||||||
|
return this.onReady(() => {
|
||||||
|
const promise = new Promise((resolve, reject) => {
|
||||||
|
this.indexedDbService.get().update(this.tablename, server).then((updated) => {
|
||||||
|
resolve(server);
|
||||||
|
}, reject);
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public findAll() {
|
public findAll() {
|
||||||
return this.onReady(() =>
|
return this.onReady(() =>
|
||||||
this.indexedDbService.get().getAll(this.tablename));
|
this.indexedDbService.get().getAll(this.tablename));
|
||||||
@ -50,6 +55,32 @@ export class ServerService {
|
|||||||
this.indexedDbService.get().delete(this.tablename, server.id));
|
this.indexedDbService.get().delete(this.tablename, server.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getLocalServer(ip: string, port: number) {
|
||||||
|
const promise = new Promise((resolve, reject) => {
|
||||||
|
this.findAll().then((servers: Server[]) => {
|
||||||
|
const local = servers.find((server) => server.is_local);
|
||||||
|
if (local) {
|
||||||
|
local.ip = ip;
|
||||||
|
local.port = port;
|
||||||
|
this.update(local).then((updated) => {
|
||||||
|
resolve(updated);
|
||||||
|
}, reject);
|
||||||
|
} else {
|
||||||
|
const server = new Server();
|
||||||
|
server.name = 'local';
|
||||||
|
server.ip = ip;
|
||||||
|
server.port = port;
|
||||||
|
server.is_local = true;
|
||||||
|
this.create(server).then((created) => {
|
||||||
|
resolve(created);
|
||||||
|
}, reject);
|
||||||
|
}
|
||||||
|
}, reject);
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
private onReady(query) {
|
private onReady(query) {
|
||||||
const promise = new Promise((resolve, reject) => {
|
const promise = new Promise((resolve, reject) => {
|
||||||
this.ready.then(() => {
|
this.ready.then(() => {
|
||||||
|
@ -5,6 +5,13 @@ import { Settings, SettingsService } from './settings.service';
|
|||||||
import createSpyObj = jasmine.createSpyObj;
|
import createSpyObj = jasmine.createSpyObj;
|
||||||
|
|
||||||
|
|
||||||
|
export class MockedSettingsService {
|
||||||
|
isExperimentalEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
describe('SettingsService', () => {
|
describe('SettingsService', () => {
|
||||||
let persistenceService: PersistenceService;
|
let persistenceService: PersistenceService;
|
||||||
|
|
||||||
@ -45,7 +52,8 @@ describe('SettingsService', () => {
|
|||||||
|
|
||||||
it('should get all values', inject([SettingsService], (service: SettingsService) => {
|
it('should get all values', inject([SettingsService], (service: SettingsService) => {
|
||||||
expect(service.getAll()).toEqual({
|
expect(service.getAll()).toEqual({
|
||||||
'crash_reports': true
|
'crash_reports': true,
|
||||||
|
'experimental_features': false
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -53,10 +61,11 @@ describe('SettingsService', () => {
|
|||||||
const settings = {
|
const settings = {
|
||||||
'crash_reports': false
|
'crash_reports': false
|
||||||
};
|
};
|
||||||
service.setAll(settings)
|
service.setAll(settings);
|
||||||
|
|
||||||
expect(service.getAll()).toEqual({
|
expect(service.getAll()).toEqual({
|
||||||
'crash_reports': false
|
'crash_reports': false,
|
||||||
|
'experimental_features': false
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
production: true
|
production: true,
|
||||||
|
electron: false,
|
||||||
|
githubio: false
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user