diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 2a28347647..8994364e87 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -27,7 +27,7 @@ font-weight: bold; white-space: nowrap; padding-bottom: 25px; - min-height: 40px; + min-height: 45px; } .Form-title--is_superuser{ diff --git a/awx/ui/client/legacy-styles/lists.less b/awx/ui/client/legacy-styles/lists.less index cb5d07ba4c..c60cc1b38f 100644 --- a/awx/ui/client/legacy-styles/lists.less +++ b/awx/ui/client/legacy-styles/lists.less @@ -246,3 +246,8 @@ table, tbody { background-color: @list-no-items-bg; color: @list-no-items-txt; } + +.List-editButton--selected { + background-color: @list-actn-bg-hov !important; + color: @list-actn-icn-hov; +} diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index f407aa8543..4283b1943f 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -1061,20 +1061,6 @@ var tower = angular.module('Tower', [ $rootScope.$on("$stateChangeStart", function (event, next, nextParams, prev) { - // broadcast event change if editing crud object - if ($location.$$path.split("/")[2]) { - var list = $location.$$path.split("/")[1]; - var id = $location.$$path.split("/")[2]; - - delete $rootScope.listBeingEdited; - delete $rootScope.rowBeingEdited; - - $rootScope.$broadcast("EditIndicatorChange", list, id); - } else if ($rootScope.addedAnItem) { - delete $rootScope.addedAnItem; - } else { - $rootScope.$broadcast("RemoveIndicator"); - } // this line removes the query params attached to a route if(prev && prev.$$route && @@ -1128,6 +1114,23 @@ var tower = angular.module('Tower', [ activateTab(); }); + $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) { + // broadcast event change if editing crud object + if ($location.$$path.split("/")[2]) { + var list = $location.$$path.split("/")[1]; + var id = $location.$$path.split("/")[2]; + + delete $rootScope.listBeingEdited; + delete $rootScope.rowBeingEdited; + + $rootScope.$broadcast("EditIndicatorChange", list, id); + } else if ($rootScope.addedAnItem) { + delete $rootScope.addedAnItem; + } else { + $rootScope.$broadcast("RemoveIndicator"); + } + }); + if (!Authorization.getToken() || !Authorization.isUserLoggedIn()) { // User not authenticated, redirect to login page $rootScope.sessionExpired = false; diff --git a/awx/ui/client/src/controllers/Projects.js b/awx/ui/client/src/controllers/Projects.js index 6c1ab1d857..8cef0c282f 100644 --- a/awx/ui/client/src/controllers/Projects.js +++ b/awx/ui/client/src/controllers/Projects.js @@ -112,7 +112,7 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams, if ($scope.removeChoicesHere) { $scope.removeChoicesHere(); } - $scope.removeChoicesHere = $scope.$on('choicesCompleteProject', function () { + $scope.removeChoicesHere = $scope.$on('choicesCompleteProjectList', function () { var opt; list.fields.scm_type.searchOptions = $scope.project_scm_type_options; @@ -164,13 +164,13 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams, $scope.search(list.iterator); }); - if ($scope.removeChoicesReady) { - $scope.removeChoicesReady(); + if ($scope.removeChoicesReadyList) { + $scope.removeChoicesReadyList(); } - $scope.removeChoicesReady = $scope.$on('choicesReadyProject', function () { + $scope.removeChoicesReadyList = $scope.$on('choicesReadyProjectList', function () { choiceCount++; if (choiceCount === 2) { - $scope.$emit('choicesCompleteProject'); + $scope.$emit('choicesCompleteProjectList'); } }); @@ -180,7 +180,7 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams, url: defaultUrl, field: 'status', variable: 'project_status_options', - callback: 'choicesReadyProject' + callback: 'choicesReadyProjectList' }); // Load the list of options for Kind @@ -189,7 +189,7 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams, url: defaultUrl, field: 'scm_type', variable: 'project_scm_type_options', - callback: 'choicesReadyProject' + callback: 'choicesReadyProjectList' }); $scope.showActivity = function () { diff --git a/awx/ui/client/src/controllers/Teams.js b/awx/ui/client/src/controllers/Teams.js index 2880e0289a..74e19f1b7d 100644 --- a/awx/ui/client/src/controllers/Teams.js +++ b/awx/ui/client/src/controllers/Teams.js @@ -14,7 +14,7 @@ export function TeamsList($scope, $rootScope, $location, $log, $stateParams, Rest, Alert, TeamList, GenerateList, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, SetTeamListeners, GetBasePath, - SelectionInit, Wait, Stream, $state) { + SelectionInit, Wait, Stream, $state, Refresh) { ClearScope(); @@ -25,7 +25,22 @@ export function TeamsList($scope, $rootScope, $location, $log, $stateParams, mode = (paths[0] === 'teams') ? 'edit' : 'select', url; - generator.inject(list, { mode: mode, scope: $scope }); + var injectForm = function() { + generator.inject(list, { mode: mode, scope: $scope }); + }; + + injectForm(); + + $scope.$on("RefreshTeamsList", function() { + injectForm(); + Refresh({ + scope: $scope, + set: 'teams', + iterator: 'team', + url: GetBasePath('teams') + "?order_by=name&page_size=" + $scope.team_page_size + }); + }); + $scope.selected = []; url = GetBasePath('base') + $location.path() + '/'; @@ -111,7 +126,7 @@ TeamsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$stateParams', 'Rest', 'Alert', 'TeamList', 'generateList', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', 'SetTeamListeners', 'GetBasePath', 'SelectionInit', 'Wait', - 'Stream', '$state' + 'Stream', '$state', 'Refresh' ]; @@ -154,6 +169,7 @@ export function TeamsAdd($scope, $rootScope, $compile, $location, $log, .success(function (data) { Wait('stop'); $rootScope.flashMessage = "New team successfully created!"; + $rootScope.$broadcast("EditIndicatorChange", "users", data.id); $location.path('/teams/' + data.id); }) .error(function (data, status) { @@ -195,6 +211,8 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $scope.permission_label = {}; $scope.permission_search_select = []; + $scope.$emit("RefreshTeamsList"); + // return a promise from the options request with the permission type choices (including adhoc) as a param var permissionsChoice = fieldChoices({ scope: $scope, diff --git a/awx/ui/client/src/controllers/Users.js b/awx/ui/client/src/controllers/Users.js index a01e330806..ee5cc02773 100644 --- a/awx/ui/client/src/controllers/Users.js +++ b/awx/ui/client/src/controllers/Users.js @@ -14,7 +14,7 @@ export function UsersList($scope, $rootScope, $location, $log, $stateParams, Rest, Alert, UserList, GenerateList, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, SelectionInit, - Wait, Stream, $state) { + Wait, Stream, $state, Refresh) { ClearScope(); @@ -26,7 +26,21 @@ export function UsersList($scope, $rootScope, $location, $log, $stateParams, url = (base === 'organizations') ? GetBasePath('organizations') + $stateParams.organization_id + '/users/' : GetBasePath('teams') + $stateParams.team_id + '/users/'; - generator.inject(UserList, { mode: mode, scope: $scope }); + var injectForm = function() { + generator.inject(UserList, { mode: mode, scope: $scope }); + }; + + injectForm(); + + $scope.$on("RefreshUsersList", function() { + injectForm(); + Refresh({ + scope: $scope, + set: 'users', + iterator: 'user', + url: GetBasePath('users') + "?order_by=username&page_size=" + $scope.user_page_size + }); + }); $scope.selected = []; @@ -101,7 +115,8 @@ export function UsersList($scope, $rootScope, $location, $log, $stateParams, UsersList.$inject = ['$scope', '$rootScope', '$location', '$log', '$stateParams', 'Rest', 'Alert', 'UserList', 'generateList', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', - 'ProcessErrors', 'GetBasePath', 'SelectionInit', 'Wait', 'Stream', '$state' + 'ProcessErrors', 'GetBasePath', 'SelectionInit', 'Wait', 'Stream', '$state', + 'Refresh' ]; @@ -173,6 +188,7 @@ export function UsersAdd($scope, $rootScope, $compile, $location, $log, var base = $location.path().replace(/^\//, '').split('/')[0]; if (base === 'users') { $rootScope.flashMessage = 'New user successfully created!'; + $rootScope.$broadcast("EditIndicatorChange", "users", data.id); $location.path('/users/' + data.id); } else { @@ -226,6 +242,8 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, $scope.permission_label = {}; $scope.permission_search_select = []; + $scope.$emit("RefreshUsersList"); + // return a promise from the options request with the permission type choices (including adhoc) as a param var permissionsChoice = fieldChoices({ scope: $scope, @@ -265,6 +283,11 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, if ($scope.removePostRefresh) { $scope.removePostRefresh(); } + $scope.removePostRefresh = $scope.$on('PostRefresh', function () { + // Cleanup after a delete + Wait('stop'); + $('#prompt-modal').modal('hide'); + }); $scope.PermissionAddAllowed = false; diff --git a/awx/ui/client/src/login/loginModal/loginModal.block.less b/awx/ui/client/src/login/loginModal/loginModal.block.less index e0a1ce11f6..464eb3c9f0 100644 --- a/awx/ui/client/src/login/loginModal/loginModal.block.less +++ b/awx/ui/client/src/login/loginModal/loginModal.block.less @@ -81,6 +81,7 @@ .LoginModal-alert { opacity: 1; + display: flex; } .LoginModal-alert.ng-hide { diff --git a/awx/ui/client/src/login/loginModal/loginModal.partial.html b/awx/ui/client/src/login/loginModal/loginModal.partial.html index 3b0b1f0f21..3d7bdb58df 100644 --- a/awx/ui/client/src/login/loginModal/loginModal.partial.html +++ b/awx/ui/client/src/login/loginModal/loginModal.partial.html @@ -14,16 +14,28 @@ Welcome to Ansible Tower!  Please sign in.
- Your session timed out due to inactivity. Please sign in. + +
+ Your session timed out due to inactivity. Please sign in. +
- Maximum per-user sessions reached. Please sign in. + +
+ Maximum per-user sessions reached. Please sign in. +
- Invalid username and/or password. Please try again. + +
+ Invalid username and/or password. Please try again. +
- {{ thirdPartyAttemptFailed }} + +
+ {{ thirdPartyAttemptFailed }} +