diff options
Diffstat (limited to 'ecomp-portal-FE/client/app/directives')
19 files changed, 1916 insertions, 0 deletions
diff --git a/ecomp-portal-FE/client/app/directives/auto-focus/auto-focus.directive.js b/ecomp-portal-FE/client/app/directives/auto-focus/auto-focus.directive.js new file mode 100644 index 00000000..73964115 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/auto-focus/auto-focus.directive.js @@ -0,0 +1,46 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + + + +//angular.module('ecompApp') +// .directive('autoFocus', function () { +// return { +// restrict: 'A', +// scope: {}, +// link: function (scope, element) { +// element[0].focus(); +// } +// }; +// }); + +/* istanbul ignore next */ +(function(){ + class AutoFocusDirective{ + constructor(){ + this.restrict = 'A'; + this.link = this._link.bind(this); + } + _link(scope, element){ + element[0].focus(); + } + } + angular.module('ecompApp').directive('autoFocus', () => new AutoFocusDirective()); +})(); diff --git a/ecomp-portal-FE/client/app/directives/image-upload/image-upload.directive.js b/ecomp-portal-FE/client/app/directives/image-upload/image-upload.directive.js new file mode 100644 index 00000000..90c88c50 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/image-upload/image-upload.directive.js @@ -0,0 +1,222 @@ +/*- + * ================================================================================ + * 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'; + +angular.module('ecompApp').directive('imageUpload', function factory($q) { + var imageMimeRgx = /^image\/[a-zA-Z0-9]*$/; + + var URL = window.URL || window.webkitURL; + + var getResizeArea = function () { + var resizeAreaId = 'fileupload-resize-area'; + + var resizeArea = document.getElementById(resizeAreaId); + + if (!resizeArea) { + resizeArea = document.createElement('canvas'); + resizeArea.id = resizeAreaId; + resizeArea.style.visibility = 'hidden'; + document.body.appendChild(resizeArea); + } + + return resizeArea; + }; + + var resizeImage = function (origImage, options) { + var maxHeight = options.resizeMaxHeight || 300; + var maxWidth = options.resizeMaxWidth || 250; + var quality = options.resizeQuality || 0.7; + var type = options.resizeType || 'image/jpg'; + + var canvas = getResizeArea(); + + var height = origImage.height; + var width = origImage.width; + + //image redraw starting points + var x0, y0; + + // calculate the width and height, constraining the proportions + if (width > height) { + if (width > maxWidth) { + height = Math.round(height *= maxWidth / width); + width = maxWidth; + + x0 = 0; + y0 = Math.round((maxHeight - height)/2); + }else{ + maxHeight = height; + maxWidth = width; + x0 = 0; + y0 = 0; + } + } else { + if (height > maxHeight) { + width = Math.round(width *= maxHeight / height); + height = maxHeight; + + x0 = Math.round((maxWidth - width)/2); + y0 = 0; + }else{ + maxHeight = height; + maxWidth = width; + x0 = 0; + y0 = 0; + } + } + + canvas.width = maxWidth; + canvas.height = maxHeight; + + //draw image on canvas + var ctx = canvas.getContext("2d"); + + //set background color + if(options.backgroundColor){ + ctx.fillStyle = options.backgroundColor; + ctx.fillRect(0,0,maxWidth,maxHeight); + } + + + ctx.drawImage(origImage, x0, y0, width, height); + + // get the data from canvas as 70% jpg (or specified type). + return canvas.toDataURL(type, quality); + }; + + var createImage = function(url, callback) { + var image = new Image(); + image.onload = function() { + callback(image); + }; + image.src = url; + }; + + var fileToDataURL = function (file) { + var deferred = $q.defer(); + var reader = new FileReader(); + reader.onload = function (e) { + deferred.resolve(e.target.result); + }; + reader.readAsDataURL(file); + return deferred.promise; + }; + + return { + restrict: 'A', + require: '^form', + scope: { + image: '=imageUpload', + resizeMaxHeight: '@?imageUploadResizeMaxHeight', + resizeMaxWidth: '@?imageUploadResizeMaxWidth', + resizeQuality: '@?imageUploadResizeQuality', + resizeType: '@?imageUploadResizeType', + imageApi: '=?imageUploadApi', + backgroundColor: '@?imageUploadBackgroundColor' + }, + compile: function compile(tElement, tAttrs, transclude) { + return function postLink(scope, iElement, iAttrs, formCtrl) { + var doResizing = function(imageResult, callback) { + createImage(imageResult.url, function(image) { + var dataURL = resizeImage(image, scope); + imageResult.resized = { + dataURL: dataURL, + type: dataURL.match(/:(.+\/.+);/)[1] + }; + callback(imageResult); + }); + }; + + var applyScope = function(imageResult) { + scope.$apply(function() { + //console.log(imageResult); + if(iAttrs.multiple) + scope.image.push(imageResult); + else + scope.image = imageResult; + }); + }; + + iElement.bind('change', function (evt) { + //when multiple always return an array of images + if(iAttrs.multiple) + scope.image = []; + + var files = evt.target.files; + for(var i = 0; i < files.length; i++) { + setInputValidity(files[i]); + + //create a result object for each file in files + var imageResult = { + file: files[i], + url: URL.createObjectURL(files[i]) + }; + + fileToDataURL(files[i]).then(function (dataURL) { + imageResult.dataURL = dataURL; + }); + + if(scope.resizeMaxHeight || scope.resizeMaxWidth) { //resize image + doResizing(imageResult, function(imageResult) { + applyScope(imageResult); + }); + } + else { //no resizing + applyScope(imageResult); + } + } + }); + + //API for otter actions + scope.imageApi = scope.imageApi || {}; + scope.imageApi.clearFile = () => { + iElement[0].value = ""; + setInputValidity(); + }; + + + let setInputValidity = file => { + //if form validation supported + + if(formCtrl && iAttrs.name && formCtrl[iAttrs.name]){ + formCtrl[iAttrs.name].$setDirty(); + if(file && file.type && !imageMimeRgx.test(file.type)){ + //set form invalid + formCtrl[iAttrs.name].$setValidity('mimeType', false); + applyScope(); + return; + } + if(file && file.size && file.size > 1000000){ + //set form invalid + formCtrl[iAttrs.name].$setValidity('imageSize', false); + applyScope(); + return; + } + //set valid + formCtrl[iAttrs.name].$setValidity('mimeType', true); + formCtrl[iAttrs.name].$setValidity('imageSize', true); + } + + } + } + } + } +}); diff --git a/ecomp-portal-FE/client/app/directives/left-menu/left-menu.directive.js b/ecomp-portal-FE/client/app/directives/left-menu/left-menu.directive.js new file mode 100644 index 00000000..363485fe --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/left-menu/left-menu.directive.js @@ -0,0 +1,96 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + +(function () { + class LeftMenu { + constructor($rootScope, $log, userbarUpdateService) { + this.templateUrl = 'app/directives/left-menu/left-menu.tpl.html'; + this.restrict = 'AE'; + this.$rootScope = $rootScope; + this.$log = $log; + this.userbarUpdateService = userbarUpdateService; + this.link = this._link.bind(this); + this.scope = { + sidebarModel: '=' + } + } + + _link(scope) { + let init = () => { + scope.isOpen = true; + }; + + init(); + + scope.refreshOnlineUsers = () => { + this.userbarUpdateService.setRefreshCount(this.userbarUpdateService.maxCount); + }; + + scope.toggleSidebar = () => { + scope.isOpen = !scope.isOpen; + if(scope.isOpen) + setContentPos(1); + else + setContentPos(0); + + }; + + scope.isBrowserInternetExplorer = false; + scope.browserName = bowser.name; + + if (bowser.msie || bowser.msedge) { + scope.isBrowserInternetExplorer = true; + } else { + scope.isBrowserInternetExplorer = false; + } + + let log = this.$log; + + this.userbarUpdateService.getWidthThresholdLeftMenu().then(function (res) { + if (res == null || res.response == null) { + log.error('userbarUpdateService: failed to get window width threshold for collapsing left menu; please make sure "window_width_threshold_left_menu" is specified in system.properties file.'); + } else { + var leftMenuCollapseWidthThreshold = parseInt(res.response.windowWidth); + if ($(window).width()<leftMenuCollapseWidthThreshold) { + scope.toggleSidebar(); + } + } + })['catch'](function (err) { + log.error('LeftMenu Controller:: getWidthThresholdLeftMenu() failed: ' + err); + }); + + + + this.$rootScope.$on('$stateChangeStart', () => { + scope.isOpen = true; + }); + } + } + angular.module('ecompApp').directive('leftMenu', ($rootScope,$log,userbarUpdateService) => new LeftMenu($rootScope,$log,userbarUpdateService)); +})(); + +function setContentPos(open) { + if(open==1){ + $("#contentId" ).css( "padding-left", "210px" ); + }else{ + $("#contentId" ).css( "padding-left", "50px" ); + } + +} diff --git a/ecomp-portal-FE/client/app/directives/left-menu/left-menu.less b/ecomp-portal-FE/client/app/directives/left-menu/left-menu.less new file mode 100644 index 00000000..276fb409 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/left-menu/left-menu.less @@ -0,0 +1,133 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ +@sidebar-width: 200px; +@transition-duration: 0.25s; +@overlayer-opacity: 0.65; + + +.close-button { + .a24r; + font-size: 3em; + line-height: 18px; + position: absolute; + cursor: pointer; + vertical-align: middle; + top: @second-level-top; + left: 0; + -webkit-font-smoothing: antialiased; + height: 53px; + z-index: 101; +} +.ecomp-sidebar-container { + position: absolute; + display: block; + left: 0; + z-index: 100; + transition: left @transition-duration; + margin-top: -15px; + + .ecomp-sidebar-main { + position: absolute; + margin-top: 65px; + width: @sidebar-width; + height: 100vh; + .bg_u; + box-shadow: 0 4px 5px rgba(0, 0, 0, .2); + + padding-right: 10px; + padding-left: 10px; + + .accordion-container{ + margin-top: 45px; + overflow-y:auto; + overflow-x:hidden; + } + .att-accordion-font{ + font-size: .875rem; + color: #666; + display: inline-block; + font-family: arial; + + } + + .att-accordion-active{ + color: #199DDF !important; + } + + .sub-item{ + .att-accordion-font; + cursor: pointer; + height: 37px; + line-height: 37px; + padding-left: 20px; + padding-bottom: 10px; + vertical-align: middle; + width: 100%; + } + .sub-item:hover{ + .att-accordion-active; + } + + .parent-item{ + .att-accordion-font; + border-bottom: 1px solid #bbb; + cursor: pointer; + height: 37px; + line-height: 37px; + padding-bottom: 10px; + vertical-align: middle; + width: 100%; + } + .parent-item:hover{ + .att-accordion-active; + } + + } +} + +.open-sidebar { + left: 0; +} + +.close-sidebar { + left: -@sidebar-width; +} + +.content-overlayed { + position: fixed; + top: 110px; + right: 0; + bottom: 0; + left: 0; + background: none repeat scroll 0 0 rgb(242, 242, 242); + z-index: 9999; +} +.fade-animation{ + opacity: @overlayer-opacity; + transition: opacity @transition-duration ease-in-out; +} +.fade-animation.ng-hide { + opacity:0; + transition: opacity @transition-duration ease-in-out; +} + +#contentId{ + padding-left:210px +}
\ No newline at end of file diff --git a/ecomp-portal-FE/client/app/directives/left-menu/left-menu.tpl.html b/ecomp-portal-FE/client/app/directives/left-menu/left-menu.tpl.html new file mode 100644 index 00000000..0059d6a4 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/left-menu/left-menu.tpl.html @@ -0,0 +1,57 @@ +<!-- + ================================================================================ + 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="close-button" ng-click="toggleSidebar()"> + <span id="icon-hamburger" class="ion-navicon-round" ></span> +</div> +<div id="ecomp-sidebar-container" class="ecomp-sidebar-container" ng-class="isOpen ? 'open-sidebar': 'close-sidebar'"> + <div class="ecomp-sidebar-main" > + <div class="accordion-container" id="accordion-container"> + <accordion close-others="true" css="att-accordion--no-box"> + <div ng-repeat="parent in sidebarModel.navItems"> + <div ng-click="refreshOnlineUsers()" id="parent-item-{{parent.name.split(' ').join('-')}}" + class="parent-item" + ng-if="!parent.subMenu" + class="child-row" + ui-sref="{{parent.state}}" ui-sref-active="att-accordion-active"> + <i id="icon-image-{{parent.name.split(' ').join('-')}}" ng-class="parent.imageSrc" class=\"pull-left\"></i> + {{parent.name}} + </div> + + <accordion-group + id="accordion-group" + ng-if="parent.subMenu" + heading="{{parent.name}}" + image-source="{{parent.imageSrc}}" > + <div id="sub-item-{{child.name.split(' ').join('-')}}" + class="sub-item" + ng-repeat="child in parent.subMenu" + class="child-row" + ui-sref="{{child.state}}" ui-sref-active="att-accordion-active" + image-source="{{parent.imageSrc}}"> + <i id="child-item-{{child.name.split(' ').join('-')}}" ng-class="child.imageSrc" class=\"pull-left\"></i> {{child.name}} + </div> + </accordion-group> + + </div> + </accordion> + + </div> + </div> +</div> diff --git a/ecomp-portal-FE/client/app/directives/multiple-select/multiple-select.directive.js b/ecomp-portal-FE/client/app/directives/multiple-select/multiple-select.directive.js new file mode 100644 index 00000000..e8f6ed94 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/multiple-select/multiple-select.directive.js @@ -0,0 +1,111 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + +angular.module('ecompApp') + .directive('multipleSelect', function ($window) { + return { + restrict: 'E', + templateUrl: 'app/directives/multiple-select/multiple-select.tpl.html', + scope: { + onChange: '&', + nameAttr: '@', + valueAttr: '@', + ngModel: '=', + placeholder: '@', + uniqueData: '@?', + onDropdownClose: '&?' + }, + link: function(scope, elm, attrs){ + scope.isExpanded = false; + + scope.isDisabled = !scope.ngModel || !scope.ngModel.length; + scope.$watch('ngModel', function(newVal){ + scope.isDisabled = !newVal || !newVal.length; + }); + + + let startListening = () => { + console.log('listening on $window!'); + angular.element($window).on('click', function () { + stopListening(); + }); + + angular.element('multiple-select').on('click', function(e) { + if($(e.target).closest('multiple-select')[0].attributes['unique-data'].value === attrs.uniqueData){ + console.log('ignored that..:', attrs.uniqueData); + e.stopPropagation(); + }else{ + console.log('shouldnt ignore, close expanded!:', attrs.uniqueData); + scope.isExpanded = false; + scope.$applyAsync(); + } + }); + }; + + let stopListening = function() { + if(scope.onDropdownClose){ + scope.onDropdownClose(); + } + scope.isExpanded = false; + scope.$applyAsync(); + console.log('stop listening on $window and multiple-element!'); + angular.element($window).off('click'); + angular.element('multiple-select').off('click'); + }; + + scope.showCheckboxes = function(){ + scope.isExpanded = !scope.isExpanded; + if(scope.isExpanded){ + startListening(); + }else{ + stopListening(); + if(scope.onDropdownClose){ + scope.onDropdownClose(); + } + } + }; + + scope.onCheckboxClicked = function() { + console.log('checkbox clicked; unique data: ',attrs.uniqueData); + if(scope.onChange) { + scope.onChange(); + } + } + + scope.getTitle = function(){ + var disp = ""; + if(!scope.ngModel || !scope.ngModel.length) { + return disp; + } + scope.ngModel.forEach(function(item){ + if(item[scope.valueAttr]){ + disp+=item[scope.nameAttr] + ","; + } + }); + if(disp!==""){ + disp = disp.slice(0,disp.length-1); + }else{ + disp = scope.placeholder; + } + return disp; + }; + } + }; + }); diff --git a/ecomp-portal-FE/client/app/directives/multiple-select/multiple-select.less b/ecomp-portal-FE/client/app/directives/multiple-select/multiple-select.less new file mode 100644 index 00000000..6e54c8b6 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/multiple-select/multiple-select.less @@ -0,0 +1,81 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + .multiple-select{ + position: relative; + width: 100%; + + .selectBox{ + cursor: pointer; + position: relative; + border: 1px solid @o; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + line-height: 30px; + height: 30px; + padding-left: 10px; + padding-right: 10px; + + &.open::after{ + content: ''; + .arrow_up; + display: block; + position: absolute; + top: 12px; + right: 4px; + } + &.closed::after{ + content: ''; + .arrow_down; + display: block; + position: absolute; + top: 12px; + right: 4px; + } + &.disabled{ + cursor: default; + background: #CCCCCC; + } + + } + + .checkboxes{ + z-index: 99999; + padding-left: 8px; + padding-right: 8px; + position: absolute; + top: 30px; + width: 100%; + background: white; + + display: block; + border: 1px #dadada solid; + + label{ + cursor: pointer; + display: block; + } + input{ + cursor: pointer; + } + + + } +}
\ No newline at end of file diff --git a/ecomp-portal-FE/client/app/directives/multiple-select/multiple-select.tpl.html b/ecomp-portal-FE/client/app/directives/multiple-select/multiple-select.tpl.html new file mode 100644 index 00000000..e55e844c --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/multiple-select/multiple-select.tpl.html @@ -0,0 +1,38 @@ +<!-- + ================================================================================ + 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="dropdown-container" style="height:30px;"> + <div class="right_arrow_down" style="left:185px"></div> + <div class="multiple-select"> + <div class="selectBox" + ng-click="isDisabled || showCheckboxes()" + title="{{getTitle()}}" + ng-bind="getTitle()" + ng-class="{open: isExpanded, closed: !isExpanded, disabled: isDisabled}"></div> + + <div class="checkboxes" ng-show="isExpanded"> + <div ng-repeat="item in ngModel"> + <label> + <input type="checkbox" ng-model="item[valueAttr]" ng-change="onCheckboxClicked()"> + {{item[nameAttr]}} + </label> + </div> + </div> + </div> +</div> diff --git a/ecomp-portal-FE/client/app/directives/right-click-menu/right-click-menu.directive.js b/ecomp-portal-FE/client/app/directives/right-click-menu/right-click-menu.directive.js new file mode 100644 index 00000000..358cc56f --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/right-click-menu/right-click-menu.directive.js @@ -0,0 +1,38 @@ +/*- + * ================================================================================ + * 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'; +angular.module('ecompApp').directive( "contextMenu", function($compile){ + contextMenu = {}; + contextMenu.restrict = "AE"; + contextMenu.link = function( lScope, lElem, lAttr ){ + lElem.on("contextmenu", function (e) { + e.preventDefault(); + lElem.append( $compile( lScope[ lAttr.contextMenu ])(lScope) ); + $("#contextmenu-node").css("left", e.clientX); + $("#contextmenu-node").css("top", e.clientY); + }); + lElem.on("mouseleave", function(e){ + console.log("Leaved the div"); + if($("#contextmenu-node") ) + $("#contextmenu-node").remove(); + }); + }; + return contextMenu; +}); diff --git a/ecomp-portal-FE/client/app/directives/right-click/ng-right-click-directive.js b/ecomp-portal-FE/client/app/directives/right-click/ng-right-click-directive.js new file mode 100644 index 00000000..075ea3ac --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/right-click/ng-right-click-directive.js @@ -0,0 +1,32 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ +angular.module('ecompApp'). + directive('ngRightClick', function($parse) { + return function(scope, element, attrs) + { + var fn = $parse(attrs.ngRightClick); + element.bind('contextmenu', function(event) { + scope.$apply(function() { + event.preventDefault(); + fn(scope, {$event:event}); + }); + }); + }; + }); diff --git a/ecomp-portal-FE/client/app/directives/right-menu/right-menu.directive.js b/ecomp-portal-FE/client/app/directives/right-menu/right-menu.directive.js new file mode 100644 index 00000000..b778ce7b --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/right-menu/right-menu.directive.js @@ -0,0 +1,140 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ +/** + * Created by nnaffar on 1/28/16. + */ +(function () { + class RightMenu { + constructor($rootScope,$window,$log,userbarUpdateService) { + this.templateUrl = 'app/directives/right-menu/right-menu.tpl.html'; + this.restrict = 'AE'; + this.$rootScope = $rootScope; + this.userbarUpdateService = userbarUpdateService; + this.$window = $window; + this.$log = $log; + this.link = this._link.bind(this); + this.scope = { + userList :'=' + } + } + + + + _link(scope) { + let init = () => { + scope.isOpen = true; + scope.rightSideToggleBtn = 'Collapse'; + + scope.openInNewTab = (url) => { + if(url == "self") { + alert("Cannot chat with self!"); + } else { + var win = window.open(url, '_blank'); + setCookie(url.split("chat_id=")[1], 'source', 1); + //window.localStorage.setItem(url.split("chat_id=")[1],'source'); + win.focus(); + } + }; + + }; + + function setCookie(cname,cvalue,exdays) { + var d = new Date(); + d.setTime(d.getTime() + (exdays*24*60*60*1000)); + var expires = "expires=" + d.toGMTString(); + document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; + } + + function getCookie(cname) { + var name = cname + "="; + var decodedCookie = decodeURIComponent(document.cookie); + var ca = decodedCookie.split(';'); + for(var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') { + c = c.substring(1); + } + if (c.indexOf(name) == 0) { + return c.substring(name.length, c.length); + } + } + return ""; + } + + + + init(); + + /***Getting the list of the users***/ + scope.toggleSidebar = () => { + scope.isOpen = !scope.isOpen; + if(scope.isOpen){ + scope.rightSideToggleBtn = 'Collapse'; + }else{ + scope.rightSideToggleBtn = 'Expand'; + } + }; + + scope.isBrowserInternetExplorer = false; + scope.browserName = bowser.name; + + if (bowser.msie || bowser.msedge) { + scope.isBrowserInternetExplorer = true; + } else { + scope.isBrowserInternetExplorer = false; + } + + + + + scope.calculateUserBarHeight = () => { + var footerOff = $('#online-userbar').offset().top; + var headOff = $('#footer').offset().top; + var userbarHeight= parseInt($(".online-user-container").css('height'),10); + var defaultOffSet = 45; + // console.log(headOff - footerOff-defaultOffSet); + $(".online-user-container").css({ + "height" : headOff - footerOff-defaultOffSet + }); + }; + + let log = this.$log; + + this.userbarUpdateService.getWidthThresholdRightMenu().then(function (res) { + if (res.status=="ERROR") { + log.error('userbarUpdateService: failed to get window width threshold for collapsing right menu; please make sure "window_width_threshold_right_menu" is specified in system.properties file.'); + } else { + var rightMenuCollapseWidthThreshold = parseInt(res.response.windowWidth); + if ($(window).width()<rightMenuCollapseWidthThreshold) { + scope.toggleSidebar(); + } + } + })['catch'](function (err) { + log.error('LeftMenu Controller:: getWidthThresholdLeftMenu() failed: ' + err); + }); + + angular.element(this.$window).bind('resize', function(){ + scope.calculateUserBarHeight(); + }); + } + + } + angular.module('ecompApp').directive('rightMenu', ($rootScope,$window,$log,userbarUpdateService) => new RightMenu($rootScope,$window,$log,userbarUpdateService)); +})(); diff --git a/ecomp-portal-FE/client/app/directives/right-menu/right-menu.less b/ecomp-portal-FE/client/app/directives/right-menu/right-menu.less new file mode 100644 index 00000000..bc23b614 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/right-menu/right-menu.less @@ -0,0 +1,178 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + /** + * Created by nnaffar on 1/28/16. + */ +@sidebar-width: 200px; +@transition-duration: 0.25s; +@overlayer-opacity: 0.65; + + +.close-button { + //width: @sidebar-width; + .a24r; + //.bg_u; + font-size: 3em; + line-height: 18px; + position: absolute; + cursor: pointer; + vertical-align: middle; + top: @second-level-top; + left: 0; + -webkit-font-smoothing: antialiased; + height: 53px; + z-index: 101; + //box-shadow: 0 4px 5px rgba(0, 0, 0, .2); + +} +.ecomp-right-sidebar-container{ + position: absolute; + display: block; + left: 0; + z-index: 100; + transition: left @transition-duration; + margin-top: -15px; + + .ecomp-sidebar-main { + //background-color: ; + position: absolute; + margin-top: 65px; + width: @sidebar-width; + height: 100vh; + .bg_u;//white for 1610 + //.bg_w; // gray for 1702 + box-shadow: 0 4px 5px rgba(0, 0, 0, .2); + + padding-right: 10px; + padding-left: 10px; + + .accordion-container{ + margin-top: 45px; + } + .att-accordion-font{ + font-size: .875rem; + color: #666; + display: inline-block; + font-family: arial; + + } + + .att-accordion-active{ + color: #199DDF !important; + } + + .sub-item{ + .att-accordion-font; + cursor: pointer; + height: 37px; + line-height: 37px; + padding-left: 20px; + padding-bottom: 10px; + vertical-align: middle; + width: 100%; + } + .sub-item:hover{ + .att-accordion-active; + } + + .parent-item{ + .att-accordion-font; + border-bottom: 1px solid #bbb; + cursor: pointer; + height: 37px; + line-height: 37px; + padding-bottom: 10px; + vertical-align: middle; + width: 100%; + } + .parent-item:hover{ + .att-accordion-active; + } + + } +} + +.open-sidebar { + right: 0; + transition: right .25s ease-in-out; + -moz-transition: right .25s ease-in-out; + -webkit-transition: right .25s ease-in-out; +} + +.close-sidebar { + right: -@sidebar-width; + transition: right .25s ease-in-out; + -moz-transition: right .25s ease-in-out; + -webkit-transition: right .25s ease-in-out; +} + +.content-overlayed { + position: fixed; + top: 110px; + right: 0; + bottom: 0; + left: 0; + background: none repeat scroll 0 0 rgb(242, 242, 242); + z-index: 9999; +} +.fade-animation{ + opacity: @overlayer-opacity; + transition: opacity @transition-duration ease-in-out; +} +.fade-animation.ng-hide { + opacity:0; + transition: opacity @transition-duration ease-in-out; +} + +.activeUserIcon { + transition: all .2s ease-in-out; + display: block; + margin-left: auto; margin-right: auto; height:55px; width:55px; border-radius: 50%; + +} +.activeUserIcon:hover { transform: scale(1.5); } + +.ecomp-right-sidebar-toggle{ + position: absolute; + top: 400px; + right: 35px; +} + +.open-sidebar-toggle { + // right: 0; + transition: right .25s ease-in-out; + -moz-transition: right .25s ease-in-out; + -webkit-transition: right .25s ease-in-out; +} + +.close-sidebar-toggle { + right: -36px; + transition: right .25s ease-in-out; + -moz-transition: right .25s ease-in-out; + -webkit-transition: right .25s ease-in-out; +} + +.ecomp-right-sidebar-title{ + font-family: arial; + font-size: 14px; + color: #ef6f00; + margin-bottom:20px; + text-align: center; +}
\ No newline at end of file diff --git a/ecomp-portal-FE/client/app/directives/right-menu/right-menu.tpl.html b/ecomp-portal-FE/client/app/directives/right-menu/right-menu.tpl.html new file mode 100644 index 00000000..39eb7087 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/right-menu/right-menu.tpl.html @@ -0,0 +1,40 @@ +<!-- + ================================================================================ + 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 id="ecomp-right-sidebar-container" class="ecomp-sidebar-container" ng-class="isOpen ? 'open-sidebar': 'close-sidebar'"> + <div id="online-userbar" class="ecomp-sidebar-main" style="right: 0px; width:75px; padding:0px;" > + <div class="online-user-container" id="online-user-container" style="margin-top:45px; overflow-y:auto; overflow-x:hidden"> + <div class="ecomp-right-sidebar-title">Online Users</div> + <div ng-repeat="user in userList"> + <div class="child-row" style="height:85px;" ui-sref-active="att-accordion-active"> + <div> + <a href="javascript:void(0)" ng-click="openInNewTab(user.linkQ)" ><img class="activeUserIcon" ng-src="assets/images/photo.png" alt="User Link" ></a> + <div style="font-family: Arial; font-size:10px; text-align: center;" >{{user.userId}}</div> + </div> + </div> + </div> + </div> + </div> +</div> +<div class="ecomp-right-sidebar-toggle" ng-class="isOpen ? 'open-sidebar-toggle': 'close-sidebar-toggle'"> + <a href="javascript:void(0)" ng-click="toggleSidebar()" style="transform: rotate(-90deg); position:relative; z-index:5" att-button btn-type="primary" size="small" att-accessibility-click="13,32"> + <span class="ion-chevron-down" ng-show="isOpen"></span> + <span class="ion-chevron-up" ng-hide="isOpen"><span style="font-family: arial">Users</span></span> + </a> +</div> diff --git a/ecomp-portal-FE/client/app/directives/scroll-top/scroll-top.directive.js b/ecomp-portal-FE/client/app/directives/scroll-top/scroll-top.directive.js new file mode 100644 index 00000000..148660b5 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/scroll-top/scroll-top.directive.js @@ -0,0 +1,35 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + +angular.module('ecompApp') + .directive('scrollTop', function () { + return { + restrict: 'A', + scope: {api: '=scrollTop'}, + link: function (scope, element) { + scope.api = scope.api || {}; + scope.api.scrollTop = function() { + element.animate({ + scrollTop : 0 + }, 500); + }; + } + }; + }); diff --git a/ecomp-portal-FE/client/app/directives/search-users/search-users.controller.js b/ecomp-portal-FE/client/app/directives/search-users/search-users.controller.js new file mode 100644 index 00000000..649b3ab2 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/search-users/search-users.controller.js @@ -0,0 +1,161 @@ +/*- + * ================================================================================ + * 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 SearchUsersCtrl { + + constructor($log, usersService,adminsService, $scope,confirmBoxService) { + + $scope.UserSearchsIsNull=false; + $scope.userExist = false; + this.scrollApi = {};//scrollTop directive + + this.showAddUser = false; + this.showSearch = true; + this.newUser ={ + firstName:'', + lastName:'', + emailAddress:'', + + middleName:'', + loginId:'', + loginPwd:'', + loginPwdCheck:'' + }; + + let activeRequests = []; + let clearReq = (req) => { + activeRequests.splice(activeRequests.indexOf(req), 1); + }; + + this.showAddUserSection = () => { + this.showAddUser = true; + this.showSearch = false; + } + + this.addNewUserFun = () => { + if (this.newUser.loginId =='' || this.newUser.loginPwd == '' || this.newUser.firstName == '' || this.newUser.lastName =='' || this.newUser.emailAddress ==''||this.newUser.loginPwd ==''){ + var warningMsg = "Please enter a value for all fields marked with *."; + confirmBoxService.showInformation(warningMsg).then(isConfirmed => {return;}); + return; + } else if (this.newUser.loginPwd != this.newUser.loginPwdCheck) { + var warningMsg = "Passwords do not match, please try again."; + confirmBoxService.showInformation(warningMsg).then(isConfirmed => {return;}); + return; + } + else { + // check password length complexity. + var warningMsg = adminsService.isComplexPassword(this.newUser.loginPwd); + if (warningMsg != null) { + confirmBoxService.showInformation(warningMsg).then(isConfirmed => {return;}); + return; + } + } // password + + adminsService.addNewUser(this.newUser,'Yes').then(res=> { + + if(res.message == 'Record already exist'){ + + this.showAddUser = true; + this.showSearch = false; + $scope.userExist = true; + + }else{ + + $scope.userExist = false; + this.selectedUser = this.newUser; + this.selectedUser.orgUserId = this.newUser.loginId; + this.searchUsersResults = []; + this.searchUsersResults.push(this.newUser); + this.showAddUser = false; + this.showSearch = true; + this.newUser ={ + firstName:'', + lastName:'', + emailAdress:'', + middleName:'', + loginId:'', + loginPwd:'', + loginPwdCheck:'' + }; + this.searchUserString =''; + $scope.UserSearchsIsNull = false; + } + + + }).catch(err=> { + $log.error('adminsService: addNewUser error:: ', err); + // $scope.errMsg=err; + confirmBoxService.showInformation('Add New User failed: ' + err); + + }).finally(() => { + //this.isLoadingTable = false; + + }); + } + + this.searchUsers = () => { + this.isLoading = true; + if(this.searchUsersInProgress){ + return; + } + this.selectedUser = null; + this.searchUsersInProgress = true; + this.searchUsersResults = null; + + let searchUsersReq = usersService.searchUsers(this.searchUserString); + activeRequests.push(searchUsersReq); + searchUsersReq.promise().then(usersList => { + $log.debug('searchUsers found the following users: ', JSON.stringify(usersList)); + this.searchUsersResults = usersList; + $scope.UserSearchsIsNull=false; + }).catch(err => { + $log.error('SearchUsersCtrl.searchUsers: ' + err); + $scope.UserSearchsIsNull=true; + }).finally(() => { + this.scrollApi.scrollTop(); + this.searchUsersInProgress = false; + clearReq(searchUsersReq); + this.isLoading = false; + }); + }; + + let init = () => { + this.isLoading = false; + this.searchUsersInProgress = false; + }; + + this.setSelectedUser = user => { + this.selectedUser = user; + }; + + init(); + + $scope.$on('$destroy', () => { + activeRequests.forEach(req => { + req.cancel(); + }); + }); + } + } + SearchUsersCtrl.$inject = ['$log', 'usersService','adminsService', '$scope','confirmBoxService']; + angular.module('ecompApp').controller('SearchUsersCtrl', SearchUsersCtrl); +})(); diff --git a/ecomp-portal-FE/client/app/directives/search-users/search-users.controller.spec.js b/ecomp-portal-FE/client/app/directives/search-users/search-users.controller.spec.js new file mode 100644 index 00000000..96f5b0df --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/search-users/search-users.controller.spec.js @@ -0,0 +1,176 @@ +/*- + * ================================================================================ + * 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: NewAdminCtrl ', () => { +// beforeEach(module('ecompApp')); +// +// //destroy $http default cache before starting to prevent the error 'default cache already exists' +// beforeEach(inject((_CacheFactory_)=> { +// _CacheFactory_.destroyAll(); +// })); +// +// +// let newCtrl, $controller, $q, $rootScope, $log; +// +// beforeEach(inject((_$controller_, _$q_, _$rootScope_, _$log_)=> { +// [$controller, $q, $rootScope, $log] = [_$controller_, _$q_, _$rootScope_, _$log_]; +// })); +// +// let deferredUsersList, deferredAdminAppsRoles, deferredUpdateRolesRes; +// let usersServiceMock, adminsServiceMock; +// beforeEach(()=> { +// [deferredUsersList, deferredAdminAppsRoles, deferredUpdateRolesRes] = [$q.defer(), $q.defer(), $q.defer()]; +// +// //usersServiceMock = jasmine.createSpyObj('usersServiceMock', ['searchUsers']); +// usersServiceMock = { +// searchUsers: () => { +// var promise = () => {return deferredUsersList.promise}; +// var cancel = jasmine.createSpy(); +// return { +// promise: promise, +// cancel: cancel +// } +// } +// }; +// +// adminsServiceMock = jasmine.createSpyObj('adminsServiceMock', ['getAdminAppsRoles', 'updateAdminAppsRoles']); +// +// //usersServiceMock.searchUsers.and.returnValue(deferredUsersList.promise); +// adminsServiceMock.getAdminAppsRoles.and.returnValue(deferredAdminAppsRoles.promise); +// adminsServiceMock.updateAdminAppsRoles.and.returnValue(deferredUpdateRolesRes.promise); +// +// newCtrl = $controller('NewAdminModalCtrl', { +// $log: $log, +// usersService: usersServiceMock, +// adminsService: adminsServiceMock, +// $scope: $rootScope +// }); +// }); +// +// it('should init default values when loading the controller', ()=> { +// //expect(newCtrl.searchUsersInProgress).toBe(false); +// expect(newCtrl.dialogState).toBe(1); +// expect(newCtrl.selectedUser).toBe(null); +// }); +// +// it('should populate retrieved users when search users service returns a list ', ()=> { +// //spyOn(usersServiceMock, 'searchUsers'); +// let usersListRes = [{user: 1}, {user: 2}]; +// newCtrl.searchUserString = 'some user name'; +// deferredUsersList.resolve(usersListRes); +// newCtrl.searchUsers(); +// $rootScope.$apply(); +// +// //expect(usersServiceMock.searchUsers).toHaveBeenCalledWith(newCtrl.searchUserString); +// expect(newCtrl.searchUsersResults).toEqual(usersListRes); +// expect(newCtrl.searchUsersInProgress).toBe(false); +// }); +// +// it('should log the error when search users fails', ()=> { +// spyOn($log, 'error'); +// deferredUsersList.reject('oh snap!'); +// newCtrl.searchUsers(); +// $rootScope.$apply(); +// expect($log.error).toHaveBeenCalled(); +// }); +// +// it('should populate admin apps roles and move to the next screen when adminsService.getAdminAppsRoles succeeded', ()=> { +// let userApps = {appsRoles: [{id: 1, isAdmin: false}, {id: 2, isAdmin: true}]}; +// deferredAdminAppsRoles.resolve(userApps); +// +// newCtrl.searchUsersInProgress = false; +// newCtrl.selectedUser = {userId: 'userId'}; +// +// newCtrl.getAdminAppsRoles(); +// $rootScope.$apply(); +// +// expect(adminsServiceMock.getAdminAppsRoles).toHaveBeenCalledWith(newCtrl.selectedUser.userId); +// expect(newCtrl.adminAppsRoles).toEqual(userApps.appsRoles); +// expect(newCtrl.dialogState).toBe(2); +// }); +// +// it('should log the error when adminsService.getAdminAppsRoles fails', ()=> { +// spyOn($log, 'error'); +// deferredAdminAppsRoles.reject('some error'); +// +// newCtrl.searchUsersInProgress = false; +// newCtrl.selectedUser = {userId: 'userId'}; +// +// newCtrl.getAdminAppsRoles(); +// $rootScope.$apply(); +// +// expect($log.error).toHaveBeenCalled(); +// }); +// it('should log the error when trying to getAdminAppsRoles without selecting user ', ()=> { +// spyOn($log, 'error'); +// +// newCtrl.searchUsersInProgress = false; +// newCtrl.selectedUser = null; +// +// newCtrl.getAdminAppsRoles(); +// $rootScope.$apply(); +// +// expect($log.error).toHaveBeenCalled(); +// }); +// //it('should setSelectedUser when choosing user', ()=> { +// // +// //}); +// //it('should set isAdmin as false when removing app from the administrated apps list', ()=> { +// //}); +// it('should set isAdmin as true when adding app via the dropdown menu', ()=> { +// newCtrl.adminAppsRoles = [{id: 1, isAdmin: false},{id: 2, isAdmin: true}]; +// //simulate UI change +// $rootScope.$apply('newAdmin.selectedNewApp = null'); +// $rootScope.$apply('newAdmin.selectedNewApp = {id: 1, isAdmin: true}'); +// +// expect(newCtrl.adminAppsRoles[0].isAdmin).toBe(true); +// expect(newCtrl.selectedNewApp).toBe(null); +// }); +// +// it('should close the modal when updating apps roles succeeded', ()=> { +// $rootScope.closeThisDialog = () => {}; +// spyOn($rootScope,'closeThisDialog'); +// +// newCtrl.selectedUser = {userId: 'userId'}; +// newCtrl.adminAppsRoles = [{id: 1}]; +// +// deferredUpdateRolesRes.resolve(); +// newCtrl.updateAdminAppsRoles(); +// $rootScope.$apply(); +// +// expect(adminsServiceMock.updateAdminAppsRoles).toHaveBeenCalledWith({userId: newCtrl.selectedUser.userId, appsRoles: newCtrl.adminAppsRoles}); +// expect($rootScope.closeThisDialog).toHaveBeenCalled(); +// }); +// it('should log the error when updating apps roles fails', ()=> { +// newCtrl.selectedUser = {userId: 'userId'}; +// newCtrl.adminAppsRoles = [{id: 1}]; +// +// spyOn($log,'error'); +// deferredUpdateRolesRes.reject(); +// newCtrl.updateAdminAppsRoles(); +// $rootScope.$apply(); +// expect($log.error).toHaveBeenCalled(); +// }); +// //it('should display the add admin dropdown when clicking the add button', ()=> { +// //}); +// +//}); diff --git a/ecomp-portal-FE/client/app/directives/search-users/search-users.directive.js b/ecomp-portal-FE/client/app/directives/search-users/search-users.directive.js new file mode 100644 index 00000000..4e5809f9 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/search-users/search-users.directive.js @@ -0,0 +1,34 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + +angular.module('ecompApp') + .directive('searchUsers', function () { + return { + restrict: 'E', + templateUrl: 'app/directives/search-users/search-users.tpl.html', + controller: 'SearchUsersCtrl', + controllerAs: 'searchUsers', + bindToController: true, + scope: { + selectedUser: '=', + searchTitle: '@' + } + }; + }); diff --git a/ecomp-portal-FE/client/app/directives/search-users/search-users.less b/ecomp-portal-FE/client/app/directives/search-users/search-users.less new file mode 100644 index 00000000..9c6de2b4 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/search-users/search-users.less @@ -0,0 +1,154 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + .search-users-directive{ + .title { + .n18r; + border-bottom: @a 3px solid; + + } + + .add-user-section{ + margin-top:0px; + margin-left:10px; + } + + .input-text-new-user { + font-style: italic; + padding: 7px 10px; + width: 200px !important; + display: inline-block; + position: relative; + margin-bottom: 10px; + border-radius: 6px; + border: 1px solid #d8d8d8; + height: 32px; + border-color: slategrey !important; + } + + .input-new-user-div{ + + margin-left:10px; + } + + .add-user-button { + cursor: pointer; + float:right; + width: 120px; + + margin-left : 5px; + + .btn-blue; + + line-height: 32px; + height: 29px; + text-align: center; + vertical-align: middle; + line-height: 28px; + + &::before { + .ico_add_user; + content: '\f211'; + font-family: "Ionicons"; + vertical-align: middle; + display: inline-block; + margin-right: 8px; + line-height: 16px; + } + } + + .main { + margin: 16px; + .search-instructions { + .n14r; + margin-bottom: 8px; + } + .search { + .input-field { + display: inline-block; + width: 250px; + height: 30px; + } + .search-button { + .btn-blue; + width: 90px; + display: inline-block; + float: right; + } + } + + .search-results { + margin-top: 10px; + .results-title { + .n14r; + margin-bottom: 8px; + } + + .results-container { + height: 208px; + overflow-y: auto; + .user { + padding-left: 10px; + padding-top: 6px; + height: 48px; + + border-top: 1px solid @p; + border-right: 1px solid @p; + border-left: 1px solid @p; + + &:last-child { + border-bottom: 1px solid @p; + } + + cursor: pointer; + &:hover { + background-color: @v; + } + + &.selected { + background-color: @v; + } + + .main-name { + .n14r; + + } + .sub-job-title { + .p13r; + + } + } + + } + + } + .error-text { + margin-top: 25px; + font-weight: 400; + font-size: 16px; + text-align: left; + color: @err; + } + + .no-user-found { + margin-top: 16px; + .n14r; + } + } +}
\ No newline at end of file diff --git a/ecomp-portal-FE/client/app/directives/search-users/search-users.tpl.html b/ecomp-portal-FE/client/app/directives/search-users/search-users.tpl.html new file mode 100644 index 00000000..6c275693 --- /dev/null +++ b/ecomp-portal-FE/client/app/directives/search-users/search-users.tpl.html @@ -0,0 +1,144 @@ +<!-- + ================================================================================ + 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="search-users-directive"> + <form name="searchUsersForm" novalidate> + <div class="title" ng-bind="searchUsers.searchTitle"></div> + <div class="main"> + <div ng-if="searchUsers.showSearch"> + <div class="search-instructions">Enter first name, last name or User ID</div> + <div class="search"> + <input id="input-user-search" + class="input-field" + autocomplete="off" + type="text" + name="searchString" + placeholder="Search" + ng-model="searchUsers.searchUserString" + ng-keyup="$event.keyCode===13 && searchUsersForm.searchString.$valid && searchUsers.searchUsers()" + pattern="[a-zA-Z0-9-'\s]{1,}" + maxlength="80" + required="true" auto-focus tabindex="0"/> + + <div id="Create-New-User-button" class="add-user-button" ng-click="searchUsers.showAddUserSection()">New User</div> + <div id="button-search-users" + class="search-button" + tabindex="2" + ng-class="{disabled: searchUsersForm.searchString.$invalid || searchUsers.searchUsersInProgress}" + ng-click="searchUsersForm.searchString.$valid && searchUsers.searchUsers()"> + Search + </div> + + </div> + + <span class="ecomp-spinner" ng-show="searchUsers.isLoading"></span> + <div ng-show="UserSearchsIsNull===false"> + <div class="search-results" + ng-show="!searchUsers.isLoading + && searchUsers.searchUsersResults + && searchUsers.searchUsersResults.length"> + <div id="search-results" ng-show="UserSearchsIsNull===false" + class="results-title" + ng-bind="'Showing ' + searchUsers.searchUsersResults.length + ' results'"></div> + <div class="results-container" scroll-top="searchUsers.scrollApi"> + <div id="search-result-{{$index}}" + class="user" + ng-repeat="user in (searchUsers.searchUsersResults | orderBy:['firstName','lastName','orgUserId']) | limitTo: 100 track by $index" + ng-click="searchUsers.setSelectedUser(user)" + ng-class="{selected: user.orgUserId === searchUsers.selectedUser.orgUserId}"> + <div id="main-name-{{$index}}" class="main-name"> + <span id="result-first-name-{{$index}}" ng-bind="::user.firstName"></span> + <span id="result-last-name-{{$index}}" ng-bind="::user.lastName"></span> + <span id="result-uuid-{{$index}}" ng-bind="::user.orgUserId"></span></div> + <div id="job-title-{{$index}}" class="sub-job-title" ng-bind="::user.jobTitle"></div> + <br/> + </div> + </div> + </div> + </div> + + <div class="error-text" + id="user-search-error-403" + ng-show="UserSearchsIsNull===true"> + No match found. + </div> + + <div id="no-user-found" + class="no-user-found" + ng-show="searchUsers.searchUsersResults && searchUsers.searchUsersResults.length===0 && !searchUsers.searchUsersInProgress"> + No users found + </div> + </div> + + + <div id="addWidget" class="add-user-section" ng-if="searchUsers.showAddUser"> + <div> + <div class="input-new-user-div" > + <div class="">*First Name</div> + <input class="input-text-new-user" type="text" ng-model="searchUsers.newUser.firstName"/> + </div> + <div class="input-new-user-div" > + <div class="">Middle Name</div> + <input class="input-text-new-user" type="text" ng-model="searchUsers.newUser.middleName"/> + </div> + <div class="input-new-user-div" > + <div class="">*Last Name</div> + <input class="input-text-new-user" type="text" ng-model="searchUsers.newUser.lastName"/> + </div> + <div class="input-new-user-div" > + <div class="">*Email Address ID</div> + <input class="input-text-new-user" type="text" ng-model="searchUsers.newUser.emailAddress"/> + </div> + <div class="input-new-user-div" > + <div class="">*Login ID</div> + <input class="input-text-new-user" type="text" ng-model="searchUsers.newUser.loginId"/> + </div> + <div class="input-new-user-div" > + <div class="">*Login Password</div> + <input class="input-text-new-user" type="password" ng-model="searchUsers.newUser.loginPwd"/> + </div> + <div class="input-new-user-div" > + <div class="">*Confirm Login Password</div> + <input class="input-text-new-user" type="password" ng-model="searchUsers.newUser.loginPwdCheck"/> + </div> + <div ng-show="searchUsers.newUser.loginPwdCheck.length>=searchUsers.newUser.loginPwd.length&&searchUsers.newUser.loginPwdCheck.length>0&&searchUsers.newUser.loginPwd!=searchUsers.newUser.loginPwdCheck" + style="color: #cf2a2a; font-size: 12px;"> + <small + style="position: absolute; margin-top: -6px;">The passwords do not match. Try again. + </small> + </div> + <div ng-show="userExist==true" + style="color: #cf2a2a; font-size: 12px;"> + <small + style="position: absolute; margin-top: -6px;">User with same loginId already exists. Try again. + </small> + </div> + </div> + <div style="height:50px;"> + <a style="margin-right:10px;margin-top:20px;margin-bottom:5px" att-button btn-type="primary" class="button button--primary" size="small" ng-click="searchUsers.addNewUserFun()">Add New User</a> + </div> + </div> + + + </div> + + </div> + + </form> +</div> |