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=========================================================
21 import * as _ from "lodash";
22 import {Component, EventEmitter, Inject, Input, OnChanges, OnInit, Output} from "@angular/core";
23 import {IHostedApplication, IUserProperties, Plugin, PluginsConfiguration} from "app/models";
24 import {MenuItem, MenuItemGroup} from "app/utils";
25 import {AuthenticationService} from "../../../services/authentication.service";
26 import {ISdcConfig, SdcConfigToken} from "../../../config/sdc-config.config";
27 import {TranslateService} from "../../../shared/translator/translate.service";
28 import {Subscription} from "rxjs";
30 declare const window:any;
33 templateUrl: './top-nav.component.html',
34 styleUrls:['./top-nav.component.less']
36 export class TopNavComponent implements OnInit, OnChanges {
37 @Input() public version:string;
38 @Input() public menuModel:Array<MenuItemGroup>;
39 @Input() public topLvlSelectedIndex:number;
40 @Input() public hideSearch:boolean;
41 @Input() public searchTerm:string;
42 @Input() public notificationIconCallback:Function;
43 @Input() public unsavedChanges: boolean;
44 @Input() public unsavedChangesCallback: (completeCallback:Function)=> Promise<any>;
45 @Output() public searchTermChange:EventEmitter<string> = new EventEmitter<string>();
46 emitSearchTerm(event:string) {
47 this.searchTermChange.emit(event);
50 private subscription: Subscription;
51 private hasUnsavedChanges: boolean;
52 public topLvlMenu:MenuItemGroup;
53 public user:IUserProperties;
54 private topNavPlugins: Array<Plugin>;
56 constructor(private translateService:TranslateService,
57 @Inject('$state') private $state:ng.ui.IStateService,
58 private authService:AuthenticationService,
59 @Inject(SdcConfigToken) private sdcConfig:ISdcConfig) {
64 private _getTopLvlSelectedIndexByState = ():number => {
65 if (!this.topLvlMenu.menuItems) {
71 //set result to current state
72 this.topLvlMenu.menuItems.every((item:MenuItem, index:number)=> {
73 if (item.state === this.$state.current.name) {
74 if (this.$state.current.name === 'plugins') {
75 const pluginIdx = _.findIndex(this.topNavPlugins, (plugin: Plugin) => plugin.pluginStateUrl === this.$state.params.path);
76 if (pluginIdx !== -1) {
77 result = index + pluginIdx;
88 //if it's a different state
90 //if in 'workspace' - checking previous state param
91 if (this.$state.includes('workspace')) {
92 // if previous state is 'dashboard' or 'catalog', then select it - otherwise, use 'catalog' as default for 'workspace'
93 const selectedStateName = (['dashboard', 'catalog'].indexOf(this.$state.params['previousState']) !== -1)
94 ? this.$state.params['previousState']
96 result = this.topLvlMenu.menuItems.findIndex((item:MenuItem) => item.state === selectedStateName);
99 //if yet, none is selected, then select the first as default
108 ngOnChanges(changes) {
109 if (changes['menuModel']) {
110 console.debug('menuModel was changed!');
116 console.debug('Nav is init!', this.menuModel);
117 this.user = this.authService.getLoggedinUser();
118 this.topNavPlugins = _.filter(PluginsConfiguration.plugins, (plugin: Plugin) => {
119 return plugin.pluginDisplayOptions["tab"] !== undefined;
122 this.translateService.languageChangedObservable.subscribe((lang) => {
123 let tmpArray: Array<MenuItem> = [
124 new MenuItem(this.translateService.translate("TOP_MENU_HOME_BUTTON"), null, "dashboard", "goToState", null, null),
125 new MenuItem(this.translateService.translate("TOP_MENU_CATALOG_BUTTON"), null, "catalog", "goToState", null, null)
128 // Only designer can perform onboarding
129 if (this.user && this.user.role === 'DESIGNER') {
130 tmpArray.push(new MenuItem(this.translateService.translate("TOP_MENU_ON_BOARD_BUTTON"), null, "onboardVendor", "goToState", null, null));
131 _.each(this.sdcConfig.hostedApplications, (hostedApp: IHostedApplication) => {
132 if (hostedApp.exists) {
133 tmpArray.push(new MenuItem(hostedApp.navTitle, null, hostedApp.defaultState, "goToState", null, null));
138 // Adding plugins to top-nav only if they can be displayed for the current connected user role
139 _.each(PluginsConfiguration.plugins, (plugin: Plugin) => {
140 if (plugin.pluginDisplayOptions["tab"] && (this.user && plugin.pluginDisplayOptions["tab"].displayRoles.includes(this.user.role))) {
141 tmpArray.push(new MenuItem(plugin.pluginDisplayOptions["tab"].displayName, null, "plugins", "goToState", {path: plugin.pluginStateUrl}, null));
145 this.topLvlMenu = new MenuItemGroup(0, tmpArray, true);
146 this.topLvlMenu.selectedIndex = isNaN(this.topLvlSelectedIndex) ? this._getTopLvlSelectedIndexByState() : this.topLvlSelectedIndex;
152 if (this.menuModel && this.topLvlMenu && this.menuModel[0] !== this.topLvlMenu) {
153 this.menuModel.unshift(this.topLvlMenu);
157 goToState(state:string, params:any):Promise<boolean> {
158 return new Promise((resolve, reject) => {
159 this.$state.go(state, params || undefined);
165 menuItemClick(itemGroup:MenuItemGroup, item:MenuItem) {
167 let onSuccessFunction = () => {
168 this.navigate(itemGroup, item);
170 if (this.unsavedChanges && this.unsavedChangesCallback){
171 this.unsavedChangesCallback(onSuccessFunction).then((onSuccess)=> {
172 this.navigate(itemGroup, item);
173 }, (onReject) => {});
175 this.navigate(itemGroup, item);
179 navigate(itemGroup:MenuItemGroup, item:MenuItem) {
180 itemGroup.itemClick = false;
181 let onSuccess = ():void => {
182 itemGroup.selectedIndex = itemGroup.menuItems.indexOf(item);
184 let onFailed = ():void => {
188 (item.callback.apply(undefined, item.params)).then(onSuccess, onFailed);
189 } else if (this[item.action]) {
190 this[item.action](item.state, item.params).then(onSuccess, onFailed);