mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-04-09 11:31:15 +00:00
commit
88f44554de
@ -323,6 +323,7 @@ import { UploadingProcessbarComponent } from './common/uploading-processbar/uplo
|
||||
import { ExportPortableProjectComponent } from './components/export-portable-project/export-portable-project.component';
|
||||
import { NodesMenuConfirmationDialogComponent } from './components/project-map/nodes-menu/nodes-menu-confirmation-dialog/nodes-menu-confirmation-dialog.component';
|
||||
import { ConfirmationDeleteAllProjectsComponent } from './components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component';
|
||||
import { ProjectMapLockConfirmationDialogComponent } from './components/project-map/project-map-menu/project-map-lock-confirmation-dialog/project-map-lock-confirmation-dialog.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -561,6 +562,7 @@ import { ConfirmationDeleteAllProjectsComponent } from './components/projects/co
|
||||
ExportPortableProjectComponent,
|
||||
NodesMenuConfirmationDialogComponent,
|
||||
ConfirmationDeleteAllProjectsComponent,
|
||||
ProjectMapLockConfirmationDialogComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -3,16 +3,17 @@ import { DrawingsDataSource } from '../../../../../cartography/datasources/drawi
|
||||
import { NodesDataSource } from '../../../../../cartography/datasources/nodes-datasource';
|
||||
import { Drawing } from '../../../../../cartography/models/drawing';
|
||||
import { Node } from '../../../../../cartography/models/node';
|
||||
import{ Controller } from '../../../../../models/controller';
|
||||
import { Controller } from '../../../../../models/controller';
|
||||
import { DrawingService } from '../../../../../services/drawing.service';
|
||||
import { NodeService } from '../../../../../services/node.service';
|
||||
import { ProjectService } from '../../../../../services/project.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-lock-action',
|
||||
templateUrl: './lock-action.component.html',
|
||||
})
|
||||
export class LockActionComponent implements OnChanges {
|
||||
@Input() controller:Controller ;
|
||||
@Input() controller: Controller;
|
||||
@Input() nodes: Node[];
|
||||
@Input() drawings: Drawing[];
|
||||
command: string;
|
||||
@ -21,7 +22,8 @@ export class LockActionComponent implements OnChanges {
|
||||
private nodesDataSource: NodesDataSource,
|
||||
private drawingsDataSource: DrawingsDataSource,
|
||||
private nodeService: NodeService,
|
||||
private drawingService: DrawingService
|
||||
private drawingService: DrawingService,
|
||||
private projectService: ProjectService
|
||||
) {}
|
||||
|
||||
ngOnChanges() {
|
||||
@ -34,19 +36,20 @@ export class LockActionComponent implements OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
lock() {
|
||||
this.nodes.forEach((node) => {
|
||||
async lock() {
|
||||
await this.nodes.forEach((node) => {
|
||||
node.locked = !node.locked;
|
||||
this.nodeService.updateNode(this.controller, node).subscribe((node) => {
|
||||
this.nodesDataSource.update(node);
|
||||
});
|
||||
});
|
||||
|
||||
this.drawings.forEach((drawing) => {
|
||||
await this.drawings.forEach((drawing) => {
|
||||
drawing.locked = !drawing.locked;
|
||||
this.drawingService.update(this.controller, drawing).subscribe((drawing) => {
|
||||
this.drawingsDataSource.update(drawing);
|
||||
});
|
||||
});
|
||||
this.projectService.projectUpdateLockIcon()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h5 class="heading-txt">Confirm {{ confirmActionData.actionType}} All</h5>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<mat-dialog-content>
|
||||
<p class="text-padding">Are you sure you want to {{confirmActionData.actionType}} all devices?</p>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-button mat-dialog-close>No</button>
|
||||
<button mat-button (click)="confirmAction()" cdkFocusInitial>Yes</button>
|
||||
</mat-dialog-actions>
|
||||
|
@ -0,0 +1,44 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
|
||||
import { ProjectMapLockConfirmationDialogComponent } from './project-map-lock-confirmation-dialog.component';
|
||||
|
||||
describe('ProjectMapLockConfirmationDialogComponent', () => {
|
||||
let component: ProjectMapLockConfirmationDialogComponent;
|
||||
let fixture: ComponentFixture<ProjectMapLockConfirmationDialogComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports:[
|
||||
MatIconModule,
|
||||
MatToolbarModule,
|
||||
MatMenuModule,
|
||||
MatCheckboxModule,
|
||||
MatDialogModule,
|
||||
MatSnackBarModule,
|
||||
],
|
||||
providers: [
|
||||
|
||||
{ provide: MAT_DIALOG_DATA, useValue: {} },
|
||||
{ provide: MatDialogRef, useValue: {} },
|
||||
],
|
||||
declarations: [ ProjectMapLockConfirmationDialogComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProjectMapLockConfirmationDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,28 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'app-project-map-lock-confirmation-dialog',
|
||||
templateUrl: './project-map-lock-confirmation-dialog.component.html',
|
||||
styleUrls: ['./project-map-lock-confirmation-dialog.component.scss']
|
||||
})
|
||||
export class ProjectMapLockConfirmationDialogComponent implements OnInit {
|
||||
confirmActionData = {
|
||||
actionType: 'Unlock',
|
||||
isAction:false
|
||||
};
|
||||
constructor(
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
public dialogRef: MatDialogRef<ProjectMapLockConfirmationDialogComponent>
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.confirmActionData.actionType = this.data.actionType;
|
||||
}
|
||||
|
||||
confirmAction() {
|
||||
this.confirmActionData.isAction = this.data.actionType == 'Lock'? true : false;
|
||||
this.dialogRef.close(this.confirmActionData);
|
||||
}
|
||||
|
||||
}
|
@ -86,7 +86,7 @@
|
||||
class="menu-button"
|
||||
(click)="changeLockValue()"
|
||||
>
|
||||
<mat-icon [ngClass]="{ unmarkedLight: !isLocked && isLightThemeEnabled, marked: isLocked }">lock</mat-icon>
|
||||
<mat-icon [ngClass]="{ unmarkedLight: !isLocked && isLightThemeEnabled, marked: isLocked }">{{lock}}</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
matTooltip="Take a screenshot"
|
||||
|
@ -7,6 +7,7 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ProjectService } from '../../../services/project.service';
|
||||
import { ElectronService } from 'ngx-electron';
|
||||
import { ANGULAR_MAP_DECLARATIONS } from '../../../cartography/angular-map.imports';
|
||||
import { D3MapComponent } from '../../../cartography/components/d3-map/d3-map.component';
|
||||
@ -15,8 +16,14 @@ import { MapSettingsService } from '../../../services/mapsettings.service';
|
||||
import { SymbolService } from '../../../services/symbol.service';
|
||||
import { ToolsService } from '../../../services/tools.service';
|
||||
import { MockedSymbolService } from '../../preferences/common/symbols/symbols.component.spec';
|
||||
import { MockedDrawingService } from '../project-map.component.spec';
|
||||
import { MockedDrawingService,MockedDrawingsDataSource } from '../project-map.component.spec';
|
||||
import { ProjectMapMenuComponent } from './project-map-menu.component';
|
||||
import { MockedProjectService } from '../../../services/project.service.spec';
|
||||
import { MockedNodesDataSource, MockedNodeService } from '../project-map.component.spec';
|
||||
import { NodeService } from '../../../services/node.service';
|
||||
import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource';
|
||||
import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source';
|
||||
import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource';
|
||||
|
||||
describe('ProjectMapMenuComponent', () => {
|
||||
let component: ProjectMapMenuComponent;
|
||||
@ -24,6 +31,11 @@ describe('ProjectMapMenuComponent', () => {
|
||||
let drawingService = new MockedDrawingService();
|
||||
let mapSettingService = new MapSettingsService();
|
||||
let mockedSymbolService = new MockedSymbolService();
|
||||
let mockedProjectService: MockedProjectService = new MockedProjectService();
|
||||
let mockedNodeService: MockedNodeService = new MockedNodeService();
|
||||
let mockedNodesDataSource: MockedNodesDataSource = new MockedNodesDataSource();
|
||||
let mockedDrawingsDataSource = new MockedDrawingsDataSource();
|
||||
let mockedDrawingsEventSource = new DrawingsEventSource();
|
||||
|
||||
beforeEach(async() => {
|
||||
await TestBed.configureTestingModule({
|
||||
@ -38,9 +50,14 @@ describe('ProjectMapMenuComponent', () => {
|
||||
],
|
||||
providers: [
|
||||
{ provide: DrawingService, useValue: drawingService },
|
||||
{ provide: ToolsService },
|
||||
{ provide: DrawingsDataSource, useValue: mockedDrawingsDataSource },
|
||||
{ provide: DrawingsEventSource, useValue: mockedDrawingsEventSource },
|
||||
{ provide: ProjectService, useValue: mockedProjectService },
|
||||
{ provide: ToolsService, useClass: ToolsService },
|
||||
{ provide: MapSettingsService, useValue: mapSettingService },
|
||||
{ provide: SymbolService, useValue: mockedSymbolService },
|
||||
{ provide: NodeService, useValue: mockedNodeService },
|
||||
{ provide: NodesDataSource, useValue: mockedNodesDataSource },
|
||||
{ provide: ElectronService },
|
||||
],
|
||||
declarations: [ProjectMapMenuComponent, D3MapComponent, ...ANGULAR_MAP_DECLARATIONS],
|
||||
@ -77,9 +94,9 @@ describe('ProjectMapMenuComponent', () => {
|
||||
spyOn(mapSettingService, 'changeMapLockValue');
|
||||
|
||||
component.changeLockValue();
|
||||
expect(mapSettingService.changeMapLockValue).toHaveBeenCalledWith(true);
|
||||
expect(mapSettingService.changeMapLockValue).toHaveBeenCalledWith(true);;
|
||||
|
||||
component.changeLockValue();
|
||||
expect(mapSettingService.changeMapLockValue).toHaveBeenCalledWith(false);
|
||||
expect(mapSettingService.changeMapLockValue).toHaveBeenCalledWith(false);;
|
||||
});
|
||||
});
|
||||
|
@ -1,17 +1,24 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { NodeService } from '../../../services/node.service';
|
||||
import { select } from 'd3-selection';
|
||||
import { Subscription } from 'rxjs';
|
||||
import * as svg from 'save-svg-as-png';
|
||||
import downloadSvg from 'svg-crowbar';
|
||||
import { Drawing } from '../../../cartography/models/drawing';
|
||||
import { Node } from '../../../cartography/models/node';
|
||||
import { Controller } from '../../../models/controller';
|
||||
import { Project } from '../../../models/project';
|
||||
import{ Controller } from '../../../models/controller';
|
||||
import { DrawingService } from '../../../services/drawing.service';
|
||||
import { MapSettingsService } from '../../../services/mapsettings.service';
|
||||
import { ProjectService } from '../../../services/project.service';
|
||||
import { SymbolService } from '../../../services/symbol.service';
|
||||
import { ThemeService } from '../../../services/theme.service';
|
||||
import { ToolsService } from '../../../services/tools.service';
|
||||
import { Screenshot, ScreenshotDialogComponent } from '../screenshot-dialog/screenshot-dialog.component';
|
||||
|
||||
import { ProjectMapLockConfirmationDialogComponent } from './project-map-lock-confirmation-dialog/project-map-lock-confirmation-dialog.component';
|
||||
import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource';
|
||||
import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource';
|
||||
@Component({
|
||||
selector: 'app-project-map-menu',
|
||||
templateUrl: './project-map-menu.component.html',
|
||||
@ -20,9 +27,12 @@ import { Screenshot, ScreenshotDialogComponent } from '../screenshot-dialog/scre
|
||||
})
|
||||
export class ProjectMapMenuComponent implements OnInit, OnDestroy {
|
||||
@Input() project: Project;
|
||||
@Input() controller:Controller ;
|
||||
@Input() controller: Controller;
|
||||
private nodes: Node[] = [];
|
||||
private drawing: Drawing[] = [];
|
||||
|
||||
public selectedDrawing: string;
|
||||
public lock: string = 'lock_open';
|
||||
public drawTools = {
|
||||
isRectangleChosen: false,
|
||||
isEllipseChosen: false,
|
||||
@ -31,20 +41,30 @@ export class ProjectMapMenuComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
public isLocked: boolean = false;
|
||||
public isLightThemeEnabled: boolean = false;
|
||||
|
||||
private projectSubscription: Subscription;
|
||||
constructor(
|
||||
private toolsService: ToolsService,
|
||||
private mapSettingsService: MapSettingsService,
|
||||
private drawingService: DrawingService,
|
||||
private symbolService: SymbolService,
|
||||
private dialog: MatDialog,
|
||||
private themeService: ThemeService
|
||||
private themeService: ThemeService,
|
||||
private projectServices: ProjectService,
|
||||
private nodeService : NodeService,
|
||||
private nodesDataSource: NodesDataSource,
|
||||
private drawingsDataSource: DrawingsDataSource,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.themeService.getActualTheme() === 'light'
|
||||
? (this.isLightThemeEnabled = true)
|
||||
: (this.isLightThemeEnabled = false);
|
||||
this.projectSubscription = this.projectServices.projectLockIconSubject.subscribe((isRedraw: boolean) => {
|
||||
if (isRedraw) {
|
||||
this.getAllNodesAndDrawingStatus();
|
||||
}
|
||||
});
|
||||
this.getAllNodesAndDrawingStatus();
|
||||
}
|
||||
|
||||
getCssClassForIcon(type: string) {
|
||||
@ -104,11 +124,15 @@ export class ProjectMapMenuComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public addDrawing(selectedObject: string) {
|
||||
if ((selectedObject === 'rectangle' && this.drawTools.isRectangleChosen) || (selectedObject === 'ellipse' && this.drawTools.isEllipseChosen) ||
|
||||
(selectedObject === 'line' && this.drawTools.isLineChosen) || (selectedObject === 'text' && this.drawTools.isTextChosen)) {
|
||||
document.documentElement.style.cursor = "default";
|
||||
if (
|
||||
(selectedObject === 'rectangle' && this.drawTools.isRectangleChosen) ||
|
||||
(selectedObject === 'ellipse' && this.drawTools.isEllipseChosen) ||
|
||||
(selectedObject === 'line' && this.drawTools.isLineChosen) ||
|
||||
(selectedObject === 'text' && this.drawTools.isTextChosen)
|
||||
) {
|
||||
document.documentElement.style.cursor = 'default';
|
||||
} else {
|
||||
document.documentElement.style.cursor = "crosshair";
|
||||
document.documentElement.style.cursor = 'crosshair';
|
||||
}
|
||||
|
||||
switch (selectedObject) {
|
||||
@ -147,8 +171,7 @@ export class ProjectMapMenuComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public resetDrawToolChoice() {
|
||||
document.documentElement.style.cursor = "default";
|
||||
|
||||
document.documentElement.style.cursor = 'default';
|
||||
this.drawTools.isRectangleChosen = false;
|
||||
this.drawTools.isEllipseChosen = false;
|
||||
this.drawTools.isLineChosen = false;
|
||||
@ -156,10 +179,70 @@ export class ProjectMapMenuComponent implements OnInit, OnDestroy {
|
||||
this.selectedDrawing = '';
|
||||
this.toolsService.textAddingToolActivation(this.drawTools.isTextChosen);
|
||||
}
|
||||
getAllNodesAndDrawingStatus() {
|
||||
this.projectServices.getProjectStatus(this.controller,this.project.project_id).subscribe((status)=>{
|
||||
if (status) {
|
||||
this.isLocked = true;
|
||||
this.lock = 'lock';
|
||||
} else {
|
||||
this.isLocked = false;
|
||||
this.lock = 'lock_open';
|
||||
}
|
||||
})
|
||||
this.projectServices.nodes(this.controller, this.project.project_id).subscribe((response) => {
|
||||
this.nodes = response;
|
||||
this.nodes.forEach((node) => {
|
||||
this.nodeService.updateNode(this.controller, node).subscribe((node) => {
|
||||
this.nodesDataSource.update(node);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
this.projectServices.drawings(this.controller, this.project.project_id).subscribe((response) => {
|
||||
this.drawing = response;
|
||||
this.drawing.forEach((drawing) => {
|
||||
this.drawingService.update(this.controller, drawing).subscribe((drawing) => {
|
||||
this.drawingsDataSource.update(drawing);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public changeLockValue() {
|
||||
this.isLocked = !this.isLocked;
|
||||
this.mapSettingsService.changeMapLockValue(this.isLocked);
|
||||
const dialogRef = this.dialog.open(ProjectMapLockConfirmationDialogComponent, {
|
||||
width: '500px',
|
||||
maxHeight: '200px',
|
||||
autoFocus: false,
|
||||
disableClose: true,
|
||||
data: { isAction: this.isLocked, actionType: this.isLocked == true ? 'Lock' : 'Unlock' },
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((confirmAction_result) => {
|
||||
if (confirmAction_result && confirmAction_result != '') {
|
||||
if (confirmAction_result.actionType == 'Lock' && confirmAction_result.isAction) {
|
||||
this.lockAllNode();
|
||||
} else {
|
||||
this.unlockAllNode();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
lockAllNode() {
|
||||
this.lock = 'lock';
|
||||
this.drawingService.lockAllNodes(this.controller, this.project).subscribe((res) => {
|
||||
this.getAllNodesAndDrawingStatus();
|
||||
});
|
||||
}
|
||||
|
||||
unlockAllNode() {
|
||||
this.lock = 'lock_open';
|
||||
this.drawingService.unLockAllNodes(this.controller, this.project).subscribe((res) => {
|
||||
this.getAllNodesAndDrawingStatus();
|
||||
});
|
||||
}
|
||||
|
||||
public uploadImageFile(event) {
|
||||
@ -190,5 +273,7 @@ export class ProjectMapMenuComponent implements OnInit, OnDestroy {
|
||||
width=\"${imageToUpload.width}\">\n<image height=\"${imageToUpload.height}\" width=\"${imageToUpload.width}\" xlink:href=\"${image}\"/>\n</svg>`;
|
||||
}
|
||||
|
||||
ngOnDestroy() {}
|
||||
ngOnDestroy() {
|
||||
// this.projectSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
@ -83,4 +83,13 @@ export class DrawingService {
|
||||
delete(controller:Controller , drawing: Drawing) {
|
||||
return this.httpController.delete<Drawing>(controller, `/projects/${drawing.project_id}/drawings/${drawing.drawing_id}`);
|
||||
}
|
||||
|
||||
lockAllNodes(controller:Controller,project:Project){
|
||||
return this.httpController.post(controller, `/projects/${project.project_id}/lock`,{});
|
||||
|
||||
}
|
||||
unLockAllNodes(controller:Controller,project:Project){
|
||||
return this.httpController.post(controller, `/projects/${project.project_id}/unlock`,{});
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ export class ProjectService {
|
||||
];
|
||||
|
||||
public projectListSubject = new Subject<boolean>();
|
||||
public projectLockIconSubject = new Subject<boolean>();
|
||||
constructor(
|
||||
private httpController: HttpController,
|
||||
private settingsService: SettingsService,
|
||||
@ -145,4 +146,13 @@ export class ProjectService {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
getProjectStatus(controller :Controller, project_id: string): Observable<any> {
|
||||
return this.get(controller,`${project_id}/locked`)
|
||||
}
|
||||
|
||||
|
||||
projectUpdateLockIcon(){
|
||||
this.projectLockIconSubject.next(true)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user