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/dashboard | |
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/dashboard')
8 files changed, 2224 insertions, 0 deletions
diff --git a/ecomp-portal-FE/client/app/views/dashboard/dashboard-widget-manage.html b/ecomp-portal-FE/client/app/views/dashboard/dashboard-widget-manage.html new file mode 100644 index 00000000..84ac2a44 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/dashboard/dashboard-widget-manage.html @@ -0,0 +1,152 @@ +<!-- + ================================================================================ + 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="margin-top: 10px; margin-bottom: 10psx;"> + <h1 class="heading1"></h1> +</div> +<br /> + +<div style="margin-top: 25px;"> + <div id="title" class="manage-contactUs-home-manageWidgets-title">Manage {{widgetTypeDisplay}} Widgets</div> + <div class="widgets-popup-margin"> + <div class="get-access-table"> + <div class="table-control" style="margin:30px;"> + <div class="c-ecomp-att-abs-table" style="height:300px""> + <table att-table id="table-main" + table-data="ignoredTableData" + current-page="ignoredCurrentPage"> + <thead att-table-row type="header"> + <tr> + <th id="th-users-1" att-table-header key="title" sortable="true" >Title</th> + <th id="th-users-2" att-table-header key="href" sortable="true" >URL</th> + <th ng-show="{{widgetType=='EVENTS'}}" id="th-users-3" att-table-header key="event_date" sortable="true" >Date</th> + <th ng-show="{{widgetType=='EVENTS'}}" id="th-users-4" att-table-header key="content" sortable="true" >Content</th> + <th id="th-users-5" att-table-header key="sortOrder" sortable="true" >Order</th> + <th id="th-users-6" att-table-header key="edit" sortable="false" >Edit</th> + <th id="th-users-7" att-table-header key="delete" sortable="false" >Delete</th> + </tr> + </thead> + <!-- Use track-by="UNIQUE KEY HERE" or leave out if no unique keys in data --> + <tbody att-table-row type="body" class="table-body" track-by="$index" row-repeat="rowData in widgetData"> + <tr id="tr-rowData" ng-click=""> + <td att-table-body> + <div id="widget-td-title" ng-hide="rowData.showEdit" ng-bind="rowData.title"></div> + <input type="text" ng-show="rowData.showEdit" ng-model="widgetData[$index].title"/> + </td> + <td att-table-body> + <div id="widget-td-href" ng-hide="rowData.showEdit" ng-bind="rowData.href"></div> + <input type="text" ng-show="rowData.showEdit" ng-model="widgetData[$index].href"/> + </td> + <td ng-show="{{widgetType=='EVENTS'}}" att-table-body> + <div id="widget-td-date" ng-hide="rowData.showEdit" ng-bind="rowData.eventDate"></div> + <input type="text" ng-show="rowData.showEdit" ng-model="widgetData[$index].eventDate"/> + </td> + <td ng-show="{{widgetType=='EVENTS'}}" att-table-body> + <div id="widget-td-content" ng-hide="rowData.showEdit">{{rowData.content | cut:true:20:' ...'}}</div> + <input type="text" ng-show="rowData.showEdit" ng-model="widgetData[$index].content"/> + </td> + <td att-table-body> + <div id="widget-td-order" ng-hide="rowData.showEdit" ng-bind="rowData.sortOrder"></div> + <input type="text" ng-show="rowData.showEdit" ng-model="widgetData[$index].sortOrder"/> + </td> + <td att-table-body> + <div class="delete-contact-us" ng-hide="rowData.showEdit" ng-click="setEdit($index);"> + <span class="ion-edit"></span> + </div> + <span ng-show="rowData.showEdit"> + <a att-button btn-type="primary" ng-click="modify($index);" class="button button--primary" size="small" >Save</a> + </span> + </td> + <td att-table-body> + <div class="delete-contact-us" ng-click="remove($index);"> + <span class="ion-trash-b"></span> + </div> + </td> + </tr> + </tbody> + </table> + </div> + + <div att-divider-lines></div> + <div style="margin-top: 15px; margin-left: -80px;" > + <form name = "widgetForm" novalidate> + <div id="addWidgetHeader" class="contact-us-margin"> + <h1 style="font-size:18px;">Add</h1> + <div class="errMsg">{{errMsg}}</div> + <div class="sucessMsg" ng-bind="successMsg"></div> + </div> + <div id="addWidget" class="contact-us-margin"> + <div> + <div> + <div class="add-widget-field"> + <div id="mots-property-label" class="property-label">Title</div> + <input class="input-text-area" type="text" ng-model="newWidgetObject.title" name="title" ng-required="true"/> + </div> + <div class="add-widget-field"> + <div class="property-label">URL</div> + <input class="input-text-area" type="text" ng-model="newWidgetObject.href" type="url" size="3" name = "url" ng-required = "true"/> + </div> + <div class="add-widget-field" > + <div class="property-label">Sort Order</div> + <input class="input-text-area" type="text" ng-model="newWidgetObject.sortOrder"/> + </div> + </div> + <div class="add-widget-field" ng-controller="DatePickerController" ng-show="{{widgetType=='EVENTS'}}"> + <h4>Event Date</h4> + <div> + <div> + <p class="input-group"> + <input type="text" name = "eventDate" datetime="yyyy-MM-dd" class="input-text-area" uib-datepicker-popup="{{format}}" + ng-model="newWidgetObject.eventDate" is-open="popup1.opened" datepicker-options="dateOptions" close-text="Close" alt-input-formats="altInputFormats" + ng-focus="open1()" + ng-required = "widgetType =='EVENTS'" /> + </p> + </div> + </div> + </div> + + <div class="add-contact-us-field-des" ng-show="{{widgetType=='EVENTS'}}"> + <div class="property-label">Content</div> + <textarea style="margin-top: 0px; margin-bottom: 0px; height: 150px" ng-model="newWidgetObject.content" name="content" ng-required = "widgetType =='EVENTS'"> + </textarea> + </div> + </div> + <div style="height:50px;"> + <a style="float:right; margin-top:20px;" att-button btn-type="primary" class="button button--primary" size="small" ng-click="saveNew()">Add New</a> + + </div> + + <div att-divider-lines></div> + + </div> + </form> + </div> + <div style="height:50px;"> + <a style="float:right;" att-button btn-type="primary" class="button button--primary" size="small" ng-click="closeDialog()">Close</a> + </div> + </div> + </div> + </div> +</div> + +<script type="application/javascript"> + $(document).ready(function(){ + $(".ngdialog-content").css("width","85%") + }); +</script> diff --git a/ecomp-portal-FE/client/app/views/dashboard/dashboard-widget.controller.js b/ecomp-portal-FE/client/app/views/dashboard/dashboard-widget.controller.js new file mode 100644 index 00000000..d489ac42 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/dashboard/dashboard-widget.controller.js @@ -0,0 +1,422 @@ +/*- + * ================================================================================ + * 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 CommonWidgetController { + constructor(dashboardService, $scope, message, $q, $http, conf, $filter,confirmBoxService,$log) { + $scope.widgetType = message.type; + $scope.widgetTypeDisplay = message.type; + $scope.modflag = false; + + switch (message.type) { + case 'EVENTS': + $scope.widgetTypeDisplay = 'Events' + break; + case 'NEWS': + $scope.widgetTypeDisplay = 'News' + break; + case 'IMPORTANTRESOURCES': + $scope.widgetTypeDisplay = 'Resources' + break; + } + + $scope.widgetData = []; + dashboardService.getCommonWidgetData(message.type) + .then(function (res) { + // console.log('CommonWidgetController: result is ' + res); + $scope.widgetData = res.response.items; + }); + + + + $scope.setEdit = function(index) { + + //for(var i=0; i<$scope.widgetData ) + + if($scope.modflag === false){ + $scope.widgetData[index].showEdit = true; + $scope.modflag = true; + } + } + + $scope.modify = function(index) { + + $scope.widgetObject = {}; + $scope.widgetObject.id = $scope.widgetData[parseInt(index)].id; + $scope.widgetObject.category = $scope.widgetData[parseInt(index)].category; + $scope.widgetObject.title = $scope.widgetData[parseInt(index)].title; + $scope.widgetObject.href = $scope.widgetData[parseInt(index)].href; + $scope.widgetObject.eventDate = $scope.widgetData[parseInt(index)].eventDate; + $scope.widgetObject.content = $scope.widgetData[parseInt(index)].content; + $scope.widgetObject.sortOrder = $scope.widgetData[parseInt(index)].sortOrder; + + var validateMsg = $scope.validateWidgetObject($scope.widgetObject); + if (validateMsg) { + confirmBoxService.showInformation(validateMsg).then(isConfirmed => {return;}); + return; + } + + dashboardService.saveCommonWidgetData($scope.widgetObject) + .then(function(res){ + if (res.status == 'OK') { + dashboardService.getCommonWidgetData(message.type) + .then(function(res){ + $scope.widgetData = res.response.items; + $scope.modflag = false; + $scope.cancelEdit(index); + }); + } + else { + // Save failed + confirmBoxService.showInformation("Save failed").then(isConfirmed => {return;}); + return; + } + }); + + }; + + $scope.newWidgetObject = {}; + + // Answers string error if validation fails; + // answers null if all is well. + $scope.validateWidgetObject = function(wo) { + if (wo.title == null || wo.title == '') + return "Please enter a title."; + if (wo.href == null || wo.href == '' || !validateUrl(wo.href)) + return "Please enter a valid URL that starts with http."; + if (wo.sortOrder == null || wo.sortOrder == '' || isNaN(parseInt(wo.sortOrder))) + return "Please enter a number for the sort order."; + if (wo.category=='EVENTS') { + if (wo.eventDate == null || wo.eventDate == '') + return "Please enter a date for the event."; + // Parses and normalizes the date with rollover. + var filteredDate = $filter('date')(wo.eventDate, "yyyy-MM-dd"); + // $log.debug('dashboard-widget-controller: date filter yields ' + filteredDate); + // The date picker shows mm/dd/yy. + if (filteredDate == null || filteredDate.length != 10) + return "Please enter a valid date as YYYY-MM-DD"; + if (wo.content==null || wo.content=='') + return "Please enter content for the event."; + } + return null; + }; + + $scope.saveNew = function() { + $scope.newWidgetObject.category = message.type; + // $log.info($scope.newWidgetObject); + var validateMsg = $scope.validateWidgetObject($scope.newWidgetObject); + if (validateMsg) { + confirmBoxService.showInformation(validateMsg).then(isConfirmed => {return;}); + return; + } + // Transform date into expected storage format + $scope.newWidgetObject.eventDate = $filter('date')($scope.newWidgetObject.eventDate, "yyyy-MM-dd"); + + dashboardService.saveCommonWidgetData($scope.newWidgetObject) + .then(function(res){ + if (res.status == 'OK') { + $scope.widgetForm.$setPristine(); + confirmBoxService.showInformation('You have added a new item').then(isConfirmed => { + }); + dashboardService.getCommonWidgetData(message.type) + .then(function(res){ + $scope.widgetData = res.response.items; + $scope.newWidgetObject = {}; + }); + } + else { + confirmBoxService.showInformation("Save failed").then(isConfirmed => {return;}); + return; + } + }); + }; + + $scope.remove = function(index) { + var confirmMsg = 'Are you sure you want to delete this item from the list?' + ' Press OK to delete.'; + confirmBoxService.confirm(confirmMsg).then(function (confirmed) { + if (confirmed == true) { + $scope.widgetObject = {}; + $scope.widgetObject.id = $scope.widgetData[parseInt(index)].id; + $scope.widgetObject.category = $scope.widgetData[parseInt(index)].category; + $scope.widgetObject.title = $scope.widgetData[parseInt(index)].title; + $scope.widgetObject.href = $scope.widgetData[parseInt(index)].href; + $scope.widgetObject.sortOrder = $scope.widgetData[parseInt(index)].sortOrder; + + + dashboardService.removeCommonWidgetData($scope.widgetObject) + .then(function(res){ + dashboardService.getCommonWidgetData(message.type) + .then(function(res){ + $scope.widgetData = res.response.items; + $scope.cancelEdit(index); + }); + }); + } + }); + + }; + $scope.closeDialog = function(){ + $scope.closeThisDialog( $scope.widgetData); + } + $scope.deleteSpeedDial = function(widget){ + + } + + $scope.manage = function(index) { + $scope.modflag = true; + + var thisdata = $scope.widgetData[index]; + $scope.editMode=true; + var category = "#category"+index; + var categoryEdit = "#categoryEdit"+index; + + var title = "#title"+index; + var titleEdit = "#titleEdit"+index; + + var url = "#href"+index; + var urlEdit = "#hrefEdit"+index; + + var order = "#order"+index; + var orderEdit = "#orderEdit"+index; + + var eventDate = "#eventDate"+index; + var eventDateEdit = "#eventDateEdit"+index; + + + var dsavebutton ="#savebutton"+index; + var dremovebutton="#removebutton"+index; + var dmanagebutton="#managebutton"+index; + var deditRbutton="#editRbutton"+index; + + $(title).css('display', 'none'); + $(titleEdit).css('display', 'inherit'); + $(url).css('display', 'none'); + $(urlEdit).css('display', 'inherit'); + $(order).css('display', 'none'); + $(orderEdit).css('display', 'inherit'); + $(eventDate).css('display', 'none'); + $(eventDateEdit).css('display', 'inherit'); + + $(dsavebutton).css('display', 'inherit'); + $(dremovebutton).css('display', 'inherit'); + $(dmanagebutton).css('display', 'none'); + $(deditRbutton).css('display', 'inherit'); + + }; + + $scope.cancelEdit = function(index) { + + $scope.editMode=false; + var category = "#category"+index; + var categoryEdit = "#categoryEdit"+index; + + var title = "#title"+index; + var titleEdit = "#titleEdit"+index; + + var url = "#href"+index; + var urlEdit = "#hrefEdit"+index; + + var order = "#order"+index; + var orderEdit = "#orderEdit"+index; + + var eventDate = "#eventDate"+index; + var eventDateEdit = "#eventDateEdit"+index; + + var dsavebutton ="#savebutton"+index; + var dremovebutton ="#removebutton"+index; + var dmanagebutton="#managebutton"+index; + var deditRbutton="#editRbutton"+index; + + $(title).css('display', 'inherit'); + $(titleEdit).css('display', 'none'); + + $(url).css('display', 'inherit'); + $(urlEdit).css('display', 'none'); + + $(order).css('display', 'inherit'); + $(orderEdit).css('display', 'none'); + + $(eventDate).css('display', 'inherit'); + $(eventDateEdit).css('display', 'none'); + + $(dsavebutton).css('display', 'none'); + $(dremovebutton).css('display', 'none'); + $(dmanagebutton).css('display', 'inherit'); + $(deditRbutton).css('display', 'none'); + + }; + + $scope.popupConfirmWin = function(title, msgBody, callback){ + modalService.popupConfirmWin.apply(null, arguments); + }; + } + } + CommonWidgetController.$inject = ['dashboardService', '$scope', 'message', '$q', '$http', 'conf', '$filter','confirmBoxService','$log']; + angular.module('ecompApp').controller('CommonWidgetController', CommonWidgetController); +})(); + +angular.module('ecompApp').filter('cut', function () { + return function (value, wordwise, max, tail) { + if (!value) return ''; + + max = parseInt(max, 10); + if (!max) return value; + if (value.length <= max) return value; + + value = value.substr(0, max); + if (wordwise) { + var lastspace = value.lastIndexOf(' '); + if (lastspace != -1) { + //Also remove . and , so its gives a cleaner result. + if (value.charAt(lastspace-1) == '.' || value.charAt(lastspace-1) == ',') { + lastspace = lastspace - 1; + } + value = value.substr(0, lastspace); + } + } + + return value + (tail || ' …'); + }; +}); + +angular.module('ecompApp').controller('DatePickerController', function ($scope, uibDateParser) { + $scope.today = function() { + $scope.dt = new Date(); + }; + $scope.today(); + + $scope.clear = function() { + $scope.dt = null; + }; + + $scope.inlineOptions = { + customClass: getDayClass, + minDate: new Date(), + showWeeks: true + }; + + $scope.dateOptions = { + dateDisabled: disabled, + formatYear: 'yy', + minDate: new Date(), + startingDay: 1 + }; + + // Disable weekend selection + function disabled(data) { + var date = data.date, + mode = data.mode; + return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6); + } + + $scope.toggleMin = function() { + $scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? null : new Date(); + $scope.dateOptions.minDate = $scope.inlineOptions.minDate; + }; + + $scope.toggleMin(); + + $scope.open1 = function() { + // console.log('In open1'); + $scope.popup1.opened = true; + }; + + $scope.open2 = function() { + // console.log('In open2'); + $scope.popup2.opened = true; + }; + + + $scope.setDate = function(year, month, day) { + $scope.dt = new Date(year, month, day); + }; + + $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate']; + $scope.format = $scope.formats[3]; + $scope.altInputFormats = ['M!/d!/yyyy']; + + $scope.popup1 = { + opened: false + }; + + $scope.popup2 = { + opened: false + }; + + var tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + var afterTomorrow = new Date(); + afterTomorrow.setDate(tomorrow.getDate() + 1); + $scope.events = [ + { + date: tomorrow, + status: 'full' + }, + { + date: afterTomorrow, + status: 'partially' + } + ]; + + function getDayClass(data) { + var date = data.date, + mode = data.mode; + if (mode === 'day') { + var dayToCheck = new Date(date).setHours(0,0,0,0); + + for (var i = 0; i < $scope.events.length; i++) { + var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0); + + if (dayToCheck === currentDay) { + return $scope.events[i].status; + } + } + } + + return ''; + } +}); + + + +function toggleCollapsible(id, clickedIconId, subtitutingIconId){ + $("#"+id).toggle(); + $("#"+clickedIconId).toggle(); + $("#"+subtitutingIconId).toggle(); + setTimeout(function(){focusFirstEle(id);}, 1000); +} + +function focusFirstEle(id){ + var focusItems = $("#"+id).find(":focusable"); + for(var i=0; i<focusItems.length; i++){ + if(!isHidden(focusItems[i])){ + var targetClassName = focusItems[i].className; + if(targetClassName!='collapsibleArrow'){ + focusItems[i].focus(); + return; + } + } + } +} + +function validateUrl(value){ + return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); + } diff --git a/ecomp-portal-FE/client/app/views/dashboard/dashboard-widget.controller.less b/ecomp-portal-FE/client/app/views/dashboard/dashboard-widget.controller.less new file mode 100644 index 00000000..dda8e300 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/dashboard/dashboard-widget.controller.less @@ -0,0 +1,101 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + .searchLiHeader { +font-weight: bold; +color: #0574ac; +font-size: 16px; +padding-bottom: 10px; +line-height: 1.5; +font-family: arial; + +} + +.searchLiItems{ +cursor: pointer; +font-weight: normal; +font-size: 12px; +color: #444444; +font-family: arial; +} + +.searchUl { +list-style: none; +border-bottom: 1px solid #bbb; +padding-bottom: 20px; +} + +#editWidgetsContent { + height: 300px; + width: 1770px; +} + +#editWidgetsContent .scroll-viewport { + height: 300px; + width: 1770px; +} + +.full button span { + background-color: limegreen; + border-radius: 32px; + color: black; +} + +.partially button span { + background-color: orange; + border-radius: 32px; + color: black; + } + + .add-widget-field{ + width:250px; + display: inline-table; + margin:10px; + + } + .uib-datepicker-popup { + th { + vertical-align: middle !important; + } + } + + .input-text-area { + font-style: italic; + padding: 7px 10px; + width: 250px !important; + display: inline-block; + position: relative; + margin-bottom: 10px; + border-radius: 6px; + border: 1px solid #d8d8d8; + height: 32px; + border-color: slategrey !important; + } + .input-inline-edit-text { + font-style: italic; + padding: 7px 10px; + display: inline-block; + position: relative; + margin-bottom: 10px; + border-radius: 6px; + border: 1px solid #d8d8d8; + height: 32px; + border-color: slategrey !important; + width:100%; + }
\ No newline at end of file diff --git a/ecomp-portal-FE/client/app/views/dashboard/dashboard.controller.js b/ecomp-portal-FE/client/app/views/dashboard/dashboard.controller.js new file mode 100644 index 00000000..3228f636 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/dashboard/dashboard.controller.js @@ -0,0 +1,312 @@ +/*- + * ================================================================================ + * 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 _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } +} + +(function() { + var HTTP_PROTOCOL_RGX = /https?:\/\//; + + var DashboardCtrl = function DashboardCtrl(applicationsService, $log, + $window, userProfileService, $scope, $cookies, $timeout, $interval, + $modal, $state, dashboardService,ngDialog) { + + var _this = this; + + _classCallCheck(this, DashboardCtrl); + + // activate spinner + this.isLoading = true; + $scope.getUserAppsIsDone = false; + this.userProfileService = userProfileService; + $scope.demoNum = 1; + $scope.event_content_show = false; + $scope.widgetData = []; + + $scope.editWidgetModalPopup = function(availableData, resourceType) { + $scope.editData = JSON.stringify(availableData); + $scope.availableDataTemp = $scope.availableData; + ngDialog.open({ + templateUrl : 'app/views/dashboard/dashboard-widget-manage.html', + controller : 'CommonWidgetController', + resolve : { + message : function message() { + var message = { + type : resourceType, + availableData : $scope.editData + }; + return message; + } + } + }).closePromise.then(needUpdate => { + if(resourceType=='NEWS'){ + $scope.updateNews(); + }else if(resourceType=='EVENTS'){ + $scope.updateEvents(); + }else if(resourceType=='IMPORTANTRESOURCES'){ + $scope.updateImportRes(); + } + }); + }; + + userProfileService.getUserProfile() + .then( + function(profile) { + // $log.info(profile); + $scope.attuid = profile.attuid; + // $log.info('user has the following attuid: ' + + // profile.attuid); + $scope.appsView = []; + + applicationsService.getPersUserApps() + .then( + function(res) { + // $log.info(res); + _this.apps = res; + + for (var i = 0; i < _this.apps.length; i++) { + $scope.appsView[i] = { + sizeX : 2, + sizeY : 2, + headerText : _this.apps[i].name, + subHeaderText : _this.apps[i].notes, + imageLink : _this.apps[i].thumbnail || _this.apps[i].imageUrl, + order : _this.apps[i].order, + restrictedApp : _this.apps[i].restrictedApp, + url : _this.apps[i].url + }; + } + + // Append the show add/remove applications tile + $scope.appsView[_this.apps.length] = { + addRemoveApps : true, + sizeX : 2, + sizeY : 2, + headerText : 'Add/Remove Applications', + subHeaderText : '', + imageLink : 'assets/images/cloud.png', + order : '', + restrictedApp : false, + url : '' + }; + + // $log.info('getUserApps apps count : ' + + // $scope.appsView.length); + // Show 2 rows in the gridster if needed + if ($scope.appsView.length > 6) { + $(".dashboard-boarder").css({ + "height" : "400px" + }); + }else{ + $(".dashboard-boarder").css({ + "height" : "210px" + }); + } + _this.isLoading = false; + $scope.getUserAppsIsDone = true; + })['catch'] + (function(err) { + $log.error('DashboardCtlr: failed to get applications list', err); + _this.isLoading = false; + $scope.getUserAppsIsDone = true; + }); + }); + + + /* Widget Gridster Section */ + $scope.newsGridsterItem = { + sizeX : 4, + sizeY : 4, + headerText : 'News', + subHeaderText : '', + imageLink : '', + order : '', + url : '' + }; + + $scope.eventsGridsterItem = { + sizeX : 4, + sizeY : 4, + headerText : 'Calendar Events', + subHeaderText : '', + imageLink : '', + order : '', + url : '' + }; + + $scope.impoResGridsterItem = { + sizeX : 4, + sizeY : 4, + headerText : 'Resources', + subHeaderText : '', + imageLink : '', + order : '', + url : '' + }; + this.gridsterOpts = { + columns : 12, + colWidth : 95, + rowHeight : 95, + margins : [ 20, 20 ], + outerMargin : true, + pushing : true, + floating : true, + swapping : true, + draggable : { + handle: 'img' + } + }; + + this.emptyGridsterOpts = { + columns : 24, + colWidth : 190, + rowHeight : 190, + margins : [ 20, 20 ], + outerMargin : true, + pushing : true, + floating : true, + swapping : true, + draggable : { + handle: 'img' + } + }; + + this.goToCatalog = function(item) { + $state.go('root.appCatalog'); + } + + // navigate to application url in new tab + this.goToPortal = function(item) { + if (!item.url) { + $log.error('No URL found for this application, doing nothing!'); + return; + } + if (item.restrictedApp) { + // Link-based apps open in their own browser tab + $window.open(item.url, '_blank'); + } else { + // cache control so browsers load app page every time + var ccParam = '?cc=' + new Date().getTime(); + var appUrl = null; + var urlParts = item.url.split('#'); + if (urlParts.length < 2) + appUrl = item.url + ccParam; + else + appUrl = urlParts[0] + ccParam + "#" + urlParts[1]; + // $log.debug('DashboardCtrlr::goToPortal: opening tab with URL + // ' + appUrl); + var tabContent = { + id : new Date(), + title : item.headerText, + url : appUrl + }; + $cookies.putObject('addTab', tabContent); + } + }; + + /* News data */ + $scope.newsData = []; + $scope.updateNews = function() { + $scope.newsData.length=0; + dashboardService.getCommonWidgetData('NEWS').then(function(res) { + // $log.info(res.message); + var newsDataJsonArray = res.response.items; + for (var i = 0; i < newsDataJsonArray.length; i++) { + $scope.newsData.push(newsDataJsonArray[i]); + } + })['catch'](function(err) { + $log.error('dashboard controller: failed to get news list', err); + _this.isLoading = false; + }); + } + $scope.updateNews(); + + /* Events data */ + $scope.eventData = []; + $scope.updateEvents = function() { + $scope.eventData.length=0; + dashboardService.getCommonWidgetData('EVENTS').then(function(res) { + var eventDataJsonArray = res.response.items; + for (var i = 0; i < eventDataJsonArray.length; i++) { + if(eventDataJsonArray[i].eventDate !=null) { + // yyyy-mm-dd + eventDataJsonArray[i].year = eventDataJsonArray[i].eventDate.substring(2,4); + eventDataJsonArray[i].mon = eventDataJsonArray[i].eventDate.substring(5,7); + eventDataJsonArray[i].day = eventDataJsonArray[i].eventDate.substring(8,10); + } + $scope.eventData.push(eventDataJsonArray[i]); + } + })['catch'](function(err) { + $log.error('dashboard controller: failed to get Events list', err); + _this.isLoading = false; + }); + } + $scope.updateEvents(); + + /* Important Resources data */ + $scope.importResData = []; + $scope.updateImportRes = function() { + $scope.importResData.length=0; + dashboardService.getCommonWidgetData('IMPORTANTRESOURCES').then( + function(res) { + // $log.error('couldnt get important list...', + // res.response.dataBlob); + // $log.info(res); + var importResDataJSONArray = res.response.items; + for (var i = 0; i < importResDataJSONArray.length; i++) { + $scope.importResData.push(importResDataJSONArray[i]); + } + })['catch'](function(err) { + $log.error('dashboard controller: failed to get resources list...', err); + _this.isLoading = false; + }); + } + $scope.updateImportRes(); + + if (getParameterByName('noUserError') != null) { + if (getParameterByName('noUserError') == "Show") { + $("#errorInfo").show(); + } + } + + }; + + DashboardCtrl.$inject = [ 'applicationsService', '$log', '$window', + 'userProfileService', '$scope', '$cookies', '$timeout', + '$interval', '$modal', '$state', 'dashboardService','ngDialog']; + angular.module('ecompApp').controller('DashboardCtrl', DashboardCtrl); +})(); + +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/dashboard/dashboard.controller.spec.js b/ecomp-portal-FE/client/app/views/dashboard/dashboard.controller.spec.js new file mode 100644 index 00000000..0a2ddd3a --- /dev/null +++ b/ecomp-portal-FE/client/app/views/dashboard/dashboard.controller.spec.js @@ -0,0 +1,78 @@ +/*- + * ================================================================================ + * 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: DashboardCtrl ', function() { + beforeEach(module('ecompApp')); + + let DashboardCtrl, $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); + + DashboardCtrl = $controller('DashboardCtrl', { + 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/dashboard/dashboard.less b/ecomp-portal-FE/client/app/views/dashboard/dashboard.less new file mode 100644 index 00000000..4dc1a6c8 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/dashboard/dashboard.less @@ -0,0 +1,766 @@ +/*- + * ================================================================================ + * 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; + + .gridster-item-container .gridster-item-body { + overflow-y:auto; + overflow-x:hidden; + } + + .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; + //display: flex; + justify-content: center; + flex-flow: row wrap; + width: 1170px; + + margin: auto; + margin-bottom: 63px; + + .app-gridster-header { + background-color: @u; + font-size:12px; + overflow:hidden + } + + .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); +} +.dashboard-boarder{ + height: 210px; + overflow: auto; +} +.dashboard-information-boarder{ + border: 2px solid #ccc!important; + border-radius: 16px!important; +} + +#information-section { + margin-top:50px; +} + +.information-section-title{ + color: #0574ac; + font-family: arial; + font-size: 25px; + margin: 20px; + width: 1170px; +} +#left { + float: left; + width: 33%; + height:300px; + background-color:white; +} + +#center { + float: right; + width: 33%; + height:300px; + background: white; +} +#right { + margin-left:34%; + margin-right:34%; + height:300px; + background:white; +} + + +.dock ul{ +display: inline-block; + +width: auto; +margin: 0px; +padding: 0px; +list-style: none; + +} +.dock ul li { +width: auto; +height: auto; +display: inline-block; +bottom: 0; +vertical-align: bottom; +margin-top: -43px; +} +.dock ul li a { +display: block; +height: 150px; +width: 150px; +position: relative; +-webkit-transition-property: width, height,margin-top; +-webkit-transition-duration: 0.5s; +-o-transition-property: width, height,margin-top; +-o-transition-duration: 0.5s; +-moz-transition-property: width, height,margin-top; +-moz-transition-duration: 0.5s; +} +.dock ul li a:hover { +width: 200px; +height: 200px; +margin-top: -50px; +} +.dock ul li a img { +width: 100%; +position: absolute; +bottom: 0; +left: 0; +border: none; +padding: 0px 0px 0px 30px; +} +.dock_left{ +width: 31px; +-webkit-transform: rotate(33deg); +-moz-transform: rotate(33deg); +-o-transform: rotate(33deg); +position: relative; +background: #EEE; +overflow: hidden; +float: left; +height: 100px; +z-index: 2; +margin: -18px; +} +.dock_right{ +width: 36px; +-webkit-transform: rotate(-33deg); +-moz-transform: rotate(-33deg); +-o-transform: rotate(-33deg); +position: relative; +background: #EEE; +overflow: hidden; +float: left; +height: 100px; +z-index: 2; +margin: -18px; +} + + + + +* {margin: 0; padding: 0;} +body {background: #ccc;} + +.slider{ + width: 640px; + position: relative; + padding-top: 320px; + + margin: 50px auto; + + box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.75); +} + +.slider>img{ + position: absolute; + left: 0; top: 0; + transition: all 0.5s; +} + +.slider input[name='slide_switch'] { + display: none; +} + +.slider label { + margin: 18px 0 0 18px; + border: 3px solid #999; + + float: left; + cursor: pointer; + transition: all 0.5s; + + opacity: 0.6; +} + +.slider label img{ + display: block; +} + +.slider input[name='slide_switch']:checked+label { + border-color: #666; + opacity: 1; +} + +.slider input[name='slide_switch'] ~ img { + opacity: 0; + transform: scale(1.1); +} +/*That hides all main images at a 110% size +On click the images will be displayed at normal size to complete the effect +*/ +.slider input[name='slide_switch']:checked+label+img { + opacity: 1; + transform: scale(1); +} + +.accordion { + width: 895px; height: 320px; + overflow: hidden; + box-shadow: 0 10px 6px -6px #111; + margin: 20px auto +} +.accordion ul { width: 200% } + +.accordion li { + position: relative; + display: block; + width: 160px; + float: left; + box-shadow: 0 0 30px 8px #222; + transition: all 0.4s ease .300ms; +} + +.accordion ul:hover li {width: 40px } +.accordion ul li:hover {width: 640px } + +.caption { + background: rgba(0, 0, 0, 0.5); + position: absolute; + bottom: 0; + width: 640px +} + +.caption a { + display: block; + color: #fff; + text-decoration: none; + font: normal 16px 'Lato', Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + padding: 15px; +} + + + +/*events*/ +.events-date{ + margin-left: 10px; + float:left; + white-space: normal; + display: inline-block; + vertical-align: middle; + width: 55px; +} +.event-title-div{ + float: left; + width: 235px; + line-height: 20px; + padding: 5px; + font-size: 14px; + margin-left: 4px; +} +.events-date{ + height: 20px; + margin-left: 4px; + font-size: 14px; +} +.events-content{ + font-size: 14px; + color: #444; + margin-right: 10px; +} +.events-content-body{ + margin-top:5px; + color:#444; + margin-left:12px; + line-height:1.5; +} +.events { + border-radius: 4px; + padding: 3px; + -webkit-user-select: none; +} +.events ul { + float: left; + width:100%; + -webkit-user-select: none +} +.events ul li { + line-height: 30px; + list-style: none; + border-bottom: 2px solid grey; + height: 100%; + min-height: 42px; +} +.events ul li:hover { + background: #ddd; + cursor: pointer; +} +.events ul li a { + color: black; + text-decoration: none; + font: 14px Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + -webkit-user-select: none; + font-family: arial; +} +.events-link{ + color: #067ab4 !important; +} + + + +/*widgets*/ +.singleBtnBorder { + border-radius: 6px 6px 6px 6px; +} + +.widgetHeaderBtn{ + + height: 30px; + background-color: #FFFFFF; + position: relative; + display: inline-block; + -moz-background-clip: padding-box; + -webkit-background-clip: padding-box; + background-clip: padding-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 8px 20px; + font-size: 14px; + line-height: 14px; + min-width: 60px; + border: none; + border-radius: 6px; + background-color: #ffffff; + background-image: none; + color: #ffffff; + vertical-align: middle; + text-align: center; + text-decoration: none; + text-transform: capitalize; + text-shadow: none; + white-space: nowrap; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + -webkit-transition: background-color 0.3s ease-out; + -moz-transition: background-color 0.3s ease-out; + transition: background-color 0.3s ease-out; + } + +.widgetHeaderBtnPosition { + width: 30px; + min-width: 0px; + border: 1px solid #AAAAAA; + padding-left: 5px; + padding-right: 5px; + } + +.icon-anchor { + color: #888; +} + +.widgetHeaderBtn:hover, .widgetHeaderBtn:focus { + background: rgba(0, 0, 0, 0); + color: #3a7999; + box-shadow: inset 0 0 0 2px #3a7999; +} + +@keyframes ticker { + 0% {margin-top: 0} + 25% {margin-top: -55px} + 50% {margin-top: -110px} + 75% {margin-top: -165px} + 100% {margin-top: 0} +} + +body { background: #333; width: 100%; height: 100% } + +.news { + + width: 350px; + height: 250px; + margin: 0px auto; + border-radius: 4px; + padding: 3px; + -webkit-user-select: none; + +} + + + +.news ul { + float: left; + width:100%; + -webkit-user-select: none +} + +.news ul li {line-height: 30px; list-style: none; + border-bottom: 2px solid grey; + min-height: 42px; + } + +.news ul li:hover { + background: #ddd; + cursor: pointer; +} + +.news ul li a { + color: black; + text-decoration: none; + font-size: 14px; + line-height: 1.5; + display: inline-block; + width:100%; + min-height:40px; + padding-top: 5px; + padding-bottom: 5px; + -webkit-font-smoothing: antialiased; + -webkit-user-select: none; + + /* font-family: arial;*/ +} + +.news ul:hover { animation-play-state: paused } +.news span:hover+ul { animation-play-state: paused } +.resources { + + width: 350px; + height: 200px; + margin-left: 5px; + border-radius: 4px; + padding: 3px; + -webkit-user-select: none; + +} + + + +.resources ul { + float: left; + width:100%; + + -webkit-user-select: none +} + +.resources ul li {line-height: 30px; list-style: none; + border-bottom: 2px solid grey; + min-height: 42px; + } + +.resources ul li:hover { + background: #ddd; + cursor: pointer; +} + +.resources ul li a { + color: black; + text-decoration: none; + font-size: 14px; + line-height: 1.5; + width:100%; + min-height:40px; + display: inline-block; + padding-top: 5px; + padding-bottom: 5px; + -webkit-font-smoothing: antialiased; + -webkit-user-select: none; +} + + +.blue { background: #347fd0 } +.blue span { background: #2c66be } +.red { background: #d23435 } +.red span { background: #c22b2c } +.green { background: #699B67 } +.green span { background: #547d52 } +.magenta { background: #b63ace } +.magenta span { background: #842696 } + + +.box-one { + -webkit-transition:all linear 0.4s; + transition:all linear 0.4s; + height:100px; width:200px; background:white; border: 2px solid #ccc!important; + border-radius: 16px!important; +} +.box-one.ng-hide { +display: block!important; + opacity:0; +} + +.gridsterContent{ + height:120px; +} +.gridsterAppContent{ + height:120px; + +} + + .gridsterImage{ + height:84px; + width:168px; + } + .grider-content-ecomp{ + transition: transform 0.5s ease-out; + } + .grider-content-ecomp:hover{ + transform: scale(1.1); +} + + +.information-section{ + /*margin-top:25px;*/ +} +.information-section-gridsterContent{ + height:300px; +} +.information-sections-gridster-header{ + color: #0574ac; + font-family: arial; + font-size: 25px; + +} +/*application empty div*/ +.app-error-block { + padding-top: 10px; + +} +.activity-error-block { + padding-top: 60px; + +} + +.activity-error-msg1{ + text-align: center; + margin-top: 20px; + font-family: arial; + color: #444; + font-size: 20px; + +} + +.newstape { + background: white; + color: black; + height: 400px; + overflow: hidden; +} + +.newstape-content { + position: relative; + padding: 15px; +} + +.newstape-drag { cursor: ns-resize; } + +.text-center { text-align: center; } + +.text-right { text-align: right; } + +.text-justify { text-align: justify; } + +.optionsMenu{ + position: absolute; + list-style: none; + top: 25px; + right: 10px; + border: 1px solid #067ab4; + display: none; + z-index: 2; + border-radius: 6px 0px 6px 6px; + background: #fff; + width: 130px; +} + +.optionsMenuLink { + position: relative; + padding-left: 8px; + padding-right: 2px; + font-size: 12px; + line-height: 30px; + color: #444444; +} +.optionsMenu > li:hover a { + color: #ffffff !important; +} +.optionsMenu > li { + width: 100%; + text-align: left; +} +.optionsMenu > li:hover { + background-color: #0faaf7; + border-color: none !important; + cursor: pointer; +} + +.simulateGridHeader{ + position: relative; + height: 50px !important; + border: 1px solid #d3d3d3; + border-bottom: 0; + background-color: #E5E5E5; + white-space: nowrap; + text-overflow: ellipsis; + z-index: 1; +} + +.simulateGridHeaderTitle{ + line-height: 44px; + margin-left: 26px; + font-family: arial; + font-size: 18px; + color: #444444; + float: left; +} + +.simulateGridHeaderHandle{ + cursor: move; + margin: 12px; + position: absolute; + top: 0; + left: 0; + border: 0; + vertical-align: middle; + -ms-interpolation-mode: bicubic; + display: block; +}
\ No newline at end of file diff --git a/ecomp-portal-FE/client/app/views/dashboard/dashboard.tpl.html b/ecomp-portal-FE/client/app/views/dashboard/dashboard.tpl.html new file mode 100644 index 00000000..0d96a585 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/dashboard/dashboard.tpl.html @@ -0,0 +1,346 @@ +<!-- + ================================================================================ + 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" id="contentId"> + <div class="applications-home-container"> + <div align="center" id="errorInfo" + style="display: none; font-size: 12px; margin-left: 5px"> + <span style="color: red">You don't have a user account in that + application. Please ask the system administrator. </span> + </div> + <div class="portals-list" style="margin-bottom: 0px;"> + <div> + <div class="simulateGridHeader"> + <span class="simulateGridHeaderTitle">Applications</span> + </div> + <div class="dashboard-boarder"> + <div class="gridster-container override_background"> + + <div att-gridster att-gridster-options="dashboard.gridsterOpts"> + + <div ng-if="appsView.length==1"> + <i class="ion-information-circled full-linear-ion-information-circled" + style="margin-left: 50%; font-size: 90px; color: black"></i> <br> + <div class="activity-error-msg1"> + <span>Click on the tile at the left to personalize your applications.</span> + </div> + </div> + + <div class="style_prevu_kit" att-gridster-item='item' + ng-repeat="item in appsView" + id="app-{{item.headerText.split(' ').join('-')}}"> + <!-- A regular application tile --> + <div class="grider-content-ecomp" ng-if="item.addRemoveApps == null"> + <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}}" + 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-color':'white', + 'background-repeat': 'no-repeat', + 'background-size': '170px 130px'}" + ng-click="dashboard.goToPortal(item)" + ng-hide="users.isLoadingTable && !users.getUserAppsIsDone" + class="gridsterContent"></div> + </div> + <!-- Format the special tile differently --> + <div class="grider-content-ecomp" style="width: 170px" ng-if="item.addRemoveApps"> + <div id="grips-add-remove-applications-tile" att-gridster-item-header + grips-img-path="assets/images/grips.png" + header-text='Select applications..' + ng-click="dashboard.goToCatalog()" + ng-style="{'cursor':'pointer'}" + class="app-gridster-header"> + </div> + <div id="app-image-empty" att-gridster-item-body + ng-style="{'cursor':'pointer', + 'text-align':'center', + 'order': item.order, + 'background-color':'white', + 'background-repeat': 'no-repeat', + 'background-size': '170px 130px', + 'width': '170px', + 'height': '120px', + 'opacity': '1'}" + ng-click="dashboard.goToCatalog()" class="gridsterContent"> + <label style="font-size:12px">Click here to personalize <br> this applications page</label> + <i class="ion-plus-circled" style="font-size:70px;color: #067ab4"></i> + </div> + </div> + </div> + + </div> + + </div> + + </div> + </div> + + <br> + <br> + + <div class="information-section"> + <div id="news-gridster-container" + class="gridster-container override_background"> + <div att-gridster att-gridster-options="dashboard.gridsterOpts"> + + <div class="style_prevu_kit"> + <!-- News --> + <div att-gridster-item='newsGridsterItem'> + <div att-gridster-item-header + grips-img-path="assets/images/grips.png" + header-text="{{newsGridsterItem.headerText | elipsis: 33}}" + header-icon="full-linear-icon-webwindow" + sub-header-text="{{newsGridsterItem.subHeaderText | elipsis: 56}}" + class="information-sections-gridster-header" + style="font-size: 18px"> + + <div ng-if="isAdminPortalAdmin == true" + style="font-size: 20px;"> + + <a id="widgetHeaderBtns" + class="widgetHeaderBtn widgetHeaderBtnPosition singleBtnBorder" + ng-mousedown="showNewsOption=!showNewsOption" + ng-mouseleave="showNewsOption=false" + ng-class="singleBtnBorder" role="button" alt="Settings" + title="Settings" att-accessibility-click="13,32" tabindex="0"> + <span class="ion-more" style="color:#888"></span> + </a> + <ul class="optionsMenu" + style="max-width: 130px; height: 32px; display: block" + ng-show="showNewsOption" ng-mouseenter="showNewsOption=true" + ng-mouseleave="showNewsOption=false"> + <!-- ngIf: widget.duplicateAllowed --> + <li ng-click="editWidgetModalPopup(newsData, 'NEWS');" + ddh-accessibility-click="13,32"><a + class="optionsMenuLink" href="javascript:void(0)">Edit</a></li> + <!-- end ngIf: widget.duplicateAllowed --> + + </ul> + </div> + + </div> + <div id="newsContainer" att-gridster-item-body + class="information-section-gridsterContent"> + <div class="news"> + <ul id="newsContent" ng-show="newsData.length!=0"> + <li ng-repeat="news in newsData"><a href="{{news.href}}" + target="_blank" ng-bind="news.title"></a></li> + </ul> + <div ng-hide="newsData.length!=0"> + <div class="activity-error-container" + style="background: rgb(255, 255, 255); overflow: auto !important; width: 100%;"> + <div class="activity-error-block"> + <i class="ion-information-circled full-linear-ion-information-circled" + style="margin-left: 125px; font-size: 90px"></i> <br> + <div class="activity-error-msg1">There's currently no + news available.</div> + </div> + </div> + </div> + </div> + </div> + </div> + <!-- Events --> + <div att-gridster-item='eventsGridsterItem'> + <div att-gridster-item-header + grips-img-path="assets/images/grips.png" + header-text="{{eventsGridsterItem.headerText | elipsis: 33}}" + header-icon="full-linear-icon-calendar" + sub-header-text="{{eventsGridsterItem.subHeaderText | elipsis: 56}}" + class="information-sections-gridster-header" + style="font-size: 18px"> + <div style="font-size: 20px;" + ng-if="isAdminPortalAdmin == true" class="ng-scope" + role="button" tabindex="0"> + <a id="widgetHeaderBtns" + class="widgetHeaderBtn widgetHeaderBtnPosition singleBtnBorder" + ng-mousedown="showEventsOption=!showEventsOption" + ng-mouseleave="showEventsOption=false" + ng-class="singleBtnBorder" role="button" alt="Settings" + title="Settings" att-accessibility-click="13,32" tabindex="0"> + <span class="ion-more" style="color:#888"></span> + </a> + <ul class="optionsMenu" + style="max-width: 130px; height: 32px; display: block" + ng-show="showEventsOption" + ng-mouseenter="showEventsOption=true" + ng-mouseleave="showEventsOption=false"> + <!-- ngIf: widget.duplicateAllowed --> + <li ng-click="editWidgetModalPopup(eventData, 'EVENTS');"> + <a class="optionsMenuLink" href="javascript:void(0)" + ddh-accessibility-click="13,32">Edit</a> + </li> + <!-- end ngIf: widget.duplicateAllowed --> + </ul> + </div> + </div> + <div att-gridster-item-body + class="information-section-gridsterContent"> + <div class="events"> + <ul ng-show="eventData.length!=0"> + <li ng-repeat="event in eventData"> + <div ng-click="event_content_show=!event_content_show"> + <div class="events-date">{{event.mon}}/{{event.day}}/{{event.year}} + </div> + <div> + <div class="event-title-div"> + <p ng-bind="event.title"></p> + </div> + <div> + <span class="ion-ios-arrow-up" ng-if="event_content_show" + style="color: #888; font-size: 22px;"></span> <span + class="ion-ios-arrow-down" ng-if="!event_content_show" + style="color: #888; font-size: 22px;"></span> + + </div> + <div style="clear: both;"></div> + </div> + </div> + <div class="events-content" ng-show="event_content_show"> + <div class="events-content-body"> + <a class="events-link" ng-href="{{event.href}}" + target="_blank"> <span ng-bind="event.content"></span> + </a> + </div> + <div></div> + </div> + </li> + + + </ul> + <div ng-hide="eventData.length!=0"> + <div class="activity-error-container" + style="background: rgb(255, 255, 255); overflow: hidden !important; width: 100%;"> + <div class="activity-error-block"> + <i class="ion-information-circled full-linear-ion-information-circled" + style="margin-left: 125px; font-size: 90px"></i> <br> + <div class="activity-error-msg1">There's currently no + event available.</div> + </div> + </div> + </div> + </div> + </div> + </div> + + <!-- Important Resources --> + <div att-gridster-item='impoResGridsterItem'> + <div att-gridster-item-header + grips-img-path="assets/images/grips.png" + header-text="{{impoResGridsterItem.headerText | elipsis: 33}}" + header-icon="full-linear-icon-cloud" + sub-header-text="{{impoResGridsterItem.subHeaderText | elipsis: 56}}" + class="information-sections-gridster-header" + style="font-size: 18px"> + <!-- <span class="full-linear-icon-cloud" style="font-size: 33px; font-weight: bold; margin-right: 10px;"></span> + --> + <div style="font-size: 20px;" + ng-if="isAdminPortalAdmin == true" class="ng-scope" + role="button" tabindex="0"> + <a id="widgetHeaderBtns" + class="widgetHeaderBtn widgetHeaderBtnPosition singleBtnBorder" + ng-class="singleBtnBorder" role="button" alt="Settings" + ng-mousedown="showImpResOption=!showImpResOption" + ng-mouseleave="showImpResOption=false" title="Settings" + att-accessibility-click="13,32" tabindex="0"> <span + class="ion-more" style="color:#888"></span> + </a> + + <ul class="optionsMenu" + style="max-width: 130px; height: 32px; display: block" + ng-show="showImpResOption" + ng-mouseenter="showImpResOption=true" + ng-mouseleave="showImpResOption=false"> + <!-- ngIf: widget.duplicateAllowed --> + <li + ng-click="editWidgetModalPopup(importResData, 'IMPORTANTRESOURCES');"> + <a class="optionsMenuLink" href="javascript:void(0)" + ddh-accessibility-click="13,32">Edit</a> + </li> + <!-- end ngIf: widget.duplicateAllowed --> + + </ul> + </div> + </div> + <div att-gridster-item-body + class="information-section-gridsterContent"> + <div class="resources"> + <ul ng-show="importResData.length!=0"> + + <li ng-repeat="item in importResData"><a + href="{{item.href}}" target="_blanl">{{item.title}}</a></li> + </ul> + <div ng-hide="importResData.length!=0"> + <div class="activity-error-container" + style="background: rgb(255, 255, 255); overflow: hidden !important; width: 100%;"> + <div class="activity-error-block"> + <i class="ion-information-circled full-linear-ion-information-circled" + style="margin-left: 125px; font-size: 90px"></i> <br> + <div class="activity-error-msg1">There's currently no + links available.</div> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + + <div class="style_prevu_kit" att-gridster-item='item' + ng-repeat="item in widgetData"> + <div> + <div 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 att-gridster-item-body></div> + </div> + + </div> + + <div class="style_prevu_kit" att-gridster-item='item' + ng-repeat="item in widgetData"> + <div> + <div 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 att-gridster-item-body></div> + </div> + + </div> + </div> + </div> + </div> + + <div></div> + + </div> + + </div> +</div>
\ No newline at end of file diff --git a/ecomp-portal-FE/client/app/views/dashboard/newsticker.controller.js b/ecomp-portal-FE/client/app/views/dashboard/newsticker.controller.js new file mode 100644 index 00000000..88e6942e --- /dev/null +++ b/ecomp-portal-FE/client/app/views/dashboard/newsticker.controller.js @@ -0,0 +1,47 @@ +/*- + * ================================================================================ + * 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 NewsTickerController { + constructor($scope) { + $scope.newstape = function(){ + jQuery('.newstape').newstape({ + + period: 30, + + offset: 1, + + mousewheel: true, + + mousewheelRate: 30, + + dragable: true, + + heightSpy: true + + }); + }; + $scope.newstape(); + + } + } + NewsTickerController.$inject = ['$scope']; + angular.module('ecompApp').controller('NewsTickerController', NewsTickerController); +})(); |