2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 import * as _ from "lodash";
21 import { Component, IAppMenu, LeftPanelModel, NodesFactory, LeftPaletteComponent, CompositionCiNodeBase, ComponentInstance, Point } from "app/models";
22 import { CompositionGraphGeneralUtils } from "../composition-graph/utils/composition-graph-general-utils";
23 import { EventListenerService } from "app/services";
24 import { ResourceType, GRAPH_EVENTS, EVENTS, ComponentInstanceFactory, ModalsHandler } from "app/utils";
25 import 'sdc-angular-dragdrop';
26 import { LeftPaletteLoaderService } from "../../../services/components/utils/composition-left-palette-service";
27 import { Resource } from "app/models/components/resource";
28 import { ComponentType } from "app/utils/constants";
29 import { LeftPaletteMetadataTypes } from "../../../models/components/displayComponent";
30 import { IDirectiveLinkFn, IScope } from "angular";
33 interface IPaletteScope extends IScope {
34 components: Array<LeftPaletteComponent>;
35 currentComponent: Component;
37 displaySortedCategories: any;
38 expandedSection: string;
41 event: JQueryEventObject,
42 components: LeftPaletteComponent,
46 addInstanceClick: () => void; // added code
47 onPopupMouseOver: () => void // added code
48 onPopupMouseOut: () => void // added code
50 sectionClick: (section: string) => void;
51 searchComponents: (searchText: string) => void;
52 onMouseOver: (displayComponent: LeftPaletteComponent, elem: HTMLElement) => void;
53 onMouseOut: (displayComponent: LeftPaletteComponent) => void;
55 dragStartCallback: (event: JQueryEventObject, ui, displayComponent: LeftPaletteComponent) => void;
56 dragStopCallback: () => void;
57 onDragCallback: (event: JQueryEventObject) => void;
59 setElementTemplate: (e: JQueryEventObject) => void;
67 export class Palette implements ng.IDirective {
68 constructor(private $log: ng.ILogService,
69 private LeftPaletteLoaderService: LeftPaletteLoaderService,
71 private ComponentFactory,
72 private ComponentInstanceFactory: ComponentInstanceFactory,
73 private NodesFactory: NodesFactory,
74 private CompositionGraphGeneralUtils: CompositionGraphGeneralUtils,
75 private EventListenerService: EventListenerService,
76 private sdcMenu: IAppMenu,
77 private ModalsHandler: ModalsHandler
81 private fetchingComponentFromServer: boolean = false;
82 private nodeHtmlSubstitute: JQuery;
85 currentComponent: '=',
90 template = require('./palette.html');
92 link: IDirectiveLinkFn = (scope: IPaletteScope, el: JQuery) => {
93 this.LeftPaletteLoaderService.loadLeftPanel(scope.currentComponent);
94 this.nodeHtmlSubstitute = $('<div class="node-substitute"><span></span><img /></div>');
95 el.append(this.nodeHtmlSubstitute);
96 this.registerEventListenerForLeftPalette(scope);
98 this.initComponents(scope);
99 this.initEvents(scope);
100 this.initDragEvents(scope);
101 this._initExpandedSection(scope, '');
102 el.on('$destroy', () => {
103 //remove listener of download event
104 this.unRegisterEventListenerForLeftPalette(scope);
109 private registerEventListenerForLeftPalette = (scope: IPaletteScope): void => {
110 this.EventListenerService.registerObserverCallback(EVENTS.LEFT_PALETTE_UPDATE_EVENT, () => {
111 this.updateLeftPanelDisplay(scope);
115 private unRegisterEventListenerForLeftPalette = (scope: IPaletteScope): void => {
116 this.EventListenerService.unRegisterObserver(EVENTS.LEFT_PALETTE_UPDATE_EVENT);
119 private leftPanelResourceFilter(resourcesNotAbstract: Array<LeftPaletteComponent>, resourceFilterTypes: Array<string>): Array<LeftPaletteComponent> {
120 let filterResources = _.filter(resourcesNotAbstract, (component) => {
121 return resourceFilterTypes.indexOf(component.getComponentSubType()) > -1;
123 return filterResources;
126 private initLeftPanel(leftPanelComponents: Array<LeftPaletteComponent>, resourceFilterTypes: Array<string>): LeftPanelModel {
127 let leftPanelModel = new LeftPanelModel();
129 if (resourceFilterTypes && resourceFilterTypes.length) {
130 leftPanelComponents = this.leftPanelResourceFilter(leftPanelComponents, resourceFilterTypes);
132 leftPanelModel.numberOfElements = leftPanelComponents && leftPanelComponents.length || 0;
134 if (leftPanelComponents && leftPanelComponents.length) {
136 let categories: any = _.groupBy(leftPanelComponents, 'mainCategory');
137 for (let category in categories)
138 categories[category] = _.groupBy(categories[category], 'subCategory');
140 leftPanelModel.sortedCategories = categories;
142 return leftPanelModel;
146 private initEvents(scope: IPaletteScope) {
147 scope.sectionClick = (section: string) => {
148 if (section === scope.expandedSection) {
149 scope.expandedSection = '';
152 scope.expandedSection = section;
155 scope.onMouseOver = (displayComponent: LeftPaletteComponent, sectionElem: HTMLElement) => {
156 if (this.isGroupOrPolicy(displayComponent)) {
157 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_SHOW_POPUP_PANEL, scope.currentComponent, displayComponent, sectionElem);
159 if (scope.isOnDrag) {
162 scope.isOnDrag = true;
163 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_IN, displayComponent);
164 this.$log.debug('palette::onMouseOver:: fired');
169 scope.onMouseOut = (displayComponent: LeftPaletteComponent) => {
170 if (this.isGroupOrPolicy(displayComponent)) {
171 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HIDE_POPUP_PANEL);
173 scope.isOnDrag = false;
174 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_OUT);
179 private isGroupOrPolicy(component: LeftPaletteComponent): boolean {
181 (component.categoryType === LeftPaletteMetadataTypes.Group ||
182 component.categoryType === LeftPaletteMetadataTypes.Policy)) {
188 private initComponents(scope: IPaletteScope) {
189 scope.searchComponents = (searchText: any): void => {
190 scope.displaySortedCategories = this._searchComponents(searchText, scope.model.sortedCategories);
191 this._initExpandedSection(scope, searchText);
194 scope.isDragable = scope.currentComponent.isComplex();
195 this.updateLeftPanelDisplay(scope);
198 private updateLeftPanelDisplay(scope: IPaletteScope) {
199 let entityType: string = scope.currentComponent.componentType.toLowerCase();
200 let resourceFilterTypes: Array<string> = this.sdcConfig.resourceTypesFilter[entityType];
201 scope.components = this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent);
202 //remove the container component from the list
203 let componentTempToDisplay = angular.copy(scope.components);
204 componentTempToDisplay = _.remove(componentTempToDisplay, function (leftPalettecomponent) {
205 return leftPalettecomponent.invariantUUID !== scope.currentComponent.invariantUUID;
207 scope.model = this.initLeftPanel(componentTempToDisplay, resourceFilterTypes);
208 scope.displaySortedCategories = angular.copy(scope.model.sortedCategories);
211 private _initExpandedSection(scope: IPaletteScope, searchText: string): void {
212 if (searchText == '') {
213 let isContainingCategory: boolean = false;
214 let categoryToExpand: string;
215 if (scope.currentComponent && scope.currentComponent.categories && scope.currentComponent.categories[0]) {
216 categoryToExpand = this.sdcMenu.categoriesDictionary[scope.currentComponent.categories[0].name];
217 for (let category in scope.model.sortedCategories) {
218 if (categoryToExpand == category) {
219 isContainingCategory = true;
224 isContainingCategory ? scope.expandedSection = categoryToExpand : scope.expandedSection = 'Generic';
227 scope.expandedSection = Object.keys(scope.displaySortedCategories).sort()[0];
231 private initDragEvents(scope: IPaletteScope) {
232 scope.dragStartCallback = (event: IDragDropEvent, ui, displayComponent: LeftPaletteComponent): void => {
233 if (scope.isLoading || !scope.isDragable || scope.isViewOnly || this.isGroupOrPolicy(displayComponent)) {
237 let component = _.find(this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent), (componentFullData: LeftPaletteComponent) => {
238 return displayComponent.uniqueId === componentFullData.uniqueId;
240 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DRAG_START, scope.dragElement, component);
242 scope.isOnDrag = true;
244 // this.graphUtils.showMatchingNodes(component, myDiagram, scope.sdcConfig.imagesPath);
245 // document.addEventListener('mousemove', moveOnDocument);
246 event.dataTransfer.component = component;
249 scope.dragStopCallback = () => {
250 scope.isOnDrag = false;
253 scope.onDragCallback = (event: IDragDropEvent): void => {
254 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DRAG_ACTION, event);
256 scope.setElementTemplate = (e) => {
257 let dragComponent: LeftPaletteComponent = _.find(this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent),
258 (fullComponent: LeftPaletteComponent) => {
259 return (<any>angular.element(e.currentTarget).scope()).component.uniqueId === fullComponent.uniqueId;
261 let componentInstance: ComponentInstance = this.ComponentInstanceFactory.createComponentInstanceFromComponent(dragComponent);
262 let node: CompositionCiNodeBase = this.NodesFactory.createNode(componentInstance);
264 // myDiagram.dragFromPalette = node;
265 this.nodeHtmlSubstitute.find("img").attr('src', node.img);
266 scope.dragElement = this.nodeHtmlSubstitute.clone().show();
268 return scope.dragElement;
272 private _searchComponents = (searchText: string, categories: any): void => {
273 let displaySortedCategories = angular.copy(categories);
274 if (searchText != '') {
275 angular.forEach(categories, function (category: any, categoryKey) {
277 angular.forEach(category, function (subcategory: Array<LeftPaletteComponent>, subcategoryKey) {
278 let filteredResources = [];
279 angular.forEach(subcategory, function (component: LeftPaletteComponent) {
281 let resourceFilterTerm: string = component.searchFilterTerms.toLowerCase();
282 if (resourceFilterTerm.indexOf(searchText.toLowerCase()) >= 0) {
283 filteredResources.push(component);
286 if (filteredResources.length > 0) {
287 displaySortedCategories[categoryKey][subcategoryKey] = filteredResources;
290 delete displaySortedCategories[categoryKey][subcategoryKey];
293 if (!(Object.keys(displaySortedCategories[categoryKey]).length > 0)) {
294 delete displaySortedCategories[categoryKey];
299 return displaySortedCategories;
302 public static factory = ($log,
303 LeftPaletteLoaderService,
306 ComponentInstanceFactory,
308 CompositionGraphGeneralUtils,
309 EventListenerService,
313 return new Palette($log,
314 LeftPaletteLoaderService,
317 ComponentInstanceFactory,
319 CompositionGraphGeneralUtils,
320 EventListenerService,
327 Palette.factory.$inject = [
329 'LeftPaletteLoaderService',
332 'ComponentInstanceFactory',
334 'CompositionGraphGeneralUtils',
335 'EventListenerService',