diff --git a/client/cat3/Gruntfile.js b/client/cat3/Gruntfile.js index 8619729ba..06a759423 100644 --- a/client/cat3/Gruntfile.js +++ b/client/cat3/Gruntfile.js @@ -89,6 +89,7 @@ module.exports = function(grunt) { {'catalyst/partials/sections/dashboard/workzone/orchestration/orchestration.css':'src/partials/sections/dashboard/workzone/orchestration/orchestration.scss'}, {'catalyst/partials/sections/dashboard/workzone/application/application.css':'src/partials/sections/dashboard/workzone/application/application.scss'}, {'catalyst/partials/sections/dashboard/analytics/analytics.css':'src/partials/sections/dashboard/analytics/analytics.scss'}, + {'catalyst/partials/sections/dashboard/bots/bots.css':'src/partials/sections/dashboard/bots/bots.scss'}, {'catalyst/partials/sections/dashboard/setting/setting.css':'src/partials/sections/dashboard/setting/setting.scss'} ] } diff --git a/client/cat3/main.html b/client/cat3/main.html index ff6eeaad7..476a55985 100644 --- a/client/cat3/main.html +++ b/client/cat3/main.html @@ -102,6 +102,8 @@ + + diff --git a/client/cat3/src/clientRoutes.js b/client/cat3/src/clientRoutes.js index 131f202c3..d9a6198b2 100644 --- a/client/cat3/src/clientRoutes.js +++ b/client/cat3/src/clientRoutes.js @@ -88,6 +88,23 @@ function routeConfig($stateProvider, $urlRouterProvider, $httpProvider, modulePe }] } + }).state('dashboard.bots', { + url: "/bots", + templateUrl: "src/partials/sections/dashboard/bots/bots.html", + controller: "botsCtrl as bts", + resolve: { + auth: ["$q", function ($q) { + var deferred = $q.defer(); + // instead, go to a different page + if (modulePerms.serviceBool()) { + // everything is fine, proceed + deferred.resolve(); + } else { + deferred.reject({redirectTo: 'dashboard'}); + } + return deferred.promise; + }] + } }).state('dashboard.settings', { url: "/settings", templateUrl: "src/partials/sections/dashboard/setting/setting.html", diff --git a/client/cat3/src/factory/appPermissionServices.js b/client/cat3/src/factory/appPermissionServices.js index f7430023e..747b9e66c 100755 --- a/client/cat3/src/factory/appPermissionServices.js +++ b/client/cat3/src/factory/appPermissionServices.js @@ -27,5 +27,10 @@ //return uac.hasPermission('track','read','module'); return true; }; + this.serviceBool = function() { + //permission response not available in the api response. + //return uac.hasPermission('track','read','module'); + return true; + }; }]); })(angular); \ No newline at end of file diff --git a/client/cat3/src/main.js b/client/cat3/src/main.js index e8a2bf542..d1ee21288 100644 --- a/client/cat3/src/main.js +++ b/client/cat3/src/main.js @@ -84,13 +84,15 @@ angularApp.controller('HeadNavigatorCtrl', ['$scope', '$rootScope', '$http', '$l design: modulePerms.designAccess(), settings: modulePerms.settingsAccess(), track: modulePerms.trackAccess(), - analyticsBool: modulePerms.analyticsBool() + analyticsBool: modulePerms.analyticsBool(), + serviceBool: modulePerms.serviceBool() }; $rootScope.workZoneBool = _permSet.workzone; $rootScope.designBool = _permSet.design; $rootScope.settingsBool = _permSet.settings; $rootScope.trackBool = _permSet.track; $rootScope.analyticsBool = _permSet.analyticsBool; + $rootScope.serviceBool = _permSet.serviceBool; }); $rootScope.$emit('SET_HEADER', $rootScope.appDetails); $scope.showLogoutConfirmationSection = false; @@ -111,4 +113,4 @@ angularApp.controller('HeadNavigatorCtrl', ['$scope', '$rootScope', '$http', '$l $rootScope.$on('USER_LOGOUT', function () { $scope.doLogout(); }); -}]); +}]); \ No newline at end of file diff --git a/client/cat3/src/partials/global.scss b/client/cat3/src/partials/global.scss index 7a29b39c0..c47e73659 100644 --- a/client/cat3/src/partials/global.scss +++ b/client/cat3/src/partials/global.scss @@ -112,6 +112,7 @@ $imagePath : "../../../../../../cat3/images"; z-index: 10; transition: all .4s ease 0s; left: -254px; + height: 100%; &.show-left-tree { left: 0px; @@ -121,6 +122,7 @@ $imagePath : "../../../../../../cat3/images"; background: linear-gradient(to right, #2c3638 99%, #2c3638 100%); color: #fff; overflow-y: auto; + height: 100%; } div[data-angular-treeview] { @@ -1161,4 +1163,10 @@ option.script { } .loading-body{ opacity: 0.4; +} +#bots .control-panel-button { + border-radius: 11px; + padding: 2px 5px; + width: 25px; + height: 25px; } \ No newline at end of file diff --git a/client/cat3/src/partials/globals/header/headerDashboard.html b/client/cat3/src/partials/globals/header/headerDashboard.html index 12f3720b7..b62130a64 100644 --- a/client/cat3/src/partials/globals/header/headerDashboard.html +++ b/client/cat3/src/partials/globals/header/headerDashboard.html @@ -40,10 +40,8 @@
  • -
    - - SETTINGS - +
    + BOTS
  • @@ -53,26 +51,18 @@ {{appDetails.cn | uppercase}} [{{appDetails.roleId}}] -
  • diff --git a/client/cat3/src/partials/sections/dashboard/bots/bots.html b/client/cat3/src/partials/sections/dashboard/bots/bots.html new file mode 100644 index 000000000..a98ad80e9 --- /dev/null +++ b/client/cat3/src/partials/sections/dashboard/bots/bots.html @@ -0,0 +1,14 @@ + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/client/cat3/src/partials/sections/dashboard/bots/bots.scss b/client/cat3/src/partials/sections/dashboard/bots/bots.scss new file mode 100644 index 000000000..cf8c2d7cf --- /dev/null +++ b/client/cat3/src/partials/sections/dashboard/bots/bots.scss @@ -0,0 +1,311 @@ +@import '../../../theme'; + +/*==== OVERRIDINGS (angular-strap-docs.css) ===========*/ +@media (max-width: 320px) { + #analyticsPage { + .panelRight { + padding-left: 1px; + + #rightPanel { + padding-top: 2px; + + .nav-tabs { + font-size: 10px; + } + + .nav>li>a { + padding: 10px 8px; + } + } + } + } +} + +@media (min-width: 321px) and (max-width : 480px) { + #analyticsPage { + .panelRight { + #rightPanel { + padding-top: 2px; + + .nav-tabs { + font-size: 12px; + } + + .nav>li>a { + padding: 4px 8px; + } + } + } + } +} + +@media (min-width : 0px) and (max-width: 767px) { + #analyticsPage { + .panelLeft { + width: 100%; + padding-left: 0px; + position: absolute; + } + + .panelRight { + width: 100%; + padding-left: 5px; + padding-right: 0px; + } + } +} + +@media (min-width : 767px) { + .panelRight { + padding-left: 5px; + } +} + +@media (min-width : 768px) and (max-width: 991px) { + #analyticsPage { + .panelLeft { + width: 254px; + } + + .panelRight { + padding-left: 5px; + padding-right: 0px; + float: right; + } + } +} + +@media (min-width:1500px){ + #section-name { + width: 11.2%; + } +} +#analyticsPage .nvd3 .nv-groups path.nv-line { + stroke-width: 3px !important; +} +.usage{ + .top-stats{ + text-align: right; + } +} + +.top-stats{ + margin: 0px 0px 15px; + .box-title{ + font-size: 16px; + .red{ + font-size: 22px; + } + } + .badge{ + margin-right: 2px; + background: #40baf1; + padding: 3px 10px; + margin-top: -5px; + } + .select2{ + width: auto; + height: 31px; + display: table-cell; + } +} + +#analyticsPage { + background: #fff; + .panelLeft { + width: 100%; + padding-left: 0px; + } + + .panelRight { + width: 100%; + background: linear-gradient(to right, #ffffff 99%, #ffffff 100%) repeat scroll 0 0 rgba(0, 0, 0, 0); + padding-right: 10px; + height: 571px; + overflow-y: auto; + } + + #rightPanel { + padding-top: 0px; + + .nav-tabs { + .dropdown-menu { + li { + a:hover { + background: #3276b1; + color: #fff; + } + } + li.active { + a { + background: #3276b1; + } + } + .active>a>.fa { + color: #fff; + } + li>a>.fa { + color: #333; + } + } + } + } + + #myTab3, .dropdown-menu { + font-size: 12px; + } + + .nav-tabs .dropdown-menu { + left: 0px; + } + + #mytab3 .InfrastructureLocalStorage .dropdown-menu .nav-tabs>li.active>a { + margin-bottom: -1px; + cursor: pointer; + background: #40BAF1; + } + + .nav-tabs>li.active>a:first-child { + color: #337ab7; + } + + .nav-tabs { + border-bottom-width: 1px; + @include theme-border-color; + + li { + margin-bottom: -1px; + cursor: pointer; + } + + li.active { + a, a:hover { + border-bottom-width: 0px; + border-top-width: 3px; + @include theme-border-color; + background: #fcfcfc; + } + } + } + + /*===== end of overridings =====*/ + .tab-pane { + .am-fade { + animation-duration: .3s; + animation-timing-function: ease; + animation-fill-mode: backwards; + opacity: 1; + + .active-remove { + display: none; + } + + .active-add { + animation-name: fadeIn; + } + } + } +} + + +#analyticsPage { + .filter-btn { + margin: 9px 10px 0 0; + } + + #sidebar-wrapper { + padding: 10px 7px 0 7px; + min-height: 80%; + top: 121px; + + .repo-job-details-wrapper { + padding: 0.05em 0.625em 0.25em; + } + + .marginbottom5 { + margin-bottom: 5px; + } + + .search { + width: 100%; + position: relative; + font-size: 18px; + padding-top: 0px; + label { + position: absolute; + left: 10px; + top: 4px; + } + } + + .search .search-input, .search .hint { + padding-left: 23px; + padding-right: -5px; + border-radius: 23px; + height: 28px; + outline: none; + font-size: 11px; + } + + .bp-select { + font-size: 11px; + height: 28px; + display: inline; + width: auto; + } + + .bp-panel-body { + max-height: 105px; + min-height: 80px; + overflow-y: auto; + } + + .activeLi { + background: #E2E2E2; + } + + .list-resources{ + padding: 0px; + ul li { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + padding: 3px 15px; + } + } + + .panel-heading { + height: 40px; + } + } + + .nav>li>a { + padding: 10px 7px; + font-size: 13px; + } + + .filter-title { + margin-top: -13px; + font-size: 12px; + } + + .filter-name { + margin-top: -21px; + } + + .selected { + background: #E49C25; + } +} +.nv-axislabel{ + font-size: 14px !important; +} +.nvd3 text { + font: normal 10px Arial; +} +.font-size-15{ + font-size: 15px !important; +} +.marginbottom10{ + margin-bottom: 10px !important; +} \ No newline at end of file diff --git a/client/cat3/src/partials/sections/dashboard/bots/botsCtrl.js b/client/cat3/src/partials/sections/dashboard/bots/botsCtrl.js new file mode 100644 index 000000000..fb1542003 --- /dev/null +++ b/client/cat3/src/partials/sections/dashboard/bots/botsCtrl.js @@ -0,0 +1,29 @@ +(function (angular) { + "use strict"; + angular.module('dashboard.bots', ['library.bots']).config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'modulePermissionProvider', function($stateProvider, $urlRouterProvider, $httpProvider, modulePermissionProvider) { + var modulePerms = modulePermissionProvider.$get(); + $stateProvider.state('dashboard.bots.library', { + url: "/library", + templateUrl: "src/partials/sections/dashboard/bots/view/library.html", + controller: "libraryCtrl as libr", + resolve: { + auth: ["$q", function ($q) { + var deferred = $q.defer(); + // instead, go to a different page + if (modulePerms.analyticsBool()) { + // everything is fine, proceed + deferred.resolve(); + } else { + deferred.reject({redirectTo: 'dashboard'}); + } + return deferred.promise; + }] + } + }) + }]) + .controller('botsCtrl',['$scope', '$rootScope','$state', function ($scope, $rootScope,$state) { + var treeNames = ['Bots']; + $rootScope.$emit('treeNameUpdate', treeNames); + $state.go('dashboard.bots.library'); + }]); +})(angular); \ No newline at end of file diff --git a/client/cat3/src/partials/sections/dashboard/bots/controller/libraryCtrl.js b/client/cat3/src/partials/sections/dashboard/bots/controller/libraryCtrl.js new file mode 100644 index 000000000..2a41dd92a --- /dev/null +++ b/client/cat3/src/partials/sections/dashboard/bots/controller/libraryCtrl.js @@ -0,0 +1,52 @@ +(function (angular) { + "use strict"; + angular.module('library.bots', []) + .controller('libraryCtrl',['$scope', '$rootScope','$state','genericServices', function ($scope, $rootScope,$state,genSevs) { + var treeNames = ['Bots','Library']; + $rootScope.$emit('treeNameUpdate', treeNames); + var lib=this; + lib.gridOptions={ + gridOption:{ + paginationPageSizes: [25, 50, 75], + paginationPageSize: 25, + enableColumnMenus:false, + multiSelect :false, + }, + columnDefs: [ + { name: 'type',field:'botType'}, + { name: 'name',field:'name'}, + { name: 'description',field:'shortDesc'}, + { name: 'run Bot' }, + { name: 'history' }, + { name: 'last run'}, + { name: 'bot Action',cellTemplate:''} + ], + data:[] + }; + $scope.launchInstance = function(lunch){ + if(lunch.botType === 'Task'){ + genSevs.executeTask(lunch); + + } else if(lunch.botType === 'blueprint') { + genSevs.lunchBlueprint(lunch); + } + }; + lib.int =function(){ + lib.gridOptions.data=[]; + var param={ + url:'/blueprints/serviceDelivery' + }; + genSevs.promiseGet(param).then(function (result) { + angular.extend(lib.gridOptions.data,result); + }); + var param2={ + url:'/tasks/serviceDelivery' + }; + genSevs.promiseGet(param2).then(function (resultTask) { + angular.extend(lib.gridOptions.data,resultTask); + }); + }; + lib.int(); + + }]); +})(angular); \ No newline at end of file diff --git a/client/cat3/src/partials/sections/dashboard/bots/view/botsTreeMenu.html b/client/cat3/src/partials/sections/dashboard/bots/view/botsTreeMenu.html new file mode 100644 index 000000000..b796404bd --- /dev/null +++ b/client/cat3/src/partials/sections/dashboard/bots/view/botsTreeMenu.html @@ -0,0 +1,41 @@ + + + +
    + +
    diff --git a/client/cat3/src/partials/sections/dashboard/bots/view/library.html b/client/cat3/src/partials/sections/dashboard/bots/view/library.html new file mode 100644 index 000000000..0e6c80888 --- /dev/null +++ b/client/cat3/src/partials/sections/dashboard/bots/view/library.html @@ -0,0 +1,5 @@ +
    +
    +
    + No data Available +
    \ No newline at end of file diff --git a/client/cat3/src/partials/sections/dashboard/dashboardCtrl.js b/client/cat3/src/partials/sections/dashboard/dashboardCtrl.js index 5b9d187e9..972322e1a 100644 --- a/client/cat3/src/partials/sections/dashboard/dashboardCtrl.js +++ b/client/cat3/src/partials/sections/dashboard/dashboardCtrl.js @@ -8,28 +8,32 @@ 'dashboard.track', 'dashboard.settings', 'dashboard.design', + 'dashboard.bots', 'apis.workzone','dashboard.genericServices']) .controller('dashboardCtrl', ['$rootScope', '$scope', '$http', 'uac', '$location', '$state', function ($rootScope, $scope, $http, uac, $location, $state) { - $rootScope.isBreadCrumbAvailable = true; - $rootScope.app.isDashboard = true; - if($state.current && $state.current.data && $state.current.data.menuName){ - $rootScope.dashboardChild = $state.current.data.menuName; - } else { - $rootScope.dashboardChild =''; - } - $rootScope.showTreeMenu = true; - /*State will be dashboard if coming via login flow. So check permission and do default landing logic*/ - /*Otherwise dont enable default landing logic. This is so that user can land on url directly*/ - if ($state.current.name === 'dashboard') { - if ($rootScope.workZoneBool) { - $state.go('dashboard.workzone'); - } else if ($rootScope.designBool) { - $state.go('dashboard.design'); - } else if ($rootScope.trackBool) { - $state.go('dashboard.track'); - } else if ($rootScope.settingsBool) { - $state.go('dashboard.settings'); + $rootScope.isBreadCrumbAvailable = true; + $rootScope.app.isDashboard = true; + if($state.current && $state.current.data && $state.current.data.menuName){ + $rootScope.dashboardChild = $state.current.data.menuName; + } else { + $rootScope.dashboardChild =''; + } + $rootScope.showTreeMenu = true; + /*State will be dashboard if coming via login flow. So check permission and do default landing logic*/ + /*Otherwise dont enable default landing logic. This is so that user can land on url directly*/ + if ($state.current.name === 'dashboard') { + if ($rootScope.workZoneBool) { + $state.go('dashboard.workzone'); + } else if ($rootScope.designBool) { + $state.go('dashboard.design'); + } else if ($rootScope.trackBool) { + $state.go('dashboard.track'); + } else if ($rootScope.settingsBool) { + $state.go('dashboard.settings'); + } else if ($rootScope.serviceBool) { + $state.go('dashboard.service'); + } + } } - } -}]); + ]); })(angular); \ No newline at end of file diff --git a/client/cat3/src/partials/sections/dashboard/genericServices.js b/client/cat3/src/partials/sections/dashboard/genericServices.js index 82401b9f7..767fe9470 100644 --- a/client/cat3/src/partials/sections/dashboard/genericServices.js +++ b/client/cat3/src/partials/sections/dashboard/genericServices.js @@ -102,6 +102,24 @@ } }; + genericServices.log=function(id,historyId,taskType) { + $modal.open({ + animation: true, + templateUrl: 'src/partials/sections/dashboard/workzone/orchestration/popups/orchestrationLog.html', + controller: 'orchestrationLogCtrl as orchLogCtrl', + backdrop: 'static', + keyboard: false, + resolve: { + items: function() { + return { + taskId: id, + historyId: historyId, + taskType: taskType + }; + } + } + }); + }; genericServices.removeBlueprint= function(blueprintObj, bpType) { var modalOptions = { closeButtonText: 'Cancel', @@ -130,6 +148,113 @@ }); } }; + + genericServices.executeTask =function(task) { + if (task.taskConfig.parameterized && task.taskConfig.parameterized.length) { + $modal.open({ + animation: true, + templateUrl: 'src/partials/sections/dashboard/workzone/orchestration/popups/runParamConfig.html', + controller: 'runParamConfigCtrl', + backdrop: 'static', + keyboard: false, + resolve: { + items: function() { + return angular.extend([], task.taskConfig.parameterized); + } + } + }).result.then(function(selectedItems) { + var choiceParam = {}; + var p = selectedItems; + for (var i = 0; i < p.length; i++) { + choiceParam[p[i].name] = p[i].defaultValue[0]; + } + workSvs.runTask(task._id, { + "choiceParam": choiceParam + }).then(function(response) { + helper.orchestrationLogModal(task._id, response.data.historyId, task.taskType); + $rootScope.$emit('WZ_ORCHESTRATION_REFRESH_CURRENT'); + }); + }, function() { + console.log("Dismiss at " + new Date()); + }); + } else { + $modal.open({ + animation: true, + templateUrl: 'src/partials/sections/dashboard/workzone/orchestration/popups/confirmJobRun.html', + controller: 'confirmJobRunCtrl', + backdrop: 'static', + keyboard: false, + resolve: { + items: function() { + return task._id; + } + } + }).result.then(function(response) { + genericServices.log(task._id,response.historyId,task.taskType); + if(response.blueprintMessage){ + $rootScope.$emit('WZ_INSTANCES_SHOW_LATEST'); + } + $rootScope.$emit('WZ_ORCHESTRATION_REFRESH_CURRENT'); + }, function() { + $rootScope.$emit('WZ_ORCHESTRATION_REFRESH_CURRENT'); + }); + } + } + genericServices.lunchBlueprint=function(blueprintObj) { + $modal.open({ + animate: true, + templateUrl: "src/partials/sections/dashboard/workzone/blueprint/popups/blueprintLaunchParams.html", + controller: "blueprintLaunchParamsCtrl", + backdrop : 'static', + keyboard: false, + resolve: { + items: function() { + return blueprintObj; + } + } + }) + .result.then(function(bpObj) { + if (bpObj.bp.blueprintType === "docker") { + $modal.open({ + animate: true, + templateUrl: "src/partials/sections/dashboard/workzone/blueprint/popups/dockerLaunchParams.html", + controller: "dockerLaunchParamsCtrl", + backdrop: 'static', + keyboard: false, + size: 'lg', + resolve: { + items: function() { + return bpObj.bp; + } + } + }).result.then(function() { + console.log('The modal close is not getting invoked currently. Goes to cancel handler'); + }, function() { + console.log('Cancel Handler getting invoked'); + }); + }else{ + $modal.open({ + animate: true, + templateUrl: "src/partials/sections/dashboard/workzone/blueprint/popups/blueprintLaunch.html", + controller: "blueprintLaunchCtrl", + backdrop: 'static', + keyboard: false, + resolve: { + bpItem: function() { + return bpObj; + } + } + }) + .result.then(function(selectedItem) { + $scope.selected = selectedItem; + }, function() { + + }); + } + }, function() { + + }); + }; /*genericServices.editRunlist = function(chefRunlist, chefAttribute) { $modal.open({ templateUrl: 'src/partials/sections/dashboard/workzone/orchestration/popups/orchestrationUpdateChefRunlist.html', diff --git a/client/htmls/private/index.html b/client/htmls/private/index.html index 6844429b9..c6ef0f064 100644 --- a/client/htmls/private/index.html +++ b/client/htmls/private/index.html @@ -53,6 +53,13 @@   ANALYTICS + + + @@ -799,7 +806,23 @@