mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-22 04:18:08 +00:00
Merge branch 'develop' into add-rectangle-change-border-position
This commit is contained in:
commit
42d1ce522e
@ -1,4 +1,4 @@
|
|||||||
# Editor configuration, see http://editorconfig.org
|
# Editor configuration, see https://editorconfig.org
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
|
@ -46,7 +46,7 @@ before_script:
|
|||||||
- greenkeeper-lockfile-update
|
- greenkeeper-lockfile-update
|
||||||
- npm install -g codecov
|
- npm install -g codecov
|
||||||
|
|
||||||
script: yarn ng test --watch=false --code-coverage
|
script: yarn coverage
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- codecov
|
- codecov
|
||||||
|
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch localhost",
|
||||||
|
"type": "firefox",
|
||||||
|
"request": "launch",
|
||||||
|
"reAttach": true,
|
||||||
|
"url": "http://localhost:4200",
|
||||||
|
"webRoot": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -133,6 +133,9 @@
|
|||||||
"assets": [
|
"assets": [
|
||||||
"src/assets",
|
"src/assets",
|
||||||
"src/favicon.ico"
|
"src/favicon.ico"
|
||||||
|
],
|
||||||
|
"codeCoverageExclude": [
|
||||||
|
"src/app/cartography/components/experimental-map/**/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
"distlinux": "yarn buildforelectron && electron-builder --linux --x64",
|
"distlinux": "yarn buildforelectron && electron-builder --linux --x64",
|
||||||
"distwin": "yarn buildforelectron && electron-builder --win --x64",
|
"distwin": "yarn buildforelectron && electron-builder --win --x64",
|
||||||
"distmac": "yarn buildforelectron && electron-builder --mac --x64",
|
"distmac": "yarn buildforelectron && electron-builder --mac --x64",
|
||||||
"release": "build"
|
"release": "build",
|
||||||
|
"coverage": "ng test --watch=false --code-coverage"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -74,6 +74,7 @@ import { DrawingService } from './services/drawing.service';
|
|||||||
import { ProjectNameValidator } from './components/projects/models/projectNameValidator';
|
import { ProjectNameValidator } from './components/projects/models/projectNameValidator';
|
||||||
import { MatSidenavModule } from '@angular/material';
|
import { MatSidenavModule } from '@angular/material';
|
||||||
import { NodeSelectInterfaceComponent } from './components/project-map/node-select-interface/node-select-interface.component';
|
import { NodeSelectInterfaceComponent } from './components/project-map/node-select-interface/node-select-interface.component';
|
||||||
|
import { DrawLinkToolComponent } from './components/project-map/draw-link-tool/draw-link-tool.component';
|
||||||
|
|
||||||
|
|
||||||
if (environment.production) {
|
if (environment.production) {
|
||||||
@ -115,7 +116,8 @@ if (environment.production) {
|
|||||||
LocalServerComponent,
|
LocalServerComponent,
|
||||||
ProgressComponent,
|
ProgressComponent,
|
||||||
ServerDiscoveryComponent,
|
ServerDiscoveryComponent,
|
||||||
NodeSelectInterfaceComponent
|
NodeSelectInterfaceComponent,
|
||||||
|
DrawLinkToolComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
NgbModule.forRoot(),
|
NgbModule.forRoot(),
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { DraggableComponent } from './components/draggable/draggable.component';
|
|
||||||
import { SelectionComponent } from './components/selection/selection.component';
|
|
||||||
import { NodeComponent } from './components/experimental-map/node/node.component';
|
import { NodeComponent } from './components/experimental-map/node/node.component';
|
||||||
import { LinkComponent } from './components/experimental-map/link/link.component';
|
import { LinkComponent } from './components/experimental-map/link/link.component';
|
||||||
import { StatusComponent } from './components/experimental-map/status/status.component';
|
import { StatusComponent } from './components/experimental-map/status/status.component';
|
||||||
@ -10,6 +8,8 @@ import { LineComponent } from './components/experimental-map/drawing/drawings/li
|
|||||||
import { RectComponent } from './components/experimental-map/drawing/drawings/rect/rect.component';
|
import { RectComponent } from './components/experimental-map/drawing/drawings/rect/rect.component';
|
||||||
import { TextComponent } from './components/experimental-map/drawing/drawings/text/text.component';
|
import { TextComponent } from './components/experimental-map/drawing/drawings/text/text.component';
|
||||||
import { InterfaceLabelComponent } from './components/experimental-map/interface-label/interface-label.component';
|
import { InterfaceLabelComponent } from './components/experimental-map/interface-label/interface-label.component';
|
||||||
|
import { DraggableComponent } from './components/experimental-map/draggable/draggable.component';
|
||||||
|
import { SelectionComponent } from './components/experimental-map/selection/selection.component';
|
||||||
|
|
||||||
|
|
||||||
export const ANGULAR_MAP_DECLARATIONS = [
|
export const ANGULAR_MAP_DECLARATIONS = [
|
||||||
|
@ -2,9 +2,7 @@ import { NgModule } from '@angular/core';
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { MatMenuModule, MatIconModule } from '@angular/material';
|
import { MatMenuModule, MatIconModule } from '@angular/material';
|
||||||
|
|
||||||
import { DrawLinkToolComponent } from './components/draw-link-tool/draw-link-tool.component';
|
|
||||||
import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.component';
|
import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.component';
|
||||||
|
|
||||||
import { CssFixer } from './helpers/css-fixer';
|
import { CssFixer } from './helpers/css-fixer';
|
||||||
import { FontFixer } from './helpers/font-fixer';
|
import { FontFixer } from './helpers/font-fixer';
|
||||||
import { MultiLinkCalculatorHelper } from './helpers/multi-link-calculator-helper';
|
import { MultiLinkCalculatorHelper } from './helpers/multi-link-calculator-helper';
|
||||||
@ -54,7 +52,6 @@ import { MapSettingsManager } from './managers/map-settings-manager';
|
|||||||
declarations: [
|
declarations: [
|
||||||
D3MapComponent,
|
D3MapComponent,
|
||||||
ExperimentalMapComponent,
|
ExperimentalMapComponent,
|
||||||
DrawLinkToolComponent,
|
|
||||||
DrawingResizingComponent,
|
DrawingResizingComponent,
|
||||||
...ANGULAR_MAP_DECLARATIONS,
|
...ANGULAR_MAP_DECLARATIONS,
|
||||||
SelectionControlComponent,
|
SelectionControlComponent,
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
</filter>
|
</filter>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<app-draw-link-tool *ngIf="drawLinkTool"></app-draw-link-tool>
|
|
||||||
<app-drawing-resizing></app-drawing-resizing>
|
<app-drawing-resizing></app-drawing-resizing>
|
||||||
<app-selection-control></app-selection-control>
|
<app-selection-control></app-selection-control>
|
||||||
<app-selection-select></app-selection-select>
|
<app-selection-select></app-selection-select>
|
||||||
|
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 372 B |
@ -1,13 +1,129 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
|
||||||
|
|
||||||
import { DraggableSelectionComponent } from './draggable-selection.component';
|
import { DraggableSelectionComponent } from './draggable-selection.component';
|
||||||
|
import { NodesWidget } from '../../widgets/nodes';
|
||||||
|
import { DrawingsWidget } from '../../widgets/drawings';
|
||||||
|
import { LinksWidget } from '../../widgets/links';
|
||||||
|
import { LabelWidget } from '../../widgets/label';
|
||||||
|
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
||||||
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
|
import { SelectionManagerMock } from '../../managers/selection-manager.spec';
|
||||||
|
import { NodesEventSource } from '../../events/nodes-event-source';
|
||||||
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
|
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||||
|
import { MockedGraphDataManager } from '../../managers/graph-data-manager.spec';
|
||||||
|
import { LinksEventSource } from '../../events/links-event-source';
|
||||||
|
import { DraggableStart, DraggableDrag, DraggableEnd } from '../../events/draggable';
|
||||||
|
import { MapNode } from '../../models/map/map-node';
|
||||||
|
import { EventEmitter } from '@angular/core';
|
||||||
|
import { MapDrawing } from '../../models/map/map-drawing';
|
||||||
|
import { MapLabel } from '../../models/map/map-label';
|
||||||
|
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||||
|
import { select } from 'd3-selection';
|
||||||
|
import { MapLink } from '../../models/map/map-link';
|
||||||
|
|
||||||
|
|
||||||
describe('DraggableSelectionComponent', () => {
|
describe('DraggableSelectionComponent', () => {
|
||||||
let component: DraggableSelectionComponent;
|
let component: DraggableSelectionComponent;
|
||||||
let fixture: ComponentFixture<DraggableSelectionComponent>;
|
let fixture: ComponentFixture<DraggableSelectionComponent>;
|
||||||
|
let mockedGraphDataManager: MockedGraphDataManager;
|
||||||
|
let nodesStartEventEmitter: EventEmitter<DraggableStart<MapNode>>;
|
||||||
|
let nodesDragEventEmitter: EventEmitter<DraggableDrag<MapNode>>;
|
||||||
|
let nodesEndEventEmitter: EventEmitter<DraggableEnd<MapNode>>;
|
||||||
|
|
||||||
|
let drawingsStartEventEmitter: EventEmitter<DraggableStart<MapDrawing>>;
|
||||||
|
let drawingsDragEventEmitter: EventEmitter<DraggableDrag<MapDrawing>>;
|
||||||
|
let drawingsEndEventEmitter: EventEmitter<DraggableEnd<MapDrawing>>;
|
||||||
|
|
||||||
|
let labelStartEventEmitter: EventEmitter<DraggableStart<MapLabel>>;
|
||||||
|
let labelDragEventEmitter: EventEmitter<DraggableDrag<MapLabel>>;
|
||||||
|
let labelEndEventEmitter: EventEmitter<DraggableEnd<MapLabel>>;
|
||||||
|
|
||||||
|
let interfaceLabelStartEventEmitter: EventEmitter<DraggableStart<MapLinkNode>>;
|
||||||
|
let interfaceLabelDragEventEmitter: EventEmitter<DraggableDrag<MapLinkNode>>;
|
||||||
|
let interfaceLabelEndEventEmitter: EventEmitter<DraggableEnd<MapLinkNode>>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
|
mockedGraphDataManager = new MockedGraphDataManager();
|
||||||
|
|
||||||
|
nodesStartEventEmitter = new EventEmitter<DraggableStart<MapNode>>();
|
||||||
|
nodesDragEventEmitter = new EventEmitter<DraggableDrag<MapNode>>();
|
||||||
|
nodesEndEventEmitter = new EventEmitter<DraggableEnd<MapNode>>();
|
||||||
|
|
||||||
|
drawingsStartEventEmitter = new EventEmitter<DraggableStart<MapDrawing>>();
|
||||||
|
drawingsDragEventEmitter = new EventEmitter<DraggableDrag<MapDrawing>>();
|
||||||
|
drawingsEndEventEmitter = new EventEmitter<DraggableEnd<MapDrawing>>();
|
||||||
|
|
||||||
|
labelStartEventEmitter = new EventEmitter<DraggableStart<MapLabel>>();
|
||||||
|
labelDragEventEmitter = new EventEmitter<DraggableDrag<MapLabel>>();
|
||||||
|
labelEndEventEmitter = new EventEmitter<DraggableEnd<MapLabel>>();
|
||||||
|
|
||||||
|
interfaceLabelStartEventEmitter = new EventEmitter<DraggableStart<MapLinkNode>>();
|
||||||
|
interfaceLabelDragEventEmitter = new EventEmitter<DraggableDrag<MapLinkNode>>();
|
||||||
|
interfaceLabelEndEventEmitter = new EventEmitter<DraggableEnd<MapLinkNode>>();
|
||||||
|
|
||||||
|
const nodesWidgetStub = {
|
||||||
|
redrawNode: () => {},
|
||||||
|
draggable: {
|
||||||
|
start: nodesStartEventEmitter,
|
||||||
|
drag: nodesDragEventEmitter,
|
||||||
|
end: nodesEndEventEmitter
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const drawingsWidgetStub = {
|
||||||
|
redrawDrawing: () => {},
|
||||||
|
draggable: {
|
||||||
|
start: drawingsStartEventEmitter,
|
||||||
|
drag: drawingsDragEventEmitter,
|
||||||
|
end: drawingsEndEventEmitter
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const linksWidgetStub = {
|
||||||
|
redrawLink: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const labelWidgetStub = {
|
||||||
|
redrawLabel: () => {},
|
||||||
|
draggable: {
|
||||||
|
start: labelStartEventEmitter,
|
||||||
|
drag: labelDragEventEmitter,
|
||||||
|
end: labelEndEventEmitter
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const interfaceLabelWidgetStub = {
|
||||||
|
draggable: {
|
||||||
|
start: interfaceLabelStartEventEmitter,
|
||||||
|
drag: interfaceLabelDragEventEmitter,
|
||||||
|
end: interfaceLabelEndEventEmitter
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const nodesEventSourceStub = {
|
||||||
|
dragged: { emit: () => {}},
|
||||||
|
labelDragged: { emit: () => {}}
|
||||||
|
};
|
||||||
|
const drawingsEventSourceStub = {
|
||||||
|
dragged: { emit: () => {}}
|
||||||
|
};
|
||||||
|
const linksEventSourceStub = {
|
||||||
|
interfaceDragged: { emit: () => {}}
|
||||||
|
};
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
|
providers: [
|
||||||
|
{ provide: NodesWidget, useValue: nodesWidgetStub },
|
||||||
|
{ provide: DrawingsWidget, useValue: drawingsWidgetStub },
|
||||||
|
{ provide: LinksWidget, useValue: linksWidgetStub },
|
||||||
|
{ provide: LabelWidget, useValue: labelWidgetStub },
|
||||||
|
{ provide: InterfaceLabelWidget, useValue: interfaceLabelWidgetStub },
|
||||||
|
{ provide: SelectionManager, useValue: new SelectionManagerMock() },
|
||||||
|
{ provide: NodesEventSource, useValue: nodesEventSourceStub },
|
||||||
|
{ provide: DrawingsEventSource, useValue: drawingsEventSourceStub },
|
||||||
|
{ provide: GraphDataManager, useValue: mockedGraphDataManager },
|
||||||
|
{ provide: LinksEventSource, useValue: linksEventSourceStub },
|
||||||
|
],
|
||||||
declarations: [ DraggableSelectionComponent ]
|
declarations: [ DraggableSelectionComponent ]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
@ -16,10 +132,418 @@ describe('DraggableSelectionComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DraggableSelectionComponent);
|
fixture = TestBed.createComponent(DraggableSelectionComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
|
component.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
|
|
||||||
|
describe('nodes dragging', () => {
|
||||||
|
let nodesWidgetStub: NodesWidget;
|
||||||
|
let linksWidgetStub: LinksWidget;
|
||||||
|
let selectionManagerStub: SelectionManager;
|
||||||
|
let node: MapNode;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
nodesWidgetStub = fixture.debugElement.injector.get(NodesWidget);
|
||||||
|
linksWidgetStub = fixture.debugElement.injector.get(LinksWidget);
|
||||||
|
selectionManagerStub = fixture.debugElement.injector.get(SelectionManager);
|
||||||
|
node = new MapNode();
|
||||||
|
node.id = "nodeid";
|
||||||
|
node.x = 1;
|
||||||
|
node.y = 2;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select node when started dragging', fakeAsync(() => {
|
||||||
|
nodesWidgetStub.draggable.start.emit(new DraggableStart<MapNode>(node));
|
||||||
|
tick();
|
||||||
|
expect(selectionManagerStub.getSelected().length).toEqual(1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should ignore node when started dragging and node is in selection', fakeAsync(() => {
|
||||||
|
selectionManagerStub.setSelected([node]);
|
||||||
|
nodesWidgetStub.draggable.start.emit(new DraggableStart<MapNode>(node));
|
||||||
|
tick();
|
||||||
|
expect(selectionManagerStub.getSelected().length).toEqual(1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should update node position when dragging', fakeAsync(() => {
|
||||||
|
spyOn(nodesWidgetStub, 'redrawNode');
|
||||||
|
selectionManagerStub.setSelected([node]);
|
||||||
|
|
||||||
|
const dragEvent = new DraggableDrag<MapNode>(node);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
nodesWidgetStub.draggable.drag.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(nodesWidgetStub.redrawNode).toHaveBeenCalledWith(select(fixture.componentInstance.svg), node);
|
||||||
|
expect(node.x).toEqual(11);
|
||||||
|
expect(node.y).toEqual(22);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should redraw related links target when dragging node', fakeAsync(() => {
|
||||||
|
spyOn(nodesWidgetStub, 'redrawNode');
|
||||||
|
spyOn(linksWidgetStub, 'redrawLink');
|
||||||
|
const link = new MapLink();
|
||||||
|
link.target = node;
|
||||||
|
mockedGraphDataManager.setLinks([link]);
|
||||||
|
selectionManagerStub.setSelected([node]);
|
||||||
|
nodesWidgetStub.draggable.drag.emit(new DraggableDrag<MapNode>(node));
|
||||||
|
|
||||||
|
tick();
|
||||||
|
expect(linksWidgetStub.redrawLink).toHaveBeenCalledWith(select(fixture.componentInstance.svg), link);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should redraw related links source when dragging node', fakeAsync(() => {
|
||||||
|
spyOn(nodesWidgetStub, 'redrawNode');
|
||||||
|
spyOn(linksWidgetStub, 'redrawLink');
|
||||||
|
const link = new MapLink();
|
||||||
|
link.source = node;
|
||||||
|
mockedGraphDataManager.setLinks([link]);
|
||||||
|
selectionManagerStub.setSelected([node]);
|
||||||
|
nodesWidgetStub.draggable.drag.emit(new DraggableDrag<MapNode>(node));
|
||||||
|
|
||||||
|
tick();
|
||||||
|
expect(linksWidgetStub.redrawLink).toHaveBeenCalledWith(select(fixture.componentInstance.svg), link);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit event when node stopped dragging', fakeAsync(() => {
|
||||||
|
const nodesEventSourceStub = fixture.debugElement.injector.get(NodesEventSource);
|
||||||
|
const spyDragged = spyOn(nodesEventSourceStub.dragged, 'emit');
|
||||||
|
|
||||||
|
selectionManagerStub.setSelected([node]);
|
||||||
|
const dragEvent = new DraggableEnd<MapNode>(node);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
nodesWidgetStub.draggable.end.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(nodesEventSourceStub.dragged.emit).toHaveBeenCalled();
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].datum).toEqual(node);
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].dx).toEqual(10);
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].dy).toEqual(20);
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('drawings dragging', () => {
|
||||||
|
let drawingsWidgetStub: DrawingsWidget;
|
||||||
|
let selectionManagerStub: SelectionManager;
|
||||||
|
let drawing: MapDrawing;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
drawingsWidgetStub = fixture.debugElement.injector.get(DrawingsWidget);
|
||||||
|
selectionManagerStub = fixture.debugElement.injector.get(SelectionManager);
|
||||||
|
drawing = new MapDrawing();
|
||||||
|
drawing.id = "drawingid";
|
||||||
|
drawing.x = 1;
|
||||||
|
drawing.y = 2;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select drawing when started dragging', fakeAsync(() => {
|
||||||
|
drawingsWidgetStub.draggable.start.emit(new DraggableStart<MapDrawing>(drawing));
|
||||||
|
tick();
|
||||||
|
expect(selectionManagerStub.getSelected().length).toEqual(1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should ignore drawing when started dragging and node is in selection', fakeAsync(() => {
|
||||||
|
selectionManagerStub.setSelected([drawing]);
|
||||||
|
drawingsWidgetStub.draggable.start.emit(new DraggableStart<MapDrawing>(drawing));
|
||||||
|
tick();
|
||||||
|
expect(selectionManagerStub.getSelected().length).toEqual(1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should update drawing position when dragging', fakeAsync(() => {
|
||||||
|
spyOn(drawingsWidgetStub, 'redrawDrawing');
|
||||||
|
selectionManagerStub.setSelected([drawing]);
|
||||||
|
|
||||||
|
const dragEvent = new DraggableDrag<MapDrawing>(drawing);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
drawingsWidgetStub.draggable.drag.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(drawingsWidgetStub.redrawDrawing).toHaveBeenCalledWith(select(fixture.componentInstance.svg), drawing);
|
||||||
|
expect(drawing.x).toEqual(11);
|
||||||
|
expect(drawing.y).toEqual(22);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit event when drawing stopped dragging', fakeAsync(() => {
|
||||||
|
const drawingsEventSourceStub = fixture.debugElement.injector.get(DrawingsEventSource);
|
||||||
|
const spyDragged = spyOn(drawingsEventSourceStub.dragged, 'emit');
|
||||||
|
|
||||||
|
selectionManagerStub.setSelected([drawing]);
|
||||||
|
const dragEvent = new DraggableEnd<MapDrawing>(drawing);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
drawingsWidgetStub.draggable.end.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(drawingsEventSourceStub.dragged.emit).toHaveBeenCalled();
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].datum).toEqual(drawing);
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].dx).toEqual(10);
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].dy).toEqual(20);
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('labels dragging', () => {
|
||||||
|
let labelWidgetStub: LabelWidget;
|
||||||
|
let selectionManagerStub: SelectionManager;
|
||||||
|
let label: MapLabel;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
labelWidgetStub = fixture.debugElement.injector.get(LabelWidget);
|
||||||
|
selectionManagerStub = fixture.debugElement.injector.get(SelectionManager);
|
||||||
|
label = new MapLabel();
|
||||||
|
label.id = "labelid";
|
||||||
|
label.x = 1;
|
||||||
|
label.y = 2;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select label when started dragging', fakeAsync(() => {
|
||||||
|
labelWidgetStub.draggable.start.emit(new DraggableStart<MapLabel>(label));
|
||||||
|
tick();
|
||||||
|
expect(selectionManagerStub.getSelected().length).toEqual(1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should ignore label when started dragging and node is in selection', fakeAsync(() => {
|
||||||
|
selectionManagerStub.setSelected([label]);
|
||||||
|
labelWidgetStub.draggable.start.emit(new DraggableStart<MapLabel>(label));
|
||||||
|
tick();
|
||||||
|
expect(selectionManagerStub.getSelected().length).toEqual(1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should update label position when dragging', fakeAsync(() => {
|
||||||
|
spyOn(labelWidgetStub, 'redrawLabel');
|
||||||
|
selectionManagerStub.setSelected([label]);
|
||||||
|
const node = new MapNode();
|
||||||
|
node.id = "nodeid";
|
||||||
|
node.label = label;
|
||||||
|
label.nodeId = node.id;
|
||||||
|
|
||||||
|
mockedGraphDataManager.setNodes([node]);
|
||||||
|
|
||||||
|
const dragEvent = new DraggableDrag<MapLabel>(label);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
labelWidgetStub.draggable.drag.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(labelWidgetStub.redrawLabel).toHaveBeenCalledWith(select(fixture.componentInstance.svg), label);
|
||||||
|
expect(label.x).toEqual(11);
|
||||||
|
expect(label.y).toEqual(22);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not update label position when dragging and parent is selected', fakeAsync(() => {
|
||||||
|
spyOn(labelWidgetStub, 'redrawLabel');
|
||||||
|
const node = new MapNode();
|
||||||
|
node.id = "nodeid";
|
||||||
|
node.label = label;
|
||||||
|
label.nodeId = node.id;
|
||||||
|
|
||||||
|
selectionManagerStub.setSelected([label, node]);
|
||||||
|
mockedGraphDataManager.setNodes([node]);
|
||||||
|
|
||||||
|
const dragEvent = new DraggableDrag<MapLabel>(label);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
labelWidgetStub.draggable.drag.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(labelWidgetStub.redrawLabel).not.toHaveBeenCalled();
|
||||||
|
expect(label.x).toEqual(1);
|
||||||
|
expect(label.y).toEqual(2);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should emit event when label stopped dragging', fakeAsync(() => {
|
||||||
|
const nodesEventSourceStub = fixture.debugElement.injector.get(NodesEventSource);
|
||||||
|
const spyDragged = spyOn(nodesEventSourceStub.labelDragged, 'emit');
|
||||||
|
|
||||||
|
selectionManagerStub.setSelected([label]);
|
||||||
|
const dragEvent = new DraggableEnd<MapLabel>(label);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
labelWidgetStub.draggable.end.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(nodesEventSourceStub.labelDragged.emit).toHaveBeenCalled();
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].datum).toEqual(label);
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].dx).toEqual(10);
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].dy).toEqual(20);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not emit event when label stopped dragging and parent node is selected', fakeAsync(() => {
|
||||||
|
const nodesEventSourceStub = fixture.debugElement.injector.get(NodesEventSource);
|
||||||
|
spyOn(nodesEventSourceStub.labelDragged, 'emit');
|
||||||
|
const node = new MapNode();
|
||||||
|
node.id = "nodeid";
|
||||||
|
label.nodeId = node.id;
|
||||||
|
|
||||||
|
selectionManagerStub.setSelected([label, node]);
|
||||||
|
const dragEvent = new DraggableEnd<MapLabel>(label);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
labelWidgetStub.draggable.end.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(nodesEventSourceStub.labelDragged.emit).not.toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('interfaces labels dragging', () => {
|
||||||
|
let linksWidgetStub: LinksWidget;
|
||||||
|
let interfaceLabelWidgetStub: InterfaceLabelWidget;
|
||||||
|
let selectionManagerStub: SelectionManager;
|
||||||
|
let linkNode: MapLinkNode;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
interfaceLabelWidgetStub = fixture.debugElement.injector.get(InterfaceLabelWidget);
|
||||||
|
linksWidgetStub = fixture.debugElement.injector.get(LinksWidget);
|
||||||
|
selectionManagerStub = fixture.debugElement.injector.get(SelectionManager);
|
||||||
|
linkNode = new MapLinkNode();
|
||||||
|
linkNode.label = new MapLabel();
|
||||||
|
linkNode.label.x = 1;
|
||||||
|
linkNode.label.y = 2;
|
||||||
|
linkNode.id = "linknodeid";
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select interface label when started dragging', fakeAsync(() => {
|
||||||
|
interfaceLabelWidgetStub.draggable.start.emit(new DraggableStart<MapLinkNode>(linkNode));
|
||||||
|
tick();
|
||||||
|
expect(selectionManagerStub.getSelected().length).toEqual(1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should ignore interface label when started dragging and node is in selection', fakeAsync(() => {
|
||||||
|
selectionManagerStub.setSelected([linkNode]);
|
||||||
|
interfaceLabelWidgetStub.draggable.start.emit(new DraggableStart<MapLinkNode>(linkNode));
|
||||||
|
tick();
|
||||||
|
expect(selectionManagerStub.getSelected().length).toEqual(1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should update interface label position when dragging first node', fakeAsync(() => {
|
||||||
|
spyOn(linksWidgetStub, 'redrawLink');
|
||||||
|
selectionManagerStub.setSelected([linkNode]);
|
||||||
|
const node = new MapNode();
|
||||||
|
node.id = "nodeid";
|
||||||
|
linkNode.nodeId = node.id;
|
||||||
|
|
||||||
|
const secondLinkNode = new MapLinkNode();
|
||||||
|
secondLinkNode.label = new MapLabel();
|
||||||
|
secondLinkNode.label.x = 1;
|
||||||
|
secondLinkNode.label.y = 2;
|
||||||
|
secondLinkNode.id = "secondlinknodeid";
|
||||||
|
|
||||||
|
const link = new MapLink();
|
||||||
|
link.nodes = [linkNode, secondLinkNode];
|
||||||
|
|
||||||
|
mockedGraphDataManager.setLinks([link]);
|
||||||
|
|
||||||
|
const dragEvent = new DraggableDrag<MapLinkNode>(linkNode);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
interfaceLabelWidgetStub.draggable.drag.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(linksWidgetStub.redrawLink).toHaveBeenCalledWith(select(fixture.componentInstance.svg), link);
|
||||||
|
expect(linkNode.label.x).toEqual(11);
|
||||||
|
expect(linkNode.label.y).toEqual(22);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should update interface label position when dragging second node', fakeAsync(() => {
|
||||||
|
spyOn(linksWidgetStub, 'redrawLink');
|
||||||
|
selectionManagerStub.setSelected([linkNode]);
|
||||||
|
const node = new MapNode();
|
||||||
|
node.id = "nodeid";
|
||||||
|
linkNode.nodeId = node.id;
|
||||||
|
|
||||||
|
const secondLinkNode = new MapLinkNode();
|
||||||
|
secondLinkNode.label = new MapLabel();
|
||||||
|
secondLinkNode.label.x = 1;
|
||||||
|
secondLinkNode.label.y = 2;
|
||||||
|
secondLinkNode.id = "secondlinknodeid";
|
||||||
|
|
||||||
|
const link = new MapLink();
|
||||||
|
link.nodes = [secondLinkNode, linkNode];
|
||||||
|
|
||||||
|
mockedGraphDataManager.setLinks([link]);
|
||||||
|
|
||||||
|
const dragEvent = new DraggableDrag<MapLinkNode>(linkNode);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
interfaceLabelWidgetStub.draggable.drag.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(linksWidgetStub.redrawLink).toHaveBeenCalledWith(select(fixture.componentInstance.svg), link);
|
||||||
|
expect(linkNode.label.x).toEqual(11);
|
||||||
|
expect(linkNode.label.y).toEqual(22);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not update interface label position when dragging and parent node is selected', fakeAsync(() => {
|
||||||
|
spyOn(linksWidgetStub, 'redrawLink');
|
||||||
|
const node = new MapNode();
|
||||||
|
node.id = "nodeid";
|
||||||
|
linkNode.nodeId = node.id;
|
||||||
|
|
||||||
|
selectionManagerStub.setSelected([linkNode, node]);
|
||||||
|
|
||||||
|
const secondLinkNode = new MapLinkNode();
|
||||||
|
secondLinkNode.label = new MapLabel();
|
||||||
|
secondLinkNode.label.x = 1;
|
||||||
|
secondLinkNode.label.y = 2;
|
||||||
|
secondLinkNode.id = "secondlinknodeid";
|
||||||
|
|
||||||
|
const link = new MapLink();
|
||||||
|
link.nodes = [linkNode, secondLinkNode];
|
||||||
|
|
||||||
|
mockedGraphDataManager.setLinks([link]);
|
||||||
|
|
||||||
|
const dragEvent = new DraggableDrag<MapLinkNode>(linkNode);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
interfaceLabelWidgetStub.draggable.drag.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(linksWidgetStub.redrawLink).not.toHaveBeenCalled();
|
||||||
|
expect(linkNode.label.x).toEqual(1);
|
||||||
|
expect(linkNode.label.y).toEqual(2);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit event when interface label stopped dragging', fakeAsync(() => {
|
||||||
|
const linksEventSourceStub = fixture.debugElement.injector.get(LinksEventSource);
|
||||||
|
const spyDragged = spyOn(linksEventSourceStub.interfaceDragged, 'emit');
|
||||||
|
|
||||||
|
selectionManagerStub.setSelected([linkNode]);
|
||||||
|
const dragEvent = new DraggableEnd<MapLinkNode>(linkNode);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
interfaceLabelWidgetStub.draggable.end.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(linksEventSourceStub.interfaceDragged.emit).toHaveBeenCalled();
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].datum).toEqual(linkNode);
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].dx).toEqual(10);
|
||||||
|
expect(spyDragged.calls.mostRecent().args[0].dy).toEqual(20);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not emit event when interface label stopped dragging and parent node is selected', fakeAsync(() => {
|
||||||
|
const linksEventSourceStub = fixture.debugElement.injector.get(LinksEventSource);
|
||||||
|
spyOn(linksEventSourceStub.interfaceDragged, 'emit');
|
||||||
|
|
||||||
|
const node = new MapNode();
|
||||||
|
node.id = "nodeid";
|
||||||
|
linkNode.nodeId = node.id;
|
||||||
|
|
||||||
|
selectionManagerStub.setSelected([linkNode, node]);
|
||||||
|
const dragEvent = new DraggableEnd<MapLinkNode>(linkNode);
|
||||||
|
dragEvent.dx = 10;
|
||||||
|
dragEvent.dy = 20;
|
||||||
|
|
||||||
|
interfaceLabelWidgetStub.draggable.end.emit(dragEvent);
|
||||||
|
tick();
|
||||||
|
expect(linksEventSourceStub.interfaceDragged.emit).not.toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -94,7 +94,8 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
|||||||
this.nodesWidget.redrawNode(svg, node);
|
this.nodesWidget.redrawNode(svg, node);
|
||||||
|
|
||||||
const links = this.graphDataManager.getLinks().filter(
|
const links = this.graphDataManager.getLinks().filter(
|
||||||
(link) => link.target.id === node.id || link.source.id === node.id);
|
(link) => (link.target !== undefined && link.target.id === node.id) || (link.source !== undefined && link.source.id === node.id));
|
||||||
|
|
||||||
links.forEach((link) => {
|
links.forEach((link) => {
|
||||||
this.linksWidget.redrawLink(svg, link);
|
this.linksWidget.redrawLink(svg, link);
|
||||||
});
|
});
|
||||||
|
@ -1 +0,0 @@
|
|||||||
<!-- <app-node-select-interface (onChooseInterface)="onChooseInterface($event)"></app-node-select-interface> -->
|
|
@ -1,61 +0,0 @@
|
|||||||
import { Component, OnInit, Output, EventEmitter, OnDestroy, ViewChild } from '@angular/core';
|
|
||||||
import { DrawingLineWidget } from '../../widgets/drawing-line';
|
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
// import { NodeSelectInterfaceComponent } from '../node-select-interface/node-select-interface.component';
|
|
||||||
import { MapLinkCreated } from '../../events/links';
|
|
||||||
import { NodeClicked } from '../../events/nodes';
|
|
||||||
import { NodeWidget } from '../../widgets/node';
|
|
||||||
import { MapNode } from '../../models/map/map-node';
|
|
||||||
import { MapPort } from '../../models/map/map-port';
|
|
||||||
import { LinksEventSource } from '../../events/links-event-source';
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-draw-link-tool',
|
|
||||||
templateUrl: './draw-link-tool.component.html',
|
|
||||||
styleUrls: ['./draw-link-tool.component.scss']
|
|
||||||
})
|
|
||||||
export class DrawLinkToolComponent implements OnInit, OnDestroy {
|
|
||||||
// @ViewChild(NodeSelectInterfaceComponent) nodeSelectInterfaceMenu: NodeSelectInterfaceComponent;
|
|
||||||
|
|
||||||
// @Output('linkCreated') linkCreated = new EventEmitter<MapLinkCreated>();
|
|
||||||
|
|
||||||
private onNodeClicked: Subscription;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private drawingLineTool: DrawingLineWidget,
|
|
||||||
private nodeWidget: NodeWidget,
|
|
||||||
private linksEventSource: LinksEventSource
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
// this.onNodeClicked = this.nodeWidget.onNodeClicked.subscribe((eventNode: NodeClicked) => {
|
|
||||||
// this.nodeSelectInterfaceMenu.open(
|
|
||||||
// eventNode.node,
|
|
||||||
// eventNode.event.clientY,
|
|
||||||
// eventNode.event.clientX
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
if (this.drawingLineTool.isDrawing()) {
|
|
||||||
this.drawingLineTool.stop();
|
|
||||||
}
|
|
||||||
// this.onNodeClicked.unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
public onChooseInterface(event) {
|
|
||||||
const node: MapNode = event.node;
|
|
||||||
const port: MapPort = event.port;
|
|
||||||
if (this.drawingLineTool.isDrawing()) {
|
|
||||||
const data = this.drawingLineTool.stop();
|
|
||||||
this.linksEventSource.created.emit(new MapLinkCreated(data['node'], data['port'], node, port));
|
|
||||||
} else {
|
|
||||||
this.drawingLineTool.start(node.x + node.width / 2., node.y + node.height / 2., {
|
|
||||||
'node': node,
|
|
||||||
'port': port
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import { Component, OnInit, ElementRef, AfterViewInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, OnInit, ElementRef, AfterViewInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
import { Point } from '../../models/point';
|
import { Point } from '../../../models/point';
|
||||||
|
|
||||||
|
|
||||||
export class DraggableDraggedEvent {
|
export class DraggableDraggedEvent {
|
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 137 B |
@ -1,6 +1,6 @@
|
|||||||
import { Component, OnInit, Input, AfterViewInit, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';
|
import { Component, OnInit, Input, AfterViewInit, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';
|
||||||
import { Observable, Subscription, Subject } from 'rxjs';
|
import { Observable, Subscription, Subject } from 'rxjs';
|
||||||
import { Rectangle } from '../../models/rectangle';
|
import { Rectangle } from '../../../models/rectangle';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-selection]',
|
selector: '[app-selection]',
|
@ -7,18 +7,18 @@ import { MapDrawing } from "../../models/map/map-drawing";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DrawingToMapDrawingConverter implements Converter<Drawing, MapDrawing> {
|
export class DrawingToMapDrawingConverter implements Converter<Drawing, MapDrawing> {
|
||||||
constructor(
|
constructor(
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
convert(drawing: Drawing) {
|
convert(drawing: Drawing) {
|
||||||
const mapDrawing = new MapDrawing();
|
const mapDrawing = new MapDrawing();
|
||||||
mapDrawing.id = drawing.drawing_id;
|
mapDrawing.id = drawing.drawing_id;
|
||||||
mapDrawing.projectId = drawing.project_id;
|
mapDrawing.projectId = drawing.project_id;
|
||||||
mapDrawing.rotation = drawing.rotation;
|
mapDrawing.rotation = drawing.rotation;
|
||||||
mapDrawing.svg = drawing.svg;
|
mapDrawing.svg = drawing.svg;
|
||||||
mapDrawing.x = drawing.x;
|
mapDrawing.x = drawing.x;
|
||||||
mapDrawing.y = drawing.y;
|
mapDrawing.y = drawing.y;
|
||||||
mapDrawing.z = drawing.z;
|
mapDrawing.z = drawing.z;
|
||||||
return mapDrawing;
|
return mapDrawing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,17 @@ import { MapLabel } from "../../models/map/map-label";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
||||||
convert(label: Label, paramaters?: {[node_id: string]: string}) {
|
convert(label: Label, paramaters?: {[node_id: string]: string}) {
|
||||||
const mapLabel = new MapLabel();
|
const mapLabel = new MapLabel();
|
||||||
mapLabel.rotation = label.rotation;
|
mapLabel.rotation = label.rotation;
|
||||||
mapLabel.style = label.style;
|
mapLabel.style = label.style;
|
||||||
mapLabel.text = label.text;
|
mapLabel.text = label.text;
|
||||||
mapLabel.x = label.x;
|
mapLabel.x = label.x;
|
||||||
mapLabel.y = label.y;
|
mapLabel.y = label.y;
|
||||||
if (paramaters !== undefined) {
|
if (paramaters !== undefined) {
|
||||||
mapLabel.id = paramaters.node_id;
|
mapLabel.id = paramaters.node_id;
|
||||||
mapLabel.nodeId = paramaters.node_id;
|
mapLabel.nodeId = paramaters.node_id;
|
||||||
}
|
|
||||||
return mapLabel;
|
|
||||||
}
|
}
|
||||||
|
return mapLabel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,3 +17,11 @@ export class ResizedDataEvent<T> {
|
|||||||
public height: number) {
|
public height: number) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ClickedDataEvent<T> {
|
||||||
|
constructor(
|
||||||
|
public datum: T,
|
||||||
|
public x: number,
|
||||||
|
public y: number
|
||||||
|
) {}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { Injectable, EventEmitter } from "@angular/core";
|
import { Injectable, EventEmitter } from "@angular/core";
|
||||||
import { DraggedDataEvent } from "./event-source";
|
import { DraggedDataEvent, ClickedDataEvent } from "./event-source";
|
||||||
import { MapNode } from "../models/map/map-node";
|
import { MapNode } from "../models/map/map-node";
|
||||||
import { MapLabel } from "../models/map/map-label";
|
import { MapLabel } from "../models/map/map-label";
|
||||||
|
|
||||||
@ -8,4 +8,5 @@ import { MapLabel } from "../models/map/map-label";
|
|||||||
export class NodesEventSource {
|
export class NodesEventSource {
|
||||||
public dragged = new EventEmitter<DraggedDataEvent<MapNode>>();
|
public dragged = new EventEmitter<DraggedDataEvent<MapNode>>();
|
||||||
public labelDragged = new EventEmitter<DraggedDataEvent<MapLabel>>();
|
public labelDragged = new EventEmitter<DraggedDataEvent<MapLabel>>();
|
||||||
|
public clicked = new EventEmitter<ClickedDataEvent<MapNode>>();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
import { MapNode } from "../models/map/map-node";
|
import { MapNode } from "../models/map/map-node";
|
||||||
import { SelectionManager } from "./selection-manager";
|
import { SelectionManager } from "./selection-manager";
|
||||||
|
|
||||||
|
export class SelectionManagerMock {
|
||||||
|
public items = [];
|
||||||
|
setSelected(items: any) {
|
||||||
|
this.items = items;
|
||||||
|
}
|
||||||
|
getSelected() {
|
||||||
|
return this.items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe('SelectionManager', () => {
|
describe('SelectionManager', () => {
|
||||||
let manager: SelectionManager;
|
let manager: SelectionManager;
|
||||||
|
@ -25,5 +25,4 @@ export class MapNode implements Indexed {
|
|||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
z: number;
|
z: number;
|
||||||
isSelected = false;
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ import { MapNode } from "../models/map/map-node";
|
|||||||
import { GraphDataManager } from "../managers/graph-data-manager";
|
import { GraphDataManager } from "../managers/graph-data-manager";
|
||||||
import { SelectionManager } from "../managers/selection-manager";
|
import { SelectionManager } from "../managers/selection-manager";
|
||||||
import { LabelWidget } from "./label";
|
import { LabelWidget } from "./label";
|
||||||
|
import { NodesEventSource } from '../events/nodes-event-source';
|
||||||
|
import { ClickedDataEvent } from '../events/event-source';
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -19,7 +21,8 @@ export class NodeWidget implements Widget {
|
|||||||
constructor(
|
constructor(
|
||||||
private graphDataManager: GraphDataManager,
|
private graphDataManager: GraphDataManager,
|
||||||
private selectionManager: SelectionManager,
|
private selectionManager: SelectionManager,
|
||||||
private labelWidget: LabelWidget
|
private labelWidget: LabelWidget,
|
||||||
|
private nodesEventSource: NodesEventSource,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
@ -42,8 +45,9 @@ export class NodeWidget implements Widget {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
self.onContextMenu.emit(new NodeContextMenu(event, n));
|
self.onContextMenu.emit(new NodeContextMenu(event, n));
|
||||||
})
|
})
|
||||||
.on('click', (n: MapNode) => {
|
.on('click', (node: MapNode) => {
|
||||||
this.onNodeClicked.emit(new NodeClicked(event, n));
|
this.nodesEventSource.clicked.emit(new ClickedDataEvent<MapNode>(node, event.clientX, event.clientY))
|
||||||
|
// this.onNodeClicked.emit(new NodeClicked(event, n));
|
||||||
});
|
});
|
||||||
|
|
||||||
// update image of node
|
// update image of node
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
<app-node-select-interface (onChooseInterface)="onChooseInterface($event)"></app-node-select-interface>
|
@ -0,0 +1,58 @@
|
|||||||
|
import { Component, OnInit, OnDestroy, ViewChild } 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';
|
||||||
|
import { NodesEventSource } from '../../../cartography/events/nodes-event-source';
|
||||||
|
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';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-draw-link-tool',
|
||||||
|
templateUrl: './draw-link-tool.component.html',
|
||||||
|
styleUrls: ['./draw-link-tool.component.scss']
|
||||||
|
})
|
||||||
|
export class DrawLinkToolComponent implements OnInit, OnDestroy {
|
||||||
|
@ViewChild(NodeSelectInterfaceComponent) nodeSelectInterfaceMenu: NodeSelectInterfaceComponent;
|
||||||
|
|
||||||
|
private nodeClicked$: Subscription;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private drawingLineTool: DrawingLineWidget,
|
||||||
|
private nodesEventSource: NodesEventSource,
|
||||||
|
private linksEventSource: LinksEventSource
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.nodeClicked$ = this.nodesEventSource.clicked.subscribe((clickedEvent) => {
|
||||||
|
this.nodeSelectInterfaceMenu.open(
|
||||||
|
clickedEvent.datum,
|
||||||
|
clickedEvent.y,
|
||||||
|
clickedEvent.x
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
if (this.drawingLineTool.isDrawing()) {
|
||||||
|
this.drawingLineTool.stop();
|
||||||
|
}
|
||||||
|
this.nodeClicked$.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
public onChooseInterface(event) {
|
||||||
|
const node: MapNode = event.node;
|
||||||
|
const port: MapPort = event.port;
|
||||||
|
if (this.drawingLineTool.isDrawing()) {
|
||||||
|
const data = this.drawingLineTool.stop();
|
||||||
|
this.linksEventSource.created.emit(new MapLinkCreated(data['node'], data['port'], node, port));
|
||||||
|
} else {
|
||||||
|
this.drawingLineTool.start(node.x + node.width / 2., node.y + node.height / 2., {
|
||||||
|
'node': node,
|
||||||
|
'port': port
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,9 +18,9 @@ export class NodeContextMenuComponent implements OnInit {
|
|||||||
|
|
||||||
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
|
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
|
||||||
|
|
||||||
protected topPosition;
|
topPosition;
|
||||||
protected leftPosition;
|
leftPosition;
|
||||||
public node: Node;
|
node: Node;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div class="context-menu" [style.left]="leftPosition" [style.top]="topPosition" *ngIf="node">
|
<div class="context-menu" [style.left]="leftPosition" [style.top]="topPosition" *ngIf="node">
|
||||||
<span [matMenuTriggerFor]="selectInterfaceMenu"></span>
|
<span [matMenuTriggerFor]="selectInterfaceMenu"></span>
|
||||||
<mat-menu #selectInterfaceMenu="matMenu">
|
<mat-menu #selectInterfaceMenu="matMenu" class="context-menu-items">
|
||||||
<button mat-menu-item *ngFor="let port of node.ports" (click)="chooseInterface(port)">
|
<button mat-menu-item *ngFor="let port of node.ports" (click)="chooseInterface(port)">
|
||||||
<mat-icon>add_circle_outline</mat-icon>
|
<mat-icon>add_circle_outline</mat-icon>
|
||||||
<span>{{ port.name }}</span>
|
<span>{{ port.name }}</span>
|
||||||
|
@ -15,8 +15,8 @@ export class NodeSelectInterfaceComponent implements OnInit {
|
|||||||
|
|
||||||
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
|
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
|
||||||
|
|
||||||
private topPosition;
|
protected topPosition;
|
||||||
private leftPosition;
|
protected leftPosition;
|
||||||
public node: Node;
|
public node: Node;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -140,3 +140,5 @@
|
|||||||
[project]="project"
|
[project]="project"
|
||||||
[server]="server">
|
[server]="server">
|
||||||
</app-project-map-shortcuts>
|
</app-project-map-shortcuts>
|
||||||
|
|
||||||
|
<app-draw-link-tool *ngIf="tools.draw_link"></app-draw-link-tool>
|
@ -64,7 +64,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
private drawListener: Function;
|
private drawListener: Function;
|
||||||
private ws: Subject<any>;
|
private ws: Subject<any>;
|
||||||
|
|
||||||
protected tools = {
|
tools = {
|
||||||
'selection': true,
|
'selection': true,
|
||||||
'moving': false,
|
'moving': false,
|
||||||
'draw_link': false
|
'draw_link': false
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
// The file contents for the current environment will overwrite these during build.
|
// This file can be replaced during build by using the `fileReplacements` array.
|
||||||
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||||
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
// The list of file replacements can be found in `angular.json`.
|
||||||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
|
||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false,
|
production: false,
|
||||||
electron: false,
|
electron: false,
|
||||||
githubio: false
|
githubio: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For easier debugging in development mode, you can import the following file
|
||||||
|
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||||
|
*
|
||||||
|
* This import should be commented out in production mode because it will have a negative impact
|
||||||
|
* on performance if an error is thrown.
|
||||||
|
*/
|
||||||
|
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
|
||||||
|
@ -8,4 +8,5 @@ if (environment.production) {
|
|||||||
enableProdMode();
|
enableProdMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||||
|
.catch(err => console.error(err));
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
||||||
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||||
*
|
*
|
||||||
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
|
* Learn more in https://angular.io/guide/browser-support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
@ -34,29 +34,47 @@
|
|||||||
// import 'core-js/es6/weak-map';
|
// import 'core-js/es6/weak-map';
|
||||||
// import 'core-js/es6/set';
|
// import 'core-js/es6/set';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the application will be indexed by Google Search, the following is required.
|
||||||
|
* Googlebot uses a renderer based on Chrome 41.
|
||||||
|
* https://developers.google.com/search/docs/guides/rendering
|
||||||
|
**/
|
||||||
|
// import 'core-js/es6/array';
|
||||||
|
|
||||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
||||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||||
|
|
||||||
/** Evergreen browsers require these. **/
|
/** IE10 and IE11 requires the following for the Reflect API. */
|
||||||
import 'core-js/es6/reflect';
|
// import 'core-js/es6/reflect';
|
||||||
import 'core-js/es7/reflect';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required to support Web Animations `@angular/animation`.
|
* Web Animations `@angular/platform-browser/animations`
|
||||||
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
|
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
|
||||||
|
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
|
||||||
**/
|
**/
|
||||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||||
|
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||||
|
*/
|
||||||
|
|
||||||
|
// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||||
|
// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||||
|
// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||||
|
|
||||||
|
/*
|
||||||
|
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
||||||
|
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||||
|
*/
|
||||||
|
// (window as any).__Zone_enable_cross_context_check = true;
|
||||||
|
|
||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
* Zone JS is required by Angular itself.
|
* Zone JS is required by default for Angular itself.
|
||||||
*/
|
*/
|
||||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
* APPLICATION IMPORTS
|
* APPLICATION IMPORTS
|
||||||
*/
|
*/
|
||||||
|
14
src/test.ts
14
src/test.ts
@ -1,24 +1,14 @@
|
|||||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||||
|
|
||||||
import 'zone.js/dist/long-stack-trace-zone';
|
import 'zone.js/dist/zone-testing';
|
||||||
import 'zone.js/dist/proxy.js';
|
|
||||||
import 'zone.js/dist/sync-test';
|
|
||||||
import 'zone.js/dist/jasmine-patch';
|
|
||||||
import 'zone.js/dist/async-test';
|
|
||||||
import 'zone.js/dist/fake-async-test';
|
|
||||||
import { getTestBed } from '@angular/core/testing';
|
import { getTestBed } from '@angular/core/testing';
|
||||||
import {
|
import {
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
platformBrowserDynamicTesting
|
platformBrowserDynamicTesting
|
||||||
} from '@angular/platform-browser-dynamic/testing';
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
|
|
||||||
declare const __karma__: any;
|
|
||||||
declare const require: any;
|
declare const require: any;
|
||||||
|
|
||||||
// Prevent Karma from running prematurely.
|
|
||||||
__karma__.loaded = function () {};
|
|
||||||
|
|
||||||
// First, initialize the Angular testing environment.
|
// First, initialize the Angular testing environment.
|
||||||
getTestBed().initTestEnvironment(
|
getTestBed().initTestEnvironment(
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
@ -28,5 +18,3 @@ getTestBed().initTestEnvironment(
|
|||||||
const context = require.context('./', true, /\.spec\.ts$/);
|
const context = require.context('./', true, /\.spec\.ts$/);
|
||||||
// And load the modules.
|
// And load the modules.
|
||||||
context.keys().map(context);
|
context.keys().map(context);
|
||||||
// Finally, start Karma to run the tests.
|
|
||||||
__karma__.start();
|
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
{
|
{
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./",
|
||||||
"outDir": "./dist/out-tsc",
|
"outDir": "./dist/out-tsc",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
|
"module": "es2015",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
|
"importHelpers": true,
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"node_modules/@types"
|
"node_modules/@types"
|
||||||
],
|
],
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2016",
|
"es2018",
|
||||||
"dom"
|
"dom"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
30
tslint.json
30
tslint.json
@ -11,10 +11,14 @@
|
|||||||
"check-space"
|
"check-space"
|
||||||
],
|
],
|
||||||
"curly": true,
|
"curly": true,
|
||||||
|
"deprecation": {
|
||||||
|
"severity": "warn"
|
||||||
|
},
|
||||||
"eofline": true,
|
"eofline": true,
|
||||||
"forin": true,
|
"forin": true,
|
||||||
"import-blacklist": [
|
"import-blacklist": [
|
||||||
true
|
true,
|
||||||
|
"rxjs/Rx"
|
||||||
],
|
],
|
||||||
"import-spacing": true,
|
"import-spacing": true,
|
||||||
"indent": [
|
"indent": [
|
||||||
@ -61,11 +65,12 @@
|
|||||||
],
|
],
|
||||||
"no-misused-new": true,
|
"no-misused-new": true,
|
||||||
"no-non-null-assertion": true,
|
"no-non-null-assertion": true,
|
||||||
|
"no-redundant-jsdoc": true,
|
||||||
"no-shadowed-variable": true,
|
"no-shadowed-variable": true,
|
||||||
"no-string-literal": false,
|
"no-string-literal": false,
|
||||||
"no-string-throw": true,
|
"no-string-throw": true,
|
||||||
"no-switch-case-fall-through": true,
|
"no-switch-case-fall-through": true,
|
||||||
"no-trailing-whitespace": false,
|
"no-trailing-whitespace": true,
|
||||||
"no-unnecessary-initializer": true,
|
"no-unnecessary-initializer": true,
|
||||||
"no-unused-expression": true,
|
"no-unused-expression": true,
|
||||||
"no-use-before-declare": true,
|
"no-use-before-declare": true,
|
||||||
@ -80,7 +85,7 @@
|
|||||||
],
|
],
|
||||||
"prefer-const": true,
|
"prefer-const": true,
|
||||||
"quotemark": [
|
"quotemark": [
|
||||||
false,
|
true,
|
||||||
"single"
|
"single"
|
||||||
],
|
],
|
||||||
"radix": true,
|
"radix": true,
|
||||||
@ -102,7 +107,6 @@
|
|||||||
"variable-declaration": "nospace"
|
"variable-declaration": "nospace"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"typeof-compare": true,
|
|
||||||
"unified-signatures": true,
|
"unified-signatures": true,
|
||||||
"variable-name": false,
|
"variable-name": false,
|
||||||
"whitespace": [
|
"whitespace": [
|
||||||
@ -113,18 +117,7 @@
|
|||||||
"check-separator",
|
"check-separator",
|
||||||
"check-type"
|
"check-type"
|
||||||
],
|
],
|
||||||
"directive-selector": [
|
"no-output-on-prefix": true,
|
||||||
true,
|
|
||||||
"attribute",
|
|
||||||
"app",
|
|
||||||
"camelCase"
|
|
||||||
],
|
|
||||||
"component-selector": [
|
|
||||||
true,
|
|
||||||
"element",
|
|
||||||
"app",
|
|
||||||
"kebab-case"
|
|
||||||
],
|
|
||||||
"use-input-property-decorator": true,
|
"use-input-property-decorator": true,
|
||||||
"use-output-property-decorator": true,
|
"use-output-property-decorator": true,
|
||||||
"use-host-property-decorator": true,
|
"use-host-property-decorator": true,
|
||||||
@ -133,9 +126,6 @@
|
|||||||
"use-life-cycle-interface": true,
|
"use-life-cycle-interface": true,
|
||||||
"use-pipe-transform-interface": true,
|
"use-pipe-transform-interface": true,
|
||||||
"component-class-suffix": true,
|
"component-class-suffix": true,
|
||||||
"directive-class-suffix": true,
|
"directive-class-suffix": true
|
||||||
"no-access-missing-member": true,
|
|
||||||
"templates-use-public": true,
|
|
||||||
"invoke-injectable": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user