e91798ef368578d9a4f83c8def8f8b6b361de82d
[sdc.git] / catalog-ui / src / app / ng2 / pages / composition / palette / palette.component.ts
1 /**
2  * Created by ob0695 on 6/28/2018.
3  */
4 /*-
5  * ============LICENSE_START=======================================================
6  * SDC
7  * ================================================================================
8  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
9  * ================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ============LICENSE_END=========================================================
22  */
23
24 import { Component, HostListener } from '@angular/core';
25 import { Select } from '@ngxs/store';
26 import { LeftPaletteComponent, LeftPaletteMetadataTypes } from 'app/models/components/displayComponent';
27 import { Point } from 'app/models/graph/point';
28 import { WorkspaceState } from 'app/ng2/store/states/workspace.state';
29 import Dictionary = _.Dictionary;
30 import { EventListenerService } from 'app/services/event-listener-service';
31 import { GRAPH_EVENTS } from 'app/utils/constants';
32 import { DndDropEvent } from 'ngx-drag-drop/ngx-drag-drop';
33 import { CompositionPaletteService } from './services/palette.service';
34 import {PolicyMetadata} from "../../../../models/policy-metadata";
35 import {GenericBrowserDomAdapter} from "@angular/platform-browser/src/browser/generic_browser_adapter";
36
37 @Component({
38     selector: 'composition-palette',
39     templateUrl: './palette.component.html',
40     styleUrls: ['./palette.component.less']
41 })
42 export class PaletteComponent {
43
44     constructor(private compositionPaletteService: CompositionPaletteService, private eventListenerService: EventListenerService) {}
45
46     @Select(WorkspaceState.isViewOnly) isViewOnly$: boolean;
47     private paletteElements: Dictionary<Dictionary<LeftPaletteComponent[]>>;
48     public numberOfElements: number = 0;
49     public isPaletteLoading: boolean;
50     private paletteDraggedElement: LeftPaletteComponent;
51     public position: Point = new Point();
52
53     ngOnInit() {
54         this.isPaletteLoading = true;
55
56         this.compositionPaletteService.subscribeToLeftPaletteElements((leftPaletteElementsResponse) => {
57             this.paletteElements = leftPaletteElementsResponse;
58             this.numberOfElements = this.countLeftPalleteElements(this.paletteElements);
59             this.isPaletteLoading = false;
60         }, () => {
61             this.isPaletteLoading = false;
62         });
63
64     }
65
66     public buildPaletteByCategories = (searchText?: string) => { // create nested by category & subcategory, filtered by search parans
67         // Flat the object and run on its leaves
68         if (searchText) {
69             searchText = searchText.toLowerCase();
70             const paletteElementsAfterSearch = {};
71             this.paletteElements = this.compositionPaletteService.getLeftPaletteElements();
72             for (const category in this.paletteElements) {
73                 for (const subCategory in this.paletteElements[category]) {
74                     const subCategoryToCheck = this.paletteElements[category][subCategory];
75                     const res = subCategoryToCheck.filter((item) => item.searchFilterTerms.toLowerCase().indexOf(searchText) >= 0)
76                     if (res.length > 0) {
77                         if (paletteElementsAfterSearch[category] == null) {
78                             paletteElementsAfterSearch[category] = {};
79                         }
80                         paletteElementsAfterSearch[category][subCategory] = res;
81                     }
82                 }
83             }
84             this.paletteElements = paletteElementsAfterSearch;
85         } else {
86             this.paletteElements = this.compositionPaletteService.getLeftPaletteElements();
87         }
88         this.numberOfElements = this.countLeftPalleteElements(this.paletteElements);
89     }
90
91     public onSearchChanged = (searchText: string) => {
92
93         if (this.compositionPaletteService.getLeftPaletteElements()) {
94             this.buildPaletteByCategories(searchText);
95         }
96     }
97
98     private countLeftPalleteElements(leftPalleteElements: Dictionary<Dictionary<LeftPaletteComponent[]>>) {
99         // Use _ & flat map
100         let counter = 0;
101         for (const category in leftPalleteElements) {
102             for (const subCategory in leftPalleteElements[category]) {
103                 counter += leftPalleteElements[category][subCategory].length;
104             }
105         }
106         return counter;
107     }
108
109     private isGroupOrPolicy(component: LeftPaletteComponent): boolean {
110         if (component &&
111             (component.categoryType === LeftPaletteMetadataTypes.Group ||
112             component.categoryType === LeftPaletteMetadataTypes.Policy)) {
113             return true;
114         }
115         return false;
116     }
117     @HostListener('document:dragover', ['$event'])
118     public onDrag(event) {
119         this.position.x = event.clientX;
120         this.position.y = event.clientY;
121     }
122     
123     //---------------------------------------Palette Events-----------------------------------------//
124
125     public onDraggableMoved = (event:DragEvent) => {  
126           let draggedElement = document.getElementById("draggable_element");
127           draggedElement.style.top = (this.position.y - 80) + "px";
128           draggedElement.style.left = (this.position.x - 30) + "px";
129           this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DRAG_ACTION, this.position);
130     }
131
132     public onDragStart = (event, draggedElement:LeftPaletteComponent) => { // Applying the dragged svg component to the draggable element
133         
134         this.paletteDraggedElement = draggedElement;
135         event.dataTransfer.dropEffect = "copy";
136         let hiddenImg = document.createElement("span");
137         event.dataTransfer.setDragImage(hiddenImg, 0, 0);
138     }
139
140
141     public onDrop = (event:DndDropEvent) => {
142         let draggedElement = document.getElementById("draggable_element");
143         draggedElement.style.top = "-9999px";
144         if(draggedElement.classList.contains('valid-drag')) {
145             if(!event.data){
146                 event.data = this.paletteDraggedElement;
147             }
148             this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DROP, event);
149         } else {
150             console.log("INVALID drop");
151         }
152         this.paletteDraggedElement = undefined;
153         
154     }
155
156     public onMouseOver = (sectionElem:MouseEvent, displayComponent:LeftPaletteComponent) => {
157         console.debug("On palette element MOUSE HOVER: ", displayComponent);
158         if (this.isGroupOrPolicy(displayComponent)) {
159             this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_SHOW_POPUP_PANEL, displayComponent, sectionElem.target);
160         } else {
161             this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_IN, displayComponent);
162         }
163     };
164
165     public onMouseOut = (displayComponent:LeftPaletteComponent) => {
166         console.debug("On palette element MOUSE OUT: ", displayComponent);
167         if (this.isGroupOrPolicy(displayComponent)) {
168             this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HIDE_POPUP_PANEL);
169         } else {
170             this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_OUT);
171         }
172     };
173
174 }