summaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/view-models/admin-dashboard
diff options
context:
space:
mode:
authorMichael Lando <ml636r@att.com>2017-06-09 03:19:04 +0300
committerMichael Lando <ml636r@att.com>2017-06-09 03:19:04 +0300
commited64b5edff15e702493df21aa3230b81593e6133 (patch)
treea4cb01fdaccc34930a8db403a3097c0d1e40914b /catalog-ui/src/app/view-models/admin-dashboard
parent280f8015d06af1f41a3ef12e8300801c7a5e0d54 (diff)
[SDC-29] catalog 1707 rebase commit.
Change-Id: I43c3dc5cf44abf5da817649bc738938a3e8388c1 Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'catalog-ui/src/app/view-models/admin-dashboard')
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view-model.ts72
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html41
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.less3
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view-model.ts61
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view.html26
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard.less49
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view-model.ts176
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view.html53
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management.less118
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/ecomp/ecomp-view.html1
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view-model.ts202
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view.html103
-rw-r--r--catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management.less251
13 files changed, 1156 insertions, 0 deletions
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view-model.ts b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view-model.ts
new file mode 100644
index 0000000000..c421e632da
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view-model.ts
@@ -0,0 +1,72 @@
+'use strict';
+import {ICategoryResourceClass, ICategoryResource} from "../../../services/category-resource-service";
+
+interface IAddCategoryModalViewModelScope extends ng.IScope {
+ category:ICategoryResource;
+ modelType:string;
+ footerButtons:Array<any>;
+ forms:any;
+
+ save():void;
+ close():void;
+}
+
+export class AddCategoryModalViewModel {
+
+ static '$inject' = [
+ '$scope',
+ 'Sdc.Services.CategoryResourceService',
+ '$uibModalInstance',
+ 'parentCategory',
+ 'type'
+ ];
+
+ constructor(private $scope:IAddCategoryModalViewModelScope,
+ private categoryResourceService:ICategoryResourceClass,
+ private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance,
+ private parentCategory:ICategoryResource,
+ private type:string) {
+ this.initScope();
+ }
+
+ private initScope = ():void => {
+ this.$scope.forms = {};
+ this.$scope.modelType = this.parentCategory ? 'sub category' : 'category';
+ this.$scope.category = new this.categoryResourceService();
+
+ this.$scope.close = ():void => {
+ this.$uibModalInstance.dismiss();
+ };
+
+ this.$scope.save = ():void => {
+
+ let onOk = (newCategory:ICategoryResource):void => {
+ this.$uibModalInstance.close(newCategory);
+ };
+
+ let onCancel = ():void => {
+ //error
+ };
+
+ if (!this.parentCategory) {
+ this.$scope.category.$save({types: this.type + "s"}, onOk, onCancel);
+ } else {
+ this.$scope.category.$saveSubCategory({
+ types: this.type + "s",
+ categoryId: this.parentCategory.uniqueId
+ }, onOk, onCancel);
+ }
+
+ };
+
+ this.$scope.footerButtons = [
+ {'name': 'OK', 'css': 'blue', 'callback': this.$scope.save, 'disabled': true},
+ {'name': 'Cancel', 'css': 'grey', 'callback': this.$scope.close}
+ ];
+
+ this.$scope.$watch("forms.editForm.$invalid", (newVal, oldVal) => {
+ this.$scope.footerButtons[0].disabled = this.$scope.forms.editForm.$invalid;
+ });
+
+ }
+}
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html
new file mode 100644
index 0000000000..a9df3e6009
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html
@@ -0,0 +1,41 @@
+<sdc-modal modal="modalInstance"
+ type="classic"
+ class="i-sdc-admin-add-category-modal modal-type-confirmation"
+ header-translate="CREATE_CATEGORY_MODAL_HEADER"
+ buttons="footerButtons"
+ header-translate-values="{'modelType': '{{modelType}}' }"
+ show-close-button="true"
+ hide-background="false"
+>
+
+ <form novalidate class="w-sdc-form" name="forms.editForm">
+
+ <div class="w-sdc-form-column">
+ <div class="i-sdc-form-item"
+ data-ng-class="{error:(editForm.categoryName.$dirty && editForm.categoryName.$invalid)}">
+ <label class="i-sdc-form-label required" translate="CREATE_CATEGORY_MODAL_CATEGORY_NAME"
+ translate-values="{'modelType': '{{modelType}}' }"></label>
+ <input class="i-sdc-form-input"
+ data-ng-model="category.name"
+ data-ng-model-options="{ debounce: 200 }"
+ type="text"
+ name="categoryName"
+ required="required"
+ data-ng-minlength="4"
+ data-ng-pattern="namePattern"
+ maxlength="25"
+ autofocus />
+
+ <div class="input-error" data-ng-show="forms.editForm.categoryName.$dirty && forms.editForm.categoryName.$invalid">
+ <span ng-show="forms.editForm.categoryName.$error.required" translate="CREATE_CATEGORY_MODAL_REQUIRED" translate-values="{'modelType': '{{modelType}}' }"></span>
+ <span ng-show="forms.editForm.categoryName.$error.minlength" translate="CREATE_CATEGORY_MODAL_MINLENGTH" translate-values="{'minlength': '4', 'modelType': '{{modelType}}' }"></span>
+ <span ng-show="forms.editForm.categoryName.$error.pattern" translate="CREATE_CATEGORY_MODAL_PATTERN" translate-values="{'modelType': '{{modelType}}' }"></span>
+ </div>
+
+ </div>
+
+ </div>
+
+ </form>
+
+</sdc-modal>
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.less b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.less
new file mode 100644
index 0000000000..39d84aab23
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.less
@@ -0,0 +1,3 @@
+.i-sdc-admin-add-category-modal {
+
+}
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view-model.ts b/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view-model.ts
new file mode 100644
index 0000000000..c8503bce42
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view-model.ts
@@ -0,0 +1,61 @@
+'use strict';
+import {CacheService} from "app/services";
+import {IAppConfigurtaion} from "app/models";
+
+interface IAdminDashboardViewModelScope extends ng.IScope {
+ version:string;
+ sdcConfig:IAppConfigurtaion;
+ isLoading:boolean;
+ currentTab:string;
+ templateUrl:string;
+ monitorUrl:string;
+ moveToTab(tab:string):void;
+ isSelected(tab:string):boolean;
+}
+
+
+export class AdminDashboardViewModel {
+ static '$inject' = [
+ '$scope',
+ '$templateCache',
+ 'Sdc.Services.CacheService',
+ 'sdcConfig'
+ ];
+
+ constructor(private $scope:IAdminDashboardViewModelScope,
+ private $templateCache:ng.ITemplateCacheService,
+ private cacheService:CacheService,
+ private sdcConfig:IAppConfigurtaion) {
+
+ this.initScope();
+ }
+
+ private initScope = ():void => {
+
+ this.$scope.version = this.cacheService.get('version');
+ this.$scope.sdcConfig = this.sdcConfig;
+ this.$scope.monitorUrl = this.$scope.sdcConfig.api.kibana;
+ this.$scope.isSelected = (tab:string):boolean => {
+ return tab === this.$scope.currentTab;
+ }
+
+ this.$scope.moveToTab = (tab:string):void => {
+ if (tab === this.$scope.currentTab) {
+ return;
+ }
+ else if (tab === 'USER_MANAGEMENT') {
+ this.$scope.templateUrl="user-management-view.html";
+ this.$templateCache.put("user-management-view.html", require('app/view-models/admin-dashboard/user-management/user-management-view.html'));
+ }
+ else if (tab === 'CATEGORY_MANAGEMENT') {
+ this.$scope.templateUrl="category-management-view.html";
+ this.$templateCache.put("category-management-view.html", require('app/view-models/admin-dashboard/category-management/category-management-view.html'));
+ }
+ this.$scope.currentTab = tab;
+ };
+
+ this.$scope.moveToTab('USER_MANAGEMENT');
+
+
+ }
+}
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view.html b/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view.html
new file mode 100644
index 0000000000..150f7c2554
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view.html
@@ -0,0 +1,26 @@
+<div class="sdc-admin-container">
+
+ <!--<ecomp-header menu-data="menuItems" version="{{version}}" clickable-logo="false"></ecomp-header>-->
+
+ <nav class="sdc-admin-top-bar-menu">
+ <button class="sdc-admin-top-bar-menu-tab" data-tests-id="usermanagmenttab"
+ data-ng-class="{'selected': isSelected('USER_MANAGEMENT')}"
+ data-ng-click="moveToTab('USER_MANAGEMENT')"
+ translate="USER_MANAGEMENT">
+ </button>
+ <button class="sdc-admin-top-bar-menu-tab" data-tests-id="categorymanagmenttab"
+ data-ng-class="{'selected': isSelected('CATEGORY_MANAGEMENT')}"
+ data-ng-click="moveToTab('CATEGORY_MANAGEMENT')"
+ translate="CATEGORY_MANAGEMENT">
+ </button>
+ <a href={{monitorUrl}} target="_blank" ng-show="monitorUrl!=''" >
+ <button class="sdc-admin-top-bar-menu-monitor-btn" translate="MONITOR" data-tests-id="monitor"></button>
+ </a>
+ </nav>
+
+ <div class="sdc-admin-body">
+ <ng-include src="templateUrl" ng-if="true"></ng-include>
+ </div>
+
+ <ecomp-footer></ecomp-footer>
+</div>
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard.less b/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard.less
new file mode 100644
index 0000000000..874a02c431
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard.less
@@ -0,0 +1,49 @@
+.sdc-admin-container{
+ height: 100%;
+
+ .sdc-admin-top-bar-menu{
+ .bg_k;
+ height: @top_nav_admin_height;
+ padding-left:260px;
+ .box-shadow(-1px 0px 3px 0px rgba(0, 0, 0, 0.33));
+ position: absolute;
+ top: @header_height;
+ left: 0;
+ right: 0;
+ z-index: 2;
+
+ .sdc-admin-top-bar-menu-tab{
+ .b_17;
+ .hand;
+ height: 44px;
+ background-color: transparent;
+ position: relative;
+ padding: 0px 10px 0px 10px;
+ border: none;
+ outline: none;
+ margin-right: 15px;
+ &.selected {
+ outline: none;
+ border-bottom: solid 4px @color_t;
+ }
+ }
+ .sdc-admin-top-bar-menu-monitor-btn{
+ .bg_a;
+ .c_6;
+ float: right;
+ border: none;
+ position: relative;
+ padding: 11px 24px;
+ }
+ }
+
+ .sdc-admin-body{
+ .bg_n;
+ padding: 40px 260px 60px 260px;
+ position: absolute;
+ top: @top_nav_admin_height;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ }
+}
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view-model.ts b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view-model.ts
new file mode 100644
index 0000000000..ba390c4bee
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view-model.ts
@@ -0,0 +1,176 @@
+'use strict';
+import {ModalsHandler, ValidationUtils} from "app/utils";
+import {CacheService, ICategoryResource} from "app/services";
+import {IAppConfigurtaion} from "app/models";
+import {ComponentType} from "../../../utils/constants";
+
+interface ICategoryManagementViewModelScope extends ng.IScope {
+ SERVICE:string;
+ RESOURCE:string;
+ categoriesToShow:Array<ICategoryResource>;
+ serviceCategories:Array<ICategoryResource>;
+ resourceCategories:Array<ICategoryResource>;
+ selectedCategory:ICategoryResource;
+ selectedSubCategory:ICategoryResource;
+ modalInstance:ng.ui.bootstrap.IModalServiceInstance;
+ isLoading:boolean;
+ type:string;
+ namePattern:RegExp;
+
+ selectCategory(category:ICategoryResource):void;
+ selectSubCategory(subcategory:ICategoryResource):void;
+ selectType(type:string):void;
+ deleteCategory(category:ICategoryResource, subCategory:ICategoryResource):void;
+ createCategoryModal(parentCategory:ICategoryResource):void;
+}
+
+export class CategoryManagementViewModel {
+ static '$inject' = [
+ '$scope',
+ 'sdcConfig',
+ 'Sdc.Services.CacheService',
+ '$uibModal',
+ '$filter',
+ 'ValidationUtils',
+ 'ModalsHandler'
+ ];
+
+ constructor(private $scope:ICategoryManagementViewModelScope,
+ private sdcConfig:IAppConfigurtaion,
+ private cacheService:CacheService,
+ private $uibModal:ng.ui.bootstrap.IModalService,
+ private $filter:ng.IFilterService,
+ private ValidationUtils:ValidationUtils,
+ private ModalsHandler:ModalsHandler) {
+
+ this.initScope();
+ this.$scope.selectType(ComponentType.SERVICE.toLocaleLowerCase());
+
+ }
+
+ private initScope = ():void => {
+ let scope:ICategoryManagementViewModelScope = this.$scope;
+ scope.SERVICE = ComponentType.SERVICE.toLocaleLowerCase();
+ scope.RESOURCE = ComponentType.RESOURCE.toLocaleLowerCase();
+
+ scope.namePattern = this.ValidationUtils.getValidationPattern('category');
+
+ scope.selectCategory = (category:ICategoryResource) => {
+ if (scope.selectedCategory !== category) {
+ scope.selectedSubCategory = null;
+ }
+ scope.selectedCategory = category;
+ };
+ scope.selectSubCategory = (subcategory:ICategoryResource) => {
+ scope.selectedSubCategory = subcategory;
+ };
+ scope.selectType = (type:string):void => {
+ if (scope.type !== type) {
+ scope.selectedCategory = null;
+ scope.selectedSubCategory = null;
+ }
+
+ scope.type = type;
+ scope.categoriesToShow = scope[type + 'Categories'];
+ };
+
+ scope.createCategoryModal = (parentCategory:ICategoryResource):void => {
+ //can't create a sub category for service
+ if (parentCategory && scope.type === ComponentType.SERVICE.toLowerCase()) {
+ return;
+ }
+
+ let type:string = scope.type;
+
+ let onOk = (newCategory:ICategoryResource):void => {
+ if (!parentCategory) {
+ scope[type + 'Categories'].push(newCategory);
+ } else {
+ if (!parentCategory.subcategories) {
+ parentCategory.subcategories = [];
+ }
+ parentCategory.subcategories.push(newCategory);
+ }
+ };
+
+ let onCancel = ():void => {
+
+ };
+
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: 'src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html',
+ controller: 'Sdc.ViewModels.AddCategoryModalViewModel',
+ size: 'sdc-xsm',
+ backdrop: 'static',
+ scope: scope,
+ resolve: {
+ parentCategory: function () {
+ return parentCategory;
+ },
+ type: function () {
+ return type;
+ }
+ }
+ };
+
+ scope.modalInstance = this.$uibModal.open(modalOptions);
+ scope.modalInstance.result.then(onOk, onCancel);
+
+ };
+
+ scope.deleteCategory = (category:ICategoryResource, subCategory:ICategoryResource):void => {
+
+ let onOk = ():void => {
+
+ scope.isLoading = true;
+ let type:string = scope.type;
+
+ let onError = (response):void => {
+ scope.isLoading = false;
+ console.info('onFaild', response);
+ };
+
+ let onSuccess = (response:any):void => {
+ let arr:Array<ICategoryResource>;
+
+ if (!subCategory) {
+ arr = this.$scope[type + 'Categories'];
+ arr.splice(arr.indexOf(category), 1);
+ if (category === scope.selectedCategory) {
+ scope.selectedCategory = null;
+ scope.selectedSubCategory = null;
+ }
+ } else {
+ arr = category.subcategories;
+ arr.splice(arr.indexOf(subCategory), 1);
+ }
+
+ scope.isLoading = false;
+ };
+
+ if (!subCategory) {
+ category.$delete({
+ types: type + "s",
+ categoryId: category.uniqueId
+ }
+ , onSuccess, onError);
+ } else {
+ category.$deleteSubCategory({
+ types: type + "s",
+ categoryId: category.uniqueId,
+ subCategoryId: subCategory.uniqueId,
+ }
+ , onSuccess, onError);
+ }
+ };
+ let modelType:string = subCategory ? 'sub category' : 'category';
+ let title:string = this.$filter('translate')("DELETE_CATEGORY_MODAL_HEADER", "{'modelType': '" + modelType + "' }");
+ let message:string = this.$filter('translate')("DELETE_CATEGORY_MODAL_CATEGORY_NAME", "{'modelType': '" + modelType + "' }");
+
+ this.ModalsHandler.openConfirmationModal(title, message, false, 'sdc-xsm').then(onOk);
+ };
+
+ this.$scope.serviceCategories = this.cacheService.get('serviceCategories');
+ this.$scope.resourceCategories = this.cacheService.get('resourceCategories');
+ }
+}
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view.html b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view.html
new file mode 100644
index 0000000000..95a002d3d7
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view.html
@@ -0,0 +1,53 @@
+<div data-ng-controller="Sdc.ViewModels.CategoryManagementViewModel" class="category-management">
+
+ <loader data-display="isLoading"></loader>
+
+ <div class="row">
+
+ <div class="col-sm-6">
+
+ <h4>
+ <span class="hand selected" data-ng-click="selectType(SERVICE)" data-tests-id="servicecategoryheader"
+ data-ng-class="{'selected': type === SERVICE}" translate="SERVICE_CATEGORY_HEADER"></span>
+ <span class="hand" data-ng-click="selectType(RESOURCE)" data-tests-id="resourcecategoryheader"
+ data-ng-class="{'selected': type === RESOURCE}" translate="RESOURCE_CATEGORY_HEADER"></span>
+ </h4>
+ <span data-ng-click="createCategoryModal(null)" translate="ADD_CATEGORY" data-tests-id="newcategory"></span>
+
+ <perfect-scrollbar class="perfect-scrollbar">
+ <ul>
+ <li data-ng-repeat="category in categoriesToShow"
+ data-ng-class="{'selected': selectedCategory === category, 'gray': selectedSubCategory}"
+ data-ng-click="selectCategory(category)"
+ data-tests-id="{{ type === SERVICE ? 'servicecategory' : 'resourcecategory' }}">
+ {{category.name}}
+
+ <!--<button class="sprite e-sdc-small-icons-delete" data-ng-click="deleteCategory(category, null)" type="button"></button>-->
+ <!--button class="sprite e-sdc-small-icons-pad" data-ng-click="" type="button"></button-->
+ </li>
+ </ul>
+ </perfect-scrollbar>
+ </div>
+
+ <div class="col-sm-6">
+
+ <h4><span translate="SUBCATEGORY_HEADER" data-tests-id="subcategoryheader"></span></h4>
+ <span data-ng-if="type === RESOURCE && selectedCategory" data-ng-click="selectedCategory ? createCategoryModal(selectedCategory) : ''" translate="ADD_SUBCATEGORY" data-tests-id="newsubcategory"></span>
+
+ <perfect-scrollbar class="perfect-scrollbar">
+ <ul>
+ <li data-ng-repeat="subcategory in selectedCategory.subcategories"
+ data-ng-class="{'selected': selectedSubCategory === subcategory}"
+ data-ng-click="selectSubCategory(subcategory)"
+ data-tests-id="subcategory">
+ {{subcategory.name}}
+
+ <!--<button class="sprite e-sdc-small-icons-delete" data-ng-click="deleteCategory(selectedCategory, subcategory)" type="button"></button>-->
+ <!--button class="sprite e-sdc-small-icon-pad" data-ng-click="" type="button"></button-->
+ </li>
+ </ul>
+ </perfect-scrollbar>
+ </div>
+
+ </div>
+</div>
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management.less b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management.less
new file mode 100644
index 0000000000..011122c9e8
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management.less
@@ -0,0 +1,118 @@
+
+.category-management {
+
+ .row {
+ display: table;
+ width: 70%;
+ min-width: 800px;
+ margin: auto;
+
+ [class*="col-"] {
+ float: none;
+ display: table-cell;
+ vertical-align: top;
+ background-color: white;
+ border: 1px solid #c1c1c1;
+ padding: 0;
+
+ &:not(:last-child) {
+ border-right: none;
+ }
+
+ h4 {
+ float:left;
+ color:white;
+ background-color: rgb(155,168,176);
+ margin: 0;
+ padding: 0px 0px 0px 16px;
+ width: 100%;
+ height: 31px;
+ font-size: 15px;
+
+ span{
+ display: inline-block;
+ line-height: 30px;
+ margin-right: 5px;
+ padding: 0 7px;
+
+ &.selected {
+ border-bottom: 2px #067ab4 solid;
+ }
+ }
+ }
+ h4+span{
+ .hand;
+ float:right;
+ display: inline-block;
+ background-color: rgb(59,124,156);
+ text-align: center;
+ padding: 5.5px 0px;
+ width: 60px;
+ color: white;
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 1;
+ color: white;
+ }
+
+
+ .perfect-scrollbar {
+ width: 100%;
+ height: 500px;
+ margin-top: 40px;
+ margin-bottom: 15px;
+ }
+
+ ul {
+ clear: both;
+ margin: 5px 0 10px 0;
+ list-style-type: none;
+ padding: 0;
+ position: relative;
+
+ li{
+ .hand;
+ padding: 0 8px;
+ text-indent: 9px;
+ font-size: 13px;
+ line-height: 25px;
+ border: 1px solid white;
+ border-right: none;
+ border-left: none;
+ margin-right: 5px;
+
+ button {
+ background-color: transparent;
+ border: none;
+ float: right;
+ margin: 5px 3px;
+ display: none;
+ }
+
+ &:hover {
+ background-color: #d9e6ec;
+ color: #3b7b9b;
+ border-color: #d9e6ec;
+
+ button {
+ display: inline-block;
+ }
+ }
+ &.selected {
+ background-color: rgb(219,230,236);
+ color: #3b7b9b;
+ border-color: rgba(59, 123, 155, 0.42);
+
+ &.gray {
+ background-color: rgba(155, 168, 176, 0.09);
+ border-color: white;
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+}
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/ecomp/ecomp-view.html b/catalog-ui/src/app/view-models/admin-dashboard/ecomp/ecomp-view.html
new file mode 100644
index 0000000000..7c89b545c5
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/ecomp/ecomp-view.html
@@ -0,0 +1 @@
+<div></div>
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view-model.ts b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view-model.ts
new file mode 100644
index 0000000000..82cc3a74da
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view-model.ts
@@ -0,0 +1,202 @@
+'use strict';
+import {ModalsHandler} from "app/utils";
+import {IUserResource, IUserResourceClass} from "app/services";
+import {User, IUserProperties, IUser, IAppConfigurtaion} from "app/models";
+
+interface IUserManagementViewModelScope extends ng.IScope {
+ sdcConfig:IAppConfigurtaion;
+ usersList:Array<IUserProperties>;
+ isLoading:boolean;
+ isNewUser:boolean;
+ sortBy:string;
+ reverse:boolean;
+ tableHeadersList:any;
+ roles:Array<string>;
+ newUser:IUser;
+ currentUser:IUserResource;
+ userIdValidationPattern:RegExp;
+ editForm:ng.IFormController;
+ getAllUsers():void;
+ editUserRole(user:IUserProperties);
+ sort(sortBy:string):void;
+ createUser():void;
+ deleteUser(userId:string):void;
+ onEditUserPressed(user:IUserProperties):void;
+ saveUserChanges(user:IUserProperties):void;
+ getTitle(role:string):string;
+ clearForm():void;
+
+}
+
+
+export class UserManagementViewModel {
+ static '$inject' = [
+ '$scope',
+ 'sdcConfig',
+ 'Sdc.Services.UserResourceService',
+ 'UserIdValidationPattern',
+ '$filter',
+ 'ModalsHandler'
+ ];
+
+ constructor(private $scope:IUserManagementViewModelScope,
+ private sdcConfig:IAppConfigurtaion,
+ private userResourceService:IUserResourceClass,
+ private UserIdValidationPattern:RegExp,
+ private $filter:ng.IFilterService,
+ private ModalsHandler:ModalsHandler) {
+
+ this.initScope();
+
+ }
+
+
+ private getAllUsers = ():void => {
+ this.$scope.isLoading = true;
+
+ let onError = (response) => {
+ this.$scope.isLoading = false;
+ console.info('onFaild', response);
+ };
+ let onSuccess = (response:Array<IUserProperties>) => {
+ this.$scope.usersList = response;
+ _.forEach(this.$scope.usersList, (user:any, i:number)=> {
+ user.index = i;
+ });
+ this.$scope.isLoading = false;
+ };
+ this.userResourceService.getAllUsers(onSuccess, onError);
+ };
+
+ private updateUserFilterTerm = (user:IUserProperties):void => {
+ user.filterTerm = user.firstName + ' ' + user.lastName + ' ' + user.userId + ' ' + user.email + ' ' + user.role + ' ' + this.$filter('date')(user.lastLoginTime, "MM/dd/yyyy");
+ };
+
+ private initScope = ():void => {
+ let self = this;
+
+ this.$scope.tableHeadersList = [{title: "First Name", property: 'firstName'}, {
+ title: "Last Name",
+ property: 'lastName'
+ },
+ {
+ title: this.$filter('translate')("USER_MANAGEMENT_TABLE_HEADER_USER_ID"),
+ property: 'userId'
+ }, {title: "Email", property: 'email'}, {title: "Role", property: 'role'}, {
+ title: "Last Active",
+ property: 'lastLoginTime'
+ }];
+ this.$scope.userIdValidationPattern = this.UserIdValidationPattern;
+ this.$scope.sortBy = 'lastLoginTime';
+ this.$scope.reverse = false;
+ this.$scope.roles = this.sdcConfig.roles;
+ this.$scope.isNewUser = false;
+ this.$scope.currentUser = this.userResourceService.getLoggedinUser();
+ this.getAllUsers();
+
+ let resource:IUserResource = <IUserResource>{};
+ this.$scope.newUser = new User(resource);
+
+ this.$scope.sort = (sortBy:string):void => {//default sort by descending last update. default for alphabetical = ascending
+ this.$scope.isNewUser = false;
+ this.$scope.reverse = (this.$scope.sortBy === sortBy) ? ( !this.$scope.reverse) : this.$scope.reverse = false;
+ this.$scope.sortBy = sortBy;
+ };
+
+ this.$scope.createUser = ():void => {
+
+ let onError = (response) => {
+ this.$scope.isLoading = false;
+ console.info('onFaild', response);
+ };
+
+ let onSuccess = (response:IUserProperties) => {
+ this.$scope.newUser.resource['index'] = this.$scope.usersList.length;
+ this.$scope.newUser.resource.lastLoginTime = "0";
+ this.$scope.newUser.resource.status = response.status;
+ this.updateUserFilterTerm(this.$scope.newUser.resource);
+ this.$scope.usersList.unshift(this.$scope.newUser.resource);
+ this.$scope.isNewUser = true;
+ this.$scope.sortBy = 'index';
+ this.$scope.reverse = true;
+ this.$scope.isLoading = false;
+ this.$scope.newUser = new User(null);
+ this.$scope.editForm.$setPristine();
+ let _self = this;
+ setTimeout(function () {
+ _self.$scope.isNewUser = false;
+ }, 7000);
+ };
+ this.userResourceService.createUser({
+ userId: this.$scope.newUser.resource.userId,
+ role: this.$scope.newUser.resource.role
+ }, onSuccess, onError);
+ };
+
+
+ this.$scope.onEditUserPressed = (user:IUserProperties):void => {
+ user.isInEditMode = true;
+ user.tempRole = user.role;
+ };
+
+ this.$scope.editUserRole = (user:IUserProperties):void => {
+ let roleBeforeUpdate:string = user.role;
+ user.role = user.tempRole;
+
+ let onError = (response) => {
+ this.$scope.isLoading = false;
+ user.role = roleBeforeUpdate;
+ console.info('onFaild', response);
+ };
+ let onSuccess = (response:any) => {
+ this.$scope.isLoading = false;
+ user.tempRole = user.role;
+ this.updateUserFilterTerm(user);
+ };
+
+ this.userResourceService.editUserRole({id: user.userId, role: user.role}, onSuccess, onError);
+ };
+
+ this.$scope.saveUserChanges = (user:IUserProperties):void => {
+ if (user.tempRole != user.role) {
+ this.$scope.editUserRole(user)
+ }
+ user.isInEditMode = false;
+ };
+
+ this.$scope.deleteUser = (userId:string):void => {
+
+ let onOk = ():void => {
+ this.$scope.isLoading = true;
+
+ let onError = (response):void => {
+ this.$scope.isLoading = false;
+ console.info('onFaild', response);
+ };
+
+ let onSuccess = (response:any):void => {
+ _.remove(this.$scope.usersList, {userId: userId});
+ this.$scope.isLoading = false;
+ };
+ this.userResourceService.deleteUser({id: userId}, onSuccess, onError);
+ };
+
+ let title:string = this.$filter('translate')("USER_MANAGEMENT_VIEW_DELETE_MODAL_TITLE");
+ let message:string = this.$filter('translate')("USER_MANAGEMENT_VIEW_DELETE_MODAL_TEXT");
+ this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk);
+ };
+
+ this.$scope.getTitle = (role:string):string => {
+ return role.toLowerCase().replace('governor', 'governance_Rep').replace('_', ' ');
+ };
+
+ this.$scope.clearForm = ():void => {
+ if (!this.$scope.editForm['contactId'].$viewValue && !this.$scope.editForm['role'].$viewValue) {
+ this.$scope.editForm.$setPristine();
+ }
+ //if(this.$scope.editForm['contactId'].$viewValue === '' && this.$scope.editForm['role'].$viewValue){
+ // this.$scope.editForm.$setPristine();
+ //}
+ };
+ }
+}
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view.html b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view.html
new file mode 100644
index 0000000000..d2983873cc
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view.html
@@ -0,0 +1,103 @@
+<div ng-controller="Sdc.ViewModels.UserManagementViewModel">
+ <loader data-display="isLoading"></loader>
+ <div class="sdc-user-management-top-bar">
+ <div class="sdc-user-management-top-bar-search-container">
+ <label class="sdc-user-management-top-bar-search-text">Search User</label>
+ <input type="text" class="sdc-user-management-top-bar-form-input" placeholder="Search user by name, userId, email or role" data-ng-model="search.filterTerm" ng-model-options="{ debounce: 500 }" data-tests-id="searchbox" />
+ <span class="w-sdc-search-icon" data-ng-class="{'cancel':search.filterTerm, 'magnification':!search.filterTerm}" data-ng-click="search.filterTerm=''" ></span>
+ </div>
+ <div class="vertical-border-container">
+ <div class="vertical-border"></div>
+ </div>
+ <form class="sdc-user-management-top-bar-create-user-container w-sdc-form" name="editForm">
+ <label class="sdc-user-management-top-bar-title">Create New User</label>
+ <div class="sdc-user-management-top-bar-wrapper">
+ <div class="i-sdc-form-item sdc-user-management-top-bar-form-container" data-ng-class="{error:(editForm.contactId.$dirty && editForm.contactId.$invalid)}">
+ <input ng-focus="search.filterTerm=''" type="text"
+ data-ng-model="newUser.resource.userId"
+ class="i-sdc-form-input"
+ placeholder="{{ USER_MANAGEMENT_SEARCH_TEXT | translate}}"
+ data-ng-model-options="{ updateOn: 'default blur', debounce: { 'default': 750, 'blur': 0 } }"
+ name="contactId"
+ data-ng-pattern="userIdValidationPattern"
+ data-ng-change="clearForm()"
+ data-ng-blur="clearForm()"
+ data-required
+ data-tests-id="newuserId" />
+
+ <div class="input-error" data-ng-show="editForm.contactId.$dirty && editForm.contactId.$invalid">
+ <span ng-show="editForm.contactId.$error.required" translate="NEW_USER_ERROR_USER_ID_REQUIRED"></span>
+ <span ng-show="editForm.contactId.$error.pattern" translate="NEW_USER_ERROR_USER_ID_NOT_VALID"></span>
+ </div>
+ </div>
+ <div class="i-sdc-form-item sdc-user-management-top-bar-form-container" data-ng-class="{error:(editForm.role.$dirty && editForm.role.$invalid
+ && editForm.contactId.$viewValue)}">
+ <select class="i-sdc-form-select capitalize"
+ data-required
+ name="role"
+ data-tests-id="selectrole"
+ data-ng-model = "newUser.resource.role"
+ data-ng-options="role as (getTitle(role)) for role in roles | orderBy:'role'"
+ ng-focus="search.filterTerm=''">
+ <option value="">Select Role</option>
+ </select>
+ <div class="input-error" data-ng-show="editForm.role.$dirty && editForm.role.$invalid && editForm.contactId.$viewValue">
+ <span ng-show="editForm.role.$error.required" translate="NEW_USER_ERROR_ROLE_REQUIRED"></span>
+ </div>
+ </div>
+ <button data-tests-id="creategreen" data-ng-disabled="editForm.$invalid" class="sdc-user-management-top-bar-create-btn" ng-click="search.filterTerm = '' ; createUser()">Create</button>
+ </div>
+ </form>
+ </div>
+
+
+ <div class="sdc-user-management-table-container-flex">
+
+ <div class="sdc-user-management-table">
+ <div class="head sdc-user-management-flex-container">
+ <div class="sdc-user-management-table-header head-row hand sdc-user-management-flex-item" data-tests-id="th{{header.title}}" ng-repeat="header in tableHeadersList" ng-click="sort(header.property)">{{header.title}}
+ <span ng-if="sortBy === header.property" class="sdc-user-management-table-header-sort-arrow" data-ng-class="{'down': reverse, 'up':!reverse}"> </span>
+ </div>
+ <div class="sdc-user-management-table-no-text-header head-row sdc-user-management-flex-item"></div>
+ <div class="sdc-user-management-table-no-text-header head-row sdc-user-management-flex-item"></div>
+ </div>
+
+ <div class="body">
+ <perfect-scrollbar scroll-y-margin-offset="0" include-padding="true" class="scrollbar-container">
+ <div ng-init="user.filterTerm = user.firstName + ' ' + user.lastName + ' ' + user.userId + ' ' + user.email + ' ' + user.role + ' ' + (user.lastLoginTime | date: 'MM/dd/yyyy')"
+ ng-repeat="user in usersList | filter: search | orderBy:sortBy:reverse"
+ data-ng-class="{'sdc-user-management-table-new-user-row': (isNewUser && $first), 'sdc-user-management-table-row-edit-mode': user.isInEditMode}"
+ class="sdc-user-management-flex-container data-row" data-tests-id="row_{{$index}}">
+
+ <div sdc-smart-tooltip class="sdc-user-management-table-col-general sdc-user-management-flex-item" data-tests-id="firstName_{{$index}}">{{user.firstName || '---'}}</div>
+ <div sdc-smart-tooltip class="sdc-user-management-table-col-general sdc-user-management-flex-item" data-tests-id="lastName__{{$index}}">{{user.lastName || '---' }}</div>
+ <div class="sdc-user-management-flex-item" data-tests-id="userId_{{$index}}">{{user.userId || '---'}}</div>
+ <div sdc-smart-tooltip class="sdc-user-management-table-col-general sdc-user-management-flex-item" data-tests-id="email_{{$index}}">{{user.email || '---'}}</div>
+ <div class="sdc-user-management-table-col-general sdc-user-management-flex-item">
+ <div class="sdc-user-management-table-role-select capitalize sdc-user-management-table-role-label"
+ data-ng-if="!user.isInEditMode"
+ data-tests-id="role_{{$index}}"
+ data-ng-bind="getTitle(user.role)"></div>
+ <select class="sdc-user-management-table-role-select capitalize"
+ data-tests-id="selectRole_{{$index}}"
+ data-ng-if="user.isInEditMode"
+ data-ng-model="user.tempRole"
+ data-ng-options="role as (getTitle(role)) for role in roles | orderBy:'role'">
+ </select>
+ </div>
+ <div class="sdc-user-management-table-col-general sdc-user-management-flex-item" data-tests-id="lastActive_{{$index}}">{{user.lastLoginTime == 0 ? 'Waiting' : (user.lastLoginTime | date:'MM/dd/yyyy')}}</div>
+ <div class="sdc-user-management-table-btn-col sdc-user-management-flex-item">
+ <button data-ng-disabled="user.isInEditMode" data-ng-hide="user.isInEditMode || currentUser.userId === user.userId" class="sdc-user-management-table-edit-btn" ng-click="onEditUserPressed(user)" data-tests-id="updateUser_{{$index}}"> </button>
+ <button data-ng-show="user.isInEditMode" class="sdc-user-management-table-save-btn" ng-click="saveUserChanges(user)" data-tests-id="save_{{$index}}"> </button>
+ </div>
+ <div class="sdc-user-management-table-btn-col sdc-user-management-flex-item">
+ <button data-ng-hide="currentUser.userId === user.userId" class="sdc-user-management-table-delete-btn" ng-click="deleteUser(user.userId)" data-tests-id="delete_{{$index}}"> </button>
+ </div>
+
+ </div>
+ </perfect-scrollbar>
+ </div>
+
+ </div>
+ </div>
+</div>
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management.less b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management.less
new file mode 100644
index 0000000000..934faab9e7
--- /dev/null
+++ b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management.less
@@ -0,0 +1,251 @@
+.sdc-user-management-top-bar {
+ display: flex;
+ width: 100%;
+ label {
+ .i_17;
+ }
+ .sdc-user-management-top-bar-form-input,
+ .sdc-user-management-top-bar-form-select {
+ .b_9;
+ color: @color_b;
+ height: 28px;
+ padding-left: 10px;
+ border-radius: 2px;
+ border: 1px solid @border_color_f;
+ }
+
+ .sdc-user-management-top-bar-search-container {
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ width: 400px;
+
+ label {
+ margin-bottom: 20px;
+ }
+
+ .w-sdc-search-icon {
+ right: 11px;
+ top: 49px;
+ }
+ }
+ .vertical-border-container {
+ min-width: 50px;
+ margin: 0px auto;
+
+ .vertical-border {
+
+ width: 1px;
+ height: 70px;
+ background-color: @color_e;
+ display: table;
+ margin: 0 auto;
+ }
+ }
+
+ .sdc-user-management-top-bar-wrapper {
+ display: flex;
+ }
+
+ .sdc-user-management-top-bar-title {
+ .i_17;
+ font-weight: bold;
+ }
+
+ .sdc-user-management-top-bar-create-user-container {
+
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ float: right;
+ padding-top: 0px;
+ text-align: left;
+ width: 650px;
+
+ label {
+ margin-bottom: 20px;
+ }
+
+ .sdc-user-management-top-bar-form-container {
+ width: 233px;
+ margin-right: 35px;
+ }
+
+ .sdc-user-management-top-bar-create-btn {
+ .w-sdc-btn-light-green;
+ height: 30px;
+ width: 100px;
+ line-height: 0px;
+ padding-bottom: 3px;
+ margin-right: 0px;
+ }
+ }
+}
+
+
+.sdc-user-management-table-container-flex {
+ height: 650px;
+ margin-top: 35px;
+ .sdc-user-management-table {
+ width: 100%;
+ border: 1px solid @color_m;
+ .head {
+ .bg_m;
+ .head-row {
+ .c_18;
+ font-weight: bold;
+
+ border-right: 1px solid @border_color_d;
+
+ .sdc-user-management-table-header-sort-arrow {
+ display: inline-block;
+ background-color: transparent;
+ border: none;
+ .c_9;
+ width: 0;
+ height: 0;
+ float: right;
+ margin: 8px 8px 0px 0px;
+ &.up {
+ border-left: 5px solid transparent;
+ border-right: 5px solid transparent;
+ border-bottom: 5px solid;
+ }
+ &.down {
+ border-left: 5px solid transparent;
+ border-right: 5px solid transparent;
+ border-top: 5px solid;
+ }
+ }
+ }
+ .sdc-user-management-table-header:hover {
+ .bg_j;
+ }
+
+ }
+ .body {
+ .scrollbar-container {
+ max-height: 421px;
+ .perfect-scrollbar;
+ }
+ .b_9;
+
+ .data-row {
+ &:nth-of-type(odd) {
+ .bg_c;
+ }
+ &.sdc-user-management-table-new-user-row {
+
+ animation: change 7s step-end both;
+
+ @keyframes change {
+ from {
+ color: @color_z
+ }
+ to {
+ color: @color_b
+ }
+ }
+ }
+ &.sdc-user-management-table-row-edit-mode {
+ .bg_j;
+ }
+ div {
+
+ border-right: 1px solid @border_color_d;
+
+ &:last-child {
+ border-right: none;
+ }
+
+ .sdc-user-management-table-role-select {
+ background-color: transparent;
+ border: 0;
+ width: 100%;
+
+ }
+ .sdc-user-management-table-role-label {
+ margin-left:4px;
+ }
+
+ }
+
+ }
+ .data-row:hover {
+ .bg_j;
+ }
+
+ }
+
+ .sdc-user-management-table-btn-col {
+
+ line-height: 0px;
+ text-align: center;
+ .sdc-user-management-table-delete-btn {
+ background-color: transparent;
+ border: none;
+ .sprite;
+ .sprite.e-sdc-small-icon-delete;
+ opacity: 0.7;
+ }
+ .sdc-user-management-table-edit-btn {
+ background-color: transparent;
+ border: none;
+ .sprite;
+ .e-sdc-small-icon-pencil;
+ opacity: 0.7;
+ }
+ .sdc-user-management-table-save-btn {
+ background-color: transparent;
+ border: none;
+ .sprite;
+ .sprite.e-sdc-green-save;
+ }
+ }
+
+ }
+
+ .sdc-user-management-flex-container {
+ display: flex;
+ }
+
+ .sdc-user-management-flex-item {
+ width:10px;
+ padding: 5px;
+ text-align: center;
+ }
+
+ .sdc-user-management-flex-item:nth-child(1) {
+ flex-grow: 5;
+ }
+
+ .sdc-user-management-flex-item:nth-child(2) {
+ flex-grow: 7;
+ }
+
+ .sdc-user-management-flex-item:nth-child(3) {
+ flex-grow: 4;
+ }
+
+ .sdc-user-management-flex-item:nth-child(4) {
+ flex-grow: 8;
+ }
+
+ .sdc-user-management-flex-item:nth-child(5) {
+ flex-grow: 8;
+ }
+
+ .sdc-user-management-flex-item:nth-child(6) {
+ flex-grow: 8;
+ }
+
+ .sdc-user-management-flex-item:nth-child(7) {
+ flex-grow: 1;
+ }
+
+ .sdc-user-management-flex-item:nth-child(8) {
+ flex-grow: 1;
+ }
+
+}
+