From a8d51da73c10b791404e8a4551248b85f8da74d4 Mon Sep 17 00:00:00 2001 From: Michael Abashian Date: Tue, 26 Jan 2016 11:11:27 -0500 Subject: [PATCH] List view styling tweaks based on UI/UX feedback. Fixed various bugs dealing with the list views/pagination/delete modal(s). Fixed the jobs list responsive weirdness. --- awx/ui/client/legacy-styles/ansible-ui.less | 1 + awx/ui/client/legacy-styles/lists.less | 22 +- awx/ui/client/src/controllers/Credentials.js | 2 +- .../client/src/controllers/Organizations.js | 2 +- awx/ui/client/src/controllers/Projects.js | 2 +- awx/ui/client/src/controllers/Teams.js | 2 +- awx/ui/client/src/controllers/Users.js | 2 +- awx/ui/client/src/forms/Inventories.js | 16 +- awx/ui/client/src/forms/Organizations.js | 4 +- awx/ui/client/src/forms/Projects.js | 2 +- awx/ui/client/src/forms/Teams.js | 8 +- awx/ui/client/src/forms/Users.js | 4 +- awx/ui/client/src/helpers/Hosts.js | 986 +++++++++--------- awx/ui/client/src/helpers/Jobs.js | 10 +- awx/ui/client/src/lists/AllJobs.js | 22 +- awx/ui/client/src/lists/CompletedJobs.js | 20 +- awx/ui/client/src/lists/InventoryGroups.js | 14 +- awx/ui/client/src/lists/InventoryHosts.js | 12 +- awx/ui/client/src/lists/JobTemplates.js | 16 +- awx/ui/client/src/lists/Jobs.js | 16 +- awx/ui/client/src/lists/ScanJobs.js | 18 +- awx/ui/client/src/lists/ScheduledJobs.js | 9 +- awx/ui/client/src/shared/form-generator.js | 2 +- awx/ui/client/src/shared/generator-helpers.js | 8 +- .../list-generator/list-generator.factory.js | 2 +- awx/ui/client/src/shared/prompt/prompt.less | 17 +- 26 files changed, 620 insertions(+), 599 deletions(-) diff --git a/awx/ui/client/legacy-styles/ansible-ui.less b/awx/ui/client/legacy-styles/ansible-ui.less index 7d070ac2ba..b2fbff05ec 100644 --- a/awx/ui/client/legacy-styles/ansible-ui.less +++ b/awx/ui/client/legacy-styles/ansible-ui.less @@ -2012,6 +2012,7 @@ button.dropdown-toggle, .modal.fade .modal-dialog { transform: translate(0, 0); + margin: 100px auto; } .modal-backdrop, .modal-backdrop.fade.in { diff --git a/awx/ui/client/legacy-styles/lists.less b/awx/ui/client/legacy-styles/lists.less index c60cc1b38f..faa4d1d343 100644 --- a/awx/ui/client/legacy-styles/lists.less +++ b/awx/ui/client/legacy-styles/lists.less @@ -81,12 +81,11 @@ table, tbody { .List-actionButton { font-size: 16px; height: 30px; - width: 30px; + min-width: 30px; color: @list-action-icon; background-color: @list-actn-bg; border: none; border-radius: 50%; - transition: background-color 0.2s, border-color 0.2s;; } .List-actionButton:hover { @@ -108,6 +107,12 @@ table, tbody { color: @list-pagin-text; text-transform: uppercase; height: 22px; + display: flex; +} + +.List-paginationPagerHolder { + display: flex; + flex: 1 0 auto; } .List-paginationPager { @@ -128,13 +133,18 @@ table, tbody { background-color: @list-pagin-bg-act!important; } +.List-paginationItemsOf { + display: flex; + justify-content: flex-end; +} + .List-header { - align-items: center; display: flex; height: 34px; } .List-title { + align-items: center; flex: 1 0 auto; display: flex; } @@ -163,7 +173,6 @@ table, tbody { } .List-buttonSubmit { - transition: background-color 0.2s; background-color: @submit-button-bg; color: @submit-button-text; } @@ -175,7 +184,6 @@ table, tbody { } .List-buttonDefault { - transition: background-color 0.2s; background-color: @btn-bg; color: @btn-txt; border-color: @btn-bord; @@ -235,6 +243,10 @@ table, tbody { color: @list-srch-btn-icon; } +.List-searchNoResults { + color: @default-interface-txt; +} + .List-noItems { display: flex; align-items: center; diff --git a/awx/ui/client/src/controllers/Credentials.js b/awx/ui/client/src/controllers/Credentials.js index eecd4cf34a..ddd664c89e 100644 --- a/awx/ui/client/src/controllers/Credentials.js +++ b/awx/ui/client/src/controllers/Credentials.js @@ -566,7 +566,7 @@ export function CredentialsEdit($scope, $rootScope, $compile, $location, $log, Prompt({ hdr: 'Delete', - body: '
Are you sure you want to remove ' + name + ' from ' + $scope.name + ' ' + title + '?
', + body: '
Are you sure you want to remove the ' + title + ' below from ' + $scope.name + '?
' + name + '
', action: action, actionText: 'DELETE' }); diff --git a/awx/ui/client/src/controllers/Organizations.js b/awx/ui/client/src/controllers/Organizations.js index ff89fb63a7..e0e5e9e36d 100644 --- a/awx/ui/client/src/controllers/Organizations.js +++ b/awx/ui/client/src/controllers/Organizations.js @@ -352,7 +352,7 @@ export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log, Prompt({ hdr: 'Delete', - body: '
Are you sure you want to remove ' + name + ' from ' + $scope.name + ' ' + title + '?
', + body: '
Are you sure you want to remove the ' + title + ' below from ' + $scope.name + '?
' + name + '
', action: action, actionText: 'DELETE' }); diff --git a/awx/ui/client/src/controllers/Projects.js b/awx/ui/client/src/controllers/Projects.js index 8cef0c282f..45b9180497 100644 --- a/awx/ui/client/src/controllers/Projects.js +++ b/awx/ui/client/src/controllers/Projects.js @@ -796,7 +796,7 @@ export function ProjectsEdit($scope, $rootScope, $compile, $location, $log, Prompt({ hdr: 'Delete', - body: '
Are you sure you want to remove ' + name + ' from ' + $scope.name + ' ' + title + '?
', + body: '
Are you sure you want to remove the ' + title + ' below from ' + $scope.name + '?
' + name + '
', action: action, actionText: 'DELETE' }); diff --git a/awx/ui/client/src/controllers/Teams.js b/awx/ui/client/src/controllers/Teams.js index 74e19f1b7d..ec2421a765 100644 --- a/awx/ui/client/src/controllers/Teams.js +++ b/awx/ui/client/src/controllers/Teams.js @@ -429,7 +429,7 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, Prompt({ hdr: 'Delete', - body: '
Are you sure you want to remove ' + name + ' from ' + $scope.name + ' ' + title + '?
', + body: '
Are you sure you want to remove the ' + title + ' below from ' + $scope.name + '?
' + name + '
', action: action, actionText: 'DELETE' }); diff --git a/awx/ui/client/src/controllers/Users.js b/awx/ui/client/src/controllers/Users.js index ee5cc02773..06e1e0f881 100644 --- a/awx/ui/client/src/controllers/Users.js +++ b/awx/ui/client/src/controllers/Users.js @@ -484,7 +484,7 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, Prompt({ hdr: 'Delete', - body: '
Are you sure you want to remove ' + name + ' from ' + $scope.username + ' ' + title + '?
', + body: '
Are you sure you want to remove the ' + title + ' below from ' + $scope.username + '?
' + name + '
', action: action, actionText: 'DELETE' }); diff --git a/awx/ui/client/src/forms/Inventories.js b/awx/ui/client/src/forms/Inventories.js index 419304cb9c..ac20caf919 100644 --- a/awx/ui/client/src/forms/Inventories.js +++ b/awx/ui/client/src/forms/Inventories.js @@ -127,6 +127,14 @@ export default awToolTip: 'Schedule future job template runs', dataPlacement: 'top', }, + copy: { + label: 'Copy', + ngClick: "copyScanJobTemplate()", + "class": 'btn-danger btn-xs', + awToolTip: 'Copy template', + dataPlacement: 'top', + ngHide: 'job_template.summary_fields.can_copy === false' + }, edit: { label: 'Edit', ngClick: "editScanJob()", @@ -140,14 +148,6 @@ export default icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Delete the scan job template' - }, - copy: { - label: 'Copy', - ngClick: "copyScanJobTemplate()", - "class": 'btn-danger btn-xs', - awToolTip: 'Copy template', - dataPlacement: 'top', - ngHide: 'job_template.summary_fields.can_copy === false' } } } diff --git a/awx/ui/client/src/forms/Organizations.js b/awx/ui/client/src/forms/Organizations.js index 0dafb8404c..0f32733c89 100644 --- a/awx/ui/client/src/forms/Organizations.js +++ b/awx/ui/client/src/forms/Organizations.js @@ -87,7 +87,7 @@ export default }, "delete": { label: 'Delete', - ngClick: "delete('users', user.id, user.username, 'users')", + ngClick: "delete('users', user.id, user.username, 'user')", icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Remove user' @@ -133,7 +133,7 @@ export default }, "delete": { label: 'Delete', - ngClick: "delete('admins', admin.id, admin.username, 'administrators')", + ngClick: "delete('admins', admin.id, admin.username, 'administrator')", icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Remove administrator' diff --git a/awx/ui/client/src/forms/Projects.js b/awx/ui/client/src/forms/Projects.js index a46d856efd..0260229773 100644 --- a/awx/ui/client/src/forms/Projects.js +++ b/awx/ui/client/src/forms/Projects.js @@ -261,7 +261,7 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition']) }, "delete": { label: 'Delete', - ngClick: "delete('organizations', organization.id, organization.name, 'organizations')", + ngClick: "delete('organizations', organization.id, organization.name, 'organization')", icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Delete the organization' diff --git a/awx/ui/client/src/forms/Teams.js b/awx/ui/client/src/forms/Teams.js index 67c9f48d45..45bc14ecbd 100644 --- a/awx/ui/client/src/forms/Teams.js +++ b/awx/ui/client/src/forms/Teams.js @@ -95,7 +95,7 @@ export default }, "delete": { label: 'Delete', - ngClick: "delete('credentials', credential.id, credential.name, 'credentials')", + ngClick: "delete('credentials', credential.id, credential.name, 'credential')", icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Remove the credential' @@ -157,7 +157,7 @@ export default "delete": { label: 'Delete', - ngClick: "delete('permissions', permission.id, permission.name, 'permissions')", + ngClick: "delete('permissions', permission.id, permission.name, 'permission')", icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Delete the permission', @@ -203,7 +203,7 @@ export default }, "delete": { label: 'Delete', - ngClick: "delete('projects', project.id, project.name, 'projects')", + ngClick: "delete('projects', project.id, project.name, 'project')", icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Remove the project' @@ -251,7 +251,7 @@ export default }, "delete": { label: 'Delete', - ngClick: "delete('users', user.id, user.username, 'users')", + ngClick: "delete('users', user.id, user.username, 'user')", icon: 'icon-terash', "class": 'btn-danger', awToolTip: 'Remove user' diff --git a/awx/ui/client/src/forms/Users.js b/awx/ui/client/src/forms/Users.js index f190c50365..5d87cac2db 100644 --- a/awx/ui/client/src/forms/Users.js +++ b/awx/ui/client/src/forms/Users.js @@ -150,7 +150,7 @@ export default }, "delete": { label: 'Delete', - ngClick: "delete('credentials', credential.id, credential.name, 'credentials')", + ngClick: "delete('credentials', credential.id, credential.name, 'credential')", icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Delete the credential' @@ -212,7 +212,7 @@ export default "delete": { label: 'Delete', - ngClick: "delete('permissions', permission.id, permission.name, 'permissions')", + ngClick: "delete('permissions', permission.id, permission.name, 'permission')", icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Delete the permission', diff --git a/awx/ui/client/src/helpers/Hosts.js b/awx/ui/client/src/helpers/Hosts.js index 65bc8de7c1..517fee8a52 100644 --- a/awx/ui/client/src/helpers/Hosts.js +++ b/awx/ui/client/src/helpers/Hosts.js @@ -739,9 +739,9 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', listGenerator.name, } }; - body = (group) ? '

Are you sure you want to remove host ' + host_name + ' from group ' + group.name + '?' + - ' It will still be part of the inventory and available in All Hosts.

' : - '

Are you sure you want to permanently delete host ' + host_name + ' from the inventory?

'; + body = (group) ? '

Are you sure you want to remove the host below from group ' + group.name + '?' + + ' It will still be part of the inventory and available in All Hosts.

' + host_name + '
' : + '
Are you sure you want to permanently delete the host below from the inventory?
' + host_name + '
'; Prompt({ hdr: 'Delete Host', body: body, @@ -752,537 +752,537 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', listGenerator.name, }; }]) - .factory('HostsCopy', ['$compile', 'Rest', 'ProcessErrors', 'CreateDialog', 'GetBasePath', 'Wait', 'generateList', 'GroupList', 'SearchInit', - 'PaginateInit', - function($compile, Rest, ProcessErrors, CreateDialog, GetBasePath, Wait, GenerateList, GroupList, SearchInit, PaginateInit) { - return function(params) { +.factory('HostsCopy', ['$compile', 'Rest', 'ProcessErrors', 'CreateDialog', 'GetBasePath', 'Wait', 'generateList', 'GroupList', 'SearchInit', +'PaginateInit', +function($compile, Rest, ProcessErrors, CreateDialog, GetBasePath, Wait, GenerateList, GroupList, SearchInit, PaginateInit) { +return function(params) { - var host_id = params.host_id, - group_scope = params.group_scope, - parent_scope = params.host_scope, - parent_group = group_scope.selected_group_id, - scope = parent_scope.$new(), - buttonSet, url, host; + var host_id = params.host_id, + group_scope = params.group_scope, + parent_scope = params.host_scope, + parent_group = group_scope.selected_group_id, + scope = parent_scope.$new(), + buttonSet, url, host; - buttonSet = [{ - label: "Cancel", - onClick: function() { - scope.cancel(); - }, - icon: "fa-times", - "class": "btn btn-default", - "id": "host-copy-cancel-button" - },{ - label: "OK", - onClick: function() { - scope.performCopy(); - }, - icon: "fa-check", - "class": "btn btn-primary", - "id": "host-copy-ok-button" - }]; + buttonSet = [{ + label: "Cancel", + onClick: function() { + scope.cancel(); + }, + icon: "fa-times", + "class": "btn btn-default", + "id": "host-copy-cancel-button" + },{ + label: "OK", + onClick: function() { + scope.performCopy(); + }, + icon: "fa-check", + "class": "btn btn-primary", + "id": "host-copy-ok-button" + }]; - if (scope.removeHostCopyPostRefresh) { - scope.removeHostCopyPostRefresh(); - } - scope.removeHostCopyPostRefresh = scope.$on('PostRefresh', function() { - scope.copy_groups.forEach(function(row, i) { - scope.copy_groups[i].checked = '0'; - }); - Wait('stop'); - $('#host-copy-dialog').dialog('open'); - $('#host-copy-ok-button').attr('disabled','disabled'); + if (scope.removeHostCopyPostRefresh) { + scope.removeHostCopyPostRefresh(); + } + scope.removeHostCopyPostRefresh = scope.$on('PostRefresh', function() { + scope.copy_groups.forEach(function(row, i) { + scope.copy_groups[i].checked = '0'; + }); + Wait('stop'); + $('#host-copy-dialog').dialog('open'); + $('#host-copy-ok-button').attr('disabled','disabled'); - // prevent backspace from navigation when not in input or textarea field - $(document).on("keydown", function (e) { - if (e.which === 8 && !$(e.target).is('input[type="text"], textarea')) { - e.preventDefault(); - } - }); - }); + // prevent backspace from navigation when not in input or textarea field + $(document).on("keydown", function (e) { + if (e.which === 8 && !$(e.target).is('input[type="text"], textarea')) { + e.preventDefault(); + } + }); + }); - if (scope.removeHostCopyDialogReady) { - scope.removeHostCopyDialogReady(); - } - scope.removeCopyDialogReady = scope.$on('HostCopyDialogReady', function() { - var url = GetBasePath('inventory') + group_scope.inventory.id + '/groups/'; - GenerateList.inject(GroupList, { - mode: 'lookup', - id: 'copy-host-select-container', - scope: scope - //, - //instructions: instructions - }); - SearchInit({ - scope: scope, - set: GroupList.name, - list: GroupList, - url: url - }); - PaginateInit({ - scope: scope, - list: GroupList, - url: url, - mode: 'lookup' - }); - scope.search(GroupList.iterator, null, true, false); - }); + if (scope.removeHostCopyDialogReady) { + scope.removeHostCopyDialogReady(); + } + scope.removeCopyDialogReady = scope.$on('HostCopyDialogReady', function() { + var url = GetBasePath('inventory') + group_scope.inventory.id + '/groups/'; + GenerateList.inject(GroupList, { + mode: 'lookup', + id: 'copy-host-select-container', + scope: scope + //, + //instructions: instructions + }); + SearchInit({ + scope: scope, + set: GroupList.name, + list: GroupList, + url: url + }); + PaginateInit({ + scope: scope, + list: GroupList, + url: url, + mode: 'lookup' + }); + scope.search(GroupList.iterator, null, true, false); + }); - if (scope.removeShowDialog) { - scope.removeShowDialog(); - } - scope.removeShowDialog = scope.$on('ShowDialog', function() { - var d; - scope.name = host.name; - scope.copy_choice = "copy"; - d = angular.element(document.getElementById('host-copy-dialog')); - $compile(d)(scope); - CreateDialog({ - id: 'host-copy-dialog', - scope: scope, - buttons: buttonSet, - width: 650, - height: 650, - minWidth: 600, - title: 'Copy or Move Host', - callback: 'HostCopyDialogReady', - onClose: function() { - scope.cancel(); - } - }); - }); + if (scope.removeShowDialog) { + scope.removeShowDialog(); + } + scope.removeShowDialog = scope.$on('ShowDialog', function() { + var d; + scope.name = host.name; + scope.copy_choice = "copy"; + d = angular.element(document.getElementById('host-copy-dialog')); + $compile(d)(scope); + CreateDialog({ + id: 'host-copy-dialog', + scope: scope, + buttons: buttonSet, + width: 650, + height: 650, + minWidth: 600, + title: 'Copy or Move Host', + callback: 'HostCopyDialogReady', + onClose: function() { + scope.cancel(); + } + }); + }); - Wait('start'); + Wait('start'); - url = GetBasePath('hosts') + host_id + '/'; - Rest.setUrl(url); - Rest.get() - .success(function(data) { - host = data; - scope.$emit('ShowDialog'); - }) - .error(function(data, status) { - ProcessErrors(scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. GET returned: ' + status }); - }); + url = GetBasePath('hosts') + host_id + '/'; + Rest.setUrl(url); + Rest.get() + .success(function(data) { + host = data; + scope.$emit('ShowDialog'); + }) + .error(function(data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + ' failed. GET returned: ' + status }); + }); - scope.cancel = function() { - $(document).off("keydown"); - try { - $('#host-copy-dialog').dialog('close'); - } - catch(e) { - // ignore - } - scope.searchCleanup(); - group_scope.restoreSearch(); // Restore all parent search stuff and refresh hosts and groups lists - scope.$destroy(); - }; + scope.cancel = function() { + $(document).off("keydown"); + try { + $('#host-copy-dialog').dialog('close'); + } + catch(e) { + // ignore + } + scope.searchCleanup(); + group_scope.restoreSearch(); // Restore all parent search stuff and refresh hosts and groups lists + scope.$destroy(); + }; - scope['toggle_' + GroupList.iterator] = function (id) { - var count = 0, - list = GroupList; - scope[list.name].forEach( function(row, i) { - if (row.id === id) { - if (row.checked) { - scope[list.name][i].success_class = 'success'; - } - else { - scope[list.name][i].success_class = ''; - } - } else { - scope[list.name][i].checked = 0; - scope[list.name][i].success_class = ''; - } - }); - // Check if any rows are checked - scope[list.name].forEach(function(row) { - if (row.checked) { - count++; - } - }); - if (count === 0) { - $('#host-copy-ok-button').attr('disabled','disabled'); - } - else { - $('#host-copy-ok-button').removeAttr('disabled'); - } - }; + scope['toggle_' + GroupList.iterator] = function (id) { + var count = 0, + list = GroupList; + scope[list.name].forEach( function(row, i) { + if (row.id === id) { + if (row.checked) { + scope[list.name][i].success_class = 'success'; + } + else { + scope[list.name][i].success_class = ''; + } + } else { + scope[list.name][i].checked = 0; + scope[list.name][i].success_class = ''; + } + }); + // Check if any rows are checked + scope[list.name].forEach(function(row) { + if (row.checked) { + count++; + } + }); + if (count === 0) { + $('#host-copy-ok-button').attr('disabled','disabled'); + } + else { + $('#host-copy-ok-button').removeAttr('disabled'); + } + }; - scope.performCopy = function() { - var list = GroupList, - target, - url; + scope.performCopy = function() { + var list = GroupList, + target, + url; - Wait('start'); + Wait('start'); - if (scope.use_root_group) { - target = null; - } - else { - scope[list.name].every(function(row) { - if (row.checked === 1) { - target = row; - return false; - } - return true; - }); - } + if (scope.use_root_group) { + target = null; + } + else { + scope[list.name].every(function(row) { + if (row.checked === 1) { + target = row; + return false; + } + return true; + }); + } - if (scope.copy_choice === 'move') { - // Respond to move + if (scope.copy_choice === 'move') { + // Respond to move - // disassociate the host from the original parent - if (scope.removeHostRemove) { - scope.removeHostRemove(); - } - scope.removeHostRemove = scope.$on('RemoveHost', function () { - if (parent_group > 0) { - // Only remove a host from a parent when the parent is a group and not the inventory root - url = GetBasePath('groups') + parent_group + '/hosts/'; - Rest.setUrl(url); - Rest.post({ id: host.id, disassociate: 1 }) - .success(function () { - scope.cancel(); - }) - .error(function (data, status) { - ProcessErrors(scope, data, status, null, { hdr: 'Error!', - msg: 'Failed to remove ' + host.name + ' from group ' + parent_group + '. POST returned: ' + status }); - }); - } else { - scope.cancel(); - } - }); + // disassociate the host from the original parent + if (scope.removeHostRemove) { + scope.removeHostRemove(); + } + scope.removeHostRemove = scope.$on('RemoveHost', function () { + if (parent_group > 0) { + // Only remove a host from a parent when the parent is a group and not the inventory root + url = GetBasePath('groups') + parent_group + '/hosts/'; + Rest.setUrl(url); + Rest.post({ id: host.id, disassociate: 1 }) + .success(function () { + scope.cancel(); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to remove ' + host.name + ' from group ' + parent_group + '. POST returned: ' + status }); + }); + } else { + scope.cancel(); + } + }); - // add the new host to the target - url = GetBasePath('groups') + target.id + '/hosts/'; - Rest.setUrl(url); - Rest.post(host) - .success(function () { - scope.$emit('RemoveHost'); - }) - .error(function (data, status) { - ProcessErrors(scope, data, status, null, { hdr: 'Error!', - msg: 'Failed to add ' + host.name + ' to ' + target.name + '. POST returned: ' + status }); - }); - } - else { - // Respond to copy by adding the new host to the target - url = GetBasePath('groups') + target.id + '/hosts/'; - Rest.setUrl(url); - Rest.post(host) - .success(function () { - scope.cancel(); - }) - .error(function (data, status) { - ProcessErrors(scope, data, status, null, { hdr: 'Error!', - msg: 'Failed to add ' + host.name + ' to ' + target.name + '. POST returned: ' + status - }); - }); - } - }; + // add the new host to the target + url = GetBasePath('groups') + target.id + '/hosts/'; + Rest.setUrl(url); + Rest.post(host) + .success(function () { + scope.$emit('RemoveHost'); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to add ' + host.name + ' to ' + target.name + '. POST returned: ' + status }); + }); + } + else { + // Respond to copy by adding the new host to the target + url = GetBasePath('groups') + target.id + '/hosts/'; + Rest.setUrl(url); + Rest.post(host) + .success(function () { + scope.cancel(); + }) + .error(function (data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to add ' + host.name + ' to ' + target.name + '. POST returned: ' + status + }); + }); + } + }; - }; - }]) +}; +}]) - .factory('EditHostGroups', ['$rootScope', '$location', '$log', '$stateParams', 'Rest', 'Alert', 'GenerateForm', 'Prompt', - 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', - function($rootScope, $location, $log, $stateParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath, HostsReload, - ParseTypeChange, Wait) { - return function(params) { +.factory('EditHostGroups', ['$rootScope', '$location', '$log', '$stateParams', 'Rest', 'Alert', 'GenerateForm', 'Prompt', + 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', + function($rootScope, $location, $log, $stateParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath, HostsReload, + ParseTypeChange, Wait) { + return function(params) { - var host_id = params.host_id, - inventory_id = params.inventory_id, - generator = GenerateForm, - actions = [], - i, html, defaultUrl, scope, postAction; + var host_id = params.host_id, + inventory_id = params.inventory_id, + generator = GenerateForm, + actions = [], + i, html, defaultUrl, scope, postAction; - html = "
\n"; - html += "
\n"; - html += "\n"; - html += "\n"; - html += "
\n"; - html += "
\n"; - html += "\n"; - html += "\n"; - html += "
\n"; - html += "
\n"; - html += "
\n"; - html += "
\n"; - html += "\n"; - html += "\n"; - html += "

(move selected groups)

\n"; - html += "
\n"; - html += "
\n"; + html = "
\n"; + html += "
\n"; + html += "\n"; + html += "\n"; + html += "
\n"; + html += "
\n"; + html += "\n"; + html += "\n"; + html += "
\n"; + html += "
\n"; + html += "
\n"; + html += "
\n"; + html += "\n"; + html += "\n"; + html += "

(move selected groups)

\n"; + html += "
\n"; + html += "
\n"; - defaultUrl = GetBasePath('hosts') + host_id + '/'; - scope = generator.inject(null, { mode: 'edit', modal: true, related: false, html: html }); + defaultUrl = GetBasePath('hosts') + host_id + '/'; + scope = generator.inject(null, { mode: 'edit', modal: true, related: false, html: html }); - for (i=0; i < scope.hosts.length; i++) { - if (scope.hosts[i].id === host_id) { - scope.host = scope.hosts[i]; - } - } + for (i=0; i < scope.hosts.length; i++) { + if (scope.hosts[i].id === host_id) { + scope.host = scope.hosts[i]; + } + } - scope.selectedGroups = null; - scope.assignedGroups = null; - scope.leftButtonDisabled = true; - scope.rightButtonDisabled = true; + scope.selectedGroups = null; + scope.assignedGroups = null; + scope.leftButtonDisabled = true; + scope.rightButtonDisabled = true; - scope.formModalActionLabel = 'Save'; - //scope.formModalHeader = 'Host Groups'; - scope.formModalHeader = scope.host.name + ' - Groups'; - scope.formModalCancelShow = true; - scope.formModalActionDisabled = true; + scope.formModalActionLabel = 'Save'; + //scope.formModalHeader = 'Host Groups'; + scope.formModalHeader = scope.host.name + ' - Groups'; + scope.formModalCancelShow = true; + scope.formModalActionDisabled = true; - $('#form-modal .btn-none').removeClass('btn-none').addClass('btn-success'); + $('#form-modal .btn-none').removeClass('btn-none').addClass('btn-success'); - if (scope.hostGroupChangeRemove) { - scope.hostGroupChangeRemove(); - } - scope.hostGroupChangeRemove = scope.$on('hostGroupChange', function() { - actions.pop(); - if (actions.length === 0) { - postAction = function() { - setTimeout(function() { Wait('stop'); }, 500); - }; - HostsReload({ scope: scope, inventory_id: inventory_id, group_id: scope.group_id , action: postAction }); - } - }); + if (scope.hostGroupChangeRemove) { + scope.hostGroupChangeRemove(); + } + scope.hostGroupChangeRemove = scope.$on('hostGroupChange', function() { + actions.pop(); + if (actions.length === 0) { + postAction = function() { + setTimeout(function() { Wait('stop'); }, 500); + }; + HostsReload({ scope: scope, inventory_id: inventory_id, group_id: scope.group_id , action: postAction }); + } + }); - // Save changes - scope.formModalAction = function() { - var i, j, found; + // Save changes + scope.formModalAction = function() { + var i, j, found; - $('#form-modal').modal('hide'); - Wait('start'); + $('#form-modal').modal('hide'); + Wait('start'); - // removed host from deleted groups - for (i=0; i < scope.original_groups.length; i++) { - found = false; - for (j=0; j < scope.host_groups.length; j++) { - if (scope.original_groups[i].id === scope.host_groups[j].id) { - found = true; - } - } - if (!found) { - // group was removed - actions.push({ group_id: scope.original_groups[i].id , action: 'delete' }); - Rest.setUrl(GetBasePath('groups') + scope.original_groups[i].id + '/hosts/'); - Rest.post({ id: host_id, disassociate: 1 }) - .success( function() { - scope.$emit('hostGroupChange'); - }) - .error( function(data, status) { - scope.$emit('hostGroupChange'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Attempt to remove host from group ' + scope.original_groups[i].name + - ' failed. POST returned status: ' + status }); - }); - } - } + // removed host from deleted groups + for (i=0; i < scope.original_groups.length; i++) { + found = false; + for (j=0; j < scope.host_groups.length; j++) { + if (scope.original_groups[i].id === scope.host_groups[j].id) { + found = true; + } + } + if (!found) { + // group was removed + actions.push({ group_id: scope.original_groups[i].id , action: 'delete' }); + Rest.setUrl(GetBasePath('groups') + scope.original_groups[i].id + '/hosts/'); + Rest.post({ id: host_id, disassociate: 1 }) + .success( function() { + scope.$emit('hostGroupChange'); + }) + .error( function(data, status) { + scope.$emit('hostGroupChange'); + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Attempt to remove host from group ' + scope.original_groups[i].name + + ' failed. POST returned status: ' + status }); + }); + } + } - // add host to new groups - for (i=0; i < scope.host_groups.length; i++) { - found = false; - for (j=0; j < scope.original_groups.length; j++) { - if (scope.original_groups[j].id === scope.host_groups[i].id) { - found = true; - } - } - if (!found) { - // group was added - actions.push({ group_id: scope.host_groups[i].id , action: 'add' }); - Rest.setUrl(GetBasePath('groups') + scope.host_groups[i].id + '/hosts/'); - Rest.post(scope.host) - .success( function() { - scope.$emit('hostGroupChange'); - }) - .error( function(data, status) { - scope.$emit('hostGroupChange'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Attempt to add host to group ' + scope.host_groups[i].name + - ' failed. POST returned status: ' + status }); - }); - } - } - }; + // add host to new groups + for (i=0; i < scope.host_groups.length; i++) { + found = false; + for (j=0; j < scope.original_groups.length; j++) { + if (scope.original_groups[j].id === scope.host_groups[i].id) { + found = true; + } + } + if (!found) { + // group was added + actions.push({ group_id: scope.host_groups[i].id , action: 'add' }); + Rest.setUrl(GetBasePath('groups') + scope.host_groups[i].id + '/hosts/'); + Rest.post(scope.host) + .success( function() { + scope.$emit('hostGroupChange'); + }) + .error( function(data, status) { + scope.$emit('hostGroupChange'); + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Attempt to add host to group ' + scope.host_groups[i].name + + ' failed. POST returned status: ' + status }); + }); + } + } + }; - scope.leftChange = function() { - // Select/deselect on available groups list - if (scope.selectedGroups !== null && scope.selectedGroups.length > 0) { - scope.assignedGroups = null; - scope.leftButtonDisabled = true; - scope.rightButtonDisabled = false; - } - else { - scope.rightButtonDisabled = true; - } - }; + scope.leftChange = function() { + // Select/deselect on available groups list + if (scope.selectedGroups !== null && scope.selectedGroups.length > 0) { + scope.assignedGroups = null; + scope.leftButtonDisabled = true; + scope.rightButtonDisabled = false; + } + else { + scope.rightButtonDisabled = true; + } + }; - scope.rightChange = function() { - // Select/deselect made on host groups list - if (scope.assignedGroups !== null && scope.assignedGroups.length > 0) { - scope.selectedGroups = null; - scope.leftButtonDisabled = false; - scope.rightButtonDisabled = true; - } - else { - scope.leftButtonDisabled = true; - } - }; + scope.rightChange = function() { + // Select/deselect made on host groups list + if (scope.assignedGroups !== null && scope.assignedGroups.length > 0) { + scope.selectedGroups = null; + scope.leftButtonDisabled = false; + scope.rightButtonDisabled = true; + } + else { + scope.leftButtonDisabled = true; + } + }; - scope.moveLeft = function() { - // Remove selected groups from the list of assigned groups + scope.moveLeft = function() { + // Remove selected groups from the list of assigned groups - var i, j, found, placed; + var i, j, found, placed; - for (i=0; i < scope.assignedGroups.length; i++){ - for (j=0 ; j < scope.host_groups.length; j++) { - if (scope.host_groups[j].id === scope.assignedGroups[i].id) { - scope.host_groups.splice(j,1); - break; - } - } - } - for (i=0; i < scope.assignedGroups.length; i++){ - found = false; - for (j=0; j < scope.available_groups.length && !found; j++){ - if (scope.available_groups[j].id === scope.assignedGroups[i].id) { - found=true; - } - } - if (!found) { - placed = false; - for (j=0; j < scope.available_groups.length && !placed; j++){ - if (j === 0 && scope.assignedGroups[i].name.toLowerCase() < scope.available_groups[j].name.toLowerCase()) { - // prepend to the beginning of the array - placed=true; - scope.available_groups.unshift(scope.assignedGroups[i]); - } - else if (j + 1 < scope.available_groups.length) { - if (scope.assignedGroups[i].name.toLowerCase() > scope.available_groups[j].name.toLowerCase() && - scope.assignedGroups[i].name.toLowerCase() < scope.available_groups[j + 1].name.toLowerCase() ) { - // insert into the middle of the array - placed = true; - scope.available_groups.splice(j + 1, 0, scope.assignedGroups[i]); - } - } - } - if (!placed) { - // append to the end of the array - scope.available_groups.push(scope.assignedGroups[i]); - } - } - } - scope.assignedGroups = null; - scope.leftButtonDisabled = true; - scope.rightButtonDisabled = true; - scope.formModalActionDisabled = false; - }; + for (i=0; i < scope.assignedGroups.length; i++){ + for (j=0 ; j < scope.host_groups.length; j++) { + if (scope.host_groups[j].id === scope.assignedGroups[i].id) { + scope.host_groups.splice(j,1); + break; + } + } + } + for (i=0; i < scope.assignedGroups.length; i++){ + found = false; + for (j=0; j < scope.available_groups.length && !found; j++){ + if (scope.available_groups[j].id === scope.assignedGroups[i].id) { + found=true; + } + } + if (!found) { + placed = false; + for (j=0; j < scope.available_groups.length && !placed; j++){ + if (j === 0 && scope.assignedGroups[i].name.toLowerCase() < scope.available_groups[j].name.toLowerCase()) { + // prepend to the beginning of the array + placed=true; + scope.available_groups.unshift(scope.assignedGroups[i]); + } + else if (j + 1 < scope.available_groups.length) { + if (scope.assignedGroups[i].name.toLowerCase() > scope.available_groups[j].name.toLowerCase() && + scope.assignedGroups[i].name.toLowerCase() < scope.available_groups[j + 1].name.toLowerCase() ) { + // insert into the middle of the array + placed = true; + scope.available_groups.splice(j + 1, 0, scope.assignedGroups[i]); + } + } + } + if (!placed) { + // append to the end of the array + scope.available_groups.push(scope.assignedGroups[i]); + } + } + } + scope.assignedGroups = null; + scope.leftButtonDisabled = true; + scope.rightButtonDisabled = true; + scope.formModalActionDisabled = false; + }; - scope.moveRight = function() { - // Remove selected groups from list of available groups + scope.moveRight = function() { + // Remove selected groups from list of available groups - var i, j, found, placed; + var i, j, found, placed; - for (i=0; i < scope.selectedGroups.length; i++){ - for (j=0 ; j < scope.available_groups.length; j++) { - if (scope.available_groups[j].id === scope.selectedGroups[i].id) { - scope.available_groups.splice(j,1); - break; - } - } - } - for (i=0; i < scope.selectedGroups.length; i++){ - found = false; - for (j=0; j < scope.host_groups.length && !found; j++){ - if (scope.host_groups[j].id === scope.selectedGroups[i].id) { - found=true; - } - } - if (!found) { - placed = false; - for (j=0; j < scope.host_groups.length && !placed; j++) { - if (j === 0 && scope.selectedGroups[i].name.toLowerCase() < scope.host_groups[j].name.toLowerCase()) { - // prepend to the beginning of the array - placed=true; - scope.host_groups.unshift(scope.selectedGroups[i]); - } - else if (j + 1 < scope.host_groups.length) { - if (scope.selectedGroups[i].name.toLowerCase() > scope.host_groups[j].name.toLowerCase() && - scope.selectedGroups[i].name.toLowerCase() < scope.host_groups[j + 1].name.toLowerCase() ) { - // insert into the middle of the array - placed = true; - scope.host_groups.splice(j + 1, 0, scope.selectedGroups[i]); - } - } - } - if (!placed) { - // append to the end of the array - scope.host_groups.push(scope.selectedGroups[i]); - } - } - } - scope.selectedGroups = null; - scope.leftButtonDisabled = true; - scope.rightButtonDisabled = true; - scope.formModalActionDisabled = false; - }; + for (i=0; i < scope.selectedGroups.length; i++){ + for (j=0 ; j < scope.available_groups.length; j++) { + if (scope.available_groups[j].id === scope.selectedGroups[i].id) { + scope.available_groups.splice(j,1); + break; + } + } + } + for (i=0; i < scope.selectedGroups.length; i++){ + found = false; + for (j=0; j < scope.host_groups.length && !found; j++){ + if (scope.host_groups[j].id === scope.selectedGroups[i].id) { + found=true; + } + } + if (!found) { + placed = false; + for (j=0; j < scope.host_groups.length && !placed; j++) { + if (j === 0 && scope.selectedGroups[i].name.toLowerCase() < scope.host_groups[j].name.toLowerCase()) { + // prepend to the beginning of the array + placed=true; + scope.host_groups.unshift(scope.selectedGroups[i]); + } + else if (j + 1 < scope.host_groups.length) { + if (scope.selectedGroups[i].name.toLowerCase() > scope.host_groups[j].name.toLowerCase() && + scope.selectedGroups[i].name.toLowerCase() < scope.host_groups[j + 1].name.toLowerCase() ) { + // insert into the middle of the array + placed = true; + scope.host_groups.splice(j + 1, 0, scope.selectedGroups[i]); + } + } + } + if (!placed) { + // append to the end of the array + scope.host_groups.push(scope.selectedGroups[i]); + } + } + } + scope.selectedGroups = null; + scope.leftButtonDisabled = true; + scope.rightButtonDisabled = true; + scope.formModalActionDisabled = false; + }; - // Load the host's current list of groups - scope.host_groups = []; - scope.original_groups = []; - scope.available_groups = []; - Rest.setUrl(scope.host.related.groups + '?order_by=name'); - Rest.get() - .success( function(data) { - var i, j, found; - for (i=0; i < data.results.length; i++) { - scope.host_groups.push({ - id: data.results[i].id, - name: data.results[i].name, - description: data.results[i].description - }); - scope.original_groups.push({ - id: data.results[i].id, - name: data.results[i].name, - description: data.results[i].description - }); - } - for (i=0; i < scope.inventory_groups.length; i++) { - found = false; - for (j=0; j < scope.host_groups.length; j++) { - if (scope.inventory_groups[i].id === scope.host_groups[j].id) { - found = true; - } - } - if (!found) { - scope.available_groups.push(scope.inventory_groups[i]); - } - } - }) - .error( function(data, status) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get current groups for host: ' + host_id + '. GET returned: ' + status }); - }); + // Load the host's current list of groups + scope.host_groups = []; + scope.original_groups = []; + scope.available_groups = []; + Rest.setUrl(scope.host.related.groups + '?order_by=name'); + Rest.get() + .success( function(data) { + var i, j, found; + for (i=0; i < data.results.length; i++) { + scope.host_groups.push({ + id: data.results[i].id, + name: data.results[i].name, + description: data.results[i].description + }); + scope.original_groups.push({ + id: data.results[i].id, + name: data.results[i].name, + description: data.results[i].description + }); + } + for (i=0; i < scope.inventory_groups.length; i++) { + found = false; + for (j=0; j < scope.host_groups.length; j++) { + if (scope.inventory_groups[i].id === scope.host_groups[j].id) { + found = true; + } + } + if (!found) { + scope.available_groups.push(scope.inventory_groups[i]); + } + } + }) + .error( function(data, status) { + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Failed to get current groups for host: ' + host_id + '. GET returned: ' + status }); + }); - if (scope.removeHostsReload) { - scope.removeHostsReload(); - } - scope.removeHostsReload = scope.$on('hostsReload', function() { - HostsReload(params); - }); + if (scope.removeHostsReload) { + scope.removeHostsReload(); + } + scope.removeHostsReload = scope.$on('hostsReload', function() { + HostsReload(params); + }); - if (!scope.$$phase) { - scope.$digest(); - } - }; - }]); + if (!scope.$$phase) { + scope.$digest(); + } + }; + }]); diff --git a/awx/ui/client/src/helpers/Jobs.js b/awx/ui/client/src/helpers/Jobs.js index e59afd9f82..7cab25fa9f 100644 --- a/awx/ui/client/src/helpers/Jobs.js +++ b/awx/ui/client/src/helpers/Jobs.js @@ -476,11 +476,11 @@ export default if (job.status === 'pending' || job.status === 'running' || job.status === 'waiting') { url = job.related.cancel; action_label = 'cancel'; - hdr = 'Cancel Job'; + hdr = 'Cancel'; } else { url = job.url; action_label = 'delete'; - hdr = 'Delete Job'; + hdr = 'Delete'; } action = function () { @@ -537,11 +537,11 @@ export default scope.removeCancelJob(); } scope.removeCancelJob = scope.$on('CancelJob', function() { - var body; - body = (action_label === 'cancel' || job.status === 'new') ? "Submit the request to cancel" : "Delete"; + var cancelBody = "
Submit the request to cancel?
"; + var deleteBody = "
Are you sure you want to delete the job below?
#" + id + " " + job.name + "
"; Prompt({ hdr: hdr, - body: "
" + body + " job #" + id + " " + job.name + "?
", + body: (action_label === 'cancel' || job.status === 'new') ? cancelBody : deleteBody, action: action, actionText: (action_label === 'cancel' || job.status === 'new') ? "YES" : "DELETE" }); diff --git a/awx/ui/client/src/lists/AllJobs.js b/awx/ui/client/src/lists/AllJobs.js index 518f1baf34..eb15a74991 100644 --- a/awx/ui/client/src/lists/AllJobs.js +++ b/awx/ui/client/src/lists/AllJobs.js @@ -27,7 +27,7 @@ export default }, status: { label: 'Status', - columnClass: 'col-lg-2 col-md-2 col-sm-2 col-xs-2', + columnClass: 'col-lg-2 col-md-2 col-sm-2 col-xs-3', awToolTip: "{{ all_job.status_tip }}", awTipPlacement: "top", dataTitle: "{{ all_job.status_popover_title }}", @@ -50,7 +50,7 @@ export default noLink: true, searchable: false, filter: "longDate", - columnClass: "col-lg-2 col-md-2 hidden-xs", + columnClass: "col-lg-2 col-md-2 col-sm-2 hidden-xs", key: true, desc: true }, @@ -66,7 +66,7 @@ export default }, name: { label: 'Name', - columnClass: 'col-md-3 col-sm-4 col-xs-4', + columnClass: 'col-lg-3 col-md-3 col-sm-3 col-xs-3', ngClick: "viewJobLog(all_job.id, all_job.nameHref)", defaultSearchField: true, awToolTip: "{{ all_job.name | sanitize }}", @@ -86,8 +86,15 @@ export default fieldActions: { - columnClass: 'col-lg-2 col-md-3 col-sm-4 col-xs-4', + columnClass: 'col-lg-2 col-md-2 col-sm-3 col-xs-4', + stdout: { + mode: 'all', + href: '/#/jobs/{{ all_job.id }}/stdout', + awToolTip: 'View standard output', + dataPlacement: 'top', + ngShow: "all_job.type == 'job'" + }, submit: { icon: 'icon-rocket', mode: 'all', @@ -109,13 +116,6 @@ export default awToolTip: 'Delete the job', dataPlacement: 'top', ngShow: "all_job.status !== 'running' && all_job.status !== 'waiting' && all_job.status !== 'pending'" - }, - stdout: { - mode: 'all', - href: '/#/jobs/{{ all_job.id }}/stdout', - awToolTip: 'View standard output', - dataPlacement: 'top', - ngShow: "all_job.type == 'job'" } } }); diff --git a/awx/ui/client/src/lists/CompletedJobs.js b/awx/ui/client/src/lists/CompletedJobs.js index cc202fd689..ec7ba5d62b 100644 --- a/awx/ui/client/src/lists/CompletedJobs.js +++ b/awx/ui/client/src/lists/CompletedJobs.js @@ -3,7 +3,7 @@ * * All Rights Reserved *************************************************/ - + @@ -86,6 +86,13 @@ export default actions: { }, fieldActions: { + stdout: { + mode: 'all', + href: '/#/jobs/{{ completed_job.id }}/stdout', + awToolTip: 'View standard output', + dataPlacement: 'top', + ngShow: "completed_job.type == 'job'" + }, submit: { icon: 'icon-rocket', mode: 'all', @@ -99,19 +106,12 @@ export default ngClick: 'deleteJob(completed_job.id)', awToolTip: 'Delete the job', dataPlacement: 'top' - }, + } // job_details: { // mode: 'all', // ngClick: "viewJobLog(completed_job.id)", // awToolTip: 'View job details', // dataPlacement: 'top' - // }, - stdout: { - mode: 'all', - href: '/#/jobs/{{ completed_job.id }}/stdout', - awToolTip: 'View standard output', - dataPlacement: 'top', - ngShow: "completed_job.type == 'job'" - } + // } } }); diff --git a/awx/ui/client/src/lists/InventoryGroups.js b/awx/ui/client/src/lists/InventoryGroups.js index 1e20536753..53881f3d7c 100644 --- a/awx/ui/client/src/lists/InventoryGroups.js +++ b/awx/ui/client/src/lists/InventoryGroups.js @@ -154,13 +154,6 @@ export default "|| group.status == 'updating'", dataPlacement: "top" }, - edit: { - //label: 'Edit', - mode: 'all', - ngClick: "editGroup(group.id)", - awToolTip: 'Edit group', - dataPlacement: "top" - }, copy: { mode: 'all', ngClick: "copyGroup(group.id)", @@ -168,6 +161,13 @@ export default ngShow: "group.id > 0", dataPlacement: "top" }, + edit: { + //label: 'Edit', + mode: 'all', + ngClick: "editGroup(group.id)", + awToolTip: 'Edit group', + dataPlacement: "top" + }, "delete": { //label: 'Delete', mode: 'all', diff --git a/awx/ui/client/src/lists/InventoryHosts.js b/awx/ui/client/src/lists/InventoryHosts.js index 60a4d776aa..c6ec74dbfa 100644 --- a/awx/ui/client/src/lists/InventoryHosts.js +++ b/awx/ui/client/src/lists/InventoryHosts.js @@ -60,6 +60,12 @@ export default iconClass: "{{ 'fa icon-job-' + host.active_failures }}", id: 'active-failutes-action' }, + copy: { + mode: 'all', + ngClick: "copyHost(host.id)", + awToolTip: 'Copy or move host to another group', + dataPlacement: "top" + }, edit: { //label: 'Edit', ngClick: "editHost(host.id)", @@ -67,12 +73,6 @@ export default awToolTip: 'Edit host', dataPlacement: 'top' }, - copy: { - mode: 'all', - ngClick: "copyHost(host.id)", - awToolTip: 'Copy or move host to another group', - dataPlacement: "top" - }, "delete": { //label: 'Delete', ngClick: "deleteHost(host.id, host.name)", diff --git a/awx/ui/client/src/lists/JobTemplates.js b/awx/ui/client/src/lists/JobTemplates.js index 14f7d6c933..fb1245d83d 100644 --- a/awx/ui/client/src/lists/JobTemplates.js +++ b/awx/ui/client/src/lists/JobTemplates.js @@ -69,6 +69,14 @@ export default awToolTip: 'Schedule future job template runs', dataPlacement: 'top', }, + copy: { + label: 'Copy', + ngClick: "copyJobTemplate(job_template.id, job_template.name)", + "class": 'btn-danger btn-xs', + awToolTip: 'Copy template', + dataPlacement: 'top', + ngHide: 'job_template.summary_fields.can_copy===false' + }, edit: { label: 'Edit', ngClick: "editJobTemplate(job_template.id)", @@ -82,14 +90,6 @@ export default "class": 'btn-danger btn-xs', awToolTip: 'Delete template', dataPlacement: 'top', - }, - copy: { - label: 'Copy', - ngClick: "copyJobTemplate(job_template.id, job_template.name)", - "class": 'btn-danger btn-xs', - awToolTip: 'Copy template', - dataPlacement: 'top', - ngHide: 'job_template.summary_fields.can_copy===false' } } }); diff --git a/awx/ui/client/src/lists/Jobs.js b/awx/ui/client/src/lists/Jobs.js index 4ad8f7ac18..53b7c74669 100644 --- a/awx/ui/client/src/lists/Jobs.js +++ b/awx/ui/client/src/lists/Jobs.js @@ -3,7 +3,7 @@ * * All Rights Reserved *************************************************/ - + export default angular.module('JobsListDefinition', []) @@ -74,6 +74,13 @@ export default actions: { }, fieldActions: { + stdout: { + mode: 'all', + href: '/#/jobs/{{ job.id }}/stdout', + awToolTip: 'View standard output', + dataPlacement: 'top', + ngShow: "job.type == 'job'" + }, submit: { mode: 'all', icon: 'icon-rocket', @@ -95,13 +102,6 @@ export default awToolTip: 'Delete the job', dataPlacement: 'top', ngShow: "job.status != 'running'" - }, - stdout: { - mode: 'all', - href: '/#/jobs/{{ job.id }}/stdout', - awToolTip: 'View standard output', - dataPlacement: 'top', - ngShow: "job.type == 'job'" } } }); diff --git a/awx/ui/client/src/lists/ScanJobs.js b/awx/ui/client/src/lists/ScanJobs.js index 599a1f54ed..9fb1f3180e 100644 --- a/awx/ui/client/src/lists/ScanJobs.js +++ b/awx/ui/client/src/lists/ScanJobs.js @@ -56,6 +56,15 @@ export default awToolTip: 'Schedule future job template runs', dataPlacement: 'top', }, + copy: { + label: 'Copy', + ngClick: "copyJobTemplate(job_template.id, job_template.name)", + "class": 'btn-danger btn-xs', + awToolTip: 'Copy template', + dataPlacement: 'top', + ngHide: 'job_template.summary_fields.can_copy===false' + + }, edit: { label: 'Edit', ngClick: "editJobTemplate(job_template.id)", @@ -69,15 +78,6 @@ export default "class": 'btn-danger btn-xs', awToolTip: 'Delete template', dataPlacement: 'top', - }, - copy: { - label: 'Copy', - ngClick: "copyJobTemplate(job_template.id, job_template.name)", - "class": 'btn-danger btn-xs', - awToolTip: 'Copy template', - dataPlacement: 'top', - ngHide: 'job_template.summary_fields.can_copy===false' - } } }); diff --git a/awx/ui/client/src/lists/ScheduledJobs.js b/awx/ui/client/src/lists/ScheduledJobs.js index a293b15ce2..9b8b1c7c54 100644 --- a/awx/ui/client/src/lists/ScheduledJobs.js +++ b/awx/ui/client/src/lists/ScheduledJobs.js @@ -3,7 +3,7 @@ * * All Rights Reserved *************************************************/ - + export default angular.module('ScheduledJobsDefinition', ['sanitizeFilter']) @@ -32,7 +32,7 @@ export default label: 'Next Run', noLink: true, searchable: false, - columnClass: "col-lg-2 col-md-2 hidden-xs", + columnClass: "col-lg-3 col-md-2 col-sm-3 hidden-xs", filter: "longDate", key: true }, @@ -55,7 +55,7 @@ export default }, name: { label: 'Name', - columnClass: 'col-md-3 col-sm-4 col-xs-4', + columnClass: 'col-lg-3 col-md-3 col-sm-3 col-xs-5', sourceModel: 'unified_job_template', sourceField: 'name', ngClick: "editSchedule(schedule.id)", @@ -68,6 +68,9 @@ export default actions: { }, fieldActions: { + + columnClass: 'col-lg-3 col-md-3 col-sm-3 col-xs-5', + "play": { mode: "all", ngClick: "toggleSchedule($event, schedule.id)", diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js index bc4e883719..e32a937051 100644 --- a/awx/ui/client/src/shared/form-generator.js +++ b/awx/ui/client/src/shared/form-generator.js @@ -1675,7 +1675,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat // Message for when a search returns no results. This should only get shown after a search is executed with no results. html += "
\n"; - html += "
No records matched your search.
\n"; + html += "
No records matched your search.
\n"; html += "
\n"; // Show the "no items" box when loading is done and the user isn't actively searching and there are no results diff --git a/awx/ui/client/src/shared/generator-helpers.js b/awx/ui/client/src/shared/generator-helpers.js index ddba7e9e63..54dd0bc839 100644 --- a/awx/ui/client/src/shared/generator-helpers.js +++ b/awx/ui/client/src/shared/generator-helpers.js @@ -705,8 +705,8 @@ angular.module('GeneratorHelpers', [systemStatus.name]) set = params.set, html = ''; html += "\n"; - html += "
\n"; - html += "\n"; return html; }; diff --git a/awx/ui/client/src/shared/list-generator/list-generator.factory.js b/awx/ui/client/src/shared/list-generator/list-generator.factory.js index 9de1e2acff..14d9102adb 100644 --- a/awx/ui/client/src/shared/list-generator/list-generator.factory.js +++ b/awx/ui/client/src/shared/list-generator/list-generator.factory.js @@ -382,7 +382,7 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate // Message for when a search returns no results. This should only get shown after a search is executed with no results. html += "
\n"; - html += "
No records matched your search.
\n"; + html += "
No records matched your search.
\n"; html += "
\n"; } diff --git a/awx/ui/client/src/shared/prompt/prompt.less b/awx/ui/client/src/shared/prompt/prompt.less index 7879374422..316a60f9fc 100644 --- a/awx/ui/client/src/shared/prompt/prompt.less +++ b/awx/ui/client/src/shared/prompt/prompt.less @@ -5,11 +5,15 @@ flex-wrap:wrap; flex-direction: row; padding: 15px 20px; + -webkit-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.25); + -moz-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.25); + box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.25); } .Prompt-header { display: flex; width: 100%; + margin-bottom: 25px; } .Prompt-title { @@ -33,13 +37,12 @@ height:20px; font-size: 20px; background-color:@default-bg; - color:@default-second-border; - transition: color 0.2s; + color:@default-icon; line-height:1; } .Prompt-exit:hover{ - color:@default-icon; + color:@default-icon-hov; } .Prompt-body { @@ -47,7 +50,7 @@ } .Prompt-bodyQuery { - padding: 15px 0px; + margin-bottom: 20px; color: @default-interface-txt; } @@ -58,7 +61,7 @@ .Prompt-footer { display: flex; justify-content: flex-end; - padding-top: 20px; + margin-top: 20px; width: 100%; } @@ -93,6 +96,10 @@ color: @btn-txt-sel; } +.Prompt-footerButton { + padding: 4px 8px; +} + .Prompt-footerButton + .Prompt-footerButton { margin-left: 20px; }