Create designer-tab component

Created designer-tab component for side-nav of resource context
Updated configuration according to new design

Change-Id: I3bbd3024318d48aa0c1560440877ecd3efbf8b89
Issue-ID: SDC-939
Signed-off-by: Idan Amit <ia096e@intl.att.com>
diff --git a/catalog-ui/src/app/app.ts b/catalog-ui/src/app/app.ts
index a3a1ba9..f3bfbb9 100644
--- a/catalog-ui/src/app/app.ts
+++ b/catalog-ui/src/app/app.ts
@@ -518,6 +518,15 @@
         );
 
         $stateProvider.state(
+            'workspace.designers', {
+                url: 'designers/*path',
+                parent: 'workspace',
+                templateUrl: './view-models/workspace/tabs/designers/designers-tab-view.html',
+                controller: viewModelsModuleName + '.DesignersTabViewModel'
+            }
+        );
+
+        $stateProvider.state(
             'adminDashboard', {
                 url: '/adminDashboard',
                 templateUrl: './view-models/admin-dashboard/admin-dashboard-view.html',
diff --git a/catalog-ui/src/app/models/designers-config.ts b/catalog-ui/src/app/models/designers-config.ts
index c218c89..6b4233f 100644
--- a/catalog-ui/src/app/models/designers-config.ts
+++ b/catalog-ui/src/app/models/designers-config.ts
@@ -11,7 +11,7 @@
 
 export class DesignerDisplayOptions {
     displayName: string;
-    validResourceTypes: Array<string>;
+    displayContext: Array<string>;
 }
 
 export type Designers = Array<Designer>;
diff --git a/catalog-ui/src/app/modules/view-model-module.ts b/catalog-ui/src/app/modules/view-model-module.ts
index 63ca901..321d039 100644
--- a/catalog-ui/src/app/modules/view-model-module.ts
+++ b/catalog-ui/src/app/modules/view-model-module.ts
@@ -74,6 +74,7 @@
 import {downgradeComponent} from "@angular/upgrade/static";
 import {ConformanceLevelModalViewModel} from "../view-models/modals/conformance-level-modal/conformance-level-modal-view-model";
 import {DesignersViewModel} from "../view-models/designers/designers-view-model";
+import {DesignersTabViewModel} from "../view-models/workspace/tabs/designers/designers-tab-view-model";
 // import {NG2ExampleComponent} from "../ng2/view-ng2/ng2.example.component/ng2.example.component";
 // import {upgradeAdapter} from "../ng2/app.module";
 // import { UpgradeAdapter } from '@angular/upgrade';
@@ -137,6 +138,7 @@
   .controller(moduleName + '.ReqAndCapabilitiesViewModel', ReqAndCapabilitiesViewModel)
   .controller(moduleName + '.InputFormViewModel', InputFormViewModel)
   .controller(moduleName + '.DesignersViewModel', DesignersViewModel)
+  .controller(moduleName + '.DesignersTabViewModel', DesignersTabViewModel)
   //
   // //TABS
   .controller(moduleName + '.HierarchyViewModel', HierarchyViewModel);
diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts
index 3ea652a..c04da62 100644
--- a/catalog-ui/src/app/utils/constants.ts
+++ b/catalog-ui/src/app/utils/constants.ts
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -198,8 +198,8 @@
 }
 
 export class GraphUIObjects {
-    public static HANDLE_SIZE = 18; 
-    public static NODE_OVERLAP_MIN_SIZE = 30; 
+    public static HANDLE_SIZE = 18;
+    public static NODE_OVERLAP_MIN_SIZE = 30;
     public static DEFAULT_RESOURCE_WIDTH = 65;
     public static SMALL_RESOURCE_WIDTH = 21;
     public static LINK_MENU_HEIGHT = 420;
@@ -239,6 +239,7 @@
     public static WORKSPACE_DISTRIBUTION = 'workspace.distribution';
     public static WORKSPACE_PROPERTIES_ASSIGNMENT = 'workspace.properties_assignment';
     public static WORKSPACE_REQUIREMENTS_AND_CAPABILITIES = 'workspace.reqAndCap';
+    public static WORKSPACE_DESIGNERS = 'workspace.designers';
     public static WORKSPACE_NG2 = 'workspace.ng2';
 }
 
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/designers/designers-tab-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/designers/designers-tab-view-model.ts
new file mode 100644
index 0000000..03ce83e
--- /dev/null
+++ b/catalog-ui/src/app/view-models/workspace/tabs/designers/designers-tab-view-model.ts
@@ -0,0 +1,28 @@
+import {Designer, DesignersConfiguration} from "app/models";
+
+
+interface IDesignerTabViewModelScope extends ng.IScope {
+    designer: Designer;
+}
+
+export class DesignersTabViewModel {
+    static '$inject' = [
+        '$scope',
+        '$stateParams'
+    ];
+
+    constructor(private $scope:IDesignerTabViewModelScope,
+                private $stateParams:any) {
+
+        this.initScope();
+    }
+
+    private initScope = ():void => {
+        // get the designer object by using the path parameter
+        let designerKey: any = _.findKey(DesignersConfiguration.designers, (designerConfig: Designer) =>{
+            return designerConfig.designerStateUrl ===  this.$stateParams.path;
+        });
+
+        this.$scope.designer = DesignersConfiguration.designers[designerKey];
+    }
+}
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/designers/designers-tab-view.html b/catalog-ui/src/app/view-models/workspace/tabs/designers/designers-tab-view.html
new file mode 100644
index 0000000..7abb81a
--- /dev/null
+++ b/catalog-ui/src/app/view-models/workspace/tabs/designers/designers-tab-view.html
@@ -0,0 +1,5 @@
+<div class="workspace-designers">
+
+    <designer-frame [designer]="designer"></designer-frame>
+
+</div>
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/designers/designers-tab.less b/catalog-ui/src/app/view-models/workspace/tabs/designers/designers-tab.less
new file mode 100644
index 0000000..c8626dc
--- /dev/null
+++ b/catalog-ui/src/app/view-models/workspace/tabs/designers/designers-tab.less
@@ -0,0 +1,3 @@
+.workspace-designers {
+
+}
diff --git a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts
index 226785e..3846cf0 100644
--- a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@
  * Created by obarda on 3/30/2016.
  */
 'use strict';
-import {IUserProperties, IAppMenu, Resource, Component} from "app/models";
+import {IUserProperties, IAppMenu, Resource, Component, Designer, DesignersConfiguration, DesignerDisplayOptions} from "app/models";
 import {
     WorkspaceMode, ComponentFactory, ChangeLifecycleStateHandler, Role, ComponentState, MenuItemGroup, MenuHandler,
     MenuItem, ModalsHandler, States, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ResourceType
@@ -58,6 +58,7 @@
     changeVersion:any;
     isComposition:boolean;
     isDeployment:boolean;
+    isDesigners:boolean;
     $state:ng.ui.IStateService;
     user:IUserProperties;
     thirdParty:boolean;
@@ -70,7 +71,7 @@
     showChangeStateButton():boolean;
     getComponent():Component;
     setComponent(component:Component):void;
-    onMenuItemPressed(state:string):ng.IPromise<boolean>;
+    onMenuItemPressed(state:string, params:any):ng.IPromise<boolean>;
     save():ng.IPromise<boolean>;
     setValidState(isValid:boolean):void;
     revert():void;
@@ -88,6 +89,7 @@
     getStatus():string;
     showLifecycleIcon():boolean;
     updateSelectedMenuItem(state:string):void;
+    isSelected(menuItem:MenuItem):boolean;
     uploadFileChangedInGeneralTab():void;
     updateMenuComponentName(ComponentName:string):void;
     getTabTitle():string;
@@ -214,14 +216,15 @@
             }
         };
 
-        this.$scope.onMenuItemPressed = (state:string):ng.IPromise<boolean> => {
+        this.$scope.onMenuItemPressed = (state:string, params:any):ng.IPromise<boolean> => {
             let deferred = this.$q.defer();
             let goToState = ():void => {
-                this.$scope.updateSelectedMenuItem(state);
-                this.$state.go(state, {
+                this.$state.go(state, Object.assign({
                     id: this.$scope.component.uniqueId,
                     type: this.$scope.component.componentType.toLowerCase(),
                     components: this.components
+                }, params)).then(() => {
+                    this.$scope.updateSelectedMenuItem(state);
                 });
                 deferred.resolve(true);
             };
@@ -616,18 +619,32 @@
         };
 
         this.$scope.updateSelectedMenuItem = (state:string):void => {
-            let stateArray:Array<string> = state.split('.');
+            let stateArray:Array<string> = state.split('.', 2);
             let stateWithoutInternalNavigate:string = stateArray[0] + '.' + stateArray[1];
             let selectedItem:MenuItem = _.find(this.$scope.leftBarTabs.menuItems, (item:MenuItem) => {
-                return _.startsWith(item.state, stateWithoutInternalNavigate);
+                let itemStateArray: Array<string> = item.state.split('.', 2);
+                let itemStateWithoutNavigation:string = itemStateArray[0] + '.' + itemStateArray[1];
+                return (itemStateWithoutNavigation === stateWithoutInternalNavigate);
             });
-            this.$scope.leftBarTabs.selectedIndex = selectedItem ? this.$scope.leftBarTabs.menuItems.indexOf(selectedItem) : 0;
+
+            let selectedIndex = selectedItem ? this.$scope.leftBarTabs.menuItems.indexOf(selectedItem) : 0;
+
+            if (stateArray[1] === 'designers') {
+                selectedIndex += _.findIndex(DesignersConfiguration.designers, (designer: Designer) => designer.designerStateUrl === this.$state.params.path);
+            }
+
+            this.$scope.leftBarTabs.selectedIndex = selectedIndex;
         };
 
+        this.$scope.isSelected = (menuItem:MenuItem): boolean => {
+            return this.$scope.leftBarTabs.selectedIndex === _.indexOf(this.$scope.leftBarTabs.menuItems, menuItem);
+        }
+
         this.$scope.$watch('$state.current.name', (newVal:string):void => {
             if (newVal) {
                 this.$scope.isComposition = (newVal.indexOf(States.WORKSPACE_COMPOSITION) > -1);
                 this.$scope.isDeployment = newVal == States.WORKSPACE_DEPLOYMENT;
+                this.$scope.isDesigners = newVal == States.WORKSPACE_DESIGNERS;
             }
         });
 
@@ -669,9 +686,9 @@
         return new MenuItem(text, null, States.WORKSPACE_GENERAL, 'goToState', [this.$state.params]);
     };
 
-    private updateMenuItemByRole = (menuItems:Array<MenuItem>, role:string) => {
-        let tempMenuItems:Array<MenuItem> = new Array<MenuItem>();
-        menuItems.forEach((item:MenuItem) => {
+    private updateMenuItemByRole = (menuItems:Array<any>, role:string) : Array<any> => {
+        let tempMenuItems:Array<any> = new Array<any>();
+        menuItems.forEach((item:any) => {
             //remove item if role is disabled
             if (!(item.disabledRoles && item.disabledRoles.indexOf(role) > -1)) {
                 tempMenuItems.push(item);
@@ -700,13 +717,37 @@
 
         let inCreateMode = this.$scope.isCreateMode();
         this.$scope.leftBarTabs = new MenuItemGroup();
-        this.$scope.leftBarTabs.menuItems = this.updateMenuItemByRole(this.sdcMenu.component_workspace_menu_option[this.$scope.component.getComponentSubType()], this.role);
+        const menuItemsObjects:Array<any> = this.updateMenuItemByRole(this.sdcMenu.component_workspace_menu_option[this.$scope.component.getComponentSubType()], this.role);
 
-        this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
-            item.params = [item.state];
-            item.callback = this.$scope.onMenuItemPressed;
+        // Only need to add designers to the menu if the current role is Designer
+        if (this.role === "DESIGNER") {
+            _.each(DesignersConfiguration.designers, (designer: Designer) => {
+                if (designer.designerDisplayOptions["context"]) {
+                    let displayOptions : DesignerDisplayOptions = designer.designerDisplayOptions["context"];
+
+                    if (displayOptions.displayContext.indexOf(this.$scope.component.getComponentSubType()) !== -1) {
+                        menuItemsObjects.push({
+                            text: displayOptions.displayName,
+                            action: 'onMenuItemPressed',
+                            state: 'workspace.designers',
+                            params: {path: designer.designerStateUrl}
+                        });
+                    }
+                }
+            });
+        }
+
+        this.$scope.leftBarTabs.menuItems = menuItemsObjects.map((item:MenuItem) => {
+            if (item.params) {
+                item.params.state = item.state;
+            }
+            else {
+                item.params = {state: item.state};
+            }
+            item.callback = () => this.$scope[item.action](item.state, item.params);
             item.isDisabled = (inCreateMode && States.WORKSPACE_GENERAL != item.state) ||
                 (States.WORKSPACE_DEPLOYMENT === item.state && this.$scope.component.groups && this.$scope.component.groups.length === 0 && this.$scope.component.isResource());
+            return new MenuItem(item.text, item.callback, item.state, item.action, item.params, item.blockedForTypes);
         });
 
         if (this.cacheService.get('breadcrumbsComponents')) {
@@ -722,16 +763,12 @@
 
     private disableMenuItems() {
         this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
-            item.params = [item.state];
-            item.callback = this.$scope.onMenuItemPressed;
             item.isDisabled = (States.WORKSPACE_GENERAL != item.state);
         });
     }
 
     private enableMenuItems() {
         this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
-            item.params = [item.state];
-            item.callback = this.$scope.onMenuItemPressed;
             item.isDisabled = false;
         });
     }
diff --git a/catalog-ui/src/app/view-models/workspace/workspace-view.html b/catalog-ui/src/app/view-models/workspace/workspace-view.html
index 0663074..f076ba0 100644
--- a/catalog-ui/src/app/view-models/workspace/workspace-view.html
+++ b/catalog-ui/src/app/view-models/workspace/workspace-view.html
@@ -6,8 +6,8 @@
             <div class="menu-header" tooltips tooltip-content="{{menuComponentTitle}}">
                 {{menuComponentTitle}}
             </div>
-            <div class="i-sdc-designer-sidebar-section-content-item" ng-class="{'selected': menuItem.state == $state.current.name}" ng-repeat="menuItem in leftBarTabs.menuItems track by $index">
-                <div class="expand-collapse-menu-box-item-text" ng-click="onMenuItemPressed(menuItem.state)" ng-class="{'disabled': menuItem.isDisabled }" data-tests-id="{{menuItem.text}}LeftSideMenu">{{menuItem.text}}</div>
+            <div class="i-sdc-designer-sidebar-section-content-item" ng-class="{'selected': isSelected(menuItem)}" ng-repeat="menuItem in leftBarTabs.menuItems track by $index">
+                <div class="expand-collapse-menu-box-item-text" ng-click="menuItem.callback()" ng-class="{'disabled': menuItem.isDisabled }" data-tests-id="{{menuItem.text}}LeftSideMenu">{{menuItem.text}}</div>
             </div>
         </div>
 
@@ -63,14 +63,14 @@
 
                     <span data-ng-if="isDesigner()" data-ng-class="{'disabled' :isDisableMode() || isViewMode()}"  ng-click="revert()" class="sprite-new revert-btn" data-tests-id="revert"
                           data-ng-show="showFullIcons()" sdc-smart-tooltip="">Revert</span>
-                    
+
                     <span class="delimiter"></span>
                     <span class="sprite-new x-btn" data-ng-click="goToBreadcrumbHome()" sdc-smart-tooltip="">Close</span>
 
                 </div>
             </div>
             <div class="w-sdc-main-container-body-content-wrapper">
-                <div class="tab-title" data-ng-if="!isComposition && !isDeployment">
+                <div class="tab-title" data-ng-if="!isComposition && !isDeployment && !isDesigners">
                     {{getTabTitle()}}
                 </div>
                 <div class="w-sdc-main-container-body-content" data-ng-class="{'third-party':thirdParty}" data-ui-view></div>