diff options
Diffstat (limited to 'ecomp-portal-FE/client/app/views/widgets')
8 files changed, 754 insertions, 0 deletions
diff --git a/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.controller.js b/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.controller.js new file mode 100644 index 00000000..f50e4683 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.controller.js @@ -0,0 +1,202 @@ +/*- + * ================================================================================ + * 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 WidgetDetailsModalCtrl { + constructor($scope, $log, applicationsService, widgetsService, errorMessageByCode, ECOMP_URL_REGEX, $window,userProfileService,$cookies) { + + let newWidgetModel = { + name: null, + appId: null, + appName: null, + width: 360, + height: 300, + url: null + }; + + let getAvailableApps = () => { + applicationsService.getAppsForSuperAdminAndAccountAdmin().then(apps => { + this.availableApps=[]; + for(var i=0;i<apps.length;i++) { + if (!apps[i].restrictedApp) { + $log.debug('WidgetDetailsModalCtrl::getAvailableApps: pushing {id: ', apps[i].id, 'name: ', apps[i].name, + 'restrictedApp: ', apps[i].restrictedApp, '}'); + this.availableApps.push({ + id: apps[i].id, + name: apps[i].name, + restrictedApp: apps[i].restrictedApp + }); + } + } + + if (this.isEditMode) { + this.selectedApp = _.find(apps, {id: this.widget.appId}); + if(!this.selectedApp){ + $scope.widgetForm.app.$dirty = true; + } + } else { + this.selectedApp = null; + } + this.updateSelectedApp(); + }).catch(err => { + $log.error(err); + }); + }; + /**/ + + let init = () => { + $log.info('AppDetailsModalCtrl::init'); + this.isSaving = false; + if ($scope.ngDialogData && $scope.ngDialogData.widget) { + $log.debug('WidgetDetailsModalCtrl::getAvailableApps: Edit widget mode for', $scope.ngDialogData.widget); + this.isEditMode = true; + this.widget = _.clone($scope.ngDialogData.widget); + } else { + $log.debug('WidgetDetailsModalCtrl::init: New app mode'); + this.isEditMode = false; + this.widget = _.clone(newWidgetModel); + } + getAvailableApps(); + }; + + this.ECOMP_URL_REGEX = ECOMP_URL_REGEX; + + this.conflictMessages = {}; + this.scrollApi = {}; + let handleConflictErrors = err => { + if(!err.data){ + return; + } + if(!err.data.length){ + err.data = [err.data] + } + _.forEach(err.data, item => { + _.forEach(item.fields, field => { + this.conflictMessages[field.name] = errorMessageByCode[item.errorCode]; + $scope.widgetForm[field.name].$setValidity('conflict', false); + watchOnce[field.name](); + }); + }); + this.scrollApi.scrollTop(); + }; + + let resetConflict = fieldName => { + delete this.conflictMessages[fieldName]; + if($scope.widgetForm[fieldName]){ + $scope.widgetForm[fieldName].$setValidity('conflict', true); + } + }; + + let watchOnce = { + name: () => { + let unregisterName = $scope.$watchGroup(['widgetDetails.selectedApp','widgetDetails.widget.name'], (newVal, oldVal) => { + if(newVal.toLowerCase() !== oldVal.toLowerCase()){ + resetConflict('name'); + unregisterName(); + } + }); + }, + url: () => { + let unregisterUrl = $scope.$watch('widgetDetails.widget.url', (newVal, oldVal) => { + if(newVal.toLowerCase() !== oldVal.toLowerCase()) { + resetConflict('url'); + unregisterUrl(); + } + }); + } + }; + + this.updateSelectedApp = () => { + if (!this.selectedApp) { + return; + } + this.widget.appId = this.selectedApp.id; + this.widget.appName = this.selectedApp.name; + }; + + let emptyCookies = () => { + userProfileService.getUserProfile() + .then(profile=> { + $log.info('AppDetailsModalCtrl::emptyCookies profile: ', profile); + $scope.userId = profile.orgUserId; + $log.info('user has the following userId: ' + profile.userId); + if ($cookies.getObject($scope.userId + '_widget') != undefined && $cookies.getObject($scope.userId + '_widget') != null) { + $cookies.remove($scope.userId + '_widget'); + } + }); + }; + + this.saveChanges = () => { + if($scope.widgetForm.$invalid){ + return; + } + this.isSaving = true; + if(this.isEditMode){ + widgetsService.updateWidget(this.widget.id, this.widget) + .then(() => { + $log.debug('WidgetDetailsModalCtrl::saveChanges: Widget update succeeded!'); + $scope.closeThisDialog(true); + emptyCookies(); + }).catch(err => { + if(err.status === 409){ + handleConflictErrors(err); + } + $log.error(err); + }).finally(()=>{ + this.isSaving = false; + var objOffsetVersion = objAgent.indexOf("MSIE"); + if (objOffsetVersion != -1) { + $log.debug('WidgetDetailsModalCtrl::saveChanges: Browser is IE, forcing Refresh'); + $window.location.reload(); + } + }); + }else{ + widgetsService.createWidget(this.widget) + .then(() => { + $log.debug('WidgetDetailsModalCtrl::createWidget: Widget creation succeeded!'); + $scope.closeThisDialog(true); + emptyCookies(); + }).catch(err => { + if(err.status === 409){ + handleConflictErrors('WidgetDetailsModalCtrl::createWidget error: ',err); + } + $log.error('WidgetDetailsModalCtrl::createWidget error: ',err); + }).finally(()=>{ + this.isSaving = false; + var objOffsetVersion = objAgent.indexOf("MSIE"); + if (objOffsetVersion != -1) { + $log.debug('WidgetDetailsModalCtrl::createWidget: Browser is IE, forcing Refresh'); + $window.location.reload(); + } + }); + } + }; + + init(); + + $scope.$on('$stateChangeStart', e => { + e.preventDefault(); + }); + } + } + WidgetDetailsModalCtrl.$inject = ['$scope', '$log', 'applicationsService', 'widgetsService', 'errorMessageByCode', 'ECOMP_URL_REGEX', '$window','userProfileService','$cookies']; + angular.module('ecompApp').controller('WidgetDetailsModalCtrl', WidgetDetailsModalCtrl); +})(); diff --git a/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.controller.spec.js b/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.controller.spec.js new file mode 100644 index 00000000..34042c14 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.controller.spec.js @@ -0,0 +1,19 @@ +/*- + * ================================================================================ + * eCOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ diff --git a/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.modal.html b/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.modal.html new file mode 100644 index 00000000..87be6f15 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.modal.html @@ -0,0 +1,132 @@ +<!-- + ================================================================================ + 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="widget-details-modal"> + <div id="'widgets-details-title" class="title">Widget Details</div> + <div class="widget-properties-main" scroll-top="widgetDetails.scrollApi"> + <form id="widgets-details-form" name="widgetForm" novalidate autocomplete="off"> + <script type="text/javascript"> + document.getElementById("appForm").reset(); + </script> + <div class="item required"> + <div class="item-label">Application Name</div> + <div class="custom-select-wrap"> + <select id="widgets-details-select-app" + class="select-field" + ng-model="widgetDetails.selectedApp" + ng-change="widgetDetails.updateSelectedApp();" + ng-options="app.name for app in widgetDetails.availableApps track by app.id" + ng-disabled="!widgetDetails.availableApps || !widgetDetails.availableApps.length" + name="app" + required> + <option id="widgets-details-select-app-disabled" value="" disabled style="display: none;">Select application</option> + </select> + </div> + <div class="error-container" ng-show="widgetForm.app.$dirty"> + <div ng-messages="widgetForm.app.$error" class="error-container"> + <small id="widgets-details-select-app-error-required" class="err-message" ng-message="required">Application is required</small> + </div> + </div> + </div> + <div class="item required"> + <div class="item-label">Widget Name</div> + <input id="widgets-details-input-name" + class="input-field" + type="text" + ng-model="widgetDetails.widget.name" + name="name" + maxlength="100" + ng-pattern="/^[a-zA-Z0-9_\s\&]*$/" + required/> + <div class="error-container" ng-show="widgetDetails.conflictMessages.name"> + <small id="widgets-details-input-name-conflict" class="err-message" ng-bind="widgetDetails.conflictMessages.name"></small> + </div> + <div class="error-container" ng-show="widgetForm.name.$dirty || widgetDetails.isEditMode"> + <div ng-messages="widgetForm.name.$error" class="error-container"> + <small id="widgets-details-input-name-required" class="err-message" ng-message="required">Widget Name is required</small> + <small id="widgets-details-input-name-pattern" class="err-message" ng-message="pattern">Widget Name must be letters, numbers, or underscore</small> + </div> + </div> + </div> + <div class="item required"> + <div class="left-item"> + <div class="item-label">Width</div> + <input id="widgets-details-input-width" + class="input-field" + type="number" + ng-model="widgetDetails.widget.width" + name="width" + min="300" + required + disabled/> + <div class="error-container" ng-show="widgetForm.width.$dirty || widgetDetails.isEditMode"> + <div ng-messages="widgetForm.width.$error" class="error-container"> + <small id="widgets-details-input-width-required" class="err-message" ng-message="required">Widget width is required</small> + <small id="widgets-details-input-min-width" class="err-message" ng-message="min">Minimum width is 300</small> + </div> + </div> + </div> + <div class="right-item required"> + <div class="item-label">Height</div> + <input id="widgets-details-input-height" + class="input-field" + type="number" + ng-model="widgetDetails.widget.height" + name="height" + min="200" + required + disabled/> + <div class="error-container" ng-show="widgetForm.height.$dirty || widgetDetails.isEditMode"> + <div ng-messages="widgetForm.height.$error" class="error-container"> + <small id="widgets-details-input-height-required" class="err-message" ng-message="required">Widget height is required</small> + <small id="widgets-details-input-height-minimum" class="err-message" ng-message="min">Minimum height is 200</small> + </div> + </div> + </div> + </div> + <div class="item required"> + <div class="item-label">URL</div> + <input id="widgets-details-input-URL" + class="input-field" + type="url" + ng-model="widgetDetails.widget.url" + name="url" + maxlength="256" + ng-pattern="widgetDetails.ECOMP_URL_REGEX" + required/> + <div class="error-container" ng-show="widgetDetails.conflictMessages.url"> + <small id="widgets-details-input-URL-conflict" class="err-message" ng-bind="widgetDetails.conflictMessages.url"></small> + </div> + <div class="error-container" ng-show="widgetForm.url.$dirty || widgetDetails.isEditMode"> + <div ng-messages="widgetForm.url.$error" class="error-container"> + <small id="widgets-details-input-URL-required" class="err-message" ng-message="required">Widget URL is required</small> + <small id="widgets-details-input-URL-pattern" class="err-message" ng-message="pattern">Incorrect URL pattern</small> + </div> + </div> + + </div> + </form> + </div> + <div class="dialog-control"> + <span class="ecomp-save-spinner" ng-show="widgetDetails.isSaving"></span> + <div id="widgets-details-next-button" class="next-button" + ng-class="{disabled: widgetForm.$invalid}" ng-click="widgetDetails.saveChanges()">Save</div> + <div id="widgets-details-cancel-button" class="cancel-button" ng-click="closeThisDialog()">Cancel</div> + </div> +</div> diff --git a/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.modal.less b/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.modal.less new file mode 100644 index 00000000..6e031b1d --- /dev/null +++ b/ecomp-portal-FE/client/app/views/widgets/widget-details-dialog/widget-details.modal.less @@ -0,0 +1,94 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + .widget-details-modal { + height: 430px; + + .title { + .n18r; + border-bottom: @a 3px solid; + + } + + .widget-properties-main { + padding: 16px; + height: 306px; + overflow-y: auto; + + .item{ + position: relative; + margin-bottom: 18px; + + .input-field{ + .custom-input-field; + width: 100%; + &.url{ + width: 78%; + display: inline-block; + } + } + + .select-field { + .custom-select-field; + } + + .item-label{ + .o14r; + } + + .right-item{ + position: relative; + display: inline-block; + width: 48%; + float: right; + } + .left-item{ + display: inline-block; + width: 48%; + } + + .url-validation-button{ + .btn-blue; + width: 20%; + display: inline-block; + float: right; + } + + .error-container{ + position: absolute; + width: 280px; + display: block; + height: 12px; + line-height: 12px; + + .err-message{ + color: red; + font-size: 9px; + } + .valid-message{ + color: green; + font-size: 9px; + } + } + + } + + } + +} diff --git a/ecomp-portal-FE/client/app/views/widgets/widgets.controller.js b/ecomp-portal-FE/client/app/views/widgets/widgets.controller.js new file mode 100644 index 00000000..c24f49cd --- /dev/null +++ b/ecomp-portal-FE/client/app/views/widgets/widgets.controller.js @@ -0,0 +1,151 @@ +/*- + * ================================================================================ + * 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 WidgetsCtrl { + constructor($log, applicationsService, widgetsService, ngDialog, confirmBoxService, + userProfileService, $cookies, $scope) { + $log.info('WidgetsCtrl::init: Starting Up'); + $scope.infoMessage = true; + + let populateAvailableApps = widgets => { + let allPortalsFilterObject = {index: 0, title: 'All applications', value: ''}; + this.availableApps = [allPortalsFilterObject]; + this.filterByApp = this.availableApps[0]; + applicationsService.getAppsForSuperAdminAndAccountAdmin().then(myApps => { + var reSortedApp = myApps.sort(getSortOrder("name")); + var realAppIndex = 1; + for (let i = 1; i <= reSortedApp.length; i++) { + if (!reSortedApp[i-1].restrictedApp) { + $log.debug('WidgetsCtrl::populateAvailableApps: pushing {index: ', realAppIndex, 'title: ', reSortedApp[i - 1].name, + 'value: ', reSortedApp[i - 1].name, '}'); + this.availableApps.push({ + index: realAppIndex, + title: reSortedApp[i - 1].name, + value: reSortedApp[i - 1].name + }) + realAppIndex = realAppIndex + 1; + } + } + }).catch(err => { + $log.error(err); + }); + }; + + let getOnboardingWidgets = () => { + this.isLoadingTable = true; + widgetsService.getManagedWidgets().then(res => { + var reSortedWidget = res.sort(getSortOrder("name")); + this.widgetsList = reSortedWidget; + populateAvailableApps(reSortedWidget); + }).catch(err => { + $log.error('WidgetsCtrl::getOnboardingWidgets error: ' + err); + }).finally(()=> { + this.isLoadingTable = false; + }); + }; + + let getSortOrder = (prop) => { + return function(a, b) { + if (a[prop].toLowerCase() > b[prop].toLowerCase()) { + return 1; + } else if (a[prop].toLowerCase() < b[prop].toLowerCase()) { + return -1; + } + return 0; + } + } + + $scope.hideMe = function () { + $scope.infoMessage = false; + } + + let init = () => { + this.isLoadingTable = false; + getOnboardingWidgets(); + + + this.searchString = ''; + + this.widgetsTableHeaders = [ + {name: 'Widget Name', value: 'name', isSortable: false}, + {name: 'Application', value: 'appName', isSortable: true}, + {name: 'Width', value: 'width', isSortable: false}, + {name: 'Height', value: 'height', isSortable: false} + ]; + this.widgetsList = []; + }; + + this.filterByDropdownValue = item => { + if(this.filterByApp.value === ''){ + return true; + } + return item.appName === this.filterByApp.value; + }; + + this.openWidgetDetailsModal = (selectedWidget) => { + let data = null; + if(selectedWidget){ + if(!selectedWidget.id){ + $log.error('Widget id not found'); + return; + } + data = { + widget: selectedWidget + } + } + ngDialog.open({ + templateUrl: 'app/views/widgets/widget-details-dialog/widget-details.modal.html', + controller: 'WidgetDetailsModalCtrl', + controllerAs: 'widgetDetails', + data: data + }).closePromise.then(needUpdate => { + if(needUpdate.value === true){ + $log.debug('WidgetsCtrl::openWidgetDetailsModal: updating table data...'); + getOnboardingWidgets(); + } + }); + }; + + this.deleteWidget = widget => { + confirmBoxService.deleteItem(widget.name).then(isConfirmed => { + if(isConfirmed){ + if(!widget || !widget.id){ + $log.error('WidgetsCtrl::deleteWidget: No widget or ID... cannot delete'); + return; + } + widgetsService.deleteWidget(widget.id).then(() => { + this.widgetsList.splice(this.widgetsList.indexOf(widget), 1); + }).catch(err => { + $log.error('WidgetsCtrl::deleteWidget error:',err); + }); + } + }).catch(err => { + $log.error('WidgetsCtrl::deleteWidget error:',err); + }); + }; + + init(); + } + } + WidgetsCtrl.$inject = ['$log', 'applicationsService', 'widgetsService', 'ngDialog', 'confirmBoxService', + 'userProfileService','$cookies', '$scope']; + angular.module('ecompApp').controller('WidgetsCtrl', WidgetsCtrl); +})(); diff --git a/ecomp-portal-FE/client/app/views/widgets/widgets.controller.spec.js b/ecomp-portal-FE/client/app/views/widgets/widgets.controller.spec.js new file mode 100644 index 00000000..34042c14 --- /dev/null +++ b/ecomp-portal-FE/client/app/views/widgets/widgets.controller.spec.js @@ -0,0 +1,19 @@ +/*- + * ================================================================================ + * eCOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ diff --git a/ecomp-portal-FE/client/app/views/widgets/widgets.less b/ecomp-portal-FE/client/app/views/widgets/widgets.less new file mode 100644 index 00000000..4b83b66f --- /dev/null +++ b/ecomp-portal-FE/client/app/views/widgets/widgets.less @@ -0,0 +1,60 @@ +/*- + * ================================================================================ + * 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. + * ================================================================================ + */ + .widgets-page-main{ + .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; + + .widgets-table{ + width: @table-width; + margin: @table-margin; + + .table-control{ + + } + + .delete-widget{ + .ico_trash_default; + } + } + .error-text { + width: 1170px; + margin: auto; + padding: 20px; + left: 20px; + font-weight: bold; + font-size: 16px; + text-align: left; + color: @err; + background-color: @u; + + .error-help { + color: @o; + font-weight: normal; + } + } + +}
\ No newline at end of file diff --git a/ecomp-portal-FE/client/app/views/widgets/widgets.tpl.html b/ecomp-portal-FE/client/app/views/widgets/widgets.tpl.html new file mode 100644 index 00000000..d255174f --- /dev/null +++ b/ecomp-portal-FE/client/app/views/widgets/widgets.tpl.html @@ -0,0 +1,77 @@ +<!-- + ================================================================================ + eCOMP Portal + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ================================================================================ + --> +<div class="w-ecomp-main"> + <div class="w-ecomp-main-container"> + <div class="widgets-page-main" id="contentId"> + <div id="widget-onboarding-title" class="w-ecomp-main-view-title">Widget Onboarding</div> + <div class="widgets-table"> + <div class="table-control"> + <div class="c-ecomp-att-abs-select default"> + <div class="form-field" id="widegets-available-apps" + att-select="widgets.availableApps" + ng-model="widgets.filterByApp"></div> + </div> + <input class="table-search" type="text" id="widget-onboarding-table-search" + placeholder="Search in entire table" + ng-model="widgets.searchString"/> + + <div id="widget-onboarding-button-add" class="add-button" ng-click="widgets.openWidgetDetailsModal()">Add Widget</div> + </div> + <div class="error-text" ng-show="infoMessage"> + <span class="error-help">Only widgets for active applications are displayed.</span> + <button type="button" class="close" ng-click="hideMe()">×</button> + </div> + + <span class="ecomp-spinner" ng-show="widgets.isLoadingTable"></span> + <div class="c-ecomp-att-abs-table default" ng-hide="widgets.isLoadingTable"> + <table att-table + table-data="widgets.widgetsList" + search-string="widgets.searchString" + view-per-page="widgets.viewPerPageIgnored" + current-page="widgets.currentPageIgnored" + total-page="widgets.totalPageIgnored"> + <thead att-table-row type="header"> + <tr> + <th id="widget-onboarding-th-header-name" ng-repeat="header in widgets.widgetsTableHeaders" att-table-header key="{{header.value}}" sortable="{{header.isSortable}}">{{header.name}}</th> + <th id="widget-onboarding-th-header-url" att-table-header key="url" sortable="{{false}}">URL</th> + <th id="widget-onboarding-th-header-delete" att-table-header sortable="{{false}}">Delete</th> + </tr> + </thead> + <tbody att-table-row type="body" + class="table-body" + row-repeat="rowData in widgets.widgetsList | filter:widgets.filterByDropdownValue"> + <tr > + <td att-table-body ng-repeat="header in widgets.widgetsTableHeaders" ng-click="widgets.openWidgetDetailsModal(rowData)"> + <div id="widget-onboarding-div-{{rowData[header.value].split(' ').join('-')}}" ng-bind="rowData[header.value]"></div> + </td> + <td att-table-body ng-click="widgets.openWidgetDetailsModal(rowData)"> + <div id="widget-onboarding-div-url-{{rowData[header.value].split(' ').join('-')}}" ng-bind="rowData.url | trusted"></div> + </td> + <td att-table-body> + <div id="widget-onboarding-div-delete-widget-{{$index}}" class="delete-widget" ng-click="widgets.deleteWidget(rowData)"><span class="ion-trash-b"></span></div> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + </div> +</div> |