summaryrefslogtreecommitdiffstats
path: root/vid-webpack-master/src/app/drawingBoard/drawing-board-tree
diff options
context:
space:
mode:
Diffstat (limited to 'vid-webpack-master/src/app/drawingBoard/drawing-board-tree')
-rw-r--r--vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.component.ts133
-rw-r--r--vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.html42
-rw-r--r--vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.scss274
3 files changed, 449 insertions, 0 deletions
diff --git a/vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.component.ts b/vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.component.ts
new file mode 100644
index 00000000..6b717a93
--- /dev/null
+++ b/vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.component.ts
@@ -0,0 +1,133 @@
+import {AfterViewInit, Component, EventEmitter, OnInit, Output, ViewChild} from '@angular/core';
+import { ContextMenuService } from 'ngx-contextmenu';
+import { Constants } from '../../shared/utils/constants';
+import {ServicePlanningService} from "../../services/service-planning.service";
+import {ITreeNode} from "angular-tree-component/dist/defs/api";
+import {ITreeOptions, TreeComponent} from "angular-tree-component";
+import {VnfPopupComponent} from "../../components/vnf-popup/vnf-popup.components";
+import {DialogService} from "ng2-bootstrap-modal";
+import {ActivatedRoute} from "@angular/router";
+import {NgRedux} from "@angular-redux/store";
+import {AppState} from "../../store/reducers";
+import { MessageBoxData, ModalSize, ModalType } from '../../shared/components/messageBox/messageBox.data';
+import { MessageBoxService } from '../../shared/components/messageBox/messageBox.service';
+import { deleteVnfInstance, deleteVfModuleInstance } from '../../service.actions';
+import { isNullOrUndefined } from 'util';
+import {IframeService} from "../../shared/utils/iframe.service";
+
+
+@Component({
+ selector: 'drawing-board-tree',
+ templateUrl: './drawing-board-tree.html',
+ styleUrls : ['./drawing-board-tree.scss']
+})
+
+
+export class DrawingBoardTreeComponent implements OnInit, AfterViewInit {
+ constructor(private _contextMenuService: ContextMenuService,
+ private _servicePlanningService: ServicePlanningService,
+ private _iframeService : IframeService,
+ private dialogService: DialogService,
+ private store: NgRedux<AppState>,
+ private route: ActivatedRoute) {
+ this.route
+ .queryParams
+ .subscribe(params => {
+ this.serviceModelId = params['serviceModelId'];
+ });
+ }
+
+ @Output()
+ highlightNode : EventEmitter<number> = new EventEmitter<number>();
+
+ @ViewChild('tree') tree: TreeComponent;
+ missingDataTooltip: string = Constants.Error.MISSING_VNF_DETAILS;
+ currentNode: ITreeNode = null; //
+ nodes = [];
+ serviceModelId: string;
+ options: ITreeOptions = {
+ nodeHeight: 45,
+ dropSlotHeight: 1
+ };
+ parentElementClassName = 'content';
+
+ ngOnInit(): void {
+ this.store.subscribe(() => {this.updateTree()});
+ this.updateTree()
+ }
+
+ updateTree() {
+ const serviceInstance = this.store.getState().service.serviceInstance[this.serviceModelId];
+ this.nodes = this._servicePlanningService.convertServiceInstanceToTreeData(serviceInstance, this.serviceModelId);
+ }
+
+ ngAfterViewInit():void {
+ // Expand drawing tree on init.
+ this.tree.treeModel.expandAll();
+ }
+
+ public onContextMenu($event: MouseEvent, node: ITreeNode): void {
+ this.currentNode = node;
+ node.focus();
+ node.setActiveAndVisible(false);
+ this.selectNode(node);
+ this._contextMenuService.show.next({
+ event: <any>$event,
+ item: node,
+ });
+ $event.preventDefault();
+ $event.stopPropagation();
+ }
+
+ public editItem(node: ITreeNode): void {
+ node = this.currentNode;
+ this._iframeService.addClassOpenModal(this.parentElementClassName);
+ this.dialogService.addDialog(VnfPopupComponent, {
+ serviceModelId: this.serviceModelId,
+ modelName: node.data.modelName,
+ modelType: node.data.type,
+ parentModelName: node.parent.data.modelName,
+ isNewVfModule : false
+ })
+ }
+
+ public deleteItem(node: ITreeNode): void {
+ if(this.currentNode.data.type === 'VF'){
+ if(!isNullOrUndefined(this.currentNode.data.children) && this.currentNode.data.children.length === 0){
+ this.store.dispatch(deleteVnfInstance(this.currentNode.data.modelName, this.serviceModelId));
+ }else {
+ let messageBoxData : MessageBoxData = new MessageBoxData(
+ "Remove VNF", // modal title
+ "You are about to remove this VNF and all its children from this service. Are you sure you want to remove it?",
+
+ ModalType.alert,
+ ModalSize.medium,
+ [
+ {text:"Remove VNF", size:"large", callback: this.removeVnf.bind(this), closeModal:true},
+ {text:"Don’t Remove", size:"medium", closeModal:true}
+ ]);
+
+ MessageBoxService.openModal.next(messageBoxData);
+ }
+ }else {
+ this.store.dispatch(deleteVfModuleInstance(this.currentNode.data.modelName, this.serviceModelId, node.parent.data.modelName));
+ }
+ }
+
+ removeVnf() {
+ this.store.dispatch(deleteVnfInstance(this.currentNode.data.modelName, this.serviceModelId));
+ }
+
+ public selectNode(node: ITreeNode): void {
+ node.expand();
+ this.highlightNode.emit(node.data.modelId);
+ }
+
+ isDataMissing(node: ITreeNode) {
+ //todo: currently not showing the alert icon. will be implemented in upcoming story.
+ return false;
+ }
+
+}
+
+
diff --git a/vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.html b/vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.html
new file mode 100644
index 00000000..c4061db9
--- /dev/null
+++ b/vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.html
@@ -0,0 +1,42 @@
+<div class="drawing-board-tree">
+ <div *ngIf="nodes?.length == 0" style="text-align: center; margin-top: 50px;">
+ <no-content-message-and-icon class="span-over"
+ data-title="Please add objects (VNFs, network, modules etc.) from the left tree to design the service instance"
+ subtitle="Once done, click Deploy to start instantiation"
+ iconPath="./assets/img/UPLOAD.svg"
+ iconClass="upload-icon-service-planing"></no-content-message-and-icon>
+ </div>
+ <tree-root [attr.data-tests-id]="'drawing-board-tree'" #tree [nodes]="nodes" [options]="options" id="drawing-board-tree">
+ <ng-template #treeNodeTemplate let-node let-index="index">
+ <div [attr.data-tests-id]="'node-'+node.data.modelId +'-' +node.data.modelName" (click)="selectNode(node)">
+ <div class="model-info">
+ <span>
+ <span class="property-name">{{node.data.type}}{{node.data.name ? ': ': ''}}<span class="auto-name">{{node.data.name? node.data.name: ''}}</span></span>
+ </span>
+ </div>
+ <div class="model-actions">
+ <span class="icon-browse" [attr.data-tests-id]="'node-'+node.data.modelId +'-' +node.data.modelName+'-menu-btn'" (click)="onContextMenu($event, node)" >
+ <context-menu>
+ <ng-template contextMenuItem (execute)="editItem(node)">
+ <div [attr.data-tests-id]="'context-menu-item'">
+ <span class="icon-edit"></span>
+ Edit
+ </div>
+ </ng-template>
+ <ng-template contextMenuItem (execute)="deleteItem(node)">
+ <div>
+ <span class="icon-trash"></span>
+ Remove
+ </div>
+ </ng-template>
+ </context-menu>
+ </span>
+ <span *ngIf="isDataMissing(node)" class="icon-alert" tooltip="{{ missingDataTooltip }}" tooltipPlacement="left" [attr.data-tests-id]="'node-'+node.data.modelId +'-' +node.data.modelName+'-alert-icon'"></span>
+ </div>
+ </div>
+
+ </ng-template>
+ </tree-root>
+</div>
+
+
diff --git a/vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.scss b/vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.scss
new file mode 100644
index 00000000..fed9ead1
--- /dev/null
+++ b/vid-webpack-master/src/app/drawingBoard/drawing-board-tree/drawing-board-tree.scss
@@ -0,0 +1,274 @@
+@mixin highlight($background-color, $color) {
+ background: none;
+ padding: 0;
+ background-color: $background-color;
+ border: $color 1px solid;
+ color: $color;
+}
+@mixin highlight-toggle-children {
+ tree-node-expander {
+ .toggle-children-wrapper {
+ span.toggle-children {
+ @include highlight(white, #009FDB);
+ border-right: none;
+ }
+ }
+ }
+}
+
+@mixin highlight-tree-node-content {
+ tree-node-content {
+ > div {
+ .model-actions {
+ .icon-browse:before {
+ display: inline-block;
+ }
+ }
+ }
+ }
+}
+
+drawing-board-tree {
+
+ .toggle-children-wrapper.toggle-children-wrapper-expanded {
+ .toggle-children:before {
+ color: #009FDB;
+ }
+ }
+
+ overflow: auto;
+ flex: 1;
+ color: #5A5A5A;
+ line-height: 14px;
+ .drawing-board-tree {
+ width: 100%;
+ }
+ tree-viewport {
+ padding: 50px 3.5% 1% 6%;
+ tree-node {
+ tree-node-drop-slot {
+ .node-drop-slot {
+ display: none;
+ }
+ }
+ & .tree-node-focused,
+ & .tree-node-active {
+ & > tree-node-wrapper {
+ .node-wrapper {
+ @include highlight-toggle-children;
+ .node-content-wrapper-focused,
+ .node-content-wrapper-active
+ {
+ @include highlight(#E6F6FB, #009FDB);
+ .property-name {
+ color: #009FDB;
+ }
+ .auto-name {
+ font-family: OpenSans-Regular !important;
+ }
+ .icon-browse:before {
+ color: #5A5A5A;
+ }
+ @include highlight-tree-node-content;
+ }
+ }
+ }
+ }
+ & .tree-node-expanded {
+ > tree-node-wrapper .node-wrapper {
+ box-shadow: 0 0px 2px rgba(90,90,90,0.24);
+ }
+ }
+
+ .tree-node-active .tree-children {
+ border: 1px solid #009FDB;
+ padding: 20px;
+ }
+
+
+
+ .tree-node.tree-node-active.tree-node-expanded {
+ border: 1px solid #009FDB;
+ }
+
+ .tree-node-leaf .node-wrapper{
+ margin-left: -45px;
+ }
+
+ tree-node-wrapper {
+ .node-wrapper {
+ height: 45px;
+ &:hover {
+ @include highlight-toggle-children;
+ .node-content-wrapper {
+ @include highlight(#E6F6FB, #009FDB);
+ .property-name {
+ color: #009FDB;
+ }
+ .icon-browse:before {
+ color: #5A5A5A;
+ }
+ @include highlight-tree-node-content;
+ }
+ }
+ tree-node-expander {
+ font-family: 'icomoon' !important;
+ height: 100%;
+ .toggle-children-wrapper {
+ padding: 0;
+ display: block;
+ height: 100%;
+ span.toggle-children {
+ display: flex;
+ width: 45px;
+ padding: 0;
+ top: 0;
+ height: inherit;
+ background-image: none;
+ background-color: white;
+ border: 1px solid #D2D2D2;
+ border-right: none;
+ &:before {
+ content: "\e900";
+ font-size: 20px;
+ font-weight: 600;
+ text-align: center;
+ display: inline-block;
+ flex: auto;
+ align-self: center;
+ }
+ }
+ }
+ .toggle-children-wrapper-expanded {
+ span.toggle-children {
+ transform: none;
+ &:before {
+ content: "\e930";
+ }
+ }
+ }
+ .toggle-children-placeholder {
+ width:45px;
+ }
+ }
+ .node-content-wrapper {
+ padding: 0;
+ background: none;
+ box-shadow: none;
+ border-radius: 0;
+ border: 1px solid #D2D2D2;
+ height: 100%;
+ flex: 1;
+ tree-node-content {
+ > div {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ .model-info {
+ flex: 1;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding-left: 8px;
+ > span {
+ flex: 1;
+ padding: 0 8px;
+ span:nth-child(2) {
+ display: block;
+ }
+ }
+ }
+ .model-actions {
+ display: flex;
+ align-items: center;
+ padding-right: 12px;
+ .icon-browse {
+ padding: 0;
+ width: 30px;
+ &:before {
+ content: "\e924";
+ font-size: 24px;
+ display: none;
+ }
+ &:hover:before {
+ color: #009FDB;
+ }
+ &:focus:before,
+ &:active:before {
+ color: #009FDB;
+ }
+ }
+
+ .icon-alert {
+ padding-left: 10px;
+ &:before {
+ content: "\e904";
+ font-size: 16px;
+ color: #ffb81c;
+ }
+ }
+ }
+ }
+ }
+ .property-name {
+ font-family: OpenSans-Semibold;
+ font-size: 12px;
+ line-height: 12px;
+ color: #191919;
+ text-transform: capitalize;
+ }
+ }
+
+
+ }
+ }
+ tree-node-children {
+ .tree-children {
+ padding: 20px;
+ .model-info span:first-child {
+ flex: 1.1 !important;
+ }
+ }
+ }
+ }
+ }
+}
+.cdk-overlay-pane.ngx-contextmenu {
+ ul.dropdown-menu {
+ width: 200px;
+ box-shadow: none;
+ padding: 0;
+ padding-top: 10px;
+ margin: 0;
+ border: 1px solid #D2D2D2;
+ border-top: 3px solid #009FDB;
+ box-shadow: 0 0px 2px rgba(90,90,90,0.24);
+ border-radius: 2px;
+ li {
+ height: 40px;
+ a {
+ font-family: OpenSans-Regular;
+ display: flex;
+ align-items: center;
+ height: 100%;
+ padding: 12px;
+ color: #5A5A5A;
+ &:hover {
+ background: #E6F6FB;
+ color: #009FDB;
+ }
+ span {
+ padding-right: 12px;
+ &.icon-edit:before {
+ content: '\e917';
+ }
+ &.icon-trash:before {
+ content: '\e937';
+ }
+ }
+ }
+ }
+ }
+}
+