diff --git a/awx/ui/static/js/app.js b/awx/ui/static/js/app.js index c2415e21e7..add7d38285 100644 --- a/awx/ui/static/js/app.js +++ b/awx/ui/static/js/app.js @@ -30,14 +30,15 @@ angular.module('ansible', [ 'InventoriesListDefinition', 'InventoryFormDefinition', 'InventoryHelper', - 'InventoryHostsFormDefinition', - 'InventoryGroupsFormDefinition', 'InventoryGroupsDefinition', + 'InventoryHostsDefinition', + 'HostsHelper', 'AWFilters', 'HostFormDefinition', 'HostListDefinition', 'GroupFormDefinition', 'GroupListDefinition', + 'GroupsHelper', 'TeamsListDefinition', 'TeamFormDefinition', 'TeamHelper', diff --git a/awx/ui/static/js/controllers/Inventories.js b/awx/ui/static/js/controllers/Inventories.js index fd738c7e79..51814ca41c 100644 --- a/awx/ui/static/js/controllers/Inventories.js +++ b/awx/ui/static/js/controllers/Inventories.js @@ -314,31 +314,39 @@ InventoriesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$lo 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', 'GetBasePath', 'ParseTypeChange', 'Wait']; -function InventoriesEdit ($rootScope, $location, $routeParams, GenerateList, ClearScope, InventoryGroups, BuildTree, Wait) +function InventoriesEdit ($rootScope, $location, $routeParams, GenerateList, ClearScope, InventoryGroups, InventoryHosts, BuildTree, Wait, + UpdateStatusMsg, InjectHosts) { - ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior - //scope. + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. - var generator = GenerateList; - var list = InventoryGroups; - var base = $location.path().replace(/^\//,'').split('/')[0]; - var scope = $rootScope.$new(); - var groupScope; + var generator = GenerateList; + var list = InventoryGroups; + var base = $location.path().replace(/^\//,'').split('/')[0]; + var scope = $rootScope.$new(); + var groupScope; - scope.$on('searchTreeReady', function(e, inventory_name, groups) { - // After the tree data loads, generate the groups list - groupScope = generator.inject(list, { mode: 'edit', id: 'groups-container', breadCrumbs: false, searchSize: 'col-lg-5' }); - Wait('stop'); - groupScope.groups = groups; - groupScope.inventory_name = inventory_name; - groupScope.inventory_id = $routeParams.inventory_id; - }); + scope.$on('searchTreeReady', function(e, inventory_name, groups) { + // After the tree data loads, generate the groups list + groupScope = generator.inject(list, { mode: 'edit', id: 'groups-container', breadCrumbs: false, searchSize: 'col-lg-5' }); + groupScope.groups = groups; + for (var i=0; i < groupScope.groups.length; i++) { + var stat = UpdateStatusMsg({ status: groupScope.groups[i].status }); + groupScope.groups[i].status_badge_class = stat['class']; + groupScope.groups[i].status_badge_tooltip = stat['tooltip']; + groupScope.groups[i].status = stat['status']; + } + groupScope.inventory_name = inventory_name; + groupScope.inventory_id = $routeParams.inventory_id; + InjectHosts({ scope: groupScope }); + Wait('stop'); + }); - BuildTree({ scope: scope, inventory_id: $routeParams.inventory_id }); + BuildTree({ scope: scope, inventory_id: $routeParams.inventory_id }); } -InventoriesEdit.$inject = [ '$rootScope','$location', '$routeParams', 'GenerateList', 'ClearScope', 'InventoryGroups', 'BuildTree', - 'Wait' +InventoriesEdit.$inject = [ '$rootScope','$location', '$routeParams', 'GenerateList', 'ClearScope', 'InventoryGroups', 'InventoryHosts', 'BuildTree', + 'Wait', 'UpdateStatusMsg', 'InjectHosts' ]; diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js index 94369c7423..caf68d7d20 100644 --- a/awx/ui/static/js/helpers/Groups.js +++ b/awx/ui/static/js/helpers/Groups.js @@ -10,7 +10,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'GroupListDefinition', 'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService', 'GroupsHelper', 'InventoryHelper', 'SelectionHelper', 'JobSubmissionHelper', 'RefreshHelper', - 'PromptDialog', 'InventorySummaryHelpDefinition', 'TreeSelector', 'CredentialsListDefinition' + 'PromptDialog', 'InventorySummaryHelpDefinition', 'CredentialsListDefinition' ]) .factory('GetSourceTypeOptions', [ 'Rest', 'ProcessErrors', 'GetBasePath', function(Rest, ProcessErrors, GetBasePath) { @@ -209,9 +209,9 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' }]) .factory('GroupsList', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupList', 'GenerateList', - 'Prompt', 'SearchInit', 'PaginateInit', 'ProcessErrors', 'GetBasePath', 'GroupsAdd', 'SelectionInit', 'BuildTree', + 'Prompt', 'SearchInit', 'PaginateInit', 'ProcessErrors', 'GetBasePath', 'GroupsAdd', 'SelectionInit', function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupList, GenerateList, Prompt, SearchInit, PaginateInit, - ProcessErrors, GetBasePath, GroupsAdd, SelectionInit, BuildTree) { + ProcessErrors, GetBasePath, GroupsAdd, SelectionInit) { return function(params) { // build and present the list of groups we can add to an existing group @@ -300,23 +300,23 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' scope.removeModalClosed(); } scope.removeModalClosed = scope.$on('modalClosed', function() { - BuildTree({ + /*BuildTree({ scope: scope, inventory_id: inventory_id, emit_on_select: 'NodeSelect', target_id: 'search-tree-container', refresh: true, moveable: true - }); + });*/ }); } }]) .factory('InventoryStatus', [ '$rootScope', '$routeParams', 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventorySummary', 'GenerateList', 'ClearScope', 'SearchInit', 'PaginateInit', 'Refresh', 'InventoryUpdate', 'GroupsEdit', 'HelpDialog', - 'InventorySummaryHelp', 'BuildTree', 'ClickNode', 'HostsStatusMsg', 'UpdateStatusMsg', 'ViewUpdateStatus', 'Wait', + 'InventorySummaryHelp', 'ClickNode', 'HostsStatusMsg', 'UpdateStatusMsg', 'ViewUpdateStatus', 'Wait', function($rootScope, $routeParams, Rest, Alert, ProcessErrors, GetBasePath, FormatDate, InventorySummary, GenerateList, ClearScope, - SearchInit, PaginateInit, Refresh, InventoryUpdate, GroupsEdit, HelpDialog, InventorySummaryHelp, BuildTree, ClickNode, + SearchInit, PaginateInit, Refresh, InventoryUpdate, GroupsEdit, HelpDialog, InventorySummaryHelp, ClickNode, HostsStatusMsg, UpdateStatusMsg, ViewUpdateStatus, Wait) { return function(params) { //Build a summary of a given inventory @@ -522,7 +522,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' // Respond to refresh button scope.refresh = function() { - scope.search(list.iterator, false, true); + /*scope.search(list.iterator, false, true); BuildTree({ scope: scope, inventory_id: scope['inventory_id'], @@ -530,7 +530,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' target_id: 'search-tree-container', refresh: true, moveable: true - }); + });*/ } // Start the update process @@ -584,9 +584,9 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' }]) .factory('GroupsAdd', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', - 'Prompt', 'ProcessErrors', 'GetBasePath', 'ParseTypeChange', 'GroupsEdit', 'BuildTree', 'ClickNode', 'Wait', + 'Prompt', 'ProcessErrors', 'GetBasePath', 'ParseTypeChange', 'GroupsEdit', 'ClickNode', 'Wait', function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, - GetBasePath, ParseTypeChange, GroupsEdit, BuildTree, ClickNode, Wait) { + GetBasePath, ParseTypeChange, GroupsEdit, ClickNode, Wait) { return function(params) { var inventory_id = params.inventory_id; @@ -664,7 +664,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' scope.formModalActionDisabled = false; scope.showGroupHelp = false; //get rid of the Hint $('#form-modal').modal('hide'); - BuildTree({ + /*BuildTree({ scope: scope, inventory_id: scope['inventory_id'], emit_on_select: 'NodeSelect', @@ -672,7 +672,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' refresh: true, moveable: true, group_id: data.id - }); + });*/ }) .error( function(data, status, headers, config) { Wait('stop'); @@ -1158,9 +1158,9 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' .factory('GroupsDelete', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', - 'Prompt', 'ProcessErrors', 'GetBasePath', 'BuildTree', 'Wait', 'ClickNode', + 'Prompt', 'ProcessErrors', 'GetBasePath', 'Wait', 'ClickNode', function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, - GetBasePath, BuildTree, Wait, ClickNode) { + GetBasePath, Wait, ClickNode) { return function(params) { // Delete the selected group node. Disassociates it from its parent. var scope = params.scope; @@ -1183,7 +1183,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' Rest.post({ id: group_id, disassociate: 1 }) .success( function(data, status, headers, config) { //DeleteNode({ selector: '#' + obj.attr('id') }); - BuildTree({ + /*BuildTree({ scope: scope, inventory_id: scope['inventory_id'], emit_on_select: 'NodeSelect', @@ -1191,7 +1191,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' refresh: true, id: parent.attr('id'), moveable: true - }); + });*/ $('#prompt-modal').off(); }) .error( function(data, status, headers, config) { diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js index 086d15a211..fbf61c425e 100644 --- a/awx/ui/static/js/helpers/Hosts.js +++ b/awx/ui/static/js/helpers/Hosts.js @@ -11,10 +11,37 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H 'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService', 'HostsHelper', 'InventoryHelper', 'RelatedSearchHelper','RelatedPaginateHelper', 'InventoryFormDefinition', 'SelectionHelper', 'HostGroupsFormDefinition', - 'InventoryHostsFormDefinition' ]) - + + .factory('HostsReload', [ 'Empty', 'InventoryHosts', 'GetBasePath', 'SearchInit', 'PaginateInit', + function(Empty, InventoryHosts, GetBasePath, SearchInit, PaginateInit) { + return function(params) { + + var group_id = params.group_id; + var scope = params.scope; + + var url = ( !Empty(group_id) ) ? GetBasePath('groups') + group_id + '/all_hosts/' : + GetBasePath('inventory') + params.inventory_id + '/hosts/'; + + SearchInit({ scope: scope, set: 'hosts', list: InventoryHosts, url: url }); + PaginateInit({ scope: scope, list: InventoryHosts, url: url }); + scope.search(InventoryHosts.iterator); + } + }]) + + .factory('InjectHosts', ['GenerateList', 'InventoryHosts', 'HostsReload', + function(GenerateList, InventoryHosts, HostsReload) { + return function(params) { + + var scope = params.scope; + + var generator = GenerateList; + generator.inject(InventoryHosts, { mode: 'edit', id: 'hosts-container', breadCrumbs: false, searchSize: 'col-lg-5' }); + HostsReload({ scope: scope, group_id: null }); + } + }]) + .factory('SetHostStatus', [ function() { return function(host) { // Set status related fields on a host object @@ -496,7 +523,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H } }]) - +/* .factory('HostsReload', ['$location', '$routeParams', 'SearchInit', 'PaginateInit', 'InventoryHostsForm', 'GetBasePath', 'Wait', 'SetHostStatus', function($location, $routeParams, SearchInit, PaginateInit, InventoryHostsForm, GetBasePath, Wait, SetHostStatus) { @@ -577,6 +604,8 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H } }]) +*/ + .factory('EditHostGroups', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm', 'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', function($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, diff --git a/awx/ui/static/js/lists/InventoryGroups.js b/awx/ui/static/js/lists/InventoryGroups.js index 7ba3d7d8e7..80ebd5264e 100644 --- a/awx/ui/static/js/lists/InventoryGroups.js +++ b/awx/ui/static/js/lists/InventoryGroups.js @@ -22,8 +22,8 @@ angular.module('InventoryGroupsDefinition', []) fields: { name: { + label: 'Group', key: true, - label: 'name', ngClick: "\{\{ 'GroupsEdit(' + group.id + ')' \}\}", //ngClass: "\{\{ 'level' + group.level \}\}", hasChildren: true @@ -103,13 +103,21 @@ angular.module('InventoryGroupsDefinition', []) label: 'Add', mode: 'all', icon: 'icon-plus', - 'class': "btn-sm", ngClick: "createGroup()", ngHide: "groupCreateHide", ngDisabled: 'grpBtnDisabled', - awToolTip: "Create a new top-level group", - dataPlacement: 'top', - iconSize: 'large' + awToolTip: "Create a new group", + dataPlacement: 'top' + }, + edit: { + label: 'Edit', + mode: 'all', + icon: 'icon-wrench', + 'class': "btn-sm", + ngHide: "groupEditHide", + ngDisabled: 'grpBtnDisabled', + awToolTip: "Edit inventory properties", + dataPlacement: 'top' }, refresh: { label: 'Refresh', @@ -118,18 +126,16 @@ angular.module('InventoryGroupsDefinition', []) mode: 'all', 'class': 'btn-sm', awToolTip: "Refresh the page", - ngClick: "refresh()", - iconSize: 'large' + ngClick: "refresh()" }, stream: { label: 'Activity', - 'class': "btn-sm activity-btn", + 'class': "activity-btn", ngClick: "showActivity()", awToolTip: "View Activity Stream", dataPlacement: "top", icon: "icon-comments-alt", mode: 'all', - iconSize: 'large', ngShow: "user_is_superuser" }, help: { @@ -142,7 +148,6 @@ angular.module('InventoryGroupsDefinition', []) //"
" + //"

Need help getting started creating your inventory?

Click here for help.

", "

Need help getting started creating your inventory?

Click here for help.

", - iconSize: 'large', ngClick: "showHelp()", id: "inventory-summary-help" } @@ -150,7 +155,7 @@ angular.module('InventoryGroupsDefinition', []) fieldActions: { group_update: { - label: 'Update', + label: 'Sync', icon: 'icon-cloud-download', "class": 'btn-xs btn-primary', ngClick: 'updateGroup(\{\{ group.id \}\})', diff --git a/awx/ui/static/js/lists/Jobs.js b/awx/ui/static/js/lists/Jobs.js index d4b5e898d5..501abf84f6 100644 --- a/awx/ui/static/js/lists/Jobs.js +++ b/awx/ui/static/js/lists/Jobs.js @@ -87,19 +87,6 @@ angular.module('JobsListDefinition', []) }, fieldActions: { - dropdown: { - type: 'DropDown', - label: 'View', - icon: 'icon-zoom-in', - 'class': 'btn-default btn-xs', - options: [ - { ngClick: "editJob(\{\{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}')", label: 'Status' }, - { ngClick: "viewEvents(\{{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}')", label: 'Events', - ngHide: "job.status == 'new'" }, - { ngClick: "viewSummary(\{{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}')", label: 'Host Summary', - ngHide: "job.status == 'new'" } - ] - }, rerun: { label: 'Launch', icon: 'icon-rocket', @@ -125,6 +112,19 @@ angular.module('JobsListDefinition', []) "class": 'btn-danger btn-xs delete-btn', awToolTip: 'Remove the selected job from the database', ngShow: "job.status != 'pending' && job.status != 'running' && job.status != 'waiting'" - } + }, + dropdown: { + type: 'DropDown', + label: 'View', + icon: 'icon-zoom-in', + 'class': 'btn-default btn-xs', + options: [ + { ngClick: "editJob(\{\{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}')", label: 'Status' }, + { ngClick: "viewEvents(\{{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}')", label: 'Events', + ngHide: "job.status == 'new'" }, + { ngClick: "viewSummary(\{{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}')", label: 'Host Summary', + ngHide: "job.status == 'new'" } + ] + }, } }); diff --git a/awx/ui/static/less/ansible-ui.less b/awx/ui/static/less/ansible-ui.less index 9c2f81780d..6fa7cf6277 100644 --- a/awx/ui/static/less/ansible-ui.less +++ b/awx/ui/static/less/ansible-ui.less @@ -8,6 +8,7 @@ */ @black: #171717; +@white: #FFF; @warning: #FF9900; @red: #da4f49; @red-hover: #AE3F3A; @@ -336,49 +337,46 @@ a:hover { } .site-footer { - width: 100%; - padding-top: 20px; - padding-bottom: 40px; - margin-top: 60px; - color: @grey; - text-align: center; - background-color: @black; - - a, - a:active, - a:visited { - margin-right: 15px; + width: 100%; + padding-top: 20px; + padding-bottom: 20px; + margin-top: 60px; color: @grey; - } + text-align: center; + background-color: @black; - a:hover { - color: @blue; - } + a, + a:active, + a:visited { + margin-right: 15px; + color: @grey; + } - .help { - font-weight: normal; - fon-size: 12px; - } + a:hover { + color: @white; + } - .social { - display: inline-block; - } + .help { + padding-top: 15px; + font-weight: normal; + } - .logo { - display: inline-block; - } + .logo { + display: inline-block; + } - .logo img { - max-width: 125px; - } + .logo img { + max-width: 125px; + } + + .copyright { + padding-top: 15px; + display: inline-block; + font-weight: normal; + text-align: center; + } } -.copyright { - display: inline-block; - font-size: 11px; - font-weight: normal; - text-align: center; -} .login-header { text-align: center; diff --git a/awx/ui/static/lib/ansible/InventoryTree.js b/awx/ui/static/lib/ansible/InventoryTree.js index 203ae1cf4f..c21b4eca30 100644 --- a/awx/ui/static/lib/ansible/InventoryTree.js +++ b/awx/ui/static/lib/ansible/InventoryTree.js @@ -5,7 +5,7 @@ * * InventoryTree.js * - * Build data for the tree selector table used on inventory detail page. + * Build data for the tree selector table used on inventory detail page. * */ @@ -197,7 +197,8 @@ angular.module('InventoryTree', ['Utilities', 'RestServices']) id: id, event_level: level, ngicon: (sorted[i].children.length > 0) ? 'icon-collapse-alt' : null, - related: { children: (sorted[i].children.length > 0) ? sorted[i].related.children : '' } + related: { children: (sorted[i].children.length > 0) ? sorted[i].related.children : '' }, + status: sorted[i].summary_fields.inventory_source.status } groups.push(group); id++; diff --git a/awx/ui/templates/ui/index.html b/awx/ui/templates/ui/index.html index 7f3db4683e..d544ddb2b0 100644 --- a/awx/ui/templates/ui/index.html +++ b/awx/ui/templates/ui/index.html @@ -62,8 +62,6 @@ - - @@ -83,9 +81,8 @@ - - + @@ -96,6 +93,8 @@ + + @@ -118,6 +117,8 @@ + + @@ -361,17 +362,9 @@