mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-18 02:39:50 +00:00
commit
2121d29a9e
@ -112,6 +112,7 @@ import { DeleteActionComponent } from './components/project-map/context-menu/act
|
||||
import { DuplicateActionComponent } from './components/project-map/context-menu/actions/duplicate-action/duplicate-action.component';
|
||||
import { EditConfigActionComponent } from './components/project-map/context-menu/actions/edit-config/edit-config-action.component';
|
||||
import { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-action.component';
|
||||
import { EditLinkStyleActionComponent } from './components/project-map/context-menu/actions/edit-link-style-action/edit-link-style-action.component';
|
||||
import { EditTextActionComponent } from './components/project-map/context-menu/actions/edit-text-action/edit-text-action.component';
|
||||
import { ExportConfigActionComponent } from './components/project-map/context-menu/actions/export-config/export-config-action.component';
|
||||
import { HttpConsoleNewTabActionComponent } from './components/project-map/context-menu/actions/http-console-new-tab/http-console-new-tab-action.component';
|
||||
@ -138,6 +139,7 @@ import { ContextMenuComponent } from './components/project-map/context-menu/cont
|
||||
import { ConfigDialogComponent } from './components/project-map/context-menu/dialogs/config-dialog/config-dialog.component';
|
||||
import { DrawLinkToolComponent } from './components/project-map/draw-link-tool/draw-link-tool.component';
|
||||
import { StyleEditorDialogComponent } from './components/project-map/drawings-editors/style-editor/style-editor.component';
|
||||
import { LinkStyleEditorDialogComponent } from './components/project-map/drawings-editors/link-style-editor/link-style-editor.component';
|
||||
import { TextEditorDialogComponent } from './components/project-map/drawings-editors/text-editor/text-editor.component';
|
||||
import { HelpDialogComponent } from './components/project-map/help-dialog/help-dialog.component';
|
||||
import { NodeCreatedLabelStylesFixer } from './components/project-map/helpers/node-created-label-styles-fixer';
|
||||
@ -303,6 +305,7 @@ import { DeleteAllImageFilesDialogComponent } from './components/image-manager/d
|
||||
MoveLayerDownActionComponent,
|
||||
MoveLayerUpActionComponent,
|
||||
EditStyleActionComponent,
|
||||
EditLinkStyleActionComponent,
|
||||
EditTextActionComponent,
|
||||
DeleteActionComponent,
|
||||
DuplicateActionComponent,
|
||||
@ -330,6 +333,7 @@ import { DeleteAllImageFilesDialogComponent } from './components/image-manager/d
|
||||
InterfaceLabelDraggedComponent,
|
||||
InstallSoftwareComponent,
|
||||
StyleEditorDialogComponent,
|
||||
LinkStyleEditorDialogComponent,
|
||||
TextEditorDialogComponent,
|
||||
PacketFiltersDialogComponent,
|
||||
QemuPreferencesComponent,
|
||||
|
@ -5,6 +5,7 @@ import { MatMenuModule } from '@angular/material/menu';
|
||||
import { ANGULAR_MAP_DECLARATIONS } from './angular-map.imports';
|
||||
import { D3MapComponent } from './components/d3-map/d3-map.component';
|
||||
import { DraggableSelectionComponent } from './components/draggable-selection/draggable-selection.component';
|
||||
import { LinkEditingComponent } from './components/link-editing/link-editing.component';
|
||||
import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component';
|
||||
import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.component';
|
||||
import { ExperimentalMapComponent } from './components/experimental-map/experimental-map.component';
|
||||
@ -73,6 +74,7 @@ import { SerialLinkWidget } from './widgets/links/serial-link';
|
||||
SelectionControlComponent,
|
||||
SelectionSelectComponent,
|
||||
DraggableSelectionComponent,
|
||||
LinkEditingComponent,
|
||||
MovingCanvasDirective,
|
||||
ZoomingCanvasDirective,
|
||||
],
|
||||
|
@ -46,3 +46,4 @@
|
||||
<app-selection-select></app-selection-select>
|
||||
<app-text-editor #textEditor [server]="server" [svg]="svg"></app-text-editor>
|
||||
<app-draggable-selection [svg]="svg"></app-draggable-selection>
|
||||
<app-link-editing [svg]="svg"></app-link-editing>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1,31 @@
|
||||
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { select } from 'd3-selection';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { LinksEventSource } from '../../events/links-event-source';
|
||||
import { MapLink } from '../../models/map/map-link';
|
||||
import { LinksWidget } from '../../widgets/links';
|
||||
|
||||
@Component({
|
||||
selector: 'app-link-editing',
|
||||
templateUrl: './link-editing.component.html',
|
||||
styleUrls: ['./link-editing.component.scss'],
|
||||
})
|
||||
export class LinkEditingComponent implements OnInit, OnDestroy {
|
||||
private linkEditedSubscription: Subscription;
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
|
||||
constructor(
|
||||
private linksWidget: LinksWidget,
|
||||
private linksEventSource: LinksEventSource ) {}
|
||||
|
||||
ngOnInit() {
|
||||
const svg = select(this.svg);
|
||||
this.linkEditedSubscription = this.linksEventSource.edited.subscribe((link: MapLink) => {
|
||||
this.linksWidget.redrawLink(svg, link);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.linkEditedSubscription.unsubscribe();
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ export class LinkToMapLinkConverter implements Converter<Link, MapLink> {
|
||||
mapLink.captureFilePath = link.capture_file_path;
|
||||
mapLink.capturing = link.capturing;
|
||||
mapLink.filters = link.filters;
|
||||
mapLink.link_style = link.link_style;
|
||||
mapLink.linkType = link.link_type;
|
||||
mapLink.nodes = link.nodes.map((linkNode) =>
|
||||
this.linkNodeToMapLinkNode.convert(linkNode, { link_id: link.link_id })
|
||||
|
@ -16,6 +16,7 @@ export class MapLinkToLinkConverter implements Converter<MapLink, Link> {
|
||||
link.capturing = mapLink.capturing;
|
||||
link.filters = mapLink.filters;
|
||||
link.link_type = mapLink.linkType;
|
||||
link.link_style = mapLink.link_style;
|
||||
link.nodes = mapLink.nodes.map((mapLinkNode) => this.mapLinkNodeToMapLinkNode.convert(mapLinkNode));
|
||||
link.project_id = mapLink.projectId;
|
||||
link.suspend = mapLink.suspend;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { EventEmitter, Injectable } from '@angular/core';
|
||||
import { MapLink } from '../models/map/map-link';
|
||||
import { MapLinkNode } from '../models/map/map-link-node';
|
||||
import { DraggedDataEvent } from './event-source';
|
||||
import { MapLinkCreated } from './links';
|
||||
@ -6,5 +7,6 @@ import { MapLinkCreated } from './links';
|
||||
@Injectable()
|
||||
export class LinksEventSource {
|
||||
public created = new EventEmitter<MapLinkCreated>();
|
||||
public edited = new EventEmitter<MapLink>();
|
||||
public interfaceDragged = new EventEmitter<DraggedDataEvent<MapLinkNode>>();
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ export class GraphDataManager {
|
||||
|
||||
public setLinks(links: Link[]) {
|
||||
if (links) {
|
||||
console.log("from set links");
|
||||
const mapLinks = links.map((l) => this.linkToMapLink.convert(l));
|
||||
this.mapLinksDataSource.set(mapLinks);
|
||||
|
||||
@ -88,6 +89,7 @@ export class GraphDataManager {
|
||||
private onDataUpdate() {
|
||||
this.layersManager.clear();
|
||||
this.layersManager.setNodes(this.getNodes());
|
||||
console.log(this.getLinks());
|
||||
this.layersManager.setLinks(this.getLinks());
|
||||
this.layersManager.setDrawings(this.getDrawings());
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ export class LayersManager {
|
||||
}
|
||||
|
||||
public setLinks(links: MapLink[]) {
|
||||
console.log('from set links 2');
|
||||
links
|
||||
.filter((link: MapLink) => link.source && link.target)
|
||||
.forEach((link: MapLink) => {
|
||||
|
@ -2,6 +2,7 @@ import { Filter } from '../../../models/filter';
|
||||
import { Indexed } from '../../datasources/map-datasource';
|
||||
import { MapLinkNode } from './map-link-node';
|
||||
import { MapNode } from './map-node';
|
||||
import { LinkStyle } from '../../../models/link-style';
|
||||
|
||||
export class MapLink implements Indexed {
|
||||
id: string;
|
||||
@ -13,6 +14,7 @@ export class MapLink implements Indexed {
|
||||
nodes: MapLinkNode[];
|
||||
projectId: string;
|
||||
suspend: boolean;
|
||||
link_style?: LinkStyle;
|
||||
|
||||
distance: number; // this is not from server
|
||||
length: number; // this is not from server
|
||||
|
@ -7,6 +7,7 @@ export class MapChangeDetectorRef {
|
||||
public hasBeenDrawn = false;
|
||||
|
||||
public detectChanges() {
|
||||
console.log('from map change detector');
|
||||
this.changesDetected.emit(true);
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ export class LinkWidget implements Widget {
|
||||
|
||||
const link_body_enter = link_body.enter().append<SVGGElement>('g').attr('class', 'link_body');
|
||||
|
||||
const link_body_merge = link_body.merge(link_body_enter).attr('transform', (link) => {
|
||||
const link_body_merge = link_body.merge(link_body_enter)
|
||||
.attr('transform', (link) => {
|
||||
const translation = this.multiLinkCalculatorHelper.linkTranslation(link.distance, link.source, link.target);
|
||||
return `translate (${translation.dx}, ${translation.dy})`;
|
||||
});
|
||||
|
@ -11,6 +11,7 @@ export class LinksWidget implements Widget {
|
||||
constructor(private multiLinkCalculatorHelper: MultiLinkCalculatorHelper, private linkWidget: LinkWidget) {}
|
||||
|
||||
public redrawLink(view: SVGSelection, link: MapLink) {
|
||||
console.log('redraw called');
|
||||
this.linkWidget.draw(this.selectLink(view, link));
|
||||
}
|
||||
|
||||
|
@ -4,21 +4,29 @@ import { LinkContextMenu } from '../../events/event-source';
|
||||
import { MapLink } from '../../models/map/map-link';
|
||||
import { SVGSelection } from '../../models/types';
|
||||
import { Widget } from '../widget';
|
||||
import { LinkStyle } from '../../../models/link-style';
|
||||
import { StyleTranslator} from './style-translator';
|
||||
|
||||
class EthernetLinkPath {
|
||||
constructor(public source: [number, number], public target: [number, number]) {}
|
||||
constructor(public source: [number, number], public target: [number, number], public style: LinkStyle) {}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class EthernetLinkWidget implements Widget {
|
||||
public onContextMenu = new EventEmitter<LinkContextMenu>();
|
||||
private defaultEthernetLinkStyle : LinkStyle = {
|
||||
color: "#000",
|
||||
width: 2,
|
||||
type: 0
|
||||
};
|
||||
|
||||
constructor() {}
|
||||
|
||||
private linktoEthernetLink(link: MapLink) {
|
||||
return new EthernetLinkPath(
|
||||
[link.source.x + link.source.width / 2, link.source.y + link.source.height / 2],
|
||||
[link.target.x + link.target.width / 2, link.target.y + link.target.height / 2]
|
||||
[link.target.x + link.target.width / 2, link.target.y + link.target.height / 2],
|
||||
link.link_style.color ? link.link_style : this.defaultEthernetLinkStyle
|
||||
);
|
||||
}
|
||||
|
||||
@ -38,15 +46,15 @@ export class EthernetLinkWidget implements Widget {
|
||||
let link: MapLink = (datum as unknown) as MapLink;
|
||||
const evt = event;
|
||||
this.onContextMenu.emit(new LinkContextMenu(evt, link));
|
||||
});
|
||||
|
||||
link_enter
|
||||
.attr('stroke', '#000')
|
||||
.attr('stroke-width', '2')
|
||||
.on('contextmenu', (datum) => {
|
||||
let link: MapLink = (datum as unknown) as MapLink;
|
||||
const evt = event;
|
||||
this.onContextMenu.emit(new LinkContextMenu(evt, link));
|
||||
})
|
||||
.attr('stroke', (datum) => {
|
||||
return datum.style.color;
|
||||
})
|
||||
.attr('stroke-width', (datum) => {
|
||||
return datum.style.width;
|
||||
})
|
||||
.attr('stroke-dasharray', (datum) => {
|
||||
return StyleTranslator.getLinkStyle(datum.style);
|
||||
});
|
||||
|
||||
const link_merge = link.merge(link_enter);
|
||||
|
@ -4,19 +4,27 @@ import { LinkContextMenu } from '../../events/event-source';
|
||||
import { MapLink } from '../../models/map/map-link';
|
||||
import { SVGSelection } from '../../models/types';
|
||||
import { Widget } from '../widget';
|
||||
import { LinkStyle } from '../../../models/link-style';
|
||||
import { StyleTranslator} from './style-translator';
|
||||
|
||||
class SerialLinkPath {
|
||||
constructor(
|
||||
public source: [number, number],
|
||||
public source_angle: [number, number],
|
||||
public target_angle: [number, number],
|
||||
public target: [number, number]
|
||||
public target: [number, number],
|
||||
public style: LinkStyle
|
||||
) {}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SerialLinkWidget implements Widget {
|
||||
public onContextMenu = new EventEmitter<LinkContextMenu>();
|
||||
private defaultSerialLinkStyle : LinkStyle = {
|
||||
color: "#B22222",
|
||||
width: 2,
|
||||
type: 0
|
||||
};
|
||||
|
||||
constructor() {}
|
||||
|
||||
@ -47,7 +55,12 @@ export class SerialLinkWidget implements Widget {
|
||||
target.y - dy / 2.0 - 15 * vect_rot[1],
|
||||
];
|
||||
|
||||
return new SerialLinkPath([source.x, source.y], angle_source, angle_target, [target.x, target.y]);
|
||||
return new SerialLinkPath(
|
||||
[source.x, source.y],
|
||||
angle_source,
|
||||
angle_target,
|
||||
[target.x, target.y],
|
||||
link.link_style.color ? link.link_style : this.defaultSerialLinkStyle);
|
||||
}
|
||||
|
||||
public draw(view: SVGSelection) {
|
||||
@ -68,7 +81,16 @@ export class SerialLinkWidget implements Widget {
|
||||
this.onContextMenu.emit(new LinkContextMenu(evt, link));
|
||||
});
|
||||
|
||||
link_enter.attr('stroke', '#B22222').attr('fill', 'none').attr('stroke-width', '2');
|
||||
link_enter
|
||||
.attr('stroke', (datum) => {
|
||||
return datum.style.color;
|
||||
})
|
||||
.attr('stroke-width', (datum) => {
|
||||
return datum.style.width;
|
||||
})
|
||||
.attr('stroke-dasharray', (datum) => {
|
||||
return StyleTranslator.getLinkStyle(datum.style);
|
||||
});
|
||||
|
||||
const link_merge = link.merge(link_enter);
|
||||
|
||||
|
16
src/app/cartography/widgets/links/style-translator.ts
Normal file
16
src/app/cartography/widgets/links/style-translator.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { LinkStyle } from '../../../models/link-style';
|
||||
|
||||
export class StyleTranslator {
|
||||
static getLinkStyle(linkStyle: LinkStyle) {
|
||||
if (linkStyle.type == 1) {
|
||||
return `10, 10`
|
||||
}
|
||||
if (linkStyle.type == 2) {
|
||||
return `${linkStyle.width}, ${linkStyle.width}`
|
||||
}
|
||||
if (linkStyle.type == 3) {
|
||||
return `20, 10, ${linkStyle.width}, ${linkStyle.width}, ${linkStyle.width}, 10`
|
||||
}
|
||||
return `0, 0`
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<button mat-menu-item (click)="editStyle()">
|
||||
<mat-icon>style</mat-icon>
|
||||
<span>Edit style</span>
|
||||
</button>
|
@ -0,0 +1,33 @@
|
||||
import { Component, Input, OnChanges } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Link } from '../../../../../models/link';
|
||||
import { Project } from '../../../../../models/project';
|
||||
import { Server } from '../../../../../models/server';
|
||||
import { LinkStyleEditorDialogComponent } from '../../../drawings-editors/link-style-editor/link-style-editor.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-edit-link-style-action',
|
||||
|
||||
templateUrl: './edit-link-style-action.component.html',
|
||||
})
|
||||
export class EditLinkStyleActionComponent implements OnChanges {
|
||||
@Input() server: Server;
|
||||
@Input() project: Project;
|
||||
@Input() link: Link;
|
||||
|
||||
constructor(private dialog: MatDialog) {}
|
||||
|
||||
ngOnChanges() {}
|
||||
|
||||
editStyle() {
|
||||
const dialogRef = this.dialog.open(LinkStyleEditorDialogComponent, {
|
||||
width: '800px',
|
||||
autoFocus: false,
|
||||
disableClose: true,
|
||||
});
|
||||
let instance = dialogRef.componentInstance;
|
||||
instance.server = this.server;
|
||||
instance.project = this.project;
|
||||
instance.link = this.link;
|
||||
}
|
||||
}
|
@ -180,6 +180,18 @@
|
||||
[server]="server"
|
||||
[link]="links[0]"
|
||||
></app-reset-link-action>
|
||||
<app-edit-link-style-action
|
||||
*ngIf="
|
||||
!projectService.isReadOnly(project) &&
|
||||
drawings.length === 0 &&
|
||||
nodes.length === 0 &&
|
||||
links.length === 1 &&
|
||||
linkNodes.length === 0
|
||||
"
|
||||
[server]="server"
|
||||
[project]="project"
|
||||
[link]="links[0]"
|
||||
></app-edit-link-style-action>
|
||||
<app-lock-action
|
||||
*ngIf="!projectService.isReadOnly(project) && (drawings.length > 0 || nodes.length > 0)"
|
||||
[server]="server"
|
||||
|
@ -0,0 +1,33 @@
|
||||
<h1 mat-dialog-title>Style editor</h1>
|
||||
|
||||
<div class="modal-form-container">
|
||||
<form [formGroup]="formGroup">
|
||||
<mat-form-field class="form-field">
|
||||
<input
|
||||
matInput
|
||||
placeholder="Color"
|
||||
formControlName="color"
|
||||
type="color"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="form-field">
|
||||
<input
|
||||
matInput
|
||||
formControlName="width"
|
||||
placeholder="Width"
|
||||
type="number" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="form-field">
|
||||
<mat-select placeholder="Type" formControlName="type">
|
||||
<mat-option *ngFor="let type of borderTypes" [value]="type"> {{ type }} </mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button (click)="onNoClick()" color="accent">Cancel</button>
|
||||
<button mat-button (click)="onYesClick()" tabindex="2" mat-raised-button color="primary">Apply</button>
|
||||
</div>
|
@ -0,0 +1,54 @@
|
||||
.item {
|
||||
height: 25px;
|
||||
font-size: 10pt;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-value {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.input-color {
|
||||
padding: 0px;
|
||||
border-width: 0px;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type='color'] {
|
||||
-webkit-appearance: none;
|
||||
border: none;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
input[type='color']::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type='color']::-webkit-color-swatch {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.modal-form-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.modal-form-container > * {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { Link } from '../../../../models/link';
|
||||
import { Project } from '../../../../models/project';
|
||||
import { Server } from '../../../../models/server';
|
||||
import { ToasterService } from '../../../../services/toaster.service';
|
||||
import { NonNegativeValidator } from '../../../../validators/non-negative-validator';
|
||||
import { LinkService } from '../../../../services/link.service';
|
||||
import { LinksDataSource } from '../../../../cartography/datasources/links-datasource';
|
||||
import { LinksEventSource } from '../../../../cartography/events/links-event-source';
|
||||
import { LinkToMapLinkConverter } from '../../../../cartography/converters/map/link-to-map-link-converter';
|
||||
|
||||
@Component({
|
||||
selector: 'app-link-style-editor',
|
||||
templateUrl: './link-style-editor.component.html',
|
||||
styleUrls: ['./link-style-editor.component.scss'],
|
||||
})
|
||||
export class LinkStyleEditorDialogComponent implements OnInit {
|
||||
server: Server;
|
||||
project: Project;
|
||||
link: Link;
|
||||
formGroup: FormGroup;
|
||||
borderTypes = ["Solid", "Dash", "Dot", "Dash Dot"];
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<LinkStyleEditorDialogComponent>,
|
||||
private formBuilder: FormBuilder,
|
||||
private toasterService: ToasterService,
|
||||
private linkService: LinkService,
|
||||
private linksDataSource: LinksDataSource,
|
||||
private linksEventSource: LinksEventSource,
|
||||
private linkToMapLink: LinkToMapLinkConverter,
|
||||
private nonNegativeValidator: NonNegativeValidator
|
||||
) {
|
||||
this.formGroup = this.formBuilder.group({
|
||||
color: new FormControl('', [Validators.required]),
|
||||
width: new FormControl('', [Validators.required, nonNegativeValidator.get]),
|
||||
type: new FormControl('', [Validators.required])
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (!this.link.link_style?.color) {
|
||||
this.formGroup.controls['color'].setValue("#000000");
|
||||
} else {
|
||||
this.formGroup.controls['color'].setValue(this.link.link_style.color);
|
||||
}
|
||||
|
||||
this.formGroup.controls['width'].setValue(this.link.link_style.width);
|
||||
|
||||
let type = this.borderTypes[0];
|
||||
if (this.link.link_style?.type) {
|
||||
type = this.borderTypes[this.link.link_style.type];
|
||||
}
|
||||
this.formGroup.controls['type'].setValue(type);
|
||||
}
|
||||
|
||||
onNoClick() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
onYesClick() {
|
||||
if (this.formGroup.valid) {
|
||||
this.link.link_style.color = this.formGroup.get('color').value;
|
||||
this.link.link_style.width = this.formGroup.get('width').value;
|
||||
|
||||
let type = this.borderTypes.indexOf(this.formGroup.get('type').value);
|
||||
this.link.link_style.type = type;
|
||||
|
||||
this.linkService.updateLinkStyle(this.server, this.link).subscribe((link) => {
|
||||
this.linksDataSource.update(link);
|
||||
this.linksEventSource.edited.next(this.linkToMapLink.convert(link));
|
||||
location.reload()
|
||||
// we add this code/line for reload the entire page because single graph/link style is not updated automatically.
|
||||
// this.toasterService.success("Link updated");
|
||||
this.dialogRef.close();
|
||||
});
|
||||
} else {
|
||||
this.toasterService.error(`Entered data is incorrect`);
|
||||
}
|
||||
}
|
||||
}
|
@ -268,6 +268,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.projectMapSubscription.add(
|
||||
this.linksDataSource.changes.subscribe((links: Link[]) => {
|
||||
console.log('from project map component');
|
||||
this.links = links;
|
||||
this.mapChangeDetectorRef.detectChanges();
|
||||
})
|
||||
|
5
src/app/models/link-style.ts
Normal file
5
src/app/models/link-style.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export class LinkStyle {
|
||||
color: string;
|
||||
width: number;
|
||||
type: number;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { Node } from '../cartography/models/node';
|
||||
import { Filter } from './filter';
|
||||
import { LinkNode } from './link-node';
|
||||
import { LinkStyle } from './link-style';
|
||||
|
||||
export class Link {
|
||||
capture_file_name: string;
|
||||
@ -12,6 +13,7 @@ export class Link {
|
||||
nodes: LinkNode[];
|
||||
project_id: string;
|
||||
suspend: boolean;
|
||||
link_style?: LinkStyle;
|
||||
|
||||
distance: number; // this is not from server
|
||||
length: number; // this is not from server
|
||||
|
@ -69,6 +69,10 @@ export class LinkService {
|
||||
return this.httpServer.put<Link>(server, `/projects/${link.project_id}/links/${link.link_id}`, link);
|
||||
}
|
||||
|
||||
updateLinkStyle(server: Server, link: Link) {
|
||||
return this.httpServer.put<Link>(server, `/projects/${link.project_id}/links/${link.link_id}`, link);
|
||||
}
|
||||
|
||||
getAvailableFilters(server: Server, link: Link) {
|
||||
return this.httpServer.get<FilterDescription[]>(
|
||||
server,
|
||||
|
Loading…
Reference in New Issue
Block a user