diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index fdbce4fe..7cecaf5f 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -164,6 +164,7 @@ import { SymbolsMenuComponent } from './components/preferences/common/symbols-me
import { SearchFilter } from './filters/searchFilter.pipe';
import { RecentlyOpenedProjectService } from './services/recentlyOpenedProject.service';
import { ServerManagementService } from './services/server-management.service';
+import { DeleteActionComponent } from './components/project-map/context-menu/actions/delete-action/delete-action.component';
if (environment.production) {
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
@@ -198,6 +199,7 @@ if (environment.production) {
MoveLayerUpActionComponent,
EditStyleActionComponent,
EditTextActionComponent,
+ DeleteActionComponent,
ProjectMapShortcutsComponent,
SettingsComponent,
PreferencesComponent,
diff --git a/src/app/cartography/components/drawing-adding/drawing-adding.component.ts b/src/app/cartography/components/drawing-adding/drawing-adding.component.ts
index c4cb1e6c..4553ae81 100644
--- a/src/app/cartography/components/drawing-adding/drawing-adding.component.ts
+++ b/src/app/cartography/components/drawing-adding/drawing-adding.component.ts
@@ -25,8 +25,8 @@ export class DrawingAddingComponent implements OnInit, OnDestroy {
activate() {
let listener = (event: MouseEvent) => {
- let x = event.clientX - this.context.getZeroZeroTransformationPoint().x;
- let y = event.clientY - this.context.getZeroZeroTransformationPoint().y;
+ let x = event.pageX - this.context.getZeroZeroTransformationPoint().x;
+ let y = event.pageY - this.context.getZeroZeroTransformationPoint().y;
this.drawingsEventSource.pointToAddSelected.emit(new AddedDataEvent(x, y));
this.deactivate();
diff --git a/src/app/cartography/components/text-editor/text-editor.component.ts b/src/app/cartography/components/text-editor/text-editor.component.ts
index f8b9fa8e..10549b48 100644
--- a/src/app/cartography/components/text-editor/text-editor.component.ts
+++ b/src/app/cartography/components/text-editor/text-editor.component.ts
@@ -45,8 +45,8 @@ export class TextEditorComponent implements OnInit, OnDestroy {
activateTextAdding() {
let addTextListener = (event: MouseEvent) => {
- this.leftPosition = event.clientX.toString() + 'px';
- this.topPosition = (event.clientY + window.pageYOffset).toString() + 'px';
+ this.leftPosition = event.pageX.toString() + 'px';
+ this.topPosition = event.pageY.toString() + 'px';
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
this.temporaryTextElement.nativeElement.focus();
@@ -54,8 +54,8 @@ export class TextEditorComponent implements OnInit, OnDestroy {
this.drawingsEventSource.textAdded.emit(
new TextAddedDataEvent(
this.temporaryTextElement.nativeElement.innerText.replace(/\n$/, ''),
- event.clientX,
- event.clientY
+ event.pageX,
+ event.pageY
)
);
this.deactivateTextAdding();
diff --git a/src/app/cartography/widgets/drawings.ts b/src/app/cartography/widgets/drawings.ts
index 819bb828..aa240980 100644
--- a/src/app/cartography/widgets/drawings.ts
+++ b/src/app/cartography/widgets/drawings.ts
@@ -111,15 +111,15 @@ export class DrawingsWidget implements Widget {
}
}
} else {
- dy = y - (evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y);
- y = evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
+ dy = y - (evt.sourceEvent.pageY - this.context.getZeroZeroTransformationPoint().y);
+ y = evt.sourceEvent.pageY - this.context.getZeroZeroTransformationPoint().y;
if (datum.element.height + dy < 0) {
isReflectedVertical = false;
y = topEdge;
datum.element.height = Math.abs(datum.element.height + evt.dy);
} else {
- datum.y = evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
+ datum.y = evt.sourceEvent.pageY - this.context.getZeroZeroTransformationPoint().y;
datum.element.height += dy;
if (datum.element instanceof EllipseElement) {
(datum.element as EllipseElement).cy =
@@ -143,7 +143,7 @@ export class DrawingsWidget implements Widget {
let top = drag()
.on('start', (datum: MapDrawing) => {
- y = event.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
+ y = event.sourceEvent.pageY - this.context.getZeroZeroTransformationPoint().y;
bottomEdge = y + datum.element.height;
document.body.style.cursor = 'ns-resize';
})
@@ -151,15 +151,15 @@ export class DrawingsWidget implements Widget {
const evt = event;
if (!isReflectedVertical) {
- dy = y - (evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y);
- y = evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
+ dy = y - (evt.sourceEvent.pageY - this.context.getZeroZeroTransformationPoint().y);
+ y = evt.sourceEvent.pageY - this.context.getZeroZeroTransformationPoint().y;
if (datum.element.height + dy < 0) {
y = bottomEdge;
isReflectedVertical = true;
datum.element.height = Math.abs(datum.element.height + evt.dy);
} else {
- datum.y = evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
+ datum.y = evt.sourceEvent.pageY - this.context.getZeroZeroTransformationPoint().y;
datum.element.height += dy;
if (datum.element instanceof EllipseElement) {
(datum.element as EllipseElement).cy =
@@ -207,7 +207,7 @@ export class DrawingsWidget implements Widget {
let isReflectedHorizontal: boolean = false;
let right = drag()
.on('start', (datum: MapDrawing) => {
- x = event.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x;
+ x = event.sourceEvent.pageX - this.context.getZeroZeroTransformationPoint().x;
leftEdge = x + datum.element.width;
document.body.style.cursor = 'ew-resize';
})
@@ -215,15 +215,15 @@ export class DrawingsWidget implements Widget {
const evt = event;
if (!isReflectedHorizontal) {
- dx = x - (evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x);
- x = evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x;
+ dx = x - (evt.sourceEvent.pageX - this.context.getZeroZeroTransformationPoint().x);
+ x = evt.sourceEvent.pageX - this.context.getZeroZeroTransformationPoint().x;
if (datum.element.width + dx < 0) {
x = leftEdge;
isReflectedHorizontal = true;
datum.element.width = Math.abs(datum.element.width + evt.dx);
} else {
- datum.x = evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x;
+ datum.x = evt.sourceEvent.pageX - this.context.getZeroZeroTransformationPoint().x;
datum.element.width += dx;
if (datum.element instanceof EllipseElement) {
(datum.element as EllipseElement).cx =
@@ -290,15 +290,15 @@ export class DrawingsWidget implements Widget {
datum.element.width = datum.element.width + evt.dx < 0 ? 1 : (datum.element.width += evt.dx);
}
} else {
- dx = x - (evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x);
- x = evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x;
+ dx = x - (evt.sourceEvent.pageX - this.context.getZeroZeroTransformationPoint().x);
+ x = evt.sourceEvent.pageX - this.context.getZeroZeroTransformationPoint().x;
if (datum.element.width + dx < 0) {
x = rightEdge;
isReflectedHorizontal = false;
datum.element.width = Math.abs(datum.element.width + evt.dx);
} else {
- datum.x = evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x;
+ datum.x = evt.sourceEvent.pageX - this.context.getZeroZeroTransformationPoint().x;
datum.element.width += dx;
if (datum.element instanceof EllipseElement) {
(datum.element as EllipseElement).cx =
diff --git a/src/app/components/project-map/context-menu/actions/delete-action/delete-action.component.html b/src/app/components/project-map/context-menu/actions/delete-action/delete-action.component.html
new file mode 100644
index 00000000..a0819a60
--- /dev/null
+++ b/src/app/components/project-map/context-menu/actions/delete-action/delete-action.component.html
@@ -0,0 +1,4 @@
+
diff --git a/src/app/components/project-map/context-menu/actions/delete-action/delete-action.component.spec.ts b/src/app/components/project-map/context-menu/actions/delete-action/delete-action.component.spec.ts
new file mode 100644
index 00000000..ec6a8f5c
--- /dev/null
+++ b/src/app/components/project-map/context-menu/actions/delete-action/delete-action.component.spec.ts
@@ -0,0 +1,86 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { DeleteActionComponent } from './delete-action.component';
+import { MatIconModule, MatMenuModule } from '@angular/material';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+import { NodesDataSource } from '../../../../../cartography/datasources/nodes-datasource';
+import { DrawingsDataSource } from '../../../../../cartography/datasources/drawings-datasource';
+import { NodeService } from '../../../../../services/node.service';
+import { DrawingService } from '../../../../../services/drawing.service';
+import { MockedDrawingService, MockedNodeService, MockedLinkService } from '../../../project-map.component.spec';
+import { Node } from '../../../../../cartography/models/node';
+import { Drawing } from '../../../../../cartography/models/drawing';
+import { of } from 'rxjs';
+import { LinksDataSource } from '../../../../../cartography/datasources/links-datasource';
+import { LinkService } from '../../../../../services/link.service';
+import { Link } from '../../../../../models/link';
+
+describe('DeleteActionComponent', () => {
+ let component: DeleteActionComponent;
+ let fixture: ComponentFixture;
+ let mockedNodeService: MockedNodeService = new MockedNodeService();
+ let mockedDrawingService: MockedDrawingService = new MockedDrawingService();
+ let mockedLinkService: MockedLinkService = new MockedLinkService();
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [MatIconModule, MatMenuModule, NoopAnimationsModule],
+ providers: [
+ { provide: NodesDataSource, useClass: NodesDataSource },
+ { provide: DrawingsDataSource, useClass: DrawingsDataSource },
+ { provide: LinksDataSource, useClass: LinksDataSource },
+ { provide: NodeService, useValue: mockedNodeService },
+ { provide: DrawingService, useValue: mockedDrawingService },
+ { provide: LinkService, useValue: mockedLinkService }
+ ],
+ declarations: [DeleteActionComponent]
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DeleteActionComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should call delete action in drawing service', () => {
+ let node = { node_id: '1' } as Node;
+ component.nodes = [node];
+ let drawing = { drawing_id: '1' } as Drawing;
+ component.drawings = [drawing];
+ component.links = [];
+ spyOn(mockedDrawingService, 'delete').and.returnValue(of());
+
+ component.delete();
+
+ expect(mockedDrawingService.delete).toHaveBeenCalled();
+ });
+
+ it('should call delete action in node service', () => {
+ let node = { node_id: '1' } as Node;
+ component.nodes = [node];
+ let drawing = { drawing_id: '1' } as Drawing;
+ component.drawings = [drawing];
+ component.links = [];
+ spyOn(mockedNodeService, 'delete').and.returnValue(of());
+
+ component.delete();
+
+ expect(mockedNodeService.delete).toHaveBeenCalled();
+ });
+
+ it('should call delete action in link service', () => {
+ component.nodes = [];
+ component.drawings = [];
+ let link = { link_id: '1', project_id: '1' } as Link;
+ component.links = [link];
+ spyOn(mockedLinkService, 'deleteLink').and.returnValue(of());
+
+ component.delete();
+
+ expect(mockedLinkService.deleteLink).toHaveBeenCalled();
+ });
+});
diff --git a/src/app/components/project-map/context-menu/actions/delete-action/delete-action.component.ts b/src/app/components/project-map/context-menu/actions/delete-action/delete-action.component.ts
new file mode 100644
index 00000000..26629dfc
--- /dev/null
+++ b/src/app/components/project-map/context-menu/actions/delete-action/delete-action.component.ts
@@ -0,0 +1,53 @@
+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';
+import { Link } from '../../../../../models/link';
+import { LinkService } from '../../../../../services/link.service';
+import { LinksDataSource } from '../../../../../cartography/datasources/links-datasource';
+
+@Component({
+ selector: 'app-delete-action',
+ templateUrl: './delete-action.component.html'
+})
+export class DeleteActionComponent implements OnInit {
+ @Input() server: Server;
+ @Input() nodes: Node[];
+ @Input() drawings: Drawing[];
+ @Input() links: Link[];
+
+ constructor(
+ private nodesDataSource: NodesDataSource,
+ private drawingsDataSource: DrawingsDataSource,
+ private linksDataSource: LinksDataSource,
+ private nodeService: NodeService,
+ private drawingService: DrawingService,
+ private linkService: LinkService
+ ) {}
+
+ ngOnInit() {}
+
+ delete() {
+ this.nodes.forEach((node) => {
+ this.nodesDataSource.remove(node);
+
+ this.nodeService.delete(this.server, node).subscribe((node: Node) => {});
+ });
+
+ this.drawings.forEach((drawing) => {
+ this.drawingsDataSource.remove(drawing);
+
+ this.drawingService.delete(this.server, drawing).subscribe((drawing: Drawing) => {});
+ });
+
+ this.links.forEach((link) => {
+ this.linksDataSource.remove(link);
+
+ this.linkService.deleteLink(this.server, link).subscribe(() => {});
+ });
+ }
+}
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 3146bbbc..0060c9f1 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
@@ -15,16 +15,23 @@
[drawing]="drawings[0]"
>
+
diff --git a/src/app/components/project-map/context-menu/context-menu.component.spec.ts b/src/app/components/project-map/context-menu/context-menu.component.spec.ts
index 30c60aef..7832fb7e 100644
--- a/src/app/components/project-map/context-menu/context-menu.component.spec.ts
+++ b/src/app/components/project-map/context-menu/context-menu.component.spec.ts
@@ -70,7 +70,7 @@ describe('ContextMenuComponent', () => {
component.contextMenu = { openMenu() {} } as MatMenuTrigger;
var spy = spyOn(component, 'resetCapabilities');
spyOn(component, 'setPosition').and.callFake(() => {});
- component.openMenuForListOfElements([], [], [], 0, 0);
+ component.openMenuForListOfElements([], [], [], [], 0, 0);
expect(spy.calls.any()).toBeTruthy();
});
diff --git a/src/app/components/project-map/context-menu/context-menu.component.ts b/src/app/components/project-map/context-menu/context-menu.component.ts
index 45da4d2f..ed34f146 100644
--- a/src/app/components/project-map/context-menu/context-menu.component.ts
+++ b/src/app/components/project-map/context-menu/context-menu.component.ts
@@ -8,6 +8,7 @@ import { ProjectService } from '../../../services/project.service';
import { Drawing } from '../../../cartography/models/drawing';
import { TextElement } from '../../../cartography/models/drawings/text-element';
import { Label } from '../../../cartography/models/label';
+import { Link } from '../../../models/link';
@Component({
@@ -27,6 +28,7 @@ export class ContextMenuComponent implements OnInit {
drawings: Drawing[] = [];
nodes: Node[] = [];
labels: Label[] = [];
+ links: Link[] = [];
hasTextCapabilities: boolean = false;
@@ -74,12 +76,13 @@ export class ContextMenuComponent implements OnInit {
this.contextMenu.openMenu();
}
- public openMenuForListOfElements(drawings: Drawing[], nodes: Node[], labels: Label[], top: number, left: number) {
+ public openMenuForListOfElements(drawings: Drawing[], nodes: Node[], labels: Label[], links: Link[], top: number, left: number) {
this.resetCapabilities();
this.drawings = drawings;
this.nodes = nodes;
this.labels = labels;
+ this.links = links;
this.setPosition(top, left);
this.contextMenu.openMenu();
diff --git a/src/app/components/project-map/draw-link-tool/draw-link-tool.component.html b/src/app/components/project-map/draw-link-tool/draw-link-tool.component.html
index 9bbaf0d3..72be0c62 100644
--- a/src/app/components/project-map/draw-link-tool/draw-link-tool.component.html
+++ b/src/app/components/project-map/draw-link-tool/draw-link-tool.component.html
@@ -1 +1 @@
-
+
diff --git a/src/app/components/project-map/draw-link-tool/draw-link-tool.component.ts b/src/app/components/project-map/draw-link-tool/draw-link-tool.component.ts
index 55cab9cf..63adb2f9 100644
--- a/src/app/components/project-map/draw-link-tool/draw-link-tool.component.ts
+++ b/src/app/components/project-map/draw-link-tool/draw-link-tool.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
+import { Component, OnInit, OnDestroy, ViewChild, Input } from '@angular/core';
import { Subscription } from 'rxjs';
import { NodeSelectInterfaceComponent } from '../../../components/project-map/node-select-interface/node-select-interface.component';
import { DrawingLineWidget } from '../../../cartography/widgets/drawing-line';
@@ -7,6 +7,8 @@ import { LinksEventSource } from '../../../cartography/events/links-event-source
import { MapNode } from '../../../cartography/models/map/map-node';
import { MapPort } from '../../../cartography/models/map/map-port';
import { MapLinkCreated } from '../../../cartography/events/links';
+import { Link } from '../../../models/link';
+import { MapNodeToNodeConverter } from '../../../cartography/converters/map/map-node-to-node-converter';
@Component({
selector: 'app-draw-link-tool',
@@ -14,6 +16,7 @@ import { MapLinkCreated } from '../../../cartography/events/links';
styleUrls: ['./draw-link-tool.component.scss']
})
export class DrawLinkToolComponent implements OnInit, OnDestroy {
+ @Input() links: Link[];
@ViewChild(NodeSelectInterfaceComponent) nodeSelectInterfaceMenu: NodeSelectInterfaceComponent;
private nodeClicked$: Subscription;
@@ -21,12 +24,14 @@ export class DrawLinkToolComponent implements OnInit, OnDestroy {
constructor(
private drawingLineTool: DrawingLineWidget,
private nodesEventSource: NodesEventSource,
- private linksEventSource: LinksEventSource
+ private linksEventSource: LinksEventSource,
+ private mapNodeToNode: MapNodeToNodeConverter
) {}
ngOnInit() {
this.nodeClicked$ = this.nodesEventSource.clicked.subscribe(clickedEvent => {
- this.nodeSelectInterfaceMenu.open(clickedEvent.datum, clickedEvent.y, clickedEvent.x);
+ let node = this.mapNodeToNode.convert(clickedEvent.datum);
+ this.nodeSelectInterfaceMenu.open(node, clickedEvent.y, clickedEvent.x);
});
}
diff --git a/src/app/components/project-map/node-select-interface/node-select-interface.component.html b/src/app/components/project-map/node-select-interface/node-select-interface.component.html
index b4321348..33d07113 100644
--- a/src/app/components/project-map/node-select-interface/node-select-interface.component.html
+++ b/src/app/components/project-map/node-select-interface/node-select-interface.component.html
@@ -1,7 +1,7 @@