mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-11 04:52:59 +00:00
Context menu for list of items
This commit is contained in:
parent
4fa82bc81d
commit
ed59d2ba02
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { SelectionManager } from '../../managers/selection-manager';
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
||||||
@ -12,7 +12,10 @@ export class SelectionSelectComponent implements OnInit, OnDestroy {
|
|||||||
private onSelected: Subscription;
|
private onSelected: Subscription;
|
||||||
private onUnselected: Subscription;
|
private onUnselected: Subscription;
|
||||||
|
|
||||||
constructor(private selectionManager: SelectionManager, private mapChangeDetectorRef: MapChangeDetectorRef) {}
|
constructor(
|
||||||
|
private selectionManager: SelectionManager,
|
||||||
|
private mapChangeDetectorRef: MapChangeDetectorRef
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.onSelected = this.selectionManager.selected.subscribe(() => {
|
this.onSelected = this.selectionManager.selected.subscribe(() => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
import { mouse, select } from 'd3-selection';
|
import { mouse, select, event } from 'd3-selection';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
import { SVGSelection } from '../models/types';
|
import { SVGSelection } from '../models/types';
|
||||||
@ -12,20 +12,39 @@ export class SelectionTool {
|
|||||||
static readonly SELECTABLE_CLASS = '.selectable';
|
static readonly SELECTABLE_CLASS = '.selectable';
|
||||||
|
|
||||||
public rectangleSelected = new Subject<Rectangle>();
|
public rectangleSelected = new Subject<Rectangle>();
|
||||||
|
public contextMenuOpened = new EventEmitter<any>();
|
||||||
|
|
||||||
private path;
|
private path;
|
||||||
private enabled = false;
|
private enabled = false;
|
||||||
|
|
||||||
public constructor(private context: Context, private selectionEventSource: SelectionEventSource) {}
|
public constructor(
|
||||||
|
private context: Context,
|
||||||
|
private selectionEventSource: SelectionEventSource
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public disableContextMenu(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public setEnabled(enabled) {
|
public setEnabled(enabled) {
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
|
this.contextMenuOpened.emit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private activate(selection) {
|
private activate(selection) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
selection.on('mousedown', function() {
|
selection.on('mousedown', function() {
|
||||||
|
// prevent deselection on right click
|
||||||
|
if (event.button == 2) {
|
||||||
|
selection.on('contextmenu', () => {
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
self.contextMenuOpened.emit(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const subject = select(window);
|
const subject = select(window);
|
||||||
const parent = this.parentElement;
|
const parent = this.parentElement;
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ import { DrawingService } from '../../../../../services/drawing.service';
|
|||||||
})
|
})
|
||||||
export class MoveLayerDownActionComponent implements OnInit {
|
export class MoveLayerDownActionComponent implements OnInit {
|
||||||
@Input() server: Server;
|
@Input() server: Server;
|
||||||
@Input() node: Node;
|
@Input() nodes: Node[];
|
||||||
@Input() drawing: Drawing;
|
@Input() drawings: Drawing[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private nodesDataSource: NodesDataSource,
|
private nodesDataSource: NodesDataSource,
|
||||||
@ -26,16 +26,18 @@ export class MoveLayerDownActionComponent implements OnInit {
|
|||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
moveLayerDown() {
|
moveLayerDown() {
|
||||||
if (this.node) {
|
this.nodes.forEach((node) => {
|
||||||
this.node.z--;
|
node.z--;
|
||||||
this.nodesDataSource.update(this.node);
|
this.nodesDataSource.update(node);
|
||||||
|
|
||||||
this.nodeService.update(this.server, this.node).subscribe((node: Node) => {});
|
this.nodeService.update(this.server, node).subscribe((node: Node) => {});
|
||||||
} else if (this.drawing) {
|
});
|
||||||
this.drawing.z--;
|
|
||||||
this.drawingsDataSource.update(this.drawing);
|
|
||||||
|
|
||||||
this.drawingService.update(this.server, this.drawing).subscribe((drawing: Drawing) => {});
|
this.drawings.forEach((drawing) => {
|
||||||
}
|
drawing.z--;
|
||||||
|
this.drawingsDataSource.update(drawing);
|
||||||
|
|
||||||
|
this.drawingService.update(this.server, drawing).subscribe((drawing: Drawing) => {});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ import { DrawingService } from '../../../../../services/drawing.service';
|
|||||||
})
|
})
|
||||||
export class MoveLayerUpActionComponent implements OnInit {
|
export class MoveLayerUpActionComponent implements OnInit {
|
||||||
@Input() server: Server;
|
@Input() server: Server;
|
||||||
@Input() node: Node;
|
@Input() nodes: Node[];
|
||||||
@Input() drawing: Drawing;
|
@Input() drawings: Drawing[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private nodesDataSource: NodesDataSource,
|
private nodesDataSource: NodesDataSource,
|
||||||
@ -26,16 +26,18 @@ export class MoveLayerUpActionComponent implements OnInit {
|
|||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
moveLayerUp() {
|
moveLayerUp() {
|
||||||
if (this.node) {
|
this.nodes.forEach((node) => {
|
||||||
this.node.z++;
|
node.z++;
|
||||||
this.nodesDataSource.update(this.node);
|
this.nodesDataSource.update(node);
|
||||||
|
|
||||||
this.nodeService.update(this.server, this.node).subscribe((node: Node) => {});
|
this.nodeService.update(this.server, node).subscribe((node: Node) => {});
|
||||||
} else if (this.drawing) {
|
});
|
||||||
this.drawing.z++;
|
|
||||||
this.drawingsDataSource.update(this.drawing);
|
|
||||||
|
|
||||||
this.drawingService.update(this.server, this.drawing).subscribe((drawing: Drawing) => {});
|
this.drawings.forEach((drawing) => {
|
||||||
}
|
drawing.z++;
|
||||||
|
this.drawingsDataSource.update(drawing);
|
||||||
|
|
||||||
|
this.drawingService.update(this.server, drawing).subscribe((drawing: Drawing) => {});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<button mat-menu-item *ngIf="node.status == 'stopped'" (click)="startNode()">
|
<button mat-menu-item *ngIf="isNodeWithStoppedStatus" (click)="startNodes()">
|
||||||
<mat-icon>play_arrow</mat-icon>
|
<mat-icon>play_arrow</mat-icon>
|
||||||
<span>Start</span>
|
<span>Start</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -9,13 +9,22 @@ import { Node } from '../../../../../cartography/models/node';
|
|||||||
})
|
})
|
||||||
export class StartNodeActionComponent implements OnInit {
|
export class StartNodeActionComponent implements OnInit {
|
||||||
@Input() server: Server;
|
@Input() server: Server;
|
||||||
@Input() node: Node;
|
@Input() nodes: Node[];
|
||||||
|
private isNodeWithStoppedStatus: boolean;
|
||||||
|
|
||||||
constructor(private nodeService: NodeService) {}
|
constructor(private nodeService: NodeService) {}
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {
|
||||||
|
this.nodes.forEach((node) => {
|
||||||
|
if (node.status === 'stopped') {
|
||||||
|
this.isNodeWithStoppedStatus = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
startNode() {
|
startNodes() {
|
||||||
this.nodeService.start(this.server, this.node).subscribe((n: Node) => {});
|
this.nodes.forEach((node) => {
|
||||||
|
this.nodeService.start(this.server, node).subscribe((n: Node) => {});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<button mat-menu-item *ngIf="node.status == 'started'" (click)="stopNode()">
|
<button mat-menu-item *ngIf="isNodeWithStartedStatus" (click)="stopNodes()">
|
||||||
<mat-icon>stop</mat-icon>
|
<mat-icon>stop</mat-icon>
|
||||||
<span>Stop</span>
|
<span>Stop</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -9,13 +9,22 @@ import { Node } from '../../../../../cartography/models/node';
|
|||||||
})
|
})
|
||||||
export class StopNodeActionComponent implements OnInit {
|
export class StopNodeActionComponent implements OnInit {
|
||||||
@Input() server: Server;
|
@Input() server: Server;
|
||||||
@Input() node: Node;
|
@Input() nodes: Node[];
|
||||||
|
private isNodeWithStartedStatus: boolean;
|
||||||
|
|
||||||
constructor(private nodeService: NodeService) {}
|
constructor(private nodeService: NodeService) {}
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {
|
||||||
|
this.nodes.forEach((node) => {
|
||||||
|
if (node.status === 'started') {
|
||||||
|
this.isNodeWithStartedStatus = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
stopNode() {
|
stopNodes() {
|
||||||
this.nodeService.stop(this.server, this.node).subscribe((n: Node) => {});
|
this.nodes.forEach((node) => {
|
||||||
|
this.nodeService.stop(this.server, node).subscribe((n: Node) => {});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,30 @@
|
|||||||
<div class="context-menu" [style.left]="leftPosition" [style.top]="topPosition" *ngIf="node || drawing">
|
<div class="context-menu" [style.left]="leftPosition" [style.top]="topPosition">
|
||||||
<span [matMenuTriggerFor]="contextMenu"></span>
|
<span [matMenuTriggerFor]="contextMenu"></span>
|
||||||
<mat-menu #contextMenu="matMenu" class="context-menu-items">
|
<mat-menu #contextMenu="matMenu" class="context-menu-items">
|
||||||
<app-start-node-action *ngIf="hasNodeCapabilities" [server]="server" [node]="node"></app-start-node-action>
|
<app-start-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-start-node-action>
|
||||||
<app-stop-node-action *ngIf="hasNodeCapabilities" [server]="server" [node]="node"></app-stop-node-action>
|
<app-stop-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-stop-node-action>
|
||||||
<app-edit-style-action
|
<app-edit-style-action *ngIf="drawings.length===1 && !hasTextCapabilities"
|
||||||
*ngIf="hasDrawingCapabilities && !isTextElement"
|
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[project]="project"
|
[project]="project"
|
||||||
[drawing]="drawing"
|
[drawing]="drawings[0]"
|
||||||
></app-edit-style-action>
|
></app-edit-style-action>
|
||||||
<app-edit-text-action
|
<app-edit-text-action
|
||||||
*ngIf="hasDrawingCapabilities && isTextElement"
|
*ngIf="drawings.length===1 && hasTextCapabilities"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[project]="project"
|
[project]="project"
|
||||||
[drawing]="drawing"
|
[drawing]="drawings[0]"
|
||||||
></app-edit-text-action>
|
></app-edit-text-action>
|
||||||
<app-move-layer-up-action
|
<app-move-layer-up-action
|
||||||
*ngIf="!projectService.isReadOnly(project)"
|
*ngIf="!projectService.isReadOnly(project)"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[node]="node"
|
[nodes]="nodes"
|
||||||
[drawing]="drawing"
|
[drawings]="drawings"
|
||||||
></app-move-layer-up-action>
|
></app-move-layer-up-action>
|
||||||
<app-move-layer-down-action
|
<app-move-layer-down-action
|
||||||
*ngIf="!projectService.isReadOnly(project)"
|
*ngIf="!projectService.isReadOnly(project)"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[node]="node"
|
[nodes]="nodes"
|
||||||
[drawing]="drawing"
|
[drawings]="drawings"
|
||||||
></app-move-layer-down-action>
|
></app-move-layer-down-action>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,7 +16,10 @@ describe('ContextMenuComponent', () => {
|
|||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [MatMenuModule, BrowserModule],
|
imports: [MatMenuModule, BrowserModule],
|
||||||
providers: [{ provide: ChangeDetectorRef }, { provide: ProjectService, useClass: MockedProjectService }],
|
providers: [
|
||||||
|
{ provide: ChangeDetectorRef },
|
||||||
|
{ provide: ProjectService, useClass: MockedProjectService }
|
||||||
|
],
|
||||||
declarations: [ContextMenuComponent],
|
declarations: [ContextMenuComponent],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@ -62,4 +65,13 @@ describe('ContextMenuComponent', () => {
|
|||||||
|
|
||||||
expect(spy.calls.any()).toBeTruthy();
|
expect(spy.calls.any()).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should reset capabilities while opening menu for list of elements', () => {
|
||||||
|
component.contextMenu = { openMenu() {} } as MatMenuTrigger;
|
||||||
|
var spy = spyOn<any>(component, 'resetCapabilities');
|
||||||
|
spyOn(component, 'setPosition').and.callFake(() => {});
|
||||||
|
component.openMenuForListOfElements([], [], [], 0, 0);
|
||||||
|
|
||||||
|
expect(spy.calls.any()).toBeTruthy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,8 @@ import { Project } from '../../../models/project';
|
|||||||
import { ProjectService } from '../../../services/project.service';
|
import { ProjectService } from '../../../services/project.service';
|
||||||
import { Drawing } from '../../../cartography/models/drawing';
|
import { Drawing } from '../../../cartography/models/drawing';
|
||||||
import { TextElement } from '../../../cartography/models/drawings/text-element';
|
import { TextElement } from '../../../cartography/models/drawings/text-element';
|
||||||
|
import { Label } from '../../../cartography/models/label';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-context-menu',
|
selector: 'app-context-menu',
|
||||||
@ -21,11 +23,12 @@ export class ContextMenuComponent implements OnInit {
|
|||||||
|
|
||||||
topPosition;
|
topPosition;
|
||||||
leftPosition;
|
leftPosition;
|
||||||
node: Node;
|
|
||||||
drawing: Drawing;
|
drawings: Drawing[] = [];
|
||||||
private hasNodeCapabilities: boolean = false;
|
nodes: Node[] = [];
|
||||||
private hasDrawingCapabilities: boolean = false;
|
labels: Label[] = [];
|
||||||
private isTextElement: boolean = false;
|
|
||||||
|
private hasTextCapabilities: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
@ -43,32 +46,49 @@ export class ContextMenuComponent implements OnInit {
|
|||||||
this.changeDetector.detectChanges();
|
this.changeDetector.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public openMenuForNode(node: Node, top: number, left: number) {
|
public openMenuForDrawing(drawing: Drawing, top: number, left: number) {
|
||||||
this.resetCapabilities();
|
this.resetCapabilities();
|
||||||
this.hasNodeCapabilities = true;
|
this.hasTextCapabilities = drawing.element instanceof TextElement;
|
||||||
|
|
||||||
this.node = node;
|
this.drawings = [drawing];
|
||||||
this.setPosition(top, left);
|
this.setPosition(top, left);
|
||||||
|
|
||||||
this.contextMenu.openMenu();
|
this.contextMenu.openMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
public openMenuForDrawing(drawing: Drawing, top: number, left: number) {
|
public openMenuForNode(node: Node, top: number, left: number) {
|
||||||
this.resetCapabilities();
|
this.resetCapabilities();
|
||||||
this.hasDrawingCapabilities = true;
|
|
||||||
this.isTextElement = drawing.element instanceof TextElement;
|
|
||||||
|
|
||||||
this.drawing = drawing;
|
this.nodes = [node];
|
||||||
|
this.setPosition(top, left);
|
||||||
|
|
||||||
|
this.contextMenu.openMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
public openMenuForLabel(label: Label, top: number, left: number) {
|
||||||
|
this.resetCapabilities();
|
||||||
|
|
||||||
|
this.labels = [label];
|
||||||
|
this.setPosition(top, left);
|
||||||
|
|
||||||
|
this.contextMenu.openMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
public openMenuForListOfElements(drawings: Drawing[], nodes: Node[], labels: Label[], top: number, left: number) {
|
||||||
|
this.resetCapabilities();
|
||||||
|
|
||||||
|
this.drawings = drawings;
|
||||||
|
this.nodes = nodes;
|
||||||
|
this.labels = labels;
|
||||||
this.setPosition(top, left);
|
this.setPosition(top, left);
|
||||||
|
|
||||||
this.contextMenu.openMenu();
|
this.contextMenu.openMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
private resetCapabilities() {
|
private resetCapabilities() {
|
||||||
this.node = null;
|
this.drawings = [];
|
||||||
this.drawing = null;
|
this.nodes = [];
|
||||||
this.hasDrawingCapabilities = false;
|
this.labels = [];
|
||||||
this.hasNodeCapabilities = false;
|
this.hasTextCapabilities = false;
|
||||||
this.isTextElement = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,9 @@ import { Node } from '../../cartography/models/node';
|
|||||||
import { ToolsService } from '../../services/tools.service';
|
import { ToolsService } from '../../services/tools.service';
|
||||||
import { DrawingsWidget } from '../../cartography/widgets/drawings';
|
import { DrawingsWidget } from '../../cartography/widgets/drawings';
|
||||||
import { MapDrawingToDrawingConverter } from '../../cartography/converters/map/map-drawing-to-drawing-converter';
|
import { MapDrawingToDrawingConverter } from '../../cartography/converters/map/map-drawing-to-drawing-converter';
|
||||||
|
import { MapLabelToLabelConverter } from '../../cartography/converters/map/map-label-to-label-converter';
|
||||||
|
import { SelectionManager } from '../../cartography/managers/selection-manager';
|
||||||
|
import { SelectionTool } from '../../cartography/tools/selection-tool';
|
||||||
|
|
||||||
export class MockedProgressService {
|
export class MockedProgressService {
|
||||||
public activate() {}
|
public activate() {}
|
||||||
@ -139,11 +142,14 @@ describe('ProjectMapComponent', () => {
|
|||||||
{ provide: DrawingsWidget },
|
{ provide: DrawingsWidget },
|
||||||
{ provide: MapNodeToNodeConverter },
|
{ provide: MapNodeToNodeConverter },
|
||||||
{ provide: MapDrawingToDrawingConverter },
|
{ provide: MapDrawingToDrawingConverter },
|
||||||
|
{ provide: MapLabelToLabelConverter },
|
||||||
{ provide: NodesDataSource },
|
{ provide: NodesDataSource },
|
||||||
{ provide: LinksDataSource },
|
{ provide: LinksDataSource },
|
||||||
{ provide: DrawingsDataSource, useValue: drawingsDataSource },
|
{ provide: DrawingsDataSource, useValue: drawingsDataSource },
|
||||||
{ provide: SettingsService, useClass: MockedSettingsService },
|
{ provide: SettingsService, useClass: MockedSettingsService },
|
||||||
{ provide: ToolsService }
|
{ provide: ToolsService },
|
||||||
|
{ provide: SelectionManager },
|
||||||
|
{ provide: SelectionTool }
|
||||||
],
|
],
|
||||||
declarations: [ProjectMapComponent, D3MapComponent, ...ANGULAR_MAP_DECLARATIONS],
|
declarations: [ProjectMapComponent, D3MapComponent, ...ANGULAR_MAP_DECLARATIONS],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
@ -32,6 +32,14 @@ import { D3MapComponent } from '../../cartography/components/d3-map/d3-map.compo
|
|||||||
import { ToolsService } from '../../services/tools.service';
|
import { ToolsService } from '../../services/tools.service';
|
||||||
import { DrawingContextMenu } from '../../cartography/events/event-source';
|
import { DrawingContextMenu } from '../../cartography/events/event-source';
|
||||||
import { MapDrawingToDrawingConverter } from '../../cartography/converters/map/map-drawing-to-drawing-converter';
|
import { MapDrawingToDrawingConverter } from '../../cartography/converters/map/map-drawing-to-drawing-converter';
|
||||||
|
import { SelectionManager } from '../../cartography/managers/selection-manager';
|
||||||
|
import { SelectionTool } from '../../cartography/tools/selection-tool';
|
||||||
|
import { MapDrawing } from '../../cartography/models/map/map-drawing';
|
||||||
|
import { MapLabel } from '../../cartography/models/map/map-label';
|
||||||
|
import { Label } from '../../cartography/models/label';
|
||||||
|
import { MapNode } from '../../cartography/models/map/map-node';
|
||||||
|
import { MapLabelToLabelConverter } from '../../cartography/converters/map/map-label-to-label-converter';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-project-map',
|
selector: 'app-project-map',
|
||||||
@ -86,11 +94,14 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
private drawingsWidget: DrawingsWidget,
|
private drawingsWidget: DrawingsWidget,
|
||||||
private mapNodeToNode: MapNodeToNodeConverter,
|
private mapNodeToNode: MapNodeToNodeConverter,
|
||||||
private mapDrawingToDrawing: MapDrawingToDrawingConverter,
|
private mapDrawingToDrawing: MapDrawingToDrawingConverter,
|
||||||
|
private mapLabelToLabel: MapLabelToLabelConverter,
|
||||||
private nodesDataSource: NodesDataSource,
|
private nodesDataSource: NodesDataSource,
|
||||||
private linksDataSource: LinksDataSource,
|
private linksDataSource: LinksDataSource,
|
||||||
private drawingsDataSource: DrawingsDataSource,
|
private drawingsDataSource: DrawingsDataSource,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
private toolsService: ToolsService
|
private toolsService: ToolsService,
|
||||||
|
private selectionManager: SelectionManager,
|
||||||
|
private selectionTool: SelectionTool
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -206,8 +217,30 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
this.contextMenu.openMenuForDrawing(drawing, eventDrawing.event.clientY, eventDrawing.event.clientX);
|
this.contextMenu.openMenuForDrawing(drawing, eventDrawing.event.clientY, eventDrawing.event.clientX);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const onContextMenu = this.selectionTool.contextMenuOpened.subscribe((event) => {
|
||||||
|
const selectedItems = this.selectionManager.getSelected();
|
||||||
|
if (selectedItems.length === 0) return;
|
||||||
|
|
||||||
|
let drawings: Drawing[] = [];
|
||||||
|
let nodes: Node[] = [];
|
||||||
|
let labels: Label[] = [];
|
||||||
|
|
||||||
|
selectedItems.forEach((elem) => {
|
||||||
|
if (elem instanceof MapDrawing) {
|
||||||
|
drawings.push(this.mapDrawingToDrawing.convert(elem));
|
||||||
|
} else if (elem instanceof MapNode) {
|
||||||
|
nodes.push(this.mapNodeToNode.convert(elem));
|
||||||
|
} else if (elem instanceof MapLabel) {
|
||||||
|
labels.push(this.mapLabelToLabel.convert(elem));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.contextMenu.openMenuForListOfElements(drawings, nodes, labels, event.clientY, event.clientX);
|
||||||
|
});
|
||||||
|
|
||||||
this.subscriptions.push(onNodeContextMenu);
|
this.subscriptions.push(onNodeContextMenu);
|
||||||
this.subscriptions.push(onDrawingContextMenu);
|
this.subscriptions.push(onDrawingContextMenu);
|
||||||
|
this.subscriptions.push(onContextMenu);
|
||||||
this.mapChangeDetectorRef.detectChanges();
|
this.mapChangeDetectorRef.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ export class MockedProjectService {
|
|||||||
add() {
|
add() {
|
||||||
return of(this.projects.pop);
|
return of(this.projects.pop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReadOnly(project: Project){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('AddBlankProjectDialogComponent', () => {
|
describe('AddBlankProjectDialogComponent', () => {
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body class="mat-app-background">
|
<body class="mat-app-background" oncontextmenu="return false;">
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user