summaryrefslogtreecommitdiffstats
path: root/ecomp-portal-FE-common/client/app/views/header
diff options
context:
space:
mode:
Diffstat (limited to 'ecomp-portal-FE-common/client/app/views/header')
-rw-r--r--ecomp-portal-FE-common/client/app/views/header/header.controller.js449
-rw-r--r--ecomp-portal-FE-common/client/app/views/header/header.controller.spec.js19
-rw-r--r--ecomp-portal-FE-common/client/app/views/header/header.less496
-rw-r--r--ecomp-portal-FE-common/client/app/views/header/header.tpl.html266
4 files changed, 1230 insertions, 0 deletions
diff --git a/ecomp-portal-FE-common/client/app/views/header/header.controller.js b/ecomp-portal-FE-common/client/app/views/header/header.controller.js
new file mode 100644
index 00000000..961362a5
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/header/header.controller.js
@@ -0,0 +1,449 @@
+/*-
+ * ================================================================================
+ * ECOMP Portal
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property
+ * ================================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ================================================================================
+ */
+'use strict';
+(function () {
+ class HeaderCtrl {
+ constructor($log, $window, userProfileService, menusService, $scope, ECOMP_URL_REGEX, $cookies, $state,auditLogService,notificationService) {
+ this.firstName = '';
+ this.lastName = '';
+ this.$log = $log;
+ this.menusService = menusService;
+ this.$scope = $scope;
+ this.favoritesMenuItems = '';
+ $scope.favoriteItemsCount = 0;
+ $scope.favoritesMenuItems = '';
+ $scope.showFavorites = false;
+ $scope.emptyFavorites = false;
+ $scope.favoritesWindow = false;
+ $scope.notificationCount=0;
+ $scope.showNotification = true;
+
+ $scope.hideMenus = false;
+
+ $scope.menuItems = [];
+ $scope.activeClickSubMenu = {
+ x: ''
+ };
+ $scope.activeClickMenu = {
+ x: ''
+ };
+ $scope.megaMenuDataObject =[];
+ $scope.notificationCount= notificationService.notificationCount;
+ this.isLoading = true;
+ this.ECOMP_URL_REGEX = ECOMP_URL_REGEX;
+
+ var unflatten = function( array, parent, tree ){
+
+ tree = typeof tree !== 'undefined' ? tree : [];
+ parent = typeof parent !== 'undefined' ? parent : { menuId: null };
+ var children = _.filter( array, function(child){ return child.parentMenuId == parent.menuId; });
+
+ if( !_.isEmpty( children ) ){
+ if( parent.menuId === null ){
+ tree = children;
+ }else{
+ parent['children'] = children
+ }
+ _.each( children, function( child ){ unflatten( array, child ) } );
+ }
+
+ return tree;
+ }
+
+ userProfileService.getFunctionalMenuStaticInfo()
+ .then(res=> {
+ // $log.debug('HeaderCtrl::getFunctionalMenuStaticInfo: getting Functional Menu Static Info init');
+ if(res==null || res.firstName==null || res.firstName=='' || res.lastName==null || res.lastName=='' ){
+ // $log.info('HeaderCtrl::getFunctionalMenuStaticInfo: failed getting userinfo from shared context.. ');
+ $log.info('HeaderCtrl: failed to get all required data, trying user profile');
+ userProfileService.getUserProfile()
+ .then(profile=> {
+ // $log.debug('HeaderCtrl:: getting userinfo from session success');
+ this.firstName = profile.firstName;
+ this.lastName = profile.lastName;
+ // $log.debug('HeaderCtrl::getFunctionalMenuStaticInfo: user has the following roles: ' + profile.roles);
+ }).catch(err=> {
+ $log.error('Header Controller:: getUserProfile() failed: ' + err);
+ });
+ } else {
+ // $log.debug('HeaderCtrl: fetched Functional Menu Static Info successfully',res);
+ this.firstName = res.firstName;
+ this.lastName = res.lastName;
+ }
+
+ menusService.GetFunctionalMenuForUser()
+ .then(jsonHeaderMenu=> {
+ $scope.menuItems = unflatten( jsonHeaderMenu );
+ $scope.megaMenuDataObject = $scope.menuItems;
+ }).catch(err=> {
+ $log.error('HeaderCtrl::GetFunctionalMenuForUser: HeaderCtrl json returned: ' + err);
+ });
+
+ }).catch(err=> {
+ $log.error('HeaderCtrl::getFunctionalMenuStaticInfo failed: ' + err);
+ });
+
+ //store audit log
+ $scope.auditLog = function(app,type) {
+ var comment = 'type: '+type+ ',title: '+app.text+",url: "+app.url;
+ auditLogService.storeAudit(app.appid,'functional',comment);
+ };
+
+ $scope.loadFavorites = function () {
+ $scope.hideMenus = false;
+ // $log.debug('HeaderCtrl::loadFavorites: loadFavorites has happened.');
+ if ($scope.favoritesMenuItems == '') {
+ generateFavoriteItems();
+ // $log.debug('HeaderCtrl::loadFavorites: loadFavorites is calling generateFavoriteItems()');
+ } else {
+ // $log.debug('HeaderCtrl::loadFavorites: loadFavorites is NOT calling generateFavoriteItems()');
+ }
+ }
+
+ $scope.goToUrl = (item) => {
+ // $log.error('HeaderCtrl::goToUrl has started',item);
+ let url = item.url;
+ let restrictedApp = item.restrictedApp;
+ if (!url) {
+ $log.warn('HeaderCtrl::goToUrl: No url found for this application, doing nothing..');
+ return;
+ }
+ if (restrictedApp) {
+ $window.open(url, '_blank');
+ } else {
+ if(item.url=="getAccess" || item.url=="contactUs"){
+ // if (url = window.location.href)
+ $state.go("root."+url);
+ } else {
+ var tabContent = { id: new Date(), title: item.text, url: item.url,appId:item.appid };
+ $cookies.putObject('addTab', tabContent );
+ }
+ // $log.debug('HeaderCtrl::goToUrl: url = ', url);
+ }
+ $scope.hideMenus = true;
+ }
+
+
+
+ $scope.submenuLevelAction = function(index, column) {
+ if ($scope.favoritesMenuItems == '') {
+ generateFavoriteItems();
+ // $log.debug('HeaderCtrl::submenuLevelAction: submenuLevelAction is calling generateFavoriteItems()');
+ } else {
+ // $log.debug('submenuLevelAction is NOT calling generateFavoriteItems()');
+ }
+ // $log.debug('item hovered: ' + index + '; column = ' + column);
+ // if (column == 2) { // 2 is Design
+ // // This is an admitted hack. See aw3218 for reasons why
+ // $log.debug('submenuLevelAction column == 2');
+ // $scope.favoritesWindow = false;
+ // $scope.showFavorites = false;
+ // $scope.emptyFavorites = false;
+ // }
+ if (index=='Favorites' && $scope.favoriteItemsCount != 0) {
+ // $log.debug('HeaderCtrl::submenuLevelAction: Showing Favorites window');
+ // generateFavoriteItems();
+ $scope.favoritesWindow = true;
+ $scope.showFavorites = true;
+ $scope.emptyFavorites = false;
+ }
+ if (index=='Favorites' && $scope.favoriteItemsCount == 0) {
+ // $log.debug('HeaderCtrl::submenuLevelAction: Hiding Favorites window in favor of No Favorites Window');
+ // generateFavoriteItems();
+ $scope.favoritesWindow = true;
+ $scope.showFavorites = false;
+ $scope.emptyFavorites = true;
+ }
+ if (index!='Favorites' ) {
+ $scope.favoritesWindow = false;
+ $scope.showFavorites = false;
+ $scope.emptyFavorites = false;
+ }
+
+ };
+
+ $scope.hideFavoritesWindow = function() {
+ $scope.showFavorites = false;
+ $scope.emptyFavorites = false;
+ // $scope.thirdFourthMenus = true;
+ }
+
+ $scope.isUrlFavorite = function (menuId) {
+ // $log.debug('array objects in menu favorites = ' + $scope.favoriteItemsCount + '; menuId=' + menuId);
+ var jsonMenu = JSON.stringify($scope.favoritesMenuItems);
+ var isMenuFavorite = jsonMenu.indexOf('menuId\":' + menuId);
+ // $log.debug('jsonMenu.indexOf(menuId:' + jsonMenu.indexOf('menuId\":'+menuId));
+ // $log.debug('isMenuFavorite= ' + isMenuFavorite);
+ if (isMenuFavorite==-1) {
+ return false;
+ } else {
+ return true;
+ }
+
+ }
+
+ let generateFavoriteItems = () => {
+ menusService.getFavoriteItems()
+ .then(favorites=> {
+ // $log.debug('HeaderCtrl.getFavoriteItems:: ' + JSON.stringify(favorites));
+ $scope.favoritesMenuItems = favorites;
+ $scope.favoriteItemsCount = Object.keys(favorites).length;
+ // $log.info('HeaderCtrl.getFavoriteItems:: number of favorite menus: ' + $scope.favoriteItemsCount);
+ }).catch(err=> {
+ $log.error('HeaderCtrl.getFavoriteItems:: Error retrieving Favorites menus: ' + err);
+ });
+ }
+
+ $scope.setAsFavoriteItem = function(event, menuId){
+ var jsonMenuID = angular.toJson({'menuId': + menuId });
+ // $log.debug('HeaderCtrl::setFavoriteItems: ' + jsonMenuID + " - " + event.target.id);
+
+ menusService.setFavoriteItem(jsonMenuID)
+ .then(() => {
+ // var elementId = '#'+ event.currentTarget.id;
+ angular.element('#' + event.target.id).css('color', '#fbb313');
+ generateFavoriteItems();
+ }).catch(err=> {
+ $log.error('HeaderCtrl::setFavoriteItems:: API setFavoriteItem error: ' + err);
+ });
+ };
+
+ $scope.removeAsFavoriteItem = function(event, menuId){
+ // $log.debug('-----------------------------removeAsFavoriteItem: ' + menuId + " - " + event.target.id);
+ menusService.removeFavoriteItem(menuId)
+ .then(() => {
+ angular.element('#' + event.target.id).css('color', '#666666');
+ generateFavoriteItems();
+ }).catch(err=> {
+ $log.error('HeaderCtrl::removeAsFavoriteItem: API removeFavoriteItem error: ' + err);
+ });
+ };
+
+ $scope.goToPortal = (headerText, url) => {
+ if (!url) {
+ $log.warn('HeaderCtrl::goToPortal: No url found for this application, doing nothing..');
+ return;
+ }
+ if (!ECOMP_URL_REGEX.test(url)) {
+ url = 'http://' + url;
+ }
+
+ if(headerText.startsWith("vUSP")) {
+ window.open(url, '_blank');//, '_self'
+ }
+ else {
+ var tabContent = { id: new Date(), title: headerText, url: url };
+ $cookies.putObject('addTab', tabContent );
+ }
+ };
+
+ }
+ }
+ class LoginSnippetCtrl {
+ constructor($log, $scope, $cookies, $timeout, userProfileService, sessionService) {
+ $scope.firstName="";
+ $scope.lastName="";
+ $scope.displayUserAppRoles=false;
+ $scope.allAppsLogout = function(){
+
+ var cookieTabs = $cookies.getObject('visInVisCookieTabs');
+ if(cookieTabs!=null){
+ for(var t in cookieTabs){
+
+ var url = cookieTabs[t].content;
+ if(url != "") {
+ sessionService.logout(url);
+ }
+ }
+ }
+ // wait for individual applications to log out before the portal logout
+ $timeout(function() {
+ window.location = "logout.htm";
+ }, 2000);
+ }
+
+
+ try {
+ userProfileService.getFunctionalMenuStaticInfo()
+ .then(res=> {
+ // $log.info('HeaderCtrl::LoginSnippetCtrl: Login information: ' + JSON.stringify(res));
+ $scope.firstName = res.firstName;
+ $scope.lastName = res.lastName;
+ $scope.loginSnippetEmail = res.email;
+ $scope.loginSnippetUserid = res.userId;
+ $scope.lastLogin = res.last_login;
+ }).catch(err=> {
+ $log.error('HeaderCtrl::LoginSnippetCtrl: failed in getFunctionalMenuStaticInfo: ' + err);
+ });
+ } catch (err) {
+ $log.error('HeaderCtrl::LoginSnippetCtrl caught exception: ' + err);
+ }
+
+ $scope.getUserApplicationRoles= function(){
+ $scope.userapproles = [];
+ if($scope.displayUserAppRoles)
+ $scope.displayUserAppRoles = false;
+ else
+ $scope.displayUserAppRoles = true;
+
+ userProfileService.getUserAppRoles($scope.loginSnippetUserid)
+ .then(res=>{
+
+ for(var i=0;i<res.length;i++){
+ var userapprole ={
+ App:res[i].appName,
+ Roles:res[i].roleNames,
+ };
+
+ $scope.userapproles.push(userapprole);
+ }
+
+ });
+
+ }
+ }
+ }
+ class NotificationCtrl{
+ constructor($log, $scope, $cookies, $timeout, sessionService,notificationService,$interval,ngDialog) {
+ $scope.notifications=[];
+ var intervalPromise = null;
+ $scope.notificationCount= notificationService.notificationCount;
+
+ $scope.getNotification = function(){
+ notificationService.getNotification()
+ .then(res=> {
+ notificationService.decrementRefreshCount();
+ var count = notificationService.getRefreshCount();
+ if (res==null || res.data==null || res.data.message!='success') {
+ $log.error('NotificationCtrl::updateNotifications: failed to get notifications');
+ if (intervalPromise != null)
+ $interval.cancel(intervalPromise);
+ } else if(count<=0){
+ if (intervalPromise != null)
+ $interval.cancel(intervalPromise);
+ } else {
+ $scope.notifications = [];
+ notificationService.setNotificationCount(res.data.response.length);
+ for(var i=0;i<res.data.response.length;i++){
+ var data = res.data.response[i];
+ var notification ={
+ id:data.notificationId,
+ title:data.msgHeader,
+ message:data.msgDescription,
+ source:data.msgSource,
+ time:data.createdDate,
+ priority:data.priority
+ };
+ $scope.notifications.push(notification);
+ }
+ }
+ }).catch(err=> {
+ $log.error('NotificationCtrl::getNotification: caught exception: ' + err);
+ if (intervalPromise != null)
+ $interval.cancel(intervalPromise);
+ });
+ }
+ $scope.getNotification();
+ function updateNotifications() {
+ $scope.getNotification();
+ }
+ $scope.start = function(rate) {
+ // stops any running interval to avoid two intervals running at the same time
+ $scope.stop();
+ // store the interval promise
+ intervalPromise = $interval(updateNotifications, rate);
+ };
+
+ $scope.stop = function() {
+ $interval.cancel(intervalPromise);
+ };
+
+
+ $scope.showDetailedJsonMessage=function (selectedAdminNotification) {
+ if (selectedAdminNotification.source!=='EP'){
+ var messageObject=JSON.parse(selectedAdminNotification.message);
+ var html="";
+ html+='<p>'+'Message Source'+' : '+selectedAdminNotification.source+'</p>';
+ html+='<p>'+'Message Title'+' : '+selectedAdminNotification.title+'</p>';
+ for(var field in messageObject){
+ if(field=='eventDate'||field=='lastModifiedDate'){
+ html+='<p>'+field+' : '+new Date(+messageObject[field])+'</p>';
+
+ }else{
+ html+='<p>'+field+' : '+messageObject[field]+'</p>';
+
+ }
+ }
+
+ var modalInstance = ngDialog.open({
+ templateUrl: 'app/views/user-notifications-admin/user.notifications.Json.details.modal.page.html',
+ controller: 'userNotificationCtrl',
+ resolve: {
+ message: function () {
+ var message = {
+ title: '',
+ text: html
+
+ };
+ return message;
+ },
+
+ }
+ });
+
+ }
+ };
+
+ notificationService.getNotificationRate().then(res=> {
+ if (res == null || res.response == null) {
+ $log.error('NotificationCtrl: failed to notification update rate or duration, check system.properties file.');
+ } else {
+ var rate = parseInt(res.response.updateRate);
+ var duration = parseInt(res.response.updateDuration);
+ notificationService.setMaxRefreshCount(parseInt(duration/rate)+1);
+ notificationService.setRefreshCount(notificationService.maxCount);
+ if (rate != NaN && duration != NaN) {
+ $scope.updateRate=rate;
+ $scope.start($scope.updateRate);
+ }
+ }
+ }).catch(err=> {
+ $log.error('NotificationCtrl: getNotificationRate() failed: ' + err);
+ });
+
+ $scope.deleteNotification = function(index){
+ if ($scope.notifications[index].id == null || $scope.notifications[index].id == '') {
+ $log.error('NotificationCtrl: failed to delete Notification.');
+ return;
+ }
+ notificationService.setNotificationRead($scope.notifications[index].id);
+ $scope.notifications.splice(index,1);
+ notificationService.setNotificationCount($scope.notifications.length);
+ }
+ }
+ }
+ NotificationCtrl.$inject = ['$log', '$scope', '$cookies', '$timeout', 'sessionService','notificationService','$interval','ngDialog'];
+ LoginSnippetCtrl.$inject = ['$log', '$scope', '$cookies', '$timeout','userProfileService', 'sessionService'];
+ HeaderCtrl.$inject = ['$log', '$window', 'userProfileService', 'menusService', '$scope', 'ECOMP_URL_REGEX','$cookies','$state','auditLogService','notificationService'];
+ angular.module('ecompApp').controller('HeaderCtrl', HeaderCtrl);
+ angular.module('ecompApp').controller('loginSnippetCtrl', LoginSnippetCtrl);
+ angular.module('ecompApp').controller('notificationCtrl', NotificationCtrl);
+
+})();
diff --git a/ecomp-portal-FE-common/client/app/views/header/header.controller.spec.js b/ecomp-portal-FE-common/client/app/views/header/header.controller.spec.js
new file mode 100644
index 00000000..3841a2b3
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/header/header.controller.spec.js
@@ -0,0 +1,19 @@
+/*-
+ * ================================================================================
+ * ECOMP Portal
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property
+ * ================================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ================================================================================
+ */
diff --git a/ecomp-portal-FE-common/client/app/views/header/header.less b/ecomp-portal-FE-common/client/app/views/header/header.less
new file mode 100644
index 00000000..ec57812c
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/header/header.less
@@ -0,0 +1,496 @@
+.header-section {
+ position: relative;
+ z-index: 999;
+}
+
+.logo-image {
+ .portal-logo;
+ display: inline-block;
+ vertical-align: middle;
+ margin-top: -3px;
+ }
+
+.portal-title {
+ font-weight: 400;
+ font-family: "Omnes-ECOMP-W02",Arial !important;
+ font-size: 18px;
+ //.c18b;
+}
+
+.parentmenu-tabs {
+ height: 55px;
+}
+
+.menu-section {
+ float: left;
+}
+
+/* Logout control*/
+.controlCls{
+ font-size: .975rem;
+ color: @portalDGray;
+ display: inline-block;
+ cursor: pointer;
+ height: 37px;
+ line-height: 37px;
+ padding-bottom: 10px;
+ vertical-align: middle;
+ width: 100%;
+}
+
+
+.controlCls:hover{
+ color:@portalLBlue !important;
+}
+
+.login-section {
+ float: right;
+ margin-top:15px;
+ min-width:150px;
+}
+
+.login-snippet-text {
+ display: inline-block;
+ font-size: 12px;
+ font-weight: bold;
+ margin-left: 5px;
+ overflow: hidden;
+ max-height: 31px;
+ max-width: 120px;
+ padding-top: 0;
+ margin-top: 0;
+ font-family: "Omnes-ECOMP-W02",Arial;
+ white-space: nowrap;
+}
+
+
+.newrow {
+ clear: left;
+}
+
+.header-columns{
+ -webkit-column-count:4;
+ -moz-column-rule: 1px outset @portalLGray;
+ -moz-column-count:4;
+ column-count: 4;
+ line-height: 12px;
+ max-height: 500px;
+ overflow-x: hidden;
+ overflow-y:hidden;
+ column-gap: 13px;
+ column-rule: 1px outset @portalLGray;
+
+
+}
+
+.header-columns li{
+ -webkit-column-break-inside: avoid;
+ break-inside: avoid;
+ //-webkit-page-break-inside: avoid;
+ page-break-inside: avoid;
+
+ margin-top: 0px !important;
+
+}
+
+.header-columns-div{
+ width:100%;
+ margin-left: 12px;
+ margin-top: 12px
+}
+
+
+//.favorites-icon li [class*=icon]:hover {
+.favorites-icon-active {
+ position: relative;
+ margin-top: 5px;
+ margin-left: 5px;
+ top: 3px;
+ color: @funcYellow;
+}
+
+.favorites-icon-inactive {
+ position: relative;
+ margin-top: 5px;
+ margin-left: 5px;
+ top: 3px;
+ color: @portalDGray;
+}
+
+.favorites-window-empty {
+ width: 100%;
+ height: auto;
+ justify-content:center;
+ align-items:center;
+ margin: auto;
+ text-align: center;
+
+ .no-fav-icon{
+ font-weight: 400;
+ font-size: 50px;
+ text-align: center;
+ color: rgb(255, 155, 0);
+ }
+ .largeText {
+ font-weight: 400;
+ font-family: Omnes-ECOMP-W02-Bold,Arial !important;
+ font-size: 18px;
+ text-align: center;
+ color: @portalDGray;
+ }
+
+ .normal {
+ color: @portalDGray;
+ font-size: 14px;
+ text-align: center;
+ }
+
+
+}
+.favorites-window {
+ width: 100%;
+ height: auto;
+ //margin: auto;
+ font-size: 14px !important;
+ display: flex;
+ margin-top: 25px;
+ margin-left: 25px;
+ z-index: 1000;
+
+ .fav-links {
+ margin-right: 25px;
+ }
+
+ .largeText {
+ font-weight: 400;
+ font-family: Omnes-ECOMP-W02-Bold,Arial !important;
+ font-size: 18px;
+ text-align: center;
+ color: @portalDGray;
+ }
+
+ a:link, a:active, a:hover {
+ margin-left: 3px;
+ margin-right: 20px;
+ text-decoration: none;
+ }
+
+ a:hover {
+ color: @portalLBlue;
+ }
+}
+
+
+
+ .notifications-count
+ {
+ .border-radius(50%);
+ background:#db3434;
+ color: @colorWhite;
+ font-size: 10px;
+ padding-top: 2px;
+ height: 16px;
+ position: absolute;
+ right: -7px;
+ text-align: center;
+ top: -8px;
+ width: 16px;
+ }
+
+ .notification-header{
+ border-bottom: 1px solid #b4b4b4;
+ padding: 10px 40px 0px 40px;
+ }
+ .notification-heading{
+ font-family: Omnes-ECOMP-W02, Arial;
+ font-size: 24px;
+ padding-top: 15px;
+ margin-bottom: 1rem;
+ }
+ .notificationBox{
+ border-bottom: 1px solid #b4b4b4;
+
+ }
+
+ .notification-info-icon{
+ padding-top: 41px;
+ font-size: 47px;
+ }
+ .notification-text {
+ line-height: 15px;
+ margin: 0;
+ padding: 0 0 24px 0;
+ text-align: center;
+ font-family: Omnes-ECOMP-W02, Arial;
+ font-size: 16px;
+ }
+
+
+
+ .notificationBox .icon-circle-action-close {
+ cursor: pointer;
+ font-size: 16px;
+ font-family: "Omnes-ECOMP-W02",Arial
+ }
+
+ .notification-close {
+ padding: 2px 2px 0px 0px;
+ float: right;
+ }
+ #notification-flag{
+ font-size: 20px;
+ color: white;
+ vertical-align: middle;
+ }
+ #notification-flag:hover{
+ color:silver
+ }
+ .notifications-list
+ {
+ list-style: none;
+ margin: 0;
+ overflow: auto;
+ height: 250px;
+ width: 270px;
+ padding: 0;
+
+
+ .item:hover{
+ background-color:#eee;
+ }
+ .item
+ {
+ .transition-transform(@transitionDefault);
+ border-bottom: 1px solid @colorSilver;
+ color: @colorAsbestos;
+ cursor: default;
+ display: block;
+ padding: 10px;
+ position: relative;
+ white-space: nowrap;
+ width: 250px;
+ font-family: "Omnes-ECOMP-W02",Arial;
+ &:before,
+ .details,
+ .button-dismiss
+ {
+ display: inline-block;
+ vertical-align: middle;
+ }
+ .icon{
+ display:inline-block;
+ .important
+ {
+ .border-radius(50%);
+ background: red;
+ content: '';
+ height: 8px;
+ width: 8px;
+ display:block;
+ }
+ .normal
+ {
+ .border-radius(50%);
+ background: @colorPeterRiver;
+ content: '';
+ height: 8px;
+ width: 8px;
+ display:block;
+ }
+ }
+ .details
+ {
+ margin-left: 10px;
+ white-space: normal;
+ width: 200px;
+ font-size:12px;
+
+ .title,
+ .date
+ {
+ display: block;
+ font-weight:bold;
+ }
+ .message-body{
+ display: block;
+ }
+ .date
+ {
+ color: @colorConcrete;
+ font-size: .85em;
+ margin-top: 3px;
+ }
+ }
+
+ .button-dismiss
+ {
+ color: @colorSilver;
+ font-size: 15px;
+
+ &:hover,
+ &:focus
+ {
+ color: @colorConcrete;
+ }
+ }
+
+ &.no-data
+ {
+ display: none;
+ text-align: center;
+
+ &:before
+ {
+ display: none;
+ }
+ }
+
+ &.expired
+ {
+ color: @colorSilver;
+
+ &:before
+ {
+ background: @colorSilver;
+ }
+
+ .details
+ {
+ .date
+ {
+ color: @colorSilver;
+ }
+ }
+ }
+
+ &.dismissed
+ {
+ .transform(translateX(100%));
+ }
+ }
+ }
+
+#header-user-div{
+ vertical-align: middle;
+ margin-top:20px;
+}
+
+#header-user-icon{
+ display: inline-block;
+ vertical-align: middle;
+ width: 20px;
+ cursor: pointer;
+ font-size:22px;
+}
+.b2b-header-tabs .header__item.b2b-headermenu a.menu__item{
+ font-family:"Omnes-ECOMP-W02", Arial;
+}
+.b2b-header-tabs .header-tertiary li a{
+ display:inline;
+ padding-left: 3px;
+}
+.b2b-header-tabs .header-secondary .header-subitem.active .header-tertiary{
+ padding:20px;
+ font-size:15px;
+}
+
+.b2b-header-tabs .header__item.notification{
+ float:right;
+}
+
+.b2b-header-tabs .header__items{
+ width:90%;
+}
+
+.b2b-header-tabs .header-secondary, .b2b-header-tabs .header-tertiary{
+ width:100%;
+
+}
+
+.third-level-menu{
+column-count: 4;
+ line-height: 12px;
+ max-height: 500px;
+ overflow-x: hidden;
+ overflow-y: hidden;
+ column-gap: 13px;
+ column-rule: 1px outset #d2d2d2;
+ margin-left:20px;
+}
+
+
+
+.third-level-menu a{
+ color:black;
+}
+
+.b2b-header-tabs .third-level-menu li a {
+ color: #333;
+ display: inline-grid;
+ padding: 7px 15px;
+ max-width: 228px;
+ font-family:"Omnes-ECOMP-W02", Arial;
+}
+
+.b2b-header-tabs .third-level-menu li{
+ display: inline-block;
+ width:100%;
+ border-bottom: 1px solid #d2d2d2;
+}
+
+
+.b2b-header-tabs .header-secondary .header-subitem a.menu__item{
+ font-size:16px;
+}
+
+.third-level-title{
+ font-size:15px;
+ font-weight: 700;
+}
+
+.notification-div{
+ width:15px;
+ font-size:23px;
+ cursor: pointer;
+}
+
+.notification-content{
+ line-height: normal;
+ right: 167px;
+ min-height: 122px;
+ height: auto;
+ width: auto;
+}
+
+.header-user-icon{
+ color:white;
+ font-size:20px;
+ display:inline-block;
+}
+#reg-header-snippet .reg-profileDetails .reg-userEmail-value .reg-userEmail-value-spn,
+#reg-header-snippet .reg-profileDetails .reg-userRole-value .reg-userRole-value-spn,
+#reg-header-snippet .reg-profileDetails .reg-userLastLogin-value .reg-userLastLogin-value-spn,
+#reg-header-snippet .reg-profileDetails .reg-userAppRoles-value .reg-userAppRoles-value-spn{
+ font-family: "Omnes-ECOMP-W02",Arial !important;
+}
+
+.reg-Details-table{
+ list-style: none;
+ border-bottom: 1px solid #bbb;
+ padding-bottom: 20px;
+}
+
+.reg-userName-table-cell{
+ font-weight:bold;
+ font-size:15px;
+ line-height:1.6 !important;
+
+}
+
+#header-favorites ul li{
+ width:100%;
+}
+
+.display-userAppRoles-label span{
+ font-family:"Omnes-ECOMP-W02", Arial;
+} \ No newline at end of file
diff --git a/ecomp-portal-FE-common/client/app/views/header/header.tpl.html b/ecomp-portal-FE-common/client/app/views/header/header.tpl.html
new file mode 100644
index 00000000..65a34ed1
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/header/header.tpl.html
@@ -0,0 +1,266 @@
+<!--
+ ================================================================================
+ ECOMP Portal
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property
+ ================================================================================
+ 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.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ================================================================================
+ -->
+<div style="position:fixed;width: 100%;top: 0px;left: 0;background-color: #222;z-index:9999">
+ <header class="b2b-header-tabs" b2b-header-responsive>
+ <ul class="header__items" role="navigation">
+<!-- Menu Icon and name -->
+ <li class="header__item icon__item" onclick="window.location = 'applicationsHome'">
+ <span id="logo-image" class="icon-primary-att-globe"></span>
+ <span id="portal-title" class="portal-title" >OpenECOMP Portal</span>
+ </li>
+<!-- First Level menu -->
+ <li b2b-header-menu
+ id="megaMenu-{{item.text.split(' ').join('-')}}"
+ class="header__item b2b-headermenu"
+ ng-repeat="item in megaMenuDataObject"
+ ng-mousedown="loadFavorites(item.text)"
+ role="presentation">
+
+ <a href="javascript:void(0);"
+ id="parentmenu-tabs"
+ class="menu__item"
+ role="menuitem">{{item.text}}</a>
+
+ <div class="header-secondary-wrapper" ng-if="item.active_yn=='Y'">
+ <ul class="header-secondary" role="menu">
+<!-- Second Level menu -->
+ <li class="header-subitem"
+ id="subItem-{{subItem.text.split(' ').join('-')}}"
+ b2b-header-submenu
+ ng-repeat="i in item.children | orderBy : 'column'"
+ ng-mousemove="submenuLevelAction(i.text,i.column)"
+ role="presentation">
+ <!-- Favorites -->
+ <div ng-if="i.text=='Favorites'" >
+ <a href="javascript:void(0);" class="menu__item" role="menuitem">{{i.text}}</a>
+ <i id="favorite-star" data-size="large" class="icon-star favorites-icon-active"></i>
+ <div class="header-columns-div" ng-show='favoritesWindow' ng-mouseleave="hideFavoritesWindow()" >
+ <div class="header-tertiary-wrapper" id="header-favorites">
+ <ul class="header-tertiary" role="menu">
+ <li role="presentation">
+ <div
+ ng-repeat="subItem in favoritesMenuItems"
+ ng-show="showFavorites"
+ ng-hide="hideMenus"
+ id="favoritesMenuItems-{{subItem.text.split(' ').join('-')}}">
+ <div class="fav-links">
+ <i id="favorite-selector-favorites-list"
+ class="icon-star favorites-icon-active"
+ data-ng-click="removeAsFavoriteItem($event, subItem.menuId)"
+ ng-mousedown="removeAsFavoriteItem($event, subItem.menuId)">
+ </i>
+ <a id="favorites-list" aria-label="{{subItem.text}}" ng-click="goToUrl(subItem)">{{subItem.text}}</a>
+ </div>
+ </div>
+
+ <div id="favorites-empty" class="favorites-window-empty" ng-show="emptyFavorites">
+ <p id="p-no-favs-icon" class="no-fav-icon">
+ <span class="icon-star" ></span>
+ </p>
+ <p id="p-no-favs" class="largeText">No Favorites</p>
+ <p id="p-no-favs-desc" class="normal">Add your favorite items for quick access.</p>
+ </div>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!-- Support or Help -->
+ <div ng-if="item.text=='Support' || item.text=='Help'" id="second-level-menus-help">
+ <a href="javascript:void(0);" ng-click="goToUrl(i);auditLog(i,'Support')" class="menu__item" role="menuitem">{{i.text| elipsis: 50}}</a>
+ </div>
+ <!-- Others -->
+ <div ng-if="i.text!='Favorites' && (item.text!='Support' && item.text!='Help')" >
+ <a href="javascript:void(0);" class="menu__item" role="menuitem">{{i.text| elipsis: 50}}</a>
+ <div class="header-tertiary-wrapper" >
+ <ul class="third-level-menu" role="menu" id="third-level-menus">
+<!-- Third Level menu -->
+
+ <li b2b-header-tertiarymenu ng-repeat="link in i.children | orderBy : 'column'" role="presentation" >
+ <i id="level3-star-inactive-{{link.menuId}}" ng-cloak
+ class="icon-star favorites-icon-inactive" data-size="large"
+ data-ng-click="setAsFavoriteItem($event, link.menuId)"
+ ng-if="link.url.length > 1 && isUrlFavorite(link.menuId)==false">
+ </i>
+ <i id="level3-star-active-{{link.menuId}}" ng-cloak
+ ng-if="link.url.length > 1 && isUrlFavorite(link.menuId)"
+ class="icon-star favorites-icon-active ng-cloak" data-size="large"
+ data-ng-click="removeAsFavoriteItem($event, link.menuId)">
+ </i>
+
+ <a class="third-level-title"
+ aria-label="{{link.text | elipsis: 50}}"
+ ng-click="goToUrl(link);auditLog(link,'application')">{{link.text| elipsis: 50}}</a>
+<!-- Fourth Level menu -->
+ <div b2b-tertiary-link ng-repeat="title in link.children" >
+ <i id="level4-star-inactive-{{title.menuId}}" ng-cloak
+ class="icon-star favorites-icon-inactive"
+ data-ng-click="setAsFavoriteItem($event, title.menuId)"
+ ng-if="title.url.length > 1 && isUrlFavorite(title.menuId)==false">
+ </i>
+ <i id="level4-star-active-{{title.menuId}}" ng-cloak
+ class="icon-star favorites-icon-active"
+ data-ng-click="removeAsFavoriteItem($event, title.menuId)"
+ ng-if="title.url.length > 1 && isUrlFavorite(title.menuId)">
+ </i>
+ <a href="javascript:void(0);" class="header-tertiaryitem" ng-class="{'disabled': title.disabled}" role="menuitem" ng-click="goToUrl(title);auditLog(title,'functional')">{{title.text | elipsis: 50}}</a>
+ </div>
+ </li>
+
+
+
+
+ </ul>
+ </div>
+ </div>
+
+ </li>
+ </ul>
+ </div>
+ </li>
+<!-- Right side of the Menu - User Icon and Notification flag -->
+ <div class="login-section">
+ <!-- User Icon -->
+ <li class="header__item profile" aria-haspopup="true">
+ <b2b-flyout>
+ <div b2b-flyout-toggler >
+ <div class="icon-people-oneperson" id="header-user-icon" tabindex="0" b2b-accessibility-click="13,32" aria-label="notifications" aria-haspopup="true" aria-expanded="{{flyoutOpened}}" role="button"></div>
+ <div id="login-snippet-text" class="login-snippet-text">{{header.isGuest ? 'Guest' : header.firstName}}</div>
+ </div>
+ <b2b-flyout-content horizontal-placement="center" vertical-placement="below">
+ <div ng-controller="loginSnippetCtrl" >
+ <div id="reg-header-snippet">
+ <div tabindex="0" class="reg-profileDetails" id="reg-profiledetails-id">
+ <ul class="reg-Details-table">
+ <li>
+ <div class="reg-userName-table">
+ <div id="reg-userName-table-row">
+ <div id="reg-userName-table-cell">
+ <h3 >
+ {{firstName}} {{lastName}}&nbsp;</h3>
+ <span>&nbsp;</span>
+ </div>
+ </div>
+ </div>
+ </li>
+ <li><div class="reg-userEmail-label"><span class="reg-userEmail-label-spn" style=font-weight:bold>Email<span class="visuallyhidden">:
+ </span></span></div></li>
+ <li><div class="reg-userEmail-value"><span class="reg-userEmail-value-spn">
+ {{loginSnippetEmail}}</span></div></li>
+ <li>&nbsp;</li>
+ <li><div class="reg-userRole-label"><span class="reg-userRole-label-spn" style=font-weight:bold>
+ User Id<span class="visuallyhidden">:</span></span></div></li>
+ <li><div class="reg-userRole-value"><span class="reg-userRole-value-spn">
+ {{loginSnippetUserid}}<span class="visuallyhidden"></span></span></div></li>
+ <li>&nbsp;</li>
+ <li><div class="reg-userLastLogin-label"><span class="reg-userLastLogin-label-spn" style=font-weight:bold>
+ Last login<span class="visuallyhidden">:</span></span></div></li>
+ <li><div class="reg-userLastLogin-value"><span class="reg-userLastLogin-value-spn">
+ {{lastLogin}}<span class="visuallyhidden"></span></span></div></li>
+ <li>&nbsp;</li>
+ <li>
+ <div class="display-userAppRoles-label">
+ <a href="javascript:void(0);" ng-click="getUserApplicationRoles()" class="icon-controls-add-maximize" ><span>Applications and Roles</span></a>
+ </div>
+
+ <div class="display-userAppRoles-label" ng-show="displayUserAppRoles" style="height:200px; overflow-y:auto;">
+ <div ng-repeat="ua in userapproles track by $index">
+ <div class="reg-userApp-value">
+ <span class="reg-userApp-value-spn" style=font-weight:bold>{{ua.App}}<span class="visuallyhidden">:</span></span>
+ </div>
+ <div ng-repeat="role in ua.Roles track by $index" class="reg-userAppRoles-value" >
+ <span class="reg-userAppRoles-value-spn">{{role}}</span>
+ </div>
+ </div>
+ </div>
+ </li>
+ </ul>
+ <div id="reg-logout-div" style="padding-top: 8px">
+ <button href="javascript:void(0)" id="allLogout" ng-click="allAppsLogout()" class="btn btn-alt btn-small">
+ Log out
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </b2b-flyout-content>
+ </b2b-flyout>
+ </li>
+ <!-- Notification flag -->
+ <li class="header__item notification" aria-haspopup="true" class="notification-li">
+ <b2b-flyout>
+ <div b2b-flyout-toggler class="notification-div">
+ <div class="notifications-count" ng-hide="notificationCount.count==0" ng-bind="notificationCount.count"></div>
+ <div class="icon-content-flag megamenu-notification-overrides" class="b2b-flyout-icon" tabindex="0" b2b-accessibility-click="13,32" aria-label="notifications" aria-haspopup="true" aria-expanded="{{flyoutOpened}}" role="button"></div>
+ </div>
+ <b2b-flyout-content horizontal-placement="center" vertical-placement="below">
+ <div class="notification-content" ng-controller="notificationCtrl" >
+ <div class="ng-scope">
+ <div id="notification" class="notificationBox ">
+ <div align ="right">
+ <a ui-sref="root.notificationHistory" style="font-size: 14px"> View All Recent Notifications </a>
+ </div>
+ <div class="notification-header">
+ <div style="float:left;">
+ <p class="notification-heading">Notifications</p>
+ </div>
+ <div style="clear:both;"></div>
+ </div>
+ <div ng-show="notifications.length==0">
+ <div class="notification-main">
+ <div style="height:113px;">
+ <div align="center" class="icon-information notification-info-icon"></div>
+ </div>
+ <div>
+ <p class="notification-text">No New Notifications.</p>
+ </div>
+
+ </div>
+ </div>
+ <div class="notification-main" ng-show="notifications.length>0">
+ <ul class="notifications-list">
+ <li class="item" data-id="5" ng-repeat="item in notifications">
+ <div class="icon">
+ <span class="important" ng-show="item.priority==2"/>
+ <span class="normal" ng-show="item.priority==1"/>
+ </div>
+ <div class="details">
+ <span class="title" ng-bind="item.title"></span>
+ <span class="message-body" ng-bind="item.message"></span>
+ <!-- <span class="date" ng-bind="item.time" ></span> -->
+ <mydate>{{item.time | date:'MM/dd/yyyy hh:mm:ss a Z'}}</mydate>
+ </div>
+ <button type="button" ng-click="deleteNotification($index)" class="button-default button-dismiss js-dismiss">x</button>
+ </li>
+ </ul>
+ </div>
+ <div class="notification-footer">
+ <div class="notification-links">
+ <div style="clear:both;"></div>
+ </div>
+ </div>
+ </div>
+ </b2b-flyout-content>
+ </b2b-flyout>
+ </li>
+ </div>
+ </ul>
+ </header>
+</div>