mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-24 07:06:38 +00:00
Merge branch 'master' into removing-console-errors
This commit is contained in:
commit
b4cb013090
@ -1,6 +1,8 @@
|
|||||||
import { TextElement } from '../models/drawings/text-element';
|
import { TextElement } from '../models/drawings/text-element';
|
||||||
import { MapDrawing } from '../models/map/map-drawing';
|
import { MapDrawing } from '../models/map/map-drawing';
|
||||||
import { MapLink } from '../models/map/map-link';
|
import { MapLink } from '../models/map/map-link';
|
||||||
|
import { MapLinkNode } from '../models/map/map-link-node';
|
||||||
|
import { MapLabel } from '../models/map/map-label';
|
||||||
|
|
||||||
export class DataEventSource<T> {
|
export class DataEventSource<T> {
|
||||||
constructor(public datum: T, public dx: number, public dy: number) {}
|
constructor(public datum: T, public dx: number, public dy: number) {}
|
||||||
@ -35,3 +37,11 @@ export class DrawingContextMenu {
|
|||||||
export class LinkContextMenu {
|
export class LinkContextMenu {
|
||||||
constructor(public event: any, public link: MapLink) {}
|
constructor(public event: any, public link: MapLink) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class InterfaceLabelContextMenu {
|
||||||
|
constructor(public event: any, public interfaceLabel: MapLinkNode) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LabelContextMenu {
|
||||||
|
constructor(public event: any, public label: MapLabel) {}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
import { SVGSelection } from '../models/types';
|
import { SVGSelection } from '../models/types';
|
||||||
import { CssFixer } from '../helpers/css-fixer';
|
import { CssFixer } from '../helpers/css-fixer';
|
||||||
@ -10,9 +10,11 @@ import { MapLinkNode } from '../models/map/map-link-node';
|
|||||||
import { MapNode } from '../models/map/map-node';
|
import { MapNode } from '../models/map/map-node';
|
||||||
import { Draggable } from '../events/draggable';
|
import { Draggable } from '../events/draggable';
|
||||||
import { MapSettingsManager } from '../managers/map-settings-manager';
|
import { MapSettingsManager } from '../managers/map-settings-manager';
|
||||||
|
import { InterfaceLabelContextMenu } from '../events/event-source';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class InterfaceLabelWidget {
|
export class InterfaceLabelWidget {
|
||||||
|
public onContextMenu = new EventEmitter<InterfaceLabelContextMenu>();
|
||||||
public draggable = new Draggable<SVGGElement, MapLinkNode>();
|
public draggable = new Draggable<SVGGElement, MapLinkNode>();
|
||||||
|
|
||||||
static SURROUNDING_TEXT_BORDER = 5;
|
static SURROUNDING_TEXT_BORDER = 5;
|
||||||
@ -30,6 +32,8 @@ export class InterfaceLabelWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw(selection: SVGSelection) {
|
draw(selection: SVGSelection) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
const link_node_position = selection
|
const link_node_position = selection
|
||||||
.selectAll<SVGGElement, MapLinkNode>('g.link_node_position')
|
.selectAll<SVGGElement, MapLinkNode>('g.link_node_position')
|
||||||
.data((link: MapLink) => [[link.source, link.nodes[0]], [link.target, link.nodes[1]]]);
|
.data((link: MapLink) => [[link.source, link.nodes[0]], [link.target, link.nodes[1]]]);
|
||||||
@ -68,7 +72,12 @@ export class InterfaceLabelWidget {
|
|||||||
.attr('class', 'interface_label noselect')
|
.attr('class', 'interface_label noselect')
|
||||||
.attr('interface_label_id', (i: MapLinkNode) => `${i.id}`);
|
.attr('interface_label_id', (i: MapLinkNode) => `${i.id}`);
|
||||||
|
|
||||||
const merge = labels.merge(enter);
|
const merge = labels
|
||||||
|
.merge(enter)
|
||||||
|
.on('contextmenu', (n: MapLinkNode, i: number) => {
|
||||||
|
event.preventDefault();
|
||||||
|
self.onContextMenu.emit(new InterfaceLabelContextMenu(event, n));
|
||||||
|
});
|
||||||
|
|
||||||
// update label
|
// update label
|
||||||
merge
|
merge
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
import { Widget } from './widget';
|
import { Widget } from './widget';
|
||||||
import { SVGSelection } from '../models/types';
|
import { SVGSelection } from '../models/types';
|
||||||
@ -10,9 +10,11 @@ import { SelectionManager } from '../managers/selection-manager';
|
|||||||
import { Draggable } from '../events/draggable';
|
import { Draggable } from '../events/draggable';
|
||||||
import { MapLabel } from '../models/map/map-label';
|
import { MapLabel } from '../models/map/map-label';
|
||||||
import { MapSettingsManager } from '../managers/map-settings-manager';
|
import { MapSettingsManager } from '../managers/map-settings-manager';
|
||||||
|
import { LabelContextMenu } from '../events/event-source';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LabelWidget implements Widget {
|
export class LabelWidget implements Widget {
|
||||||
|
public onContextMenu = new EventEmitter<LabelContextMenu>();
|
||||||
public draggable = new Draggable<SVGGElement, MapLabel>();
|
public draggable = new Draggable<SVGGElement, MapLabel>();
|
||||||
|
|
||||||
static NODE_LABEL_MARGIN = 3;
|
static NODE_LABEL_MARGIN = 3;
|
||||||
@ -29,6 +31,7 @@ export class LabelWidget implements Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
|
const self = this;
|
||||||
const label_view = view.selectAll<SVGGElement, MapLabel>('g.label_container').data((node: MapNode) => {
|
const label_view = view.selectAll<SVGGElement, MapLabel>('g.label_container').data((node: MapNode) => {
|
||||||
return [node.label];
|
return [node.label];
|
||||||
});
|
});
|
||||||
@ -39,7 +42,12 @@ export class LabelWidget implements Widget {
|
|||||||
.attr('class', 'label_container')
|
.attr('class', 'label_container')
|
||||||
.attr('label_id', (label: MapLabel) => label.id);
|
.attr('label_id', (label: MapLabel) => label.id);
|
||||||
|
|
||||||
const merge = label_view.merge(label_enter);
|
const merge = label_view
|
||||||
|
.merge(label_enter)
|
||||||
|
.on('contextmenu', (n: MapLabel, i: number) => {
|
||||||
|
event.preventDefault();
|
||||||
|
self.onContextMenu.emit(new LabelContextMenu(event, n));
|
||||||
|
});
|
||||||
|
|
||||||
this.drawLabel(merge);
|
this.drawLabel(merge);
|
||||||
|
|
||||||
@ -63,7 +71,8 @@ export class LabelWidget implements Widget {
|
|||||||
|
|
||||||
label_body_enter.append<SVGRectElement>('rect').attr('class', 'label_selection');
|
label_body_enter.append<SVGRectElement>('rect').attr('class', 'label_selection');
|
||||||
|
|
||||||
const label_body_merge = label_body.merge(label_body_enter);
|
const label_body_merge = label_body
|
||||||
|
.merge(label_body_enter);
|
||||||
|
|
||||||
label_body_merge
|
label_body_merge
|
||||||
.select<SVGTextElement>('text.label')
|
.select<SVGTextElement>('text.label')
|
||||||
|
@ -38,10 +38,6 @@ export class NodeWidget implements Widget {
|
|||||||
const node_body_merge = node_body
|
const node_body_merge = node_body
|
||||||
.merge(node_body_enter)
|
.merge(node_body_enter)
|
||||||
.classed('selected', (n: MapNode) => this.selectionManager.isSelected(n))
|
.classed('selected', (n: MapNode) => this.selectionManager.isSelected(n))
|
||||||
.on('contextmenu', function(n: MapNode, i: number) {
|
|
||||||
event.preventDefault();
|
|
||||||
self.onContextMenu.emit(new NodeContextMenu(event, n));
|
|
||||||
})
|
|
||||||
.on('click', (node: MapNode) => {
|
.on('click', (node: MapNode) => {
|
||||||
this.nodesEventSource.clicked.emit(new ClickedDataEvent<MapNode>(node, event.pageX, event.pageY));
|
this.nodesEventSource.clicked.emit(new ClickedDataEvent<MapNode>(node, event.pageX, event.pageY));
|
||||||
});
|
});
|
||||||
@ -49,6 +45,10 @@ export class NodeWidget implements Widget {
|
|||||||
// update image of node
|
// update image of node
|
||||||
node_body_merge
|
node_body_merge
|
||||||
.select<SVGImageElement>('image')
|
.select<SVGImageElement>('image')
|
||||||
|
.on('contextmenu', function(n: MapNode, i: number) {
|
||||||
|
event.preventDefault();
|
||||||
|
self.onContextMenu.emit(new NodeContextMenu(event, n));
|
||||||
|
})
|
||||||
.attr('xnode:href', (n: MapNode) => n.symbolUrl)
|
.attr('xnode:href', (n: MapNode) => n.symbolUrl)
|
||||||
.attr('width', (n: MapNode) => n.width)
|
.attr('width', (n: MapNode) => n.width)
|
||||||
.attr('height', (n: MapNode) => n.height)
|
.attr('height', (n: MapNode) => n.height)
|
||||||
|
@ -4,6 +4,10 @@ import { Project } from '../../../../../models/project';
|
|||||||
import { Drawing } from '../../../../../cartography/models/drawing';
|
import { Drawing } from '../../../../../cartography/models/drawing';
|
||||||
import { MatDialog } from '@angular/material';
|
import { MatDialog } from '@angular/material';
|
||||||
import { TextEditorDialogComponent } from '../../../drawings-editors/text-editor/text-editor.component';
|
import { TextEditorDialogComponent } from '../../../drawings-editors/text-editor/text-editor.component';
|
||||||
|
import { Label } from '../../../../../cartography/models/label';
|
||||||
|
import { Node } from '../../../../../cartography/models/node';
|
||||||
|
import { Link } from '../../../../../models/link';
|
||||||
|
import { LinkNode } from '../../../../../models/link-node';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-edit-text-action',
|
selector: 'app-edit-text-action',
|
||||||
@ -13,6 +17,10 @@ export class EditTextActionComponent implements OnInit {
|
|||||||
@Input() server: Server;
|
@Input() server: Server;
|
||||||
@Input() project: Project;
|
@Input() project: Project;
|
||||||
@Input() drawing: Drawing;
|
@Input() drawing: Drawing;
|
||||||
|
@Input() node: Node;
|
||||||
|
@Input() label: Label;
|
||||||
|
@Input() link: Link;
|
||||||
|
@Input() linkNode: LinkNode;
|
||||||
|
|
||||||
constructor(private dialog: MatDialog) {}
|
constructor(private dialog: MatDialog) {}
|
||||||
|
|
||||||
@ -27,5 +35,9 @@ export class EditTextActionComponent implements OnInit {
|
|||||||
instance.server = this.server;
|
instance.server = this.server;
|
||||||
instance.project = this.project;
|
instance.project = this.project;
|
||||||
instance.drawing = this.drawing;
|
instance.drawing = this.drawing;
|
||||||
|
instance.node = this.node;
|
||||||
|
instance.label = this.label;
|
||||||
|
instance.link = this.link;
|
||||||
|
instance.linkNode = this.linkNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<div class="context-menu" [style.left]="leftPosition" [style.top]="topPosition">
|
<div class="context-menu" [style.left]="leftPosition" [style.top]="topPosition">
|
||||||
<span [matMenuTriggerFor]="contextMenu"></span>
|
<span [matMenuTriggerFor]="contextMenu"></span>
|
||||||
<mat-menu #contextMenu="matMenu" class="context-menu-items">
|
<mat-menu #contextMenu="matMenu" class="context-menu-items">
|
||||||
<app-start-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-start-node-action>
|
<app-start-node-action *ngIf="nodes.length && labels.length===0" [server]="server" [nodes]="nodes"></app-start-node-action>
|
||||||
<app-stop-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-stop-node-action>
|
<app-stop-node-action *ngIf="nodes.length && labels.length===0" [server]="server" [nodes]="nodes"></app-stop-node-action>
|
||||||
<app-console-device-action
|
<app-console-device-action
|
||||||
*ngIf="!projectService.isReadOnly(project) && nodes.length && isElectronApp"
|
*ngIf="!projectService.isReadOnly(project) && nodes.length && isElectronApp"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
@ -14,25 +14,32 @@
|
|||||||
[nodes]="nodes"
|
[nodes]="nodes"
|
||||||
[drawings]="drawings"
|
[drawings]="drawings"
|
||||||
></app-duplicate-action>
|
></app-duplicate-action>
|
||||||
<app-edit-style-action *ngIf="drawings.length===1 && !hasTextCapabilities"
|
<app-edit-style-action *ngIf="!projectService.isReadOnly(project) && drawings.length===1 && !hasTextCapabilities"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[project]="project"
|
[project]="project"
|
||||||
[drawing]="drawings[0]"
|
[drawing]="drawings[0]"
|
||||||
></app-edit-style-action>
|
></app-edit-style-action>
|
||||||
<app-edit-text-action
|
<app-edit-text-action
|
||||||
*ngIf="drawings.length===1 && hasTextCapabilities"
|
*ngIf="!projectService.isReadOnly(project) &&
|
||||||
|
(drawings.length===1 && hasTextCapabilities && labels.length===0 && linkNodes.length===0 ||
|
||||||
|
labels.length===1 && linkNodes.length===0 && drawings.length===0 ||
|
||||||
|
linkNodes.length===1 && labels.length===0 && drawings.length===0)"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[project]="project"
|
[project]="project"
|
||||||
[drawing]="drawings[0]"
|
[drawing]="drawings[0]"
|
||||||
|
[node]="nodes[0]"
|
||||||
|
[label]="labels[0]"
|
||||||
|
[link]="links[0]"
|
||||||
|
[linkNode]="linkNodes[0]"
|
||||||
></app-edit-text-action>
|
></app-edit-text-action>
|
||||||
<app-move-layer-up-action
|
<app-move-layer-up-action
|
||||||
*ngIf="!projectService.isReadOnly(project) && (drawings.length || nodes.length)"
|
*ngIf="!projectService.isReadOnly(project) && (drawings.length || nodes.length) && labels.length===0"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[nodes]="nodes"
|
[nodes]="nodes"
|
||||||
[drawings]="drawings"
|
[drawings]="drawings"
|
||||||
></app-move-layer-up-action>
|
></app-move-layer-up-action>
|
||||||
<app-move-layer-down-action
|
<app-move-layer-down-action
|
||||||
*ngIf="!projectService.isReadOnly(project) && (drawings.length || nodes.length)"
|
*ngIf="!projectService.isReadOnly(project) && (drawings.length || nodes.length) && labels.length===0"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[nodes]="nodes"
|
[nodes]="nodes"
|
||||||
[drawings]="drawings"
|
[drawings]="drawings"
|
||||||
@ -45,28 +52,28 @@
|
|||||||
></app-start-capture-action>
|
></app-start-capture-action>
|
||||||
<app-stop-capture-action
|
<app-stop-capture-action
|
||||||
*ngIf="!projectService.isReadOnly(project) && isBundledServer
|
*ngIf="!projectService.isReadOnly(project) && isBundledServer
|
||||||
&& drawings.length===0 && nodes.length===0 && links.length===1"
|
&& drawings.length===0 && nodes.length===0 && links.length===1 && linkNodes.length === 0"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[link]="links[0]"
|
[link]="links[0]"
|
||||||
></app-stop-capture-action>
|
></app-stop-capture-action>
|
||||||
<app-packet-filters-action
|
<app-packet-filters-action
|
||||||
*ngIf="!projectService.isReadOnly(project) && drawings.length===0 && nodes.length===0 && links.length===1"
|
*ngIf="!projectService.isReadOnly(project) && drawings.length===0 && nodes.length===0 && links.length===1 && linkNodes.length === 0"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[project]="project"
|
[project]="project"
|
||||||
[link]="links[0]"
|
[link]="links[0]"
|
||||||
></app-packet-filters-action>
|
></app-packet-filters-action>
|
||||||
<app-resume-link-action
|
<app-resume-link-action
|
||||||
*ngIf="!projectService.isReadOnly(project) && drawings.length===0 && nodes.length===0 && links.length===1"
|
*ngIf="!projectService.isReadOnly(project) && drawings.length===0 && nodes.length===0 && links.length===1 && linkNodes.length === 0"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[link]="links[0]"
|
[link]="links[0]"
|
||||||
></app-resume-link-action>
|
></app-resume-link-action>
|
||||||
<app-suspend-link-action
|
<app-suspend-link-action
|
||||||
*ngIf="!projectService.isReadOnly(project) && drawings.length===0 && nodes.length===0 && links.length===1"
|
*ngIf="!projectService.isReadOnly(project) && drawings.length===0 && nodes.length===0 && links.length===1 && linkNodes.length === 0"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[link]="links[0]"
|
[link]="links[0]"
|
||||||
></app-suspend-link-action>
|
></app-suspend-link-action>
|
||||||
<app-delete-action
|
<app-delete-action
|
||||||
*ngIf="!projectService.isReadOnly(project)"
|
*ngIf="!projectService.isReadOnly(project) && (drawings.length>0 || nodes.length>0 || links.length>0) && linkNodes.length === 0"
|
||||||
[server]="server"
|
[server]="server"
|
||||||
[nodes]="nodes"
|
[nodes]="nodes"
|
||||||
[drawings]="drawings"
|
[drawings]="drawings"
|
||||||
|
@ -10,6 +10,7 @@ import { TextElement } from '../../../cartography/models/drawings/text-element';
|
|||||||
import { Label } from '../../../cartography/models/label';
|
import { Label } from '../../../cartography/models/label';
|
||||||
import { Link } from '../../../models/link';
|
import { Link } from '../../../models/link';
|
||||||
import { ElectronService } from 'ngx-electron';
|
import { ElectronService } from 'ngx-electron';
|
||||||
|
import { LinkNode } from '../../../models/link-node';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -30,6 +31,7 @@ export class ContextMenuComponent implements OnInit {
|
|||||||
nodes: Node[] = [];
|
nodes: Node[] = [];
|
||||||
labels: Label[] = [];
|
labels: Label[] = [];
|
||||||
links: Link[] = [];
|
links: Link[] = [];
|
||||||
|
linkNodes: LinkNode[] = [];
|
||||||
|
|
||||||
hasTextCapabilities = false;
|
hasTextCapabilities = false;
|
||||||
isElectronApp = false;
|
isElectronApp = false;
|
||||||
@ -74,10 +76,21 @@ export class ContextMenuComponent implements OnInit {
|
|||||||
this.contextMenu.openMenu();
|
this.contextMenu.openMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
public openMenuForLabel(label: Label, top: number, left: number) {
|
public openMenuForLabel(label: Label, node: Node, top: number, left: number) {
|
||||||
this.resetCapabilities();
|
this.resetCapabilities();
|
||||||
|
|
||||||
this.labels = [label];
|
this.labels = [label];
|
||||||
|
this.nodes = [node];
|
||||||
|
this.setPosition(top, left);
|
||||||
|
|
||||||
|
this.contextMenu.openMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
public openMenuForInterfaceLabel(linkNode: LinkNode, link: Link, top: number, left: number) {
|
||||||
|
this.resetCapabilities();
|
||||||
|
|
||||||
|
this.linkNodes = [linkNode];
|
||||||
|
this.links = [link];
|
||||||
this.setPosition(top, left);
|
this.setPosition(top, left);
|
||||||
|
|
||||||
this.contextMenu.openMenu();
|
this.contextMenu.openMenu();
|
||||||
@ -99,6 +112,8 @@ export class ContextMenuComponent implements OnInit {
|
|||||||
this.drawings = [];
|
this.drawings = [];
|
||||||
this.nodes = [];
|
this.nodes = [];
|
||||||
this.labels = [];
|
this.labels = [];
|
||||||
|
this.linkNodes = [];
|
||||||
|
this.links = [];
|
||||||
this.hasTextCapabilities = false;
|
this.hasTextCapabilities = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<textarea #textArea id="textArea" class="text" [(ngModel)]="element.text"> </textarea>
|
<textarea #textArea id="textArea" class="text" [(ngModel)]="element.text" [readonly]="!isTextEditable"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
|
@ -8,6 +8,14 @@ import { MapDrawingToSvgConverter } from '../../../../cartography/converters/map
|
|||||||
import { DrawingService } from '../../../../services/drawing.service';
|
import { DrawingService } from '../../../../services/drawing.service';
|
||||||
import { DrawingsDataSource } from '../../../../cartography/datasources/drawings-datasource';
|
import { DrawingsDataSource } from '../../../../cartography/datasources/drawings-datasource';
|
||||||
import { TextElement } from '../../../../cartography/models/drawings/text-element';
|
import { TextElement } from '../../../../cartography/models/drawings/text-element';
|
||||||
|
import { Label } from '../../../../cartography/models/label';
|
||||||
|
import { NodeService } from '../../../../services/node.service';
|
||||||
|
import { Node } from '../../../../cartography/models/node';
|
||||||
|
import { NodesDataSource } from '../../../../cartography/datasources/nodes-datasource';
|
||||||
|
import { Link } from '../../../../models/link';
|
||||||
|
import { LinkNode } from '../../../../models/link-node';
|
||||||
|
import { LinkService } from '../../../../services/link.service';
|
||||||
|
import { LinksDataSource } from '../../../../cartography/datasources/links-datasource';
|
||||||
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
|
||||||
import { ToasterService } from '../../../../services/toaster.service';
|
import { ToasterService } from '../../../../services/toaster.service';
|
||||||
import { RotationValidator } from '../../../../validators/rotation-validator';
|
import { RotationValidator } from '../../../../validators/rotation-validator';
|
||||||
@ -23,7 +31,13 @@ export class TextEditorDialogComponent implements OnInit {
|
|||||||
server: Server;
|
server: Server;
|
||||||
project: Project;
|
project: Project;
|
||||||
drawing: Drawing;
|
drawing: Drawing;
|
||||||
|
node: Node;
|
||||||
|
label: Label;
|
||||||
|
link: Link;
|
||||||
|
linkNode: LinkNode;
|
||||||
element: TextElement;
|
element: TextElement;
|
||||||
|
rotation: string;
|
||||||
|
isTextEditable: boolean;
|
||||||
formGroup: FormGroup;
|
formGroup: FormGroup;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -33,31 +47,94 @@ export class TextEditorDialogComponent implements OnInit {
|
|||||||
private drawingService: DrawingService,
|
private drawingService: DrawingService,
|
||||||
private drawingsDataSource: DrawingsDataSource,
|
private drawingsDataSource: DrawingsDataSource,
|
||||||
private renderer: Renderer2,
|
private renderer: Renderer2,
|
||||||
|
private nodeService: NodeService,
|
||||||
|
private nodesDataSource: NodesDataSource,
|
||||||
|
private linkService: LinkService,
|
||||||
|
private linksDataSource: LinksDataSource,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private toasterService: ToasterService,
|
private toasterService: ToasterService,
|
||||||
private rotationValidator: RotationValidator
|
private rotationValidator: RotationValidator
|
||||||
) {
|
) {}
|
||||||
this.formGroup = this.formBuilder.group({
|
|
||||||
rotation: new FormControl('', [Validators.required, rotationValidator.get])
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.formGroup.controls['rotation'].setValue(this.drawing.rotation);
|
this.formGroup = this.formBuilder.group({
|
||||||
|
rotation: new FormControl('', [Validators.required, this.rotationValidator.get])
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.label && this.node) {
|
||||||
|
this.isTextEditable = false;
|
||||||
|
this.rotation = this.label.rotation.toString();
|
||||||
|
this.element = this.getTextElementFromLabel();
|
||||||
|
} else if (this.linkNode && this.link) {
|
||||||
|
this.isTextEditable = true;
|
||||||
|
this.label = this.link.nodes.find(n => n.node_id === this.linkNode.node_id).label;
|
||||||
|
this.rotation = this.label.rotation.toString();
|
||||||
|
this.element = this.getTextElementFromLabel();
|
||||||
|
} else if (this.drawing) {
|
||||||
|
this.isTextEditable = true;
|
||||||
|
this.rotation = this.drawing.rotation.toString();
|
||||||
this.element = this.drawing.element as TextElement;
|
this.element = this.drawing.element as TextElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.formGroup.controls['rotation'].setValue(this.rotation);
|
||||||
this.renderer.setStyle(this.textArea.nativeElement, 'color', this.element.fill);
|
this.renderer.setStyle(this.textArea.nativeElement, 'color', this.element.fill);
|
||||||
this.renderer.setStyle(this.textArea.nativeElement, 'font-family', this.element.font_family);
|
this.renderer.setStyle(this.textArea.nativeElement, 'font-family', this.element.font_family);
|
||||||
this.renderer.setStyle(this.textArea.nativeElement, 'font-size', `${this.element.font_size}pt`);
|
this.renderer.setStyle(this.textArea.nativeElement, 'font-size', `${this.element.font_size}pt`);
|
||||||
this.renderer.setStyle(this.textArea.nativeElement, 'font-weight', this.element.font_weight);
|
this.renderer.setStyle(this.textArea.nativeElement, 'font-weight', this.element.font_weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTextElementFromLabel(): TextElement{
|
||||||
|
var styleProperties: StyleProperty[] = [];
|
||||||
|
var textElement = new TextElement();
|
||||||
|
|
||||||
|
for (var property of this.label.style.split(";")){
|
||||||
|
styleProperties.push({
|
||||||
|
property: property.split(": ")[0],
|
||||||
|
value: property.split(": ")[1]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
textElement.text = this.label.text ? this.label.text : '';
|
||||||
|
textElement.font_family = styleProperties.find(p => p.property === 'font-family') ? styleProperties.find(p => p.property === 'font-family').value : 'TypeWriter';
|
||||||
|
textElement.font_size = styleProperties.find(p => p.property === 'font-size') ? +styleProperties.find(p => p.property === 'font-size').value : 10.0;
|
||||||
|
textElement.font_weight = styleProperties.find(p => p.property === 'font-weight') ? styleProperties.find(p => p.property === 'font-weight').value : 'normal';
|
||||||
|
textElement.fill = styleProperties.find(p => p.property === 'fill') ? styleProperties.find(p => p.property === 'fill').value : '#000000';
|
||||||
|
textElement.fill_opacity = styleProperties.find(p => p.property === 'fill-opacity') ? +styleProperties.find(p => p.property === 'fill-opacity').value : 1.0;
|
||||||
|
|
||||||
|
return textElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStyleFromTextElement(): string{
|
||||||
|
return `font-family: ${this.element.font_family};font-size: ${this.element.font_size};font-weight: ${this.element.font_weight};fill: ${this.element.fill};fill-opacity: ${this.element.fill_opacity};`;
|
||||||
|
}
|
||||||
|
|
||||||
onNoClick() {
|
onNoClick() {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
onYesClick() {
|
onYesClick() {
|
||||||
if (this.formGroup.valid) {
|
if (this.formGroup.valid) {
|
||||||
this.drawing.rotation = this.formGroup.get('rotation').value;
|
this.rotation = this.formGroup.get('rotation').value;
|
||||||
|
|
||||||
|
if (this.label && this.node) {
|
||||||
|
this.node.label.style = this.getStyleFromTextElement();
|
||||||
|
this.node.label.rotation = +this.rotation;
|
||||||
|
|
||||||
|
this.nodeService.updateLabel(this.server, this.node, this.node.label).subscribe((node: Node) => {
|
||||||
|
this.nodesDataSource.update(node);
|
||||||
|
this.dialogRef.close();
|
||||||
|
});
|
||||||
|
} else if (this.linkNode && this.link) {
|
||||||
|
this.label.style = this.getStyleFromTextElement();
|
||||||
|
this.label.rotation = +this.rotation;
|
||||||
|
this.label.text = this.element.text;
|
||||||
|
|
||||||
|
this.linkService.updateLink(this.server, this.link).subscribe((link: Link) => {
|
||||||
|
this.linksDataSource.update(link);
|
||||||
|
this.dialogRef.close();
|
||||||
|
});
|
||||||
|
} else if (this.drawing) {
|
||||||
|
this.drawing.rotation = +this.rotation;
|
||||||
this.drawing.element = this.element;
|
this.drawing.element = this.element;
|
||||||
|
|
||||||
let mapDrawing = this.drawingToMapDrawingConverter.convert(this.drawing);
|
let mapDrawing = this.drawingToMapDrawingConverter.convert(this.drawing);
|
||||||
@ -69,6 +146,7 @@ export class TextEditorDialogComponent implements OnInit {
|
|||||||
this.drawingsDataSource.update(serverDrawing);
|
this.drawingsDataSource.update(serverDrawing);
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
});
|
});
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
this.toasterService.error(`Entered data is incorrect`);
|
this.toasterService.error(`Entered data is incorrect`);
|
||||||
}
|
}
|
||||||
@ -78,3 +156,8 @@ export class TextEditorDialogComponent implements OnInit {
|
|||||||
this.renderer.setStyle(this.textArea.nativeElement, 'color', changedColor);
|
this.renderer.setStyle(this.textArea.nativeElement, 'color', changedColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StyleProperty {
|
||||||
|
property: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
@ -45,6 +45,9 @@ import { CapturingSettings } from '../../models/capturingSettings';
|
|||||||
import { LinkWidget } from '../../cartography/widgets/link';
|
import { LinkWidget } from '../../cartography/widgets/link';
|
||||||
import { MapScaleService } from '../../services/mapScale.service';
|
import { MapScaleService } from '../../services/mapScale.service';
|
||||||
import { NodeCreatedLabelStylesFixer } from './helpers/node-created-label-styles-fixer';
|
import { NodeCreatedLabelStylesFixer } from './helpers/node-created-label-styles-fixer';
|
||||||
|
import { LabelWidget } from '../../cartography/widgets/label';
|
||||||
|
import { InterfaceLabelWidget } from '../../cartography/widgets/interface-label';
|
||||||
|
import { MapLinkNodeToLinkNodeConverter } from '../../cartography/converters/map/map-link-node-to-link-node-converter';
|
||||||
import { MapSettingService } from '../../services/mapsettings.service';
|
import { MapSettingService } from '../../services/mapsettings.service';
|
||||||
import { ProjectMapMenuComponent } from './project-map-menu/project-map-menu.component';
|
import { ProjectMapMenuComponent } from './project-map-menu/project-map-menu.component';
|
||||||
|
|
||||||
@ -217,10 +220,13 @@ describe('ProjectMapComponent', () => {
|
|||||||
{ provide: NodeWidget },
|
{ provide: NodeWidget },
|
||||||
{ provide: LinkWidget },
|
{ provide: LinkWidget },
|
||||||
{ provide: DrawingsWidget },
|
{ provide: DrawingsWidget },
|
||||||
|
{ provide: LabelWidget },
|
||||||
|
{ provide: InterfaceLabelWidget },
|
||||||
{ provide: MapNodeToNodeConverter },
|
{ provide: MapNodeToNodeConverter },
|
||||||
{ provide: MapDrawingToDrawingConverter },
|
{ provide: MapDrawingToDrawingConverter },
|
||||||
{ provide: MapLabelToLabelConverter },
|
{ provide: MapLabelToLabelConverter },
|
||||||
{ provide: MapLinkToLinkConverter },
|
{ provide: MapLinkToLinkConverter },
|
||||||
|
{ provide: MapLinkNodeToLinkNodeConverter },
|
||||||
{ provide: NodesDataSource, useValue: nodesDataSource },
|
{ provide: NodesDataSource, useValue: nodesDataSource },
|
||||||
{ provide: LinksDataSource, useValue: linksDataSource },
|
{ provide: LinksDataSource, useValue: linksDataSource },
|
||||||
{ provide: DrawingsDataSource, useValue: drawingsDataSource },
|
{ provide: DrawingsDataSource, useValue: drawingsDataSource },
|
||||||
|
@ -30,7 +30,7 @@ import { MapNodeToNodeConverter } from '../../cartography/converters/map/map-nod
|
|||||||
import { SettingsService, Settings } from '../../services/settings.service';
|
import { SettingsService, Settings } from '../../services/settings.service';
|
||||||
import { D3MapComponent } from '../../cartography/components/d3-map/d3-map.component';
|
import { D3MapComponent } from '../../cartography/components/d3-map/d3-map.component';
|
||||||
import { ToolsService } from '../../services/tools.service';
|
import { ToolsService } from '../../services/tools.service';
|
||||||
import { DrawingContextMenu, LinkContextMenu } from '../../cartography/events/event-source';
|
import { DrawingContextMenu, LinkContextMenu, LabelContextMenu, InterfaceLabelContextMenu } from '../../cartography/events/event-source';
|
||||||
import { MapDrawingToDrawingConverter } from '../../cartography/converters/map/map-drawing-to-drawing-converter';
|
import { MapDrawingToDrawingConverter } from '../../cartography/converters/map/map-drawing-to-drawing-converter';
|
||||||
import { SelectionManager } from '../../cartography/managers/selection-manager';
|
import { SelectionManager } from '../../cartography/managers/selection-manager';
|
||||||
import { SelectionTool } from '../../cartography/tools/selection-tool';
|
import { SelectionTool } from '../../cartography/tools/selection-tool';
|
||||||
@ -46,6 +46,9 @@ import { MovingEventSource } from '../../cartography/events/moving-event-source'
|
|||||||
import { LinkWidget } from '../../cartography/widgets/link';
|
import { LinkWidget } from '../../cartography/widgets/link';
|
||||||
import { MapScaleService } from '../../services/mapScale.service';
|
import { MapScaleService } from '../../services/mapScale.service';
|
||||||
import { NodeCreatedLabelStylesFixer } from './helpers/node-created-label-styles-fixer';
|
import { NodeCreatedLabelStylesFixer } from './helpers/node-created-label-styles-fixer';
|
||||||
|
import { InterfaceLabelWidget } from '../../cartography/widgets/interface-label';
|
||||||
|
import { LabelWidget } from '../../cartography/widgets/label';
|
||||||
|
import { MapLinkNodeToLinkNodeConverter } from '../../cartography/converters/map/map-link-node-to-link-node-converter';
|
||||||
import { ProjectMapMenuComponent } from './project-map-menu/project-map-menu.component';
|
import { ProjectMapMenuComponent } from './project-map-menu/project-map-menu.component';
|
||||||
|
|
||||||
|
|
||||||
@ -93,10 +96,13 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
private nodeWidget: NodeWidget,
|
private nodeWidget: NodeWidget,
|
||||||
private drawingsWidget: DrawingsWidget,
|
private drawingsWidget: DrawingsWidget,
|
||||||
private linkWidget: LinkWidget,
|
private linkWidget: LinkWidget,
|
||||||
|
private labelWidget: LabelWidget,
|
||||||
|
private interfaceLabelWidget: InterfaceLabelWidget,
|
||||||
private mapNodeToNode: MapNodeToNodeConverter,
|
private mapNodeToNode: MapNodeToNodeConverter,
|
||||||
private mapDrawingToDrawing: MapDrawingToDrawingConverter,
|
private mapDrawingToDrawing: MapDrawingToDrawingConverter,
|
||||||
private mapLabelToLabel: MapLabelToLabelConverter,
|
private mapLabelToLabel: MapLabelToLabelConverter,
|
||||||
private mapLinkToLink: MapLinkToLinkConverter,
|
private mapLinkToLink: MapLinkToLinkConverter,
|
||||||
|
private mapLinkNodeToLinkNode: MapLinkNodeToLinkNodeConverter,
|
||||||
private nodesDataSource: NodesDataSource,
|
private nodesDataSource: NodesDataSource,
|
||||||
private linksDataSource: LinksDataSource,
|
private linksDataSource: LinksDataSource,
|
||||||
private drawingsDataSource: DrawingsDataSource,
|
private drawingsDataSource: DrawingsDataSource,
|
||||||
@ -247,9 +253,21 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
this.contextMenu.openMenuForDrawing(drawing, eventDrawing.event.pageY, eventDrawing.event.pageX);
|
this.contextMenu.openMenuForDrawing(drawing, eventDrawing.event.pageY, eventDrawing.event.pageX);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const onLabelContextMenu = this.labelWidget.onContextMenu.subscribe((eventLabel: LabelContextMenu) => {
|
||||||
|
const label = this.mapLabelToLabel.convert(eventLabel.label);
|
||||||
|
const node = this.nodes.find(n => n.node_id === eventLabel.label.nodeId);
|
||||||
|
this.contextMenu.openMenuForLabel(label, node, eventLabel.event.pageY, eventLabel.event.pageX);
|
||||||
|
});
|
||||||
|
|
||||||
|
const onInterfaceLabelContextMenu = this.interfaceLabelWidget.onContextMenu.subscribe((eventInterfaceLabel: InterfaceLabelContextMenu) => {
|
||||||
|
const linkNode = this.mapLinkNodeToLinkNode.convert(eventInterfaceLabel.interfaceLabel);
|
||||||
|
const link = this.links.find(l => l.link_id === eventInterfaceLabel.interfaceLabel.linkId);
|
||||||
|
this.contextMenu.openMenuForInterfaceLabel(linkNode, link, eventInterfaceLabel.event.pageY, eventInterfaceLabel.event.pageX);
|
||||||
|
});
|
||||||
|
|
||||||
const onContextMenu = this.selectionTool.contextMenuOpened.subscribe((event) => {
|
const onContextMenu = this.selectionTool.contextMenuOpened.subscribe((event) => {
|
||||||
const selectedItems = this.selectionManager.getSelected();
|
const selectedItems = this.selectionManager.getSelected();
|
||||||
if (selectedItems.length === 0 || !(event instanceof MouseEvent)) return;
|
if (selectedItems.length < 2 || !(event instanceof MouseEvent)) return;
|
||||||
|
|
||||||
let drawings: Drawing[] = [];
|
let drawings: Drawing[] = [];
|
||||||
let nodes: Node[] = [];
|
let nodes: Node[] = [];
|
||||||
@ -275,6 +293,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
this.subscriptions.push(onNodeContextMenu);
|
this.subscriptions.push(onNodeContextMenu);
|
||||||
this.subscriptions.push(onDrawingContextMenu);
|
this.subscriptions.push(onDrawingContextMenu);
|
||||||
this.subscriptions.push(onContextMenu);
|
this.subscriptions.push(onContextMenu);
|
||||||
|
this.subscriptions.push(onLabelContextMenu);
|
||||||
|
this.subscriptions.push(onInterfaceLabelContextMenu);
|
||||||
this.mapChangeDetectorRef.detectChanges();
|
this.mapChangeDetectorRef.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user