diff options
author | talasila <talasila@research.att.com> | 2017-02-07 15:03:57 -0500 |
---|---|---|
committer | talasila <talasila@research.att.com> | 2017-02-07 15:05:15 -0500 |
commit | 4ad39a5c96dd99acf819ce189b13fec946d7506b (patch) | |
tree | a1449286441947cc3d07a45227fa0d6f978e1a7d /ecomp-portal-FE/client/app/views/home/applications-home | |
parent | 5500448cbd1f374d0ac743ee2fd636fe2d3c0027 (diff) |
Initial OpenECOMP Portal commit
Change-Id: I804b80e0830c092e307da1599bd9fbb5c3e2da77
Signed-off-by: talasila <talasila@research.att.com>
Diffstat (limited to 'ecomp-portal-FE/client/app/views/home/applications-home')
4 files changed, 544 insertions, 0 deletions
diff --git a/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.controller.js b/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.controller.js new file mode 100644 index 00000000..2071f4cc --- /dev/null +++ b/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.controller.js @@ -0,0 +1,244 @@ +/*- + * ================================================================================ + * 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 () { + const HTTP_PROTOCOL_RGX = /https?:\/\//; + class ApplicationsHomeCtrl { + constructor(applicationsService, $log, $window, userProfileService, $scope,$cookies, utilsService) { + //activate spinner + this.isLoading = true; + $scope.getUserAppsIsDone = false; + this.userProfileService = userProfileService; + //get all user's applications on init + $scope.buildNumber = "OpenECOMP Portal Version: 1.0.0" + + userProfileService.getUserProfile() + .then(profile=> { + $log.info('ApplicationsHomeCtrl::getUserProfile', profile); + $scope.userId = profile.orgUserId; + //$scope.appsViewData = ['notempty']; // initialize with length != 0 + $scope.appsViewData = []; + $scope.appsView = []; + + //redirect to login.htm, if the EPService cookie is missing and logged in user is not a guest. + if (!$cookies.get('EPService') && !profile.guestSession) { + this.isLoading = false; + var myHostName; + myHostName = location.host; + $log.info("EPService cookie is missing, so attempting to redirecting to login page."); + if (utilsService.isRunningInLocalDevEnv()) { + $log.info("Portal is running in local development and redirecting to 'http://localhost:8080/ecompportal/login.htm'."); + $window.location.href = "http://localhost:8080/ecompportal/login.htm"; + } else { + $log.info("Redirecting to 'login.htm'."); + $window.location.href = "login.htm"; + } + } + + applicationsService.getUserApps() + .then(res => { + $log.info('ApplicationsHomeCtrl::getUserApps: ', res); + this.apps = res; + let rowNo = 0; + for (let i = 0; i < this.apps.length; i++) { + $scope.appsView[i] = { + sizeX: 2, + sizeY: 2, + headerText: '', + subHeaderText: '', + imageLink: '', + order: '', + url: '' + }; + $scope.appsView[i].headerText = this.apps[i].name; + $scope.appsView[i].subHeaderText = this.apps[i].notes; + $scope.appsView[i].imageLink = this.apps[i].thumbnail || this.apps[i].imageUrl; + $scope.appsView[i].order = this.apps[i].order; + $scope.appsView[i].url = this.apps[i].url; + $scope.appsView[i].restrictedApp = this.apps[i].restrictedApp; + } + $log.info('ApplicationsHomeCtrl::getUserApps: apps count : ' + $scope.appsView.length); + + if ($cookies.getObject($scope.userId+'_apps') == undefined || $cookies.getObject($scope.userId+'_apps') == null || $cookies.getObject($scope.userId+'_apps').length == 0) { + if (($scope.appsView != undefined) && ($scope.appsView != null) && ($scope.appsView.length > 0)){ + $scope.appsViewData = $scope.appsView; + $cookies.putObject($scope.userId + '_apps', $scope.appsView); + } + } + else{ + this.listChanged = false; + this.appsListFromCookie = $cookies.getObject($scope.userId+'_apps'); + this.finalAppsList = []; + // + // If an app is still valid for this user from backend(appsView) and + // it was in the cookie already, put it in the list in the same order + // it was in within the cookie. + // + let finalCount = 0; + for (let i = 0; i < this.appsListFromCookie.length; i++) { + this.foundAppInListFromBackend = false; + for (let j = 0; j < $scope.appsView.length; j++) { + if (this.appsListFromCookie[i].url == $scope.appsView[j].url) { + this.finalAppsList[finalCount] = { + sizeX: 2, + sizeY: 2, + headerText: '', + subHeaderText: '', + imageLink: '', + order: '', + url: '' + }; + this.finalAppsList[finalCount].headerText = this.appsListFromCookie[i].headerText; + this.finalAppsList[finalCount].subHeaderText = this.appsListFromCookie[i].subHeaderText; + this.finalAppsList[finalCount].imageLink = this.appsListFromCookie[i].imageLink; + this.finalAppsList[finalCount].order = this.appsListFromCookie[i].order; + this.finalAppsList[finalCount].url = this.appsListFromCookie[i].url; + this.finalAppsList[finalCount].restrictedApp = this.appsListFromCookie[i].restrictedApp; + finalCount++; + this.foundAppInListFromBackend = true; + break; + } + } + if (this.foundAppInListFromBackend == false) { + this.listChanged = true; + } + } + + // + // Fill in the rest of the list with the Apps retrieved from the backend that we did not already add. There could have been + // new Apps configured for the user that are not in the cookie. + // + for (let i = 0; i < $scope.appsView.length; i++) { + this.found = false; + for (let j = 0; j < this.finalAppsList.length; j++) { + if ($scope.appsView[i].url == this.finalAppsList[j].url) { + // already present + this.found = true; + break; + } + } + if (this.found == false) { + this.finalAppsList[finalCount] = { + sizeX: 2, + sizeY: 2, + headerText: '', + subHeaderText: '', + imageLink: '', + order: '', + url: '' + }; + this.finalAppsList[finalCount].headerText = $scope.appsView[i].headerText; + this.finalAppsList[finalCount].subHeaderText = $scope.appsView[i].subHeaderText; + this.finalAppsList[finalCount].imageLink = $scope.appsView[i].imageLink; + this.finalAppsList[finalCount].order = $scope.appsView[i].order; + this.finalAppsList[finalCount].url = $scope.appsView[i].url; + this.finalAppsList[finalCount].restrictedApp = $scope.appsView[i].restrictedApp; + finalCount++; + this.listChanged = true; + } + } + + if ((this.finalAppsList != undefined) && (this.finalAppsList != null) && (this.finalAppsList.length > 0)) { + if (this.listChanged) { + $scope.appsViewData = this.finalAppsList; + $cookies.putObject($scope.userId + '_apps', this.finalAppsList); + } else { + $scope.appsViewData = $cookies.getObject($scope.userId+'_apps'); + } + } + this.isLoading = false; + $scope.getUserAppsIsDone = true; + } + }).catch(err => { + $log.error('oh no! couldnt get applications list...', err); + this.isLoading = false; + $scope.getUserAppsIsDone = true; + }); + }); + + + this.gridsterOpts = { + columns: 6, + colWidth: 190, + rowHeight: 190, + margins: [20, 20], + outerMargin: true, + pushing: true, + floating: true, + swapping: true, + draggable : { + stop: function () { + $cookies.putObject($scope.userId + '_apps', $scope.appsViewData); + } + } + }; + + //navigate to application url in new tab + this.goToPortal = (item) => { + $log.info("goToPortal called with item: " + item); + let url = item.url; + let restrictedApp = item.restrictedApp; + if (!url) { + $log.info('No url found for this application, doing nothing..'); + return; + } + if (!HTTP_PROTOCOL_RGX.test(url)) { + url = 'http://' + url; + } + if (restrictedApp) { + $window.open(url, '_blank'); + } else { + var tabContent = { id: new Date(), title: item.headerText, url:item.url.split('#')[0] + '?' + (new Date).getTime() + "#" + item.url.split('#')[1]}; + $cookies.putObject('addTab', tabContent ); + } + + }; + // try { + // userProfileService.getUserProfile() + // .then(profile=> { + // if (profile.roles.indexOf('superAdmin') > -1) { + // $scope.buildNumber = "ECOMP Portal Version: 1610.0.2058" + // } + // }).catch(err=> { + // $log.error('Applications Home:: getUserProfile() failed: ' + err); + // }); + // } catch (err) { + // $log.error('Applications Home:: getUserProfile() failed: ' + err); + // } + if(getParameterByName('noUserError')!=null){ + if(getParameterByName('noUserError')=="Show"){ + $("#errorInfo").show(); + } + } + } + } + ApplicationsHomeCtrl.$inject = ['applicationsService', '$log', '$window', 'userProfileService', '$scope','$cookies', 'utilsService']; + angular.module('ecompApp').controller('ApplicationsHomeCtrl', ApplicationsHomeCtrl); +})(); + +function getParameterByName(name, url) { + if (!url) url = window.location.href; + name = name.replace(/[\[\]]/g, "\\$&"); + var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), + results = regex.exec(url); + if (!results) return ''; + if (!results[2]) return ''; + return (results[2].replace(/\+/g, " ")); +} diff --git a/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.controller.spec.js b/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.controller.spec.js new file mode 100644 index 00000000..e3782ab2 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.controller.spec.js @@ -0,0 +1,77 @@ +/*- + * ================================================================================ + * 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'; +describe('Controller: ApplicationsHomeCtrl ', function() { + beforeEach(module('ecompApp')); + + let ApplicationsHomeCtrl, $controller, $q, rootScope, $log, $window, $cookies, scope; + let deferredApps, deferredUserProfile, applicationsServiceMock, userProfileServiceMock; + + + beforeEach(inject( (_$controller_, _$q_, _$rootScope_, _$log_, _$window_, _$cookies_, _CacheFactory_)=>{ + rootScope = _$rootScope_; + scope = rootScope.$new(); + $q = _$q_; + $controller = _$controller_; + $log = _$log_; + $window = _$window_; + $cookies = _$cookies_; + + _CacheFactory_.destroyAll(); + + deferredApps = $q.defer(); + deferredUserProfile = $q.defer(); + applicationsServiceMock = jasmine.createSpyObj('applicationsServiceMock', ['getUserApps']); + applicationsServiceMock.getUserApps.and.returnValue(deferredApps.promise); + + userProfileServiceMock = jasmine.createSpyObj('userProfileServiceMock',['getUserProfile']); + userProfileServiceMock.getUserProfile.and.returnValue(deferredUserProfile.promise); + + ApplicationsHomeCtrl = $controller('ApplicationsHomeCtrl', { + applicationsService: applicationsServiceMock, + $log: $log, + $window: $window, + userProfileService: userProfileServiceMock, + $scope: scope, + $cookies: $cookies + }); + scope.$digest(); + })); + + it('should populate this.apps with data from portals service getUserApps', inject(function ( _$q_) { + $q = _$q_; + + let profile = {roles: 'superAdmin', userId: 'userid'}; + + deferredUserProfile.resolve(profile) + deferredApps.resolve([{name: 'portal1'},{name: 'portal2'},{name: 'portal3'}]); + scope.$digest(); + expect(scope.appsViewData.length).toBe(3); + })); + + it('should call $log error when getAllPortals fail', inject(function ( _$q_) { + $q = _$q_; + spyOn($log, 'error'); + deferredUserProfile.reject('something happened!'); + scope.$digest(); + expect($log.error).toHaveBeenCalled(); + })); + +}); diff --git a/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.less b/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.less new file mode 100644 index 00000000..d91acc17 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.less @@ -0,0 +1,164 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + .w-ecomp-applications-home { + .bg_w; + position: @page-main-position; + top: @page-main-top; + left: @page-main-left; + right: @page-main-right; + bottom: @page-main-bottom; + padding-top: @padding-top; + overflow-y: @page-main-overflow-y; + padding-left: @padding-left-side; + + .go-button { + .btn-green; + width: 96px; + position: absolute; + border-radius: 0px; + } + + .applications-home-container { + .content_justify; + position: relative; + padding: 15px 0 32px 0; + width: 100%; + + .applications-home-title { + .a24r; + margin: auto; + .content_justify; + } + .portals-list { + min-height: 70vh; + justify-content: center; + flex-flow: row wrap; + width: 1170px; + + margin: auto; + margin-bottom: 63px; + + .app-gridster-header { + background-color: @u; + } + + .app-gridster-footer { + background-color: @u; + } + + .portals-list-item { + background-color: @u; + border-radius: 2px; + box-shadow: 0px -1px 2px 0px rgba(0, 0, 0, 0.1); + display: inline-block; + width: 360px; + height: 300px; + background-size: cover; + cursor: pointer; + margin: 15px; + overflow: hidden; + + .portals-item-info { + background-color: @u; + height: 120px; + top: 180px; + position: relative; + box-shadow: 0px -1px 2px 0px rgba(0, 0, 0, 0.1); + padding: 16px; + + .info-title { + .a24r; + margin-bottom: 4px; + + text-overflow: ellipsis; + overflow: hidden; + } + .info-description { + .c16r; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + .info-button { + .btn-green; + width: 96px; + position: absolute; + bottom: 16px; + left: 16px; + } + + &:hover { + opacity: .93; + z-index: 3; + } + } + } + } + } +} +.w-ecomp-main-error{ + .o14r; + position: absolute; + width: 100%; + line-height: 1.5em; +} +.w-ecomp-main-disclaimer { + text-align: center; + .o14r; + //position: absolute; + bottom: -75px; + line-height: 1.5em; + margin: 0 auto; + width:1170px; + position: relative; + +} +.build-number { + .o12i; +} + +@keyframes fadein { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.slide.ng-hide-add, +.slide.ng-hide-remove, +.slide.ng-enter, +.slide.ng-leave { + transition: all 0.5s ease; +} +.slide.ng-hide, +.slide.ng-enter { + transform: translate(-100%, 0); +} +.slide.ng-enter-active { + transform: translate(0, 0); +} +.slide.ng-leave { + transform: translate(0, 0); +} +.slide.ng-leave-active { + transform: translate(+100%, 0); +} diff --git a/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.tpl.html b/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.tpl.html new file mode 100644 index 00000000..645807f6 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/home/applications-home/applications-home.tpl.html @@ -0,0 +1,59 @@ +<!-- + ================================================================================ + 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 class="w-ecomp-applications-home" ng-style="{bottom: tabBottom}"> + <div class="applications-home-container"> + <div id="app-home-title" class="applications-home-title" >Applications</div> + <div align="center" id="errorInfo" style="display:none;font-size:12px;margin-left:5px"> + <span style="color:red">You don't have user account in that application.Please ask system administrator </span></div> + <div class="portals-list"> + <div class="gridster-container override_background"> + <span class="ecomp-spinner" ng-show="applicationsHome.isLoading" ></span> + <div att-gridster att-gridster-options="applicationsHome.gridsterOpts" > + <div att-gridster-item='item' ng-repeat="item in appsViewData" id="app-{{item.headerText.split(' ').join('-')}}" > + <div id="grips-{{item.headerText.split(' ').join('-')}}" ng-hide="users.isLoadingTable && !users.getUserAppsIsDone" + att-gridster-item-header grips-img-path="assets/images/grips.png" + header-text="{{item.headerText | elipsis: 33}}" sub-header-text="{{item.subHeaderText | elipsis: 56}}" class="app-gridster-header"> + </div> + <div id="app-image-{{item.headerText.split(' ').join('-')}}"att-gridster-item-body + ng-style="{'cursor':'pointer', + 'background-image': 'url('+(item.imageLink)+')', + 'order': item.order, + 'background-repeat': 'no-repeat'}" + ng-click="applicationsHome.goToPortal(item)" ng-hide="users.isLoadingTable && !users.getUserAppsIsDone"> + </div> + <div att-gridster-item-footer class="app-gridster-footer" ng-hide="users.isLoadingTable && !users.getUserAppsIsDone"> + <span id="go-{{item.headerText.split(' ').join('-')}}" class="go-button" ng-click="applicationsHome.goToPortal(item)" >GO</span> + </div> + </div> + </div> + </div> + <div> + <div id="app-home-disclaimer" class="w-ecomp-main-error" ng-if="appsViewData.length==0" ng-hide="users.isLoadingTable && !users.getUserAppsIsDone"> + You do not have access to any application/functionality within OpenECOMP Portal. Please contact your administrator to get access to ECOMP Portal</a><br> + </div> + </div> + </div> + <div id="app-home-disclaimer-mylogins" class="w-ecomp-main-disclaimer"> + + <p id="build-number" class="build-number" ng-bind-html="buildNumber"></p> + </div> + + </div> +</div> |