mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-17 06:18:09 +00:00
Move node to one layer up/down
This commit is contained in:
@ -60,6 +60,8 @@ import { SymbolsDataSource } from "./cartography/shared/datasources/symbols-data
|
|||||||
import { SelectionManager } from "./cartography/shared/managers/selection-manager";
|
import { SelectionManager } from "./cartography/shared/managers/selection-manager";
|
||||||
import { InRectangleHelper } from "./cartography/map/helpers/in-rectangle-helper";
|
import { InRectangleHelper } from "./cartography/map/helpers/in-rectangle-helper";
|
||||||
import { DrawingsDataSource } from "./cartography/shared/datasources/drawings-datasource";
|
import { DrawingsDataSource } from "./cartography/shared/datasources/drawings-datasource";
|
||||||
|
import { MoveLayerDownActionComponent } from './shared/node-context-menu/actions/move-layer-down-action/move-layer-down-action.component';
|
||||||
|
import { MoveLayerUpActionComponent } from './shared/node-context-menu/actions/move-layer-up-action/move-layer-up-action.component';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -78,6 +80,8 @@ import { DrawingsDataSource } from "./cartography/shared/datasources/drawings-da
|
|||||||
ApplianceComponent,
|
ApplianceComponent,
|
||||||
ApplianceListDialogComponent,
|
ApplianceListDialogComponent,
|
||||||
NodeSelectInterfaceComponent,
|
NodeSelectInterfaceComponent,
|
||||||
|
MoveLayerDownActionComponent,
|
||||||
|
MoveLayerUpActionComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
NgbModule.forRoot(),
|
NgbModule.forRoot(),
|
||||||
|
@ -11,7 +11,9 @@ export class LayersWidget implements Widget {
|
|||||||
|
|
||||||
const layers_selection = view
|
const layers_selection = view
|
||||||
.selectAll<SVGGElement, Layer>('g.layer')
|
.selectAll<SVGGElement, Layer>('g.layer')
|
||||||
.data(layers);
|
.data(layers, (l: Layer) => {
|
||||||
|
return l.index.toString();
|
||||||
|
});
|
||||||
|
|
||||||
const layers_enter = layers_selection
|
const layers_enter = layers_selection
|
||||||
.enter()
|
.enter()
|
||||||
|
@ -16,9 +16,11 @@ export class NodesWidget implements Widget {
|
|||||||
private onNodeDraggedCallback: (event: any, node: Node) => void;
|
private onNodeDraggedCallback: (event: any, node: Node) => void;
|
||||||
private onNodeDraggingCallbacks: ((event: any, node: Node) => void)[] = [];
|
private onNodeDraggingCallbacks: ((event: any, node: Node) => void)[] = [];
|
||||||
|
|
||||||
private symbols: Symbol[] = [];
|
private symbols: Symbol[];
|
||||||
|
|
||||||
constructor() {}
|
constructor() {
|
||||||
|
this.symbols = [];
|
||||||
|
}
|
||||||
|
|
||||||
public setOnContextMenuCallback(onContextMenuCallback: (event: any, node: Node) => void) {
|
public setOnContextMenuCallback(onContextMenuCallback: (event: any, node: Node) => void) {
|
||||||
this.onContextMenuCallback = onContextMenuCallback;
|
this.onContextMenuCallback = onContextMenuCallback;
|
||||||
@ -101,31 +103,11 @@ export class NodesWidget implements Widget {
|
|||||||
.append<SVGGElement>('g')
|
.append<SVGGElement>('g')
|
||||||
.attr('class', 'node');
|
.attr('class', 'node');
|
||||||
|
|
||||||
|
// add image to node
|
||||||
node_enter
|
node_enter
|
||||||
.append<SVGImageElement>('image')
|
.append<SVGImageElement>('image');
|
||||||
.attr('xlink:href', (n: Node) => {
|
|
||||||
const symbol = this.symbols.find((s: Symbol) => s.symbol_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('width', (n: Node) => n.width)
|
|
||||||
.attr('height', (n: Node) => n.height)
|
|
||||||
.attr('x', (n: Node) => -n.width / 2.)
|
|
||||||
.attr('y', (n: Node) => -n.height / 2.)
|
|
||||||
.on('mouseover', function (this, n: Node) {
|
|
||||||
select(this).attr("class", "over");
|
|
||||||
})
|
|
||||||
.on('mouseout', function (this, n: Node) {
|
|
||||||
select(this).attr("class", "");
|
|
||||||
});
|
|
||||||
|
|
||||||
// .attr('width', (n: Node) => n.width)
|
|
||||||
// .attr('height', (n: Node) => n.height);
|
|
||||||
|
|
||||||
|
|
||||||
|
// add label of node
|
||||||
node_enter
|
node_enter
|
||||||
.append<SVGTextElement>('text')
|
.append<SVGTextElement>('text')
|
||||||
.attr('class', 'label');
|
.attr('class', 'label');
|
||||||
@ -158,6 +140,27 @@ export class NodesWidget implements Widget {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// update image of node
|
||||||
|
node_merge
|
||||||
|
.select<SVGImageElement>('image')
|
||||||
|
.attr('xlink:href', (n: Node) => {
|
||||||
|
const symbol = this.symbols.find((s: Symbol) => s.symbol_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('width', (n: Node) => n.width)
|
||||||
|
.attr('height', (n: Node) => n.height)
|
||||||
|
.attr('x', (n: Node) => -n.width / 2.)
|
||||||
|
.attr('y', (n: Node) => -n.height / 2.)
|
||||||
|
.on('mouseover', function (this, n: Node) {
|
||||||
|
select(this).attr("class", "over");
|
||||||
|
})
|
||||||
|
.on('mouseout', function (this, n: Node) {
|
||||||
|
select(this).attr("class", "");
|
||||||
|
});
|
||||||
|
|
||||||
this.revise(node_merge);
|
this.revise(node_merge);
|
||||||
|
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
<button mat-menu-item (click)="moveLayerDown()">
|
||||||
|
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||||
|
<span>Move layer down</span>
|
||||||
|
</button>
|
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MoveLayerDownActionComponent } from './move-layer-down-action.component';
|
||||||
|
|
||||||
|
describe('MoveLayerDownActionComponent', () => {
|
||||||
|
let component: MoveLayerDownActionComponent;
|
||||||
|
let fixture: ComponentFixture<MoveLayerDownActionComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ MoveLayerDownActionComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(MoveLayerDownActionComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,29 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { Server } from '../../../models/server';
|
||||||
|
import { Node } from '../../../../cartography/shared/models/node';
|
||||||
|
import { NodesDataSource } from '../../../../cartography/shared/datasources/nodes-datasource';
|
||||||
|
import { NodeService } from '../../../services/node.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-move-layer-down-action',
|
||||||
|
templateUrl: './move-layer-down-action.component.html'
|
||||||
|
})
|
||||||
|
export class MoveLayerDownActionComponent implements OnInit {
|
||||||
|
@Input() server: Server;
|
||||||
|
@Input() node: Node;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private nodesDataSource: NodesDataSource,
|
||||||
|
private nodeService: NodeService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
|
moveLayerDown() {
|
||||||
|
this.node.z--;
|
||||||
|
this.nodesDataSource.update(this.node);
|
||||||
|
this.nodeService
|
||||||
|
.update(this.server, this.node)
|
||||||
|
.subscribe((node: Node) => {});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
<button mat-menu-item (click)="moveLayerUp()">
|
||||||
|
<mat-icon>keyboard_arrow_up</mat-icon>
|
||||||
|
<span>Move layer up</span>
|
||||||
|
</button>
|
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MoveLayerUpActionComponent } from './move-layer-up-action.component';
|
||||||
|
|
||||||
|
describe('MoveLayerUpActionComponent', () => {
|
||||||
|
let component: MoveLayerUpActionComponent;
|
||||||
|
let fixture: ComponentFixture<MoveLayerUpActionComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ MoveLayerUpActionComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(MoveLayerUpActionComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,28 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { Server } from '../../../models/server';
|
||||||
|
import { Node } from '../../../../cartography/shared/models/node';
|
||||||
|
import { NodesDataSource } from '../../../../cartography/shared/datasources/nodes-datasource';
|
||||||
|
import { NodeService } from '../../../services/node.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-move-layer-up-action',
|
||||||
|
templateUrl: './move-layer-up-action.component.html'
|
||||||
|
})
|
||||||
|
export class MoveLayerUpActionComponent implements OnInit {
|
||||||
|
@Input() server: Server;
|
||||||
|
@Input() node: Node;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private nodesDataSource: NodesDataSource,
|
||||||
|
private nodeService: NodeService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
|
moveLayerUp() {
|
||||||
|
this.node.z++;
|
||||||
|
this.nodeService
|
||||||
|
.update(this.server, this.node)
|
||||||
|
.subscribe((node: Node) => {});
|
||||||
|
}
|
||||||
|
}
|
@ -3,5 +3,7 @@
|
|||||||
<mat-menu #contextMenu="matMenu">
|
<mat-menu #contextMenu="matMenu">
|
||||||
<app-start-node-action [server]="server" [node]="node"></app-start-node-action>
|
<app-start-node-action [server]="server" [node]="node"></app-start-node-action>
|
||||||
<app-stop-node-action [server]="server" [node]="node"></app-stop-node-action>
|
<app-stop-node-action [server]="server" [node]="node"></app-stop-node-action>
|
||||||
|
<app-move-layer-up-action [server]="server" [node]="node"></app-move-layer-up-action>
|
||||||
|
<app-move-layer-down-action [server]="server" [node]="node"></app-move-layer-down-action>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,4 +41,14 @@ export class NodeService {
|
|||||||
'y': y
|
'y': y
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update(server: Server, node: Node): Observable<Node> {
|
||||||
|
return this.httpServer
|
||||||
|
.put<Node>(server, `/projects/${node.project_id}/nodes/${node.node_id}`, {
|
||||||
|
'x': node.x,
|
||||||
|
'y': node.y,
|
||||||
|
'z': node.z
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user