Merge branch 'add-rectangle-change-border-position' of https://github.com/GNS3/gns3-web-ui into add-rectangle-change-border-position

This commit is contained in:
Piotr Pekala 2018-12-11 00:46:19 -08:00
commit c466275e62
21 changed files with 1350 additions and 1617 deletions

3
.gitignore vendored
View File

@ -49,3 +49,6 @@ package-lock.json
# System Files
.DS_Store
Thumbs.db
# Licenses file
licenses.csv

9
.prettierrc Normal file
View File

@ -0,0 +1,9 @@
{
"printWidth": 120,
"singleQuote": true,
"useTabs": false,
"tabWidth": 2,
"semi": true,
"bracketSpacing": true,
"jsxBracketSameLine": false,
}

View File

@ -18,6 +18,10 @@ Please use GNS3 WebUI bundled in `gns3server` and `gns3`.
## Development
### Branches policy
On branch `master` you can find the latest codebase including under development features. If you are looking for stable version with features promoted to be included in the current/next release please switch to `stable` branch.
### Installation
We're using [yarn](https://yarnpkg.com/lang/en/) for packages installation:

View File

@ -23,70 +23,76 @@
"distwin": "yarn buildforelectron && electron-builder --win --x64",
"distmac": "yarn buildforelectron && electron-builder --mac --x64",
"release": "build",
"coverage": "ng test --watch=false --code-coverage"
"coverage": "ng test --watch=false --code-coverage",
"prettier:base": "prettier",
"prettier:check": "yarn prettier:base -- --list-different \"src/**/*.{ts,js,html,scss}\"",
"prettier:write": "yarn prettier:base -- --write \"src/**/*.{ts,js,html,scss}\"",
"generate-licenses-file": "yarn license-checker --production --csv --out licenses.csv"
},
"private": true,
"dependencies": {
"@angular/animations": "^7.0.4",
"@angular/cdk": "^7.0.4",
"@angular/common": "^7.0.4",
"@angular/compiler": "^7.0.4",
"@angular/core": "^7.0.4",
"@angular/forms": "^7.0.4",
"@angular/http": "^7.0.4",
"@angular/material": "^7.0.4",
"@angular/platform-browser": "^7.0.4",
"@angular/platform-browser-dynamic": "^7.0.4",
"@angular/router": "^7.0.4",
"@ng-bootstrap/ng-bootstrap": "^4.0.0",
"@angular/animations": "^7.1.2",
"@angular/cdk": "^7.1.1",
"@angular/common": "^7.1.2",
"@angular/compiler": "^7.1.2",
"@angular/core": "^7.1.2",
"@angular/forms": "^7.1.2",
"@angular/http": "^7.1.2",
"@angular/material": "^7.1.1",
"@angular/platform-browser": "^7.1.2",
"@angular/platform-browser-dynamic": "^7.1.2",
"@angular/router": "^7.1.2",
"angular-persistence": "^1.0.1",
"angular2-hotkeys": "^2.1.4",
"angular2-indexeddb": "^1.2.3",
"bootstrap": "4.1.3",
"core-js": "^2.5.7",
"core-js": "^2.6.0",
"css-tree": "^1.0.0-alpha.29",
"d3-ng2-service": "^2.1.0",
"electron-settings": "^3.2.0",
"hammerjs": "^2.0.8",
"material-design-icons": "^3.0.1",
"ng2-file-upload": "^1.3.0",
"ngx-electron": "^2.0.0",
"notosans-fontface": "^1.1.0",
"npm-check-updates": "^2.14.3",
"raven-js": "^3.27.0",
"rxjs": "^6.3.3",
"rxjs-compat": "^6.3.3",
"typeface-roboto": "^0.0.54",
"yargs": "^12.0.4",
"yargs": "^12.0.5",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.10.6",
"@angular/cli": "^7.0.6",
"@angular/compiler-cli": "^7.0.4",
"@angular/language-service": "^7.0.4",
"@sentry/electron": "^0.13.0",
"@angular-devkit/build-angular": "~0.11.2",
"@angular/cli": "^7.1.2",
"@angular/compiler-cli": "^7.1.2",
"@angular/language-service": "^7.1.2",
"@sentry/electron": "^0.14.0",
"@types/jasmine": "~3.3.0",
"@types/jasminewd2": "~2.0.6",
"@types/node": "~10.12.9",
"@types/node": "~10.12.12",
"codelyzer": "~4.5.0",
"electron": "3.0.9",
"electron-builder": "^20.36.2",
"electron": "3.0.11",
"electron-builder": "^20.38.2",
"jasmine-core": "~3.3.0",
"jasmine-spec-reporter": "~4.2.1",
"jquery": "^3.3.1",
"karma": "~3.1.1",
"karma": "~3.1.3",
"karma-chrome-launcher": "~2.2.0",
"karma-cli": "~1.0.1",
"karma-cli": "~2.0.0",
"karma-coverage-istanbul-reporter": "^2.0.4",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"node-sass": "^4.10.0",
"popper.js": "^1.14.5",
"license-checker": "^24.0.1",
"node-sass": "^4.11.0",
"popper.js": "^1.14.6",
"prettier": "^1.15.2",
"protractor": "~5.4.1",
"ts-mockito": "^2.3.1",
"ts-node": "~7.0.1",
"tslint": "~5.11.0",
"typescript": "3.1.6"
"tslint-config-prettier": "^1.16.0",
"typescript": "<3.2.0"
},
"greenkeeper": {
"ignore": [

View File

@ -8,7 +8,6 @@ import { HttpClientModule } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { D3Service } from 'd3-ng2-service';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { HotkeyModule } from 'angular2-hotkeys';
import { PersistenceModule } from 'angular-persistence';
import { NgxElectronModule } from 'ngx-electron';
@ -120,7 +119,6 @@ if (environment.production) {
DrawLinkToolComponent
],
imports: [
NgbModule.forRoot(),
BrowserModule,
HttpClientModule,
AppRoutingModule,

View File

@ -22,6 +22,7 @@ import { DraggedDataEvent } from '../../events/event-source';
import { MapSettingsManager } from '../../managers/map-settings-manager';
import { TextEditingTool } from '../../tools/text-editing-tool';
import { TextAddingComponent } from '../text-adding/text-adding.component';
import { Server } from '../../../models/server';
@Component({
@ -34,6 +35,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
@Input() links: Link[] = [];
@Input() drawings: Drawing[] = [];
@Input() symbols: Symbol[] = [];
@Input() server: Server;
@Input() width = 1500;
@Input() height = 600;

View File

@ -5,9 +5,6 @@ import { MapNode } from "../../models/map/map-node";
import { MapLabelToLabelConverter } from "./map-label-to-label-converter";
import { MapPortToPortConverter } from "./map-port-to-port-converter";
import { Node } from "../../models/node";
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
import { CssFixer } from '../../helpers/css-fixer';
import { FontFixer } from '../../helpers/font-fixer';
@Injectable()
@ -36,6 +33,7 @@ export class MapNodeToNodeConverter implements Converter<MapNode, Node> {
node.project_id = mapNode.projectId;
node.status = mapNode.status;
node.symbol = mapNode.symbol;
node.symbol_url = mapNode.symbolUrl;
node.width = mapNode.width;
node.x = mapNode.x;
node.y = mapNode.y;

View File

@ -39,6 +39,7 @@ export class NodeToMapNodeConverter implements Converter<Node, MapNode> {
mapNode.projectId = node.project_id;
mapNode.status = node.status;
mapNode.symbol = node.symbol;
mapNode.symbolUrl = node.symbol_url;
mapNode.width = node.width;
mapNode.x = node.x;
mapNode.y = node.y;

View File

@ -21,6 +21,7 @@ export class MapNode implements Indexed {
projectId: string;
status: string;
symbol: string;
symbolUrl: string;
width: number;
x: number;
y: number;

View File

@ -21,6 +21,7 @@ export class Node {
project_id: string;
status: string;
symbol: string;
symbol_url: string; // @TODO: full URL to symbol, move to MapNode once converters are moved to app module
width: number;
x: number;
y: number;

View File

@ -0,0 +1,368 @@
import { Injectable, EventEmitter } from "@angular/core";
import { Widget } from "./widget";
import { SVGSelection } from "../models/types";
import { Layer } from "../models/layer";
import { SvgToDrawingConverter } from "../helpers/svg-to-drawing-converter";
import { Draggable, DraggableDrag, DraggableStart, DraggableEnd } from "../events/draggable";
import { DrawingWidget } from "./drawing";
import { drag, D3DragEvent } from "d3-drag";
import { event } from "d3-selection";
import { MapDrawing } from "../models/map/map-drawing";
import { Context } from "../models/context";
import { EllipseElement } from "../models/drawings/ellipse-element";
import { ResizingEnd } from "../events/resizing";
import { LineElement } from "../models/drawings/line-element";
import { MapSettingsManager } from "../managers/map-settings-manager";
@Injectable()
export class DrawingsWidget implements Widget {
public draggable = new Draggable<SVGGElement, MapDrawing>();
public draggingEnabled = false;
public resizingFinished = new EventEmitter<ResizingEnd<MapDrawing>>();
// public onContextMenu = new EventEmitter<NodeContextMenu>();
// public onDrawingClicked = new EventEmitter<NodeClicked>();
// public onDrawingDragged = new EventEmitter<NodeDragged>();
// public onDrawingDragging = new EventEmitter<NodeDragging>();
constructor(
private drawingWidget: DrawingWidget,
private svgToDrawingConverter: SvgToDrawingConverter,
private context: Context,
private mapSettings: MapSettingsManager
) {
this.svgToDrawingConverter = new SvgToDrawingConverter();
}
public redrawDrawing(view: SVGSelection, drawing: MapDrawing) {
this.drawingWidget.draw(this.selectDrawing(view, drawing));
}
public draw(view: SVGSelection) {
const drawing = view
.selectAll<SVGGElement, MapDrawing>("g.drawing")
.data((layer: Layer) => {
layer.drawings.forEach((d: MapDrawing) => {
try {
d.element = this.svgToDrawingConverter.convert(d.svg);
} catch (error) {
console.log(`Cannot convert due to Error: '${error}'`);
}
});
return layer.drawings;
}, (l: MapDrawing) => {
return l.id;
});
const drawing_enter = drawing.enter()
.append<SVGGElement>('g')
.attr('class', 'drawing')
.attr('drawing_id', (l: MapDrawing) => l.id)
const merge = drawing.merge(drawing_enter);
this.drawingWidget.draw(merge);
drawing
.exit()
.remove();
if (!this.mapSettings.isReadOnly) {
this.draggable.call(merge);
}
let y: number;
let dy: number;
let topEdge: number;
let bottomEdge: number;
let isReflectedVertical: boolean = false;
let startEvent;
let bottom = drag()
.on('start', (datum: MapDrawing) => {
document.body.style.cursor = "ns-resize";
topEdge = datum.y;
console.log("started");
y = event.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
// startEvent = event;
})
.on('drag', (datum: MapDrawing) => {
const evt = event;
dy = y - (evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y);
y = event.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
let height = datum.element.height - dy;
if(height < 0) {
// height = datum.y - startEvent.y;
datum.y += height;
height = topEdge - datum.y;
// console.log(topEdge - datum.y);
}
console.log("Height", height);
datum.element.height = height;
// datum.element.height -= dy;
// if(datum.element.height < 0) {
// datum.y -= datum.element.height;
// datum.element.height = Math.abs(datum.element.height);
// }
// if (!isReflectedVertical) {
// if ((datum.element.height + evt.dy) < 0) {
// isReflectedVertical = true;
// y = topEdge;
// console.log(y);
// datum.element.height = Math.abs(datum.element.height + evt.dy);
// console.log(datum.element.height);
// } else {
// datum.element.height += evt.dy;
// if (datum.element instanceof EllipseElement){
// (datum.element as EllipseElement).cy = (datum.element as EllipseElement).cy + evt.dy/2 < 0 ? 1 : (datum.element as EllipseElement).cy += evt.dy/2;
// (datum.element as EllipseElement).ry = (datum.element as EllipseElement).ry + evt.dy/2 < 0 ? 1 : (datum.element as EllipseElement).ry += evt.dy/2;
// }
// }
// } else {
// dy = y - (evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y);
// y = evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
// if ((datum.element.height + dy) < 0){
// isReflectedVertical = false;
// y = topEdge;
// console.log(y);
// datum.element.height = Math.abs(datum.element.height + evt.dy);
// console.log(datum.element.height);
// } else {
// datum.y = evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
// datum.element.height += dy;
// if (datum.element instanceof EllipseElement) {
// (datum.element as EllipseElement).cy = (datum.element as EllipseElement).cy + dy/2 < 0 ? 1 : (datum.element as EllipseElement).cy += dy/2;
// (datum.element as EllipseElement).ry = (datum.element as EllipseElement).ry + dy/2 < 0 ? 1 : (datum.element as EllipseElement).ry += dy/2;
// }
// }
// }
this.redrawDrawing(view, datum);
})
.on('end', (datum: MapDrawing) => {
document.body.style.cursor = "initial";
this.resizingFinished.emit(this.createResizingEvent(datum));
});
let top = drag()
.on('start', (datum: MapDrawing) => {
y = event.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
bottomEdge = y + datum.element.height;
document.body.style.cursor = "ns-resize";
})
.on('drag', (datum: MapDrawing) => {
const evt = event;
if (!isReflectedVertical) {
dy = y - (evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y);
y = evt.sourceEvent.clientY - 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.element.height += dy;
if (datum.element instanceof EllipseElement) {
(datum.element as EllipseElement).cy = (datum.element as EllipseElement).cy + dy/2 < 0 ? 1 : (datum.element as EllipseElement).cy += dy/2;
(datum.element as EllipseElement).ry = (datum.element as EllipseElement).ry + dy/2 < 0 ? 1 : (datum.element as EllipseElement).ry += dy/2;
}
}
} else {
if ((datum.element.height + evt.dy) < 0) {
isReflectedVertical = false;
y = bottomEdge;
datum.element.height = Math.abs(datum.element.height + evt.dy);
} else {
datum.element.height += evt.dy;
if (datum.element instanceof EllipseElement){
(datum.element as EllipseElement).cy = (datum.element as EllipseElement).cy + evt.dy/2 < 0 ? 1 : (datum.element as EllipseElement).cy += evt.dy/2;
(datum.element as EllipseElement).ry = (datum.element as EllipseElement).ry + evt.dy/2 < 0 ? 1 : (datum.element as EllipseElement).ry += evt.dy/2;
}
}
}
this.redrawDrawing(view, datum);
})
.on('end', (datum: MapDrawing) => {
document.body.style.cursor = "initial";
this.resizingFinished.emit(this.createResizingEvent(datum));
});
let x: number;
let dx: number;
let rightEdge: number;
let leftEdge: number;
let isReflectedHorizontal: boolean = false;
let right = drag()
.on('start', (datum: MapDrawing) => {
x = event.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x;
leftEdge = x + datum.element.width;
document.body.style.cursor = "ew-resize";
})
.on('drag', (datum: MapDrawing) => {
const evt = event;
if (!isReflectedHorizontal) {
dx = x - (evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x);
x = evt.sourceEvent.clientX - 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.element.width += dx;
if (datum.element instanceof EllipseElement) {
(datum.element as EllipseElement).cx = (datum.element as EllipseElement).cx + dx/2 < 0 ? 1 : (datum.element as EllipseElement).cx += dx/2;
(datum.element as EllipseElement).rx = (datum.element as EllipseElement).rx + dx/2 < 0 ? 1 : (datum.element as EllipseElement).rx += dx/2;
}
}
} else {
if ((datum.element.width + evt.dx) < 0) {
x = leftEdge;
isReflectedHorizontal = false;
datum.element.width = Math.abs(datum.element.width + evt.dx);
} else {
if (datum.element instanceof EllipseElement){
(datum.element as EllipseElement).cx = (datum.element as EllipseElement).cx + evt.dx/2 < 0 ? 1 : (datum.element as EllipseElement).cx += evt.dx/2;
(datum.element as EllipseElement).rx = (datum.element as EllipseElement).rx + evt.dx/2 < 0 ? 1 : (datum.element as EllipseElement).rx += evt.dx/2;
}
datum.element.width = (datum.element.width + evt.dx) < 0 ? 1 : datum.element.width += evt.dx;
}
}
this.redrawDrawing(view, datum);
})
.on('end', (datum: MapDrawing) => {
document.body.style.cursor = "initial";
this.resizingFinished.emit(this.createResizingEvent(datum));
});
let left = drag()
.on('start', (datum: MapDrawing) => {
document.body.style.cursor = "ew-resize";
rightEdge = datum.x;
})
.on('drag', (datum: MapDrawing) => {
const evt = event;
if (!isReflectedHorizontal) {
if ((datum.element.width + evt.dx) < 0) {
x = rightEdge;
isReflectedHorizontal = true;
datum.element.width = Math.abs(datum.element.width + evt.dx);
} else {
if (datum.element instanceof EllipseElement){
(datum.element as EllipseElement).cx = (datum.element as EllipseElement).cx + evt.dx/2 < 0 ? 1 : (datum.element as EllipseElement).cx += evt.dx/2;
(datum.element as EllipseElement).rx = (datum.element as EllipseElement).rx + evt.dx/2 < 0 ? 1 : (datum.element as EllipseElement).rx += evt.dx/2;
}
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;
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.element.width += dx;
if (datum.element instanceof EllipseElement) {
(datum.element as EllipseElement).cx = (datum.element as EllipseElement).cx + dx/2 < 0 ? 1 : (datum.element as EllipseElement).cx += dx/2;
(datum.element as EllipseElement).rx = (datum.element as EllipseElement).rx + dx/2 < 0 ? 1 : (datum.element as EllipseElement).rx += dx/2;
}
}
}
this.redrawDrawing(view, datum);
})
.on('end', (datum: MapDrawing) => {
document.body.style.cursor = "initial";
this.resizingFinished.emit(this.createResizingEvent(datum));
});
let circleMoveRight = drag()
.on('start', () => {
document.body.style.cursor = "move";
})
.on('drag', (datum: MapDrawing) => {
const evt = event;
datum.element.width += evt.dx;
datum.element.height += evt.dy;
(datum.element as LineElement).x2 += evt.dx;
(datum.element as LineElement).y2 += evt.dy;
this.redrawDrawing(view, datum);
})
.on('end', (datum: MapDrawing) => {
document.body.style.cursor = "initial";
this.resizingFinished.emit(this.createResizingEvent(datum));
});
let circleMoveLeft = drag()
.on('start', () => {
document.body.style.cursor = "move";
})
.on('drag', (datum: MapDrawing) => {
const evt = event;
datum.element.width += evt.dx;
datum.element.height += evt.dy;
(datum.element as LineElement).x1 += evt.dx;
(datum.element as LineElement).y1 += evt.dy;
this.redrawDrawing(view, datum);
})
.on('end', (datum: MapDrawing) => {
document.body.style.cursor = "initial";
this.resizingFinished.emit(this.createResizingEvent(datum));
});
merge
.select<SVGAElement>('line.bottom')
.call(bottom);
merge
.select<SVGAElement>('line.top')
.call(top);
merge
.select<SVGAElement>('line.right')
.call(right);
merge
.select<SVGAElement>('line.left')
.call(left);
merge
.select<SVGAElement>('circle.right')
.call(circleMoveRight)
merge
.select<SVGAElement>('circle.left')
.call(circleMoveLeft)
}
private createResizingEvent(datum: MapDrawing){
const evt = new ResizingEnd<MapDrawing>();
evt.x = datum.x;
evt.y = datum. y;
evt.width = datum.element.width;
evt.height = datum.element.height;
evt.datum = datum;
return evt;
}
private selectDrawing(view: SVGSelection, drawing: MapDrawing) {
return view.selectAll<SVGGElement, MapDrawing>(`g.drawing[drawing_id="${drawing.id}"]`);
}
}

View File

@ -4,7 +4,6 @@ import { Widget } from "./widget";
import { SVGSelection } from "../models/types";
import { NodeContextMenu, NodeClicked } from "../events/nodes";
import { select, event } from "d3-selection";
import { MapSymbol } from "../models/map/map-symbol";
import { MapNode } from "../models/map/map-node";
import { GraphDataManager } from "../managers/graph-data-manager";
import { SelectionManager } from "../managers/selection-manager";
@ -47,20 +46,12 @@ export class NodeWidget implements Widget {
})
.on('click', (node: MapNode) => {
this.nodesEventSource.clicked.emit(new ClickedDataEvent<MapNode>(node, event.clientX, event.clientY))
// this.onNodeClicked.emit(new NodeClicked(event, n));
});
// update image of node
node_body_merge
.select<SVGImageElement>('image')
.attr('xnode:href', (n: MapNode) => {
const symbol = this.graphDataManager.getSymbols().find((s: MapSymbol) => s.id === n.symbol);
if (symbol) {
return 'data:image/svg+xml;base64,' + btoa(symbol.raw);
}
// @todo; we need to have default image
return 'data:image/svg+xml;base64,none';
})
.attr('xnode:href', (n: MapNode) => n.symbolUrl)
.attr('width', (n: MapNode) => n.width)
.attr('height', (n: MapNode) => n.height)
.attr('x', (n: MapNode) => 0)

View File

@ -7,7 +7,6 @@ import { map, mergeMap } from "rxjs/operators";
import { Project } from '../../models/project';
import { Node } from '../../cartography/models/node';
import { SymbolService } from '../../services/symbol.service';
import { Link } from "../../models/link";
import { ServerService } from "../../services/server.service";
import { ProjectService } from '../../services/project.service';
@ -62,8 +61,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
public links: Link[] = [];
public drawings: Drawing[] = [];
public symbols: Symbol[] = [];
project: Project;
public project: Project;
public server: Server;
private drawListener: Function;
private ws: Subject<any>;
@ -74,6 +72,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
'draw_link': false,
'text_editing': true
};
protected settings: Settings;
protected drawTools = {
@ -92,11 +91,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
@ViewChild(D3MapComponent) mapChild: D3MapComponent;
private subscriptions: Subscription[] = [];
constructor(
private route: ActivatedRoute,
private serverService: ServerService,
private projectService: ProjectService,
private symbolService: SymbolService,
private nodeService: NodeService,
private linkService: LinkService,
public drawingService: DrawingService,
@ -155,12 +154,6 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
this.subscriptions.push(routeSub);
this.subscriptions.push(
this.symbolService.symbols.subscribe((symbols: Symbol[]) => {
this.symbols = symbols;
})
);
this.subscriptions.push(
this.drawingsDataSource.changes.subscribe((drawings: Drawing[]) => {
this.drawings = drawings;
@ -170,6 +163,10 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
this.subscriptions.push(
this.nodesDataSource.changes.subscribe((nodes: Node[]) => {
nodes.forEach((node: Node) => {
node.symbol_url = `http://${this.server.ip}:${this.server.port}/v2/symbols/${node.symbol}/raw`;
});
this.nodes = nodes;
this.mapChangeDetectorRef.detectChanges();
})
@ -214,12 +211,9 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
onProjectLoad(project: Project) {
this.readonly = this.projectService.isReadOnly(project);
const subscription = this.symbolService
.load(this.server)
const subscription = this.projectService
.nodes(this.server, project.project_id)
.pipe(
mergeMap(() => {
return this.projectService.nodes(this.server, project.project_id);
}),
mergeMap((nodes: Node[]) => {
this.nodesDataSource.set(nodes);
return this.projectService.links(this.server, project.project_id);

View File

@ -7,3 +7,5 @@
<button mat-button (click)="accept(discoveredServer)">YES</button>
</mat-card-actions>
</mat-card>
<mat-divider *ngIf="discoveredServer"></mat-divider>

View File

@ -1,5 +1,5 @@
import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
import { MatCardModule } from "@angular/material";
import { MatCardModule, MatDividerModule } from "@angular/material";
import { Observable } from "rxjs/Rx";
@ -23,7 +23,7 @@ describe('ServerDiscoveryComponent', () => {
mockedServerService = new MockedServerService();
mockedVersionService = new MockedVersionService();
TestBed.configureTestingModule({
imports: [ MatCardModule ],
imports: [ MatCardModule, MatDividerModule ],
providers: [
{ provide: VersionService, useFactory: () => mockedVersionService },
{ provide: ServerService, useFactory: () => mockedServerService },

View File

@ -5,8 +5,6 @@
<div class="default-content">
<app-server-discovery></app-server-discovery>
<mat-divider></mat-divider>
<div class="example-container mat-elevation-z8">
<mat-table #table [dataSource]="dataSource">

View File

@ -1,8 +1,8 @@
import { Component, Inject, OnInit, Injectable } from '@angular/core';
import { Component, Inject, OnInit } from '@angular/core';
import { DataSource } from "@angular/cdk/collections";
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Observable, BehaviorSubject, merge } from "rxjs";
import { Observable, merge } from "rxjs";
import { map } from "rxjs/operators";
import { Server } from "../../models/server";

View File

@ -1,3 +1,4 @@
import 'hammerjs';
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

View File

@ -1,5 +1,5 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'hammerjs';
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {

View File

@ -11,14 +11,10 @@
"check-space"
],
"curly": true,
"deprecation": {
"severity": "warn"
},
"eofline": true,
"forin": true,
"import-blacklist": [
true,
"rxjs/Rx"
true
],
"import-spacing": true,
"indent": [
@ -65,12 +61,11 @@
],
"no-misused-new": true,
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-string-throw": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-trailing-whitespace": false,
"no-unnecessary-initializer": true,
"no-unused-expression": true,
"no-use-before-declare": true,
@ -85,7 +80,7 @@
],
"prefer-const": true,
"quotemark": [
true,
false,
"single"
],
"radix": true,
@ -107,6 +102,7 @@
"variable-declaration": "nospace"
}
],
"typeof-compare": true,
"unified-signatures": true,
"variable-name": false,
"whitespace": [
@ -117,7 +113,18 @@
"check-separator",
"check-type"
],
"no-output-on-prefix": true,
"directive-selector": [
true,
"attribute",
"app",
"camelCase"
],
"component-selector": [
true,
"element",
"app",
"kebab-case"
],
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"use-host-property-decorator": true,
@ -126,6 +133,13 @@
"use-life-cycle-interface": true,
"use-pipe-transform-interface": 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
},
"extends": [
"tslint:latest",
"tslint-config-prettier"
]
}

2422
yarn.lock

File diff suppressed because it is too large Load Diff