mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-21 03:54:58 +00:00
Initial implementation of drag & drop to add new node
This commit is contained in:
parent
6860efa2a6
commit
01d49a7321
@ -1 +1,43 @@
|
||||
<button class="addNode" matTooltip="Add a node" mat-icon-button (click)="listTemplatesModal()"><mat-icon>add_to_queue</mat-icon></button>
|
||||
<button class="addNode" matTooltip="Add a node" mat-icon-button [matMenuTriggerFor]="mainMenu">
|
||||
<mat-icon>add_to_queue</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #mainMenu="matMenu">
|
||||
<button mat-menu-item (click)="openDialog()">
|
||||
<mat-icon>add</mat-icon>
|
||||
<span>Open dialog to configure</span>
|
||||
</button>
|
||||
|
||||
<mat-form-field (click)="$event.stopPropagation()" class="form-field" floatPlaceholder="never">
|
||||
<input
|
||||
matInput
|
||||
placeholder="Search by name"
|
||||
(keyup)="filterTemplates($event)"
|
||||
[(ngModel)]="searchText"
|
||||
[ngModelOptions]="{standalone: true}">
|
||||
</mat-form-field>
|
||||
<mat-form-field (click)="$event.stopPropagation()" class="form-field">
|
||||
<mat-select
|
||||
[ngModelOptions]="{standalone: true}"
|
||||
placeholder="Filter templates by type"
|
||||
(selectionChange)="filterTemplates($event)"
|
||||
[(ngModel)]="selectedType">
|
||||
<mat-option *ngFor="let type of templateTypes" [value]="type">
|
||||
{{type}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="menu">
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let template of filteredTemplates" class="templateIcon">
|
||||
<span>
|
||||
<span mwlDraggable (dragEnd)="dragEnd($event, template)">
|
||||
<img class="image" [src]="getImageSourceForTemplate(template)"/>
|
||||
</span>
|
||||
{{template.name}}
|
||||
</span>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
</mat-menu>
|
||||
|
@ -0,0 +1,41 @@
|
||||
// ::ng-deep .menu {
|
||||
// scrollbar-color: darkgrey #263238!important;
|
||||
// scrollbar-width: thin!important;
|
||||
// }
|
||||
|
||||
.menu {
|
||||
height: 200px;
|
||||
overflow-y: scroll;
|
||||
scrollbar-color: darkgrey #263238;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0.5em;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: darkgrey;
|
||||
outline: 1px solid #263238;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
width: 90%;
|
||||
margin-left: 5%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 65px;
|
||||
height: 65px;
|
||||
filter: invert(0);
|
||||
--webkit-filter: invert(0)!important;
|
||||
}
|
||||
|
||||
.templateIcon {
|
||||
height: 80px!important;
|
||||
}
|
@ -5,6 +5,8 @@ import { TemplateListDialogComponent, NodeAddedEvent } from './template-list-dia
|
||||
import { Server } from '../../models/server';
|
||||
import { Template } from '../../models/template';
|
||||
import { Project } from '../../models/project';
|
||||
import { TemplateService } from '../../services/template.service';
|
||||
import { MapScaleService } from '../../services/mapScale.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-template',
|
||||
@ -16,11 +18,54 @@ export class TemplateComponent implements OnInit {
|
||||
@Input() project: Project;
|
||||
@Output() onNodeCreation = new EventEmitter<any>();
|
||||
|
||||
constructor(private dialog: MatDialog) {}
|
||||
templates: Template[] = [];
|
||||
filteredTemplates: Template[] = [];
|
||||
searchText: string = '';
|
||||
templateTypes: string[] = ['all', 'cloud', 'ethernet_hub', 'ethernet_switch', 'docker', 'dynamips', 'vpcs', 'traceng', 'virtualbox', 'vmware', 'iou', 'qemu'];
|
||||
selectedType: string;
|
||||
|
||||
ngOnInit() {}
|
||||
constructor(
|
||||
private dialog: MatDialog,
|
||||
private templateService: TemplateService,
|
||||
private scaleService: MapScaleService
|
||||
) {}
|
||||
|
||||
listTemplatesModal() {
|
||||
ngOnInit() {
|
||||
this.templateService.list(this.server).subscribe((listOfTemplates: Template[]) => {
|
||||
this.filteredTemplates = listOfTemplates;
|
||||
this.templates = listOfTemplates;
|
||||
});
|
||||
}
|
||||
|
||||
filterTemplates(event) {
|
||||
let temporaryTemplates = this.templates.filter(item => {
|
||||
return item.name.toLowerCase().includes(this.searchText.toLowerCase());
|
||||
});
|
||||
|
||||
if (this.selectedType === 'all') {
|
||||
this.filteredTemplates = temporaryTemplates;
|
||||
} else {
|
||||
this.filteredTemplates = temporaryTemplates.filter(t => t.template_type === this.selectedType);
|
||||
}
|
||||
}
|
||||
|
||||
dragEnd(ev, template) {
|
||||
console.log('Element was dragged', ev);
|
||||
console.log('Template', template);
|
||||
console.log((event as MouseEvent).clientX, (event as MouseEvent).clientY);
|
||||
|
||||
let scale = this.scaleService.getScale();
|
||||
let nodeAddedEvent: NodeAddedEvent = {
|
||||
template: template,
|
||||
server: 'local',
|
||||
numberOfNodes: 1,
|
||||
x: ((event as MouseEvent).clientX - this.project.scene_width/2 + window.scrollX) * scale, //template.width
|
||||
y: ((event as MouseEvent).clientY - this.project.scene_height/2 + window.scrollY) * scale
|
||||
};
|
||||
this.onNodeCreation.emit(nodeAddedEvent);
|
||||
}
|
||||
|
||||
openDialog() {
|
||||
const dialogRef = this.dialog.open(TemplateListDialogComponent, {
|
||||
width: '600px',
|
||||
data: {
|
||||
@ -37,4 +82,8 @@ export class TemplateComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getImageSourceForTemplate(template: Template) {
|
||||
return `http://${this.server.host}:${this.server.port}/v2${template.symbol.substring(1)}/raw`;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user