mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-02-22 10:20:48 +00:00
Merge pull request #940 from GNS3/Integrate-link-labels-to-links
Integrate link labels to links
This commit is contained in:
commit
97d259c7f4
@ -1,3 +1,3 @@
|
|||||||
export class LinkStatus {
|
export class LinkStatus {
|
||||||
public constructor(public x: number, public y: number, public status: string) {}
|
public constructor(public x: number, public y: number, public status: string, public port?: string) {}
|
||||||
}
|
}
|
||||||
|
@ -6,81 +6,205 @@ import { Widget } from './widget';
|
|||||||
import { SVGSelection } from '../models/types';
|
import { SVGSelection } from '../models/types';
|
||||||
import { LinkStatus } from '../models/link-status';
|
import { LinkStatus } from '../models/link-status';
|
||||||
import { MapLink } from '../models/map/map-link';
|
import { MapLink } from '../models/map/map-link';
|
||||||
|
import { MapSettingsService } from '../../services/mapsettings.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class InterfaceStatusWidget implements Widget {
|
export class InterfaceStatusWidget implements Widget {
|
||||||
constructor() {}
|
private mapSettingsService: MapSettingsService
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _mapSettingsService: MapSettingsService
|
||||||
|
) {
|
||||||
|
this.mapSettingsService = _mapSettingsService;
|
||||||
|
}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
view.each(function(this: SVGGElement, l: MapLink) {
|
view.each(function(this: SVGGElement, l: MapLink) {
|
||||||
const link_group = select<SVGGElement, MapLink>(this);
|
const link_group = select<SVGGElement, MapLink>(this);
|
||||||
const link_path = link_group.select<SVGPathElement>('path');
|
const link_path = link_group.select<SVGPathElement>('path');
|
||||||
|
|
||||||
let statuses = [];
|
let statuses = [];
|
||||||
if (link_path.node()) {
|
if (link_path.node()) {
|
||||||
const start_point: SVGPoint = link_path.node().getPointAtLength(45);
|
const start_point: SVGPoint = link_path.node().getPointAtLength(100);
|
||||||
const end_point: SVGPoint = link_path.node().getPointAtLength(link_path.node().getTotalLength() - 45);
|
const end_point: SVGPoint = link_path.node().getPointAtLength(link_path.node().getTotalLength() - 100);
|
||||||
|
|
||||||
if (link_path.node().getTotalLength() > 2 * 45 + 10) {
|
if (link_path.node().getTotalLength() > 2 * 45 + 10) {
|
||||||
if (l.source && l.target) {
|
if (l.source && l.target) {
|
||||||
|
let sourcePort = l.nodes.find(node => node.nodeId === l.source.id).label.text;
|
||||||
|
let destinationPort = l.nodes.find(node => node.nodeId === l.target.id).label.text;
|
||||||
statuses = [
|
statuses = [
|
||||||
new LinkStatus(start_point.x, start_point.y, (l.capturing && l.suspend) ? 'suspended' : l.source.status),
|
new LinkStatus(start_point.x, start_point.y, (l.capturing && l.suspend) ? 'suspended' : l.source.status, sourcePort),
|
||||||
new LinkStatus(end_point.x, end_point.y, (l.capturing && l.suspend) ? 'suspended' : l.target.status)
|
new LinkStatus(end_point.x, end_point.y, (l.capturing && l.suspend) ? 'suspended' : l.target.status, destinationPort)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const status_started = link_group
|
link_group
|
||||||
.selectAll<SVGCircleElement, LinkStatus>('circle.status_started')
|
.selectAll<SVGCircleElement, LinkStatus>('circle.status_started').remove();
|
||||||
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'started'));
|
link_group
|
||||||
|
.selectAll<SVGCircleElement, LinkStatus>('circle.status_stopped').remove();
|
||||||
|
link_group
|
||||||
|
.selectAll<SVGCircleElement, LinkStatus>('circle.status_suspended').remove();
|
||||||
|
|
||||||
const status_started_enter = status_started.enter().append<SVGCircleElement>('circle');
|
link_group
|
||||||
|
.selectAll<SVGRectElement, LinkStatus>('rect.status_started').remove();
|
||||||
|
link_group
|
||||||
|
.selectAll<SVGTextElement, LinkStatus>('text.status_started_label').remove();
|
||||||
|
link_group
|
||||||
|
.selectAll<SVGRectElement, LinkStatus>('rect.status_stopped').remove();
|
||||||
|
link_group
|
||||||
|
.selectAll<SVGTextElement, LinkStatus>('text.status_stopped_label').remove();
|
||||||
|
link_group
|
||||||
|
.selectAll<SVGRectElement, LinkStatus>('rect.status_suspended').remove();
|
||||||
|
link_group
|
||||||
|
.selectAll<SVGTextElement, LinkStatus>('text.status_suspended_label').remove();
|
||||||
|
|
||||||
status_started
|
if (self.mapSettingsService.integrateLinkLabelsToLinks) {
|
||||||
.merge(status_started_enter)
|
const status_started = link_group
|
||||||
.attr('class', 'status_started')
|
.selectAll<SVGRectElement, LinkStatus>('rect.status_started')
|
||||||
.attr('cx', (ls: LinkStatus) => ls.x)
|
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'started'));
|
||||||
.attr('cy', (ls: LinkStatus) => ls.y)
|
const status_started_enter = status_started.enter().append<SVGRectElement>('rect');
|
||||||
.attr('r', 6)
|
status_started
|
||||||
.attr('fill', '#2ecc71');
|
.merge(status_started_enter)
|
||||||
|
.attr('class', 'status_started')
|
||||||
|
.attr('width', 40)
|
||||||
|
.attr('height', 20)
|
||||||
|
.attr('x', (ls: LinkStatus) => ls.x - 10)
|
||||||
|
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
||||||
|
.attr('rx', 8)
|
||||||
|
.attr('ry', 8)
|
||||||
|
.style('fill', 'white')
|
||||||
|
.attr('stroke', '#2ecc71')
|
||||||
|
.attr('stroke-width', 3);
|
||||||
|
status_started.exit().remove();
|
||||||
|
const status_started_label = link_group
|
||||||
|
.selectAll<SVGTextElement, LinkStatus>('text.status_started_label')
|
||||||
|
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'started'));
|
||||||
|
const status_started_label_enter = status_started_label.enter().append<SVGTextElement>('text');
|
||||||
|
status_started_label
|
||||||
|
.merge(status_started_label_enter)
|
||||||
|
.attr('class', 'status_started_label')
|
||||||
|
.text((ls: LinkStatus) => ls.port)
|
||||||
|
.attr('x', (ls: LinkStatus) => ls.x - 5)
|
||||||
|
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
||||||
|
.attr('fill', `black`);
|
||||||
|
status_started_label.exit().remove();
|
||||||
|
|
||||||
|
const status_stopped = link_group
|
||||||
|
.selectAll<SVGRectElement, LinkStatus>('rect.status_stopped')
|
||||||
|
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'stopped'));
|
||||||
|
const status_stopped_enter = status_stopped.enter().append<SVGRectElement>('rect');
|
||||||
|
status_stopped
|
||||||
|
.merge(status_stopped_enter)
|
||||||
|
.attr('class', 'status_stopped')
|
||||||
|
.attr('width', 40)
|
||||||
|
.attr('height', 20)
|
||||||
|
.attr('x', (ls: LinkStatus) => ls.x - 10)
|
||||||
|
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
||||||
|
.attr('rx', 8)
|
||||||
|
.attr('ry', 8)
|
||||||
|
.style('fill', 'white')
|
||||||
|
.attr('stroke', 'red')
|
||||||
|
.attr('stroke-width', 3);
|
||||||
|
status_stopped.exit().remove();
|
||||||
|
const status_stopped_label = link_group
|
||||||
|
.selectAll<SVGTextElement, LinkStatus>('text.status_stopped_label')
|
||||||
|
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'stopped'));
|
||||||
|
const status_stopped_label_enter = status_stopped_label.enter().append<SVGTextElement>('text');
|
||||||
|
status_stopped_label
|
||||||
|
.merge(status_stopped_label_enter)
|
||||||
|
.attr('class', 'status_stopped_label')
|
||||||
|
.text((ls: LinkStatus) => ls.port)
|
||||||
|
.attr('x', (ls: LinkStatus) => ls.x - 5)
|
||||||
|
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
||||||
|
.attr('fill', `black`);
|
||||||
|
status_stopped_label.exit().remove();
|
||||||
|
|
||||||
status_started.exit().remove();
|
const status_suspended = link_group
|
||||||
|
.selectAll<SVGRectElement, LinkStatus>('rect.status_suspended')
|
||||||
|
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'suspended'));
|
||||||
|
const status_suspended_enter = status_suspended.enter().append<SVGRectElement>('rect');
|
||||||
|
status_suspended
|
||||||
|
.merge(status_suspended_enter)
|
||||||
|
.attr('class', 'status_suspended')
|
||||||
|
.attr('width', 40)
|
||||||
|
.attr('height', 20)
|
||||||
|
.attr('x', (ls: LinkStatus) => ls.x - 10)
|
||||||
|
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
||||||
|
.attr('rx', 8)
|
||||||
|
.attr('ry', 8)
|
||||||
|
.style('fill', 'white')
|
||||||
|
.attr('stroke', '#FFFF00')
|
||||||
|
.attr('stroke-width', 3);
|
||||||
|
status_suspended.exit().remove();
|
||||||
|
const status_suspended_label = link_group
|
||||||
|
.selectAll<SVGTextElement, LinkStatus>('text.status_suspended_label')
|
||||||
|
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'suspended'));
|
||||||
|
const status_suspended_label_enter = status_suspended_label.enter().append<SVGTextElement>('text');
|
||||||
|
status_suspended_label
|
||||||
|
.merge(status_suspended_label_enter)
|
||||||
|
.attr('class', 'status_suspended_label')
|
||||||
|
.text((ls: LinkStatus) => ls.port)
|
||||||
|
.attr('x', (ls: LinkStatus) => ls.x - 5)
|
||||||
|
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
||||||
|
.attr('fill', `black`);
|
||||||
|
status_suspended_label.exit().remove();
|
||||||
|
} else {
|
||||||
|
const status_started = link_group
|
||||||
|
.selectAll<SVGCircleElement, LinkStatus>('circle.status_started')
|
||||||
|
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'started'));
|
||||||
|
|
||||||
const status_stopped = link_group
|
const status_started_enter = status_started.enter().append<SVGCircleElement>('circle');
|
||||||
.selectAll<SVGRectElement, LinkStatus>('rect.status_stopped')
|
|
||||||
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'stopped'));
|
|
||||||
|
|
||||||
const status_stopped_enter = status_stopped.enter().append<SVGRectElement>('rect');
|
status_started
|
||||||
|
.merge(status_started_enter)
|
||||||
|
.attr('class', 'status_started')
|
||||||
|
.attr('cx', (ls: LinkStatus) => ls.x)
|
||||||
|
.attr('cy', (ls: LinkStatus) => ls.y)
|
||||||
|
.attr('r', 6)
|
||||||
|
.attr('text', (ls: LinkStatus) => ls.port)
|
||||||
|
.attr('fill', '#2ecc71');
|
||||||
|
|
||||||
const STOPPED_STATUS_RECT_WIDTH = 10;
|
status_started.exit().remove();
|
||||||
|
|
||||||
status_stopped
|
const status_stopped = link_group
|
||||||
.merge(status_stopped_enter)
|
.selectAll<SVGRectElement, LinkStatus>('rect.status_stopped')
|
||||||
.attr('class', 'status_stopped')
|
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'stopped'));
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - STOPPED_STATUS_RECT_WIDTH / 2)
|
|
||||||
.attr('y', (ls: LinkStatus) => ls.y - STOPPED_STATUS_RECT_WIDTH / 2)
|
|
||||||
.attr('width', STOPPED_STATUS_RECT_WIDTH)
|
|
||||||
.attr('height', STOPPED_STATUS_RECT_WIDTH)
|
|
||||||
.attr('fill', 'red');
|
|
||||||
|
|
||||||
status_stopped.exit().remove();
|
const status_stopped_enter = status_stopped.enter().append<SVGRectElement>('rect');
|
||||||
|
|
||||||
const status_suspended = link_group
|
const STOPPED_STATUS_RECT_WIDTH = 10;
|
||||||
.selectAll<SVGCircleElement, LinkStatus>('circle.status_suspended')
|
|
||||||
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'suspended'));
|
|
||||||
|
|
||||||
const status_suspended_enter = status_suspended.enter().append<SVGCircleElement>('circle');
|
status_stopped
|
||||||
|
.merge(status_stopped_enter)
|
||||||
|
.attr('class', 'status_stopped')
|
||||||
|
.attr('x', (ls: LinkStatus) => ls.x - STOPPED_STATUS_RECT_WIDTH / 2)
|
||||||
|
.attr('y', (ls: LinkStatus) => ls.y - STOPPED_STATUS_RECT_WIDTH / 2)
|
||||||
|
.attr('width', STOPPED_STATUS_RECT_WIDTH)
|
||||||
|
.attr('height', STOPPED_STATUS_RECT_WIDTH)
|
||||||
|
.attr('fill', 'red');
|
||||||
|
|
||||||
status_suspended
|
status_stopped.exit().remove();
|
||||||
.merge(status_suspended_enter)
|
|
||||||
.attr('class', 'status_suspended')
|
|
||||||
.attr('cx', (ls: LinkStatus) => ls.x)
|
|
||||||
.attr('cy', (ls: LinkStatus) => ls.y)
|
|
||||||
.attr('r', 6)
|
|
||||||
.attr('fill', '#FFFF00');
|
|
||||||
|
|
||||||
status_suspended.exit().remove();
|
const status_suspended = link_group
|
||||||
|
.selectAll<SVGCircleElement, LinkStatus>('circle.status_suspended')
|
||||||
|
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'suspended'));
|
||||||
|
|
||||||
|
const status_suspended_enter = status_suspended.enter().append<SVGCircleElement>('circle');
|
||||||
|
|
||||||
|
status_suspended
|
||||||
|
.merge(status_suspended_enter)
|
||||||
|
.attr('class', 'status_suspended')
|
||||||
|
.attr('cx', (ls: LinkStatus) => ls.x)
|
||||||
|
.attr('cy', (ls: LinkStatus) => ls.y)
|
||||||
|
.attr('r', 6)
|
||||||
|
.attr('fill', '#FFFF00');
|
||||||
|
|
||||||
|
status_suspended.exit().remove();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,8 +109,11 @@
|
|||||||
|
|
||||||
<mat-menu #viewMenu="matMenu" [overlapTrigger]="false">
|
<mat-menu #viewMenu="matMenu" [overlapTrigger]="false">
|
||||||
<div class="options-item">
|
<div class="options-item">
|
||||||
|
<mat-checkbox [ngModel]="mapSettingsService.integrateLinkLabelsToLinks" (change)="toggleIntegrateLinkLabelsToLinks($event.checked)">
|
||||||
|
Integrate link labels to links
|
||||||
|
</mat-checkbox>
|
||||||
<mat-checkbox [ngModel]="isInterfaceLabelVisible" (change)="toggleShowInterfaceLabels($event.checked)">
|
<mat-checkbox [ngModel]="isInterfaceLabelVisible" (change)="toggleShowInterfaceLabels($event.checked)">
|
||||||
Show interface labels
|
Show interface labels separately
|
||||||
</mat-checkbox><br/>
|
</mat-checkbox><br/>
|
||||||
<mat-checkbox [ngModel]="isConsoleVisible" (change)="toggleShowConsole($event.checked)">
|
<mat-checkbox [ngModel]="isConsoleVisible" (change)="toggleShowConsole($event.checked)">
|
||||||
Show console
|
Show console
|
||||||
@ -129,7 +132,7 @@
|
|||||||
</mat-checkbox><br/>
|
</mat-checkbox><br/>
|
||||||
<mat-checkbox [ngModel]="project.snap_to_grid" (change)="toggleSnapToGrid($event.checked)">
|
<mat-checkbox [ngModel]="project.snap_to_grid" (change)="toggleSnapToGrid($event.checked)">
|
||||||
Snap to grid
|
Snap to grid
|
||||||
</mat-checkbox>
|
</mat-checkbox><br/>
|
||||||
</div>
|
</div>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
|
@ -258,11 +258,12 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
this.projectService.open(this.server, this.project.project_id);
|
this.projectService.open(this.server, this.project.project_id);
|
||||||
this.title.setTitle(this.project.name);
|
this.title.setTitle(this.project.name);
|
||||||
|
|
||||||
if (this.mapSettingsService.interfaceLabels.has(project.project_id)) {
|
// old settings
|
||||||
this.isInterfaceLabelVisible = this.mapSettingsService.interfaceLabels.get(project.project_id);
|
// if (this.mapSettingsService.interfaceLabels.has(project.project_id)) {
|
||||||
} else {
|
// this.isInterfaceLabelVisible = this.mapSettingsService.interfaceLabels.get(project.project_id);
|
||||||
this.isInterfaceLabelVisible = this.project.show_interface_labels;
|
// } else {
|
||||||
}
|
// this.isInterfaceLabelVisible = this.project.show_interface_labels;
|
||||||
|
// }
|
||||||
|
|
||||||
this.recentlyOpenedProjectService.setServerId(this.server.id.toString());
|
this.recentlyOpenedProjectService.setServerId(this.server.id.toString());
|
||||||
this.recentlyOpenedProjectService.setProjectId(this.project.project_id);
|
this.recentlyOpenedProjectService.setProjectId(this.project.project_id);
|
||||||
@ -672,9 +673,20 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
this.toolsService.drawLinkToolActivation(this.tools.draw_link);
|
this.toolsService.drawLinkToolActivation(this.tools.draw_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggleShowInterfaceLabels(visible: boolean) {
|
public toggleShowInterfaceLabels(enabled: boolean) {
|
||||||
this.isInterfaceLabelVisible = visible;
|
this.isInterfaceLabelVisible = enabled;
|
||||||
this.mapSettingsService.toggleShowInterfaceLabels(this.project.project_id, this.isInterfaceLabelVisible);
|
this.mapSettingsService.toggleShowInterfaceLabels(this.project.project_id, this.isInterfaceLabelVisible);
|
||||||
|
|
||||||
|
this.mapSettingsService.integrateLinkLabelsToLinks = false;
|
||||||
|
this.mapSettingsService.mapRenderedEmitter.emit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleIntegrateLinkLabelsToLinks(enabled: boolean) {
|
||||||
|
this.isInterfaceLabelVisible = false;
|
||||||
|
this.mapSettingsService.toggleShowInterfaceLabels(this.project.project_id, this.isInterfaceLabelVisible);
|
||||||
|
|
||||||
|
this.mapSettingsService.integrateLinkLabelsToLinks = enabled;
|
||||||
|
this.mapSettingsService.mapRenderedEmitter.emit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggleShowConsole(visible: boolean) {
|
public toggleShowConsole(visible: boolean) {
|
||||||
|
@ -55,8 +55,8 @@ export class LinkService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateLink(server: Server, link: Link) {
|
updateLink(server: Server, link: Link) {
|
||||||
link.x = Math.round(link.x);
|
// link.x = Math.round(link.x);
|
||||||
link.y = Math.round(link.y);
|
// link.y = Math.round(link.y);
|
||||||
|
|
||||||
return this.httpServer.put<Link>(server, `/projects/${link.project_id}/links/${link.link_id}`, link);
|
return this.httpServer.put<Link>(server, `/projects/${link.project_id}/links/${link.link_id}`, link);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ export class MapSettingsService {
|
|||||||
public logConsoleSubject = new Subject<boolean>();
|
public logConsoleSubject = new Subject<boolean>();
|
||||||
public mapRenderedEmitter = new EventEmitter<boolean>();
|
public mapRenderedEmitter = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
public integrateLinkLabelsToLinks: boolean = true;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.isLayerNumberVisible = localStorage.getItem('layersVisibility') === 'true' ? true : false;
|
this.isLayerNumberVisible = localStorage.getItem('layersVisibility') === 'true' ? true : false;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user