diff --git a/awx/ui/client/src/activity-stream/factories/build-anchor.factory.js b/awx/ui/client/src/activity-stream/factories/build-anchor.factory.js index f3ccd0b9b0..914b22c53a 100644 --- a/awx/ui/client/src/activity-stream/factories/build-anchor.factory.js +++ b/awx/ui/client/src/activity-stream/factories/build-anchor.factory.js @@ -20,14 +20,14 @@ export default function BuildAnchor($log, $filter) { if (activity.operation === 'create' || activity.operation === 'delete'){ // the API formats the changes.inventory field as str 'myInventoryName-PrimaryKey' var inventory_id = _.last(activity.changes.inventory.split('-')); - url += 'inventories/' + inventory_id + '/manage?group=' + activity.changes.id; + url += 'inventories/' + inventory_id + '/groups/edit/' + activity.changes.id; } else { - url += 'inventories/' + activity.summary_fields.inventory[0].id + '/manage?group=' + (activity.changes.id || activity.changes.object1_pk); + url += 'inventories/' + activity.summary_fields.inventory[0].id + '/groups/edit/' + (activity.changes.id || activity.changes.object1_pk); } break; case 'host': - url += 'home/hosts/' + obj.id; + url += 'hosts/' + obj.id; break; case 'job': url += 'jobs/' + obj.id; diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index e367c4d935..ccbf9b04ef 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -39,7 +39,7 @@ if ($basePath) { // Modules import portalMode from './portal-mode/main'; import systemTracking from './system-tracking/main'; -import inventories from './inventories/main'; +import inventoriesHosts from './inventories-hosts/main'; import inventoryScripts from './inventory-scripts/main'; import credentials from './credentials/main'; import credentialTypes from './credential-types/main'; @@ -104,7 +104,7 @@ var tower = angular.module('Tower', [ browserData.name, configuration.name, systemTracking.name, - inventories.name, + inventoriesHosts.name, inventoryScripts.name, credentials.name, credentialTypes.name, diff --git a/awx/ui/client/src/inventories/hosts/edit/host-edit.controller.js b/awx/ui/client/src/inventories-hosts/hosts/edit/host-edit.controller.js similarity index 94% rename from awx/ui/client/src/inventories/hosts/edit/host-edit.controller.js rename to awx/ui/client/src/inventories-hosts/hosts/edit/host-edit.controller.js index f467e8c62f..3cd6a00c28 100644 --- a/awx/ui/client/src/inventories/hosts/edit/host-edit.controller.js +++ b/awx/ui/client/src/inventories-hosts/hosts/edit/host-edit.controller.js @@ -5,8 +5,8 @@ *************************************************/ export default - ['$scope', '$state', '$stateParams', 'GenerateForm', 'ParseTypeChange', 'HostManageService', 'host', '$rootScope', - function($scope, $state, $stateParams, GenerateForm, ParseTypeChange, HostManageService, host, $rootScope){ + ['$scope', '$state', '$stateParams', 'GenerateForm', 'ParseTypeChange', 'HostsService', 'host', '$rootScope', + function($scope, $state, $stateParams, GenerateForm, ParseTypeChange, HostsService, host, $rootScope){ $scope.parseType = 'yaml'; $scope.formCancel = function(){ $state.go('^', null, {reload: true}); @@ -32,7 +32,7 @@ description: $scope.description, enabled: $scope.host.enabled }; - HostManageService.put(host).then(function(){ + HostsService.put(host).then(function(){ $state.go('.', null, {reload: true}); }); diff --git a/awx/ui/client/src/inventories/hosts/edit/main.js b/awx/ui/client/src/inventories-hosts/hosts/edit/main.js similarity index 100% rename from awx/ui/client/src/inventories/hosts/edit/main.js rename to awx/ui/client/src/inventories-hosts/hosts/edit/main.js diff --git a/awx/ui/client/src/inventories/hosts/host.form.js b/awx/ui/client/src/inventories-hosts/hosts/host.form.js similarity index 100% rename from awx/ui/client/src/inventories/hosts/host.form.js rename to awx/ui/client/src/inventories-hosts/hosts/host.form.js diff --git a/awx/ui/client/src/inventories/hosts/host.list.js b/awx/ui/client/src/inventories-hosts/hosts/host.list.js similarity index 98% rename from awx/ui/client/src/inventories/hosts/host.list.js rename to awx/ui/client/src/inventories-hosts/hosts/host.list.js index bf8ed8673e..865d3eb108 100644 --- a/awx/ui/client/src/inventories/hosts/host.list.js +++ b/awx/ui/client/src/inventories-hosts/hosts/host.list.js @@ -110,7 +110,7 @@ export default ['i18n', function(i18n) { awToolTip: "Create a new Smart Inventory from search results.", actionClass: 'btn List-buttonDefault', buttonContent: 'SMART INVENTORY', - ngShow: 'canAdd', + ngShow: 'canAdd && (hosts.length > 0 || !(searchTags | isEmpty))', dataPlacement: "top", ngDisabled: '!enableSmartInventoryButton' } diff --git a/awx/ui/client/src/inventories/hosts/hosts.partial.html b/awx/ui/client/src/inventories-hosts/hosts/hosts.partial.html similarity index 100% rename from awx/ui/client/src/inventories/hosts/hosts.partial.html rename to awx/ui/client/src/inventories-hosts/hosts/hosts.partial.html diff --git a/awx/ui/client/src/inventories/hosts/list/host-list.controller.js b/awx/ui/client/src/inventories-hosts/hosts/list/host-list.controller.js similarity index 95% rename from awx/ui/client/src/inventories/hosts/list/host-list.controller.js rename to awx/ui/client/src/inventories-hosts/hosts/list/host-list.controller.js index d88bfadeb3..3853d80462 100644 --- a/awx/ui/client/src/inventories/hosts/list/host-list.controller.js +++ b/awx/ui/client/src/inventories-hosts/hosts/list/host-list.controller.js @@ -7,7 +7,7 @@ function HostsList($scope, HostsList, $rootScope, GetBasePath, rbacUiControlService, Dataset, $state, $filter, Prompt, Wait, - HostManageService, SetStatus, canAdd) { + HostsService, SetStatus, canAdd) { let list = HostsList; @@ -73,7 +73,7 @@ function HostsList($scope, HostsList, $rootScope, GetBasePath, var action = function(){ delete $rootScope.promptActionBtnClass; Wait('start'); - HostManageService.delete(id).then(() => { + HostsService.delete(id).then(() => { $('#prompt-modal').modal('hide'); if (parseInt($state.params.host_id) === id) { $state.go("hosts", null, {reload: true}); @@ -102,7 +102,7 @@ function HostsList($scope, HostsList, $rootScope, GetBasePath, host.enabled = !host.enabled; - HostManageService.put(host).then(function(){ + HostsService.put(host).then(function(){ $state.go($state.current, null, {reload: true}); }); }; @@ -139,5 +139,5 @@ function HostsList($scope, HostsList, $rootScope, GetBasePath, export default ['$scope', 'HostsList', '$rootScope', 'GetBasePath', 'rbacUiControlService', 'Dataset', '$state', '$filter', 'Prompt', 'Wait', - 'HostManageService', 'SetStatus', 'canAdd', HostsList + 'HostsService', 'SetStatus', 'canAdd', HostsList ]; diff --git a/awx/ui/client/src/inventories/hosts/list/main.js b/awx/ui/client/src/inventories-hosts/hosts/list/main.js similarity index 100% rename from awx/ui/client/src/inventories/hosts/list/main.js rename to awx/ui/client/src/inventories-hosts/hosts/list/main.js diff --git a/awx/ui/client/src/inventories-hosts/hosts/main.js b/awx/ui/client/src/inventories-hosts/hosts/main.js new file mode 100644 index 0000000000..09a368a825 --- /dev/null +++ b/awx/ui/client/src/inventories-hosts/hosts/main.js @@ -0,0 +1,112 @@ +/************************************************* + * Copyright (c) 2017 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + + import hostEdit from './edit/main'; + import hostList from './list/main'; + import HostsList from './host.list'; + import HostsForm from './host.form'; + import { templateUrl } from '../../shared/template-url/template-url.factory'; + import { N_ } from '../../i18n'; + import ansibleFactsRoute from '../shared/ansible-facts/ansible-facts.route'; + import insightsRoute from '../inventories/insights/insights.route'; + import hostGroupsRoute from './related/groups/hosts-related-groups.route'; + import hostGroupsAssociateRoute from './related/groups/hosts-related-groups-associate.route'; + import hostGroups from './related/groups/main'; + +export default +angular.module('host', [ + hostEdit.name, + hostList.name, + hostGroups.name + ]) + .factory('HostsForm', HostsForm) + .factory('HostsList', HostsList) + .config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider', + function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) { + let stateDefinitions = stateDefinitionsProvider.$get(), + stateExtender = $stateExtenderProvider.$get(); + + let generateHostStates = function(){ + let hostTree = stateDefinitions.generateTree({ + parent: 'hosts', // top-most node in the generated tree (will replace this state definition) + modes: ['edit'], + list: 'HostsList', + form: 'HostsForm', + controllers: { + edit: 'HostEditController' + }, + breadcrumbs: { + edit: '{{breadcrumb.host_name}}' + }, + urls: { + list: '/hosts' + }, + data: { + activityStream: true, + activityStreamTarget: 'host' + }, + resolve: { + edit: { + host: ['Rest', '$stateParams', 'GetBasePath', + function(Rest, $stateParams, GetBasePath) { + let path = GetBasePath('hosts') + $stateParams.host_id; + Rest.setUrl(path); + return Rest.get(); + } + ] + }, + list: { + canAdd: ['rbacUiControlService', function(rbacUiControlService) { + return rbacUiControlService.canAdd('hosts') + .then(function(res) { + return res.canAdd; + }) + .catch(function() { + return false; + }); + }] + } + }, + views: { + '@': { + templateUrl: templateUrl('inventories-hosts/hosts/hosts'), + controller: 'HostListController' + } + }, + ncyBreadcrumb: { + label: N_('HOSTS') + } + }); + + let hostAnsibleFacts = _.cloneDeep(ansibleFactsRoute); + hostAnsibleFacts.name = 'hosts.edit.ansible_facts'; + + let hostInsights = _.cloneDeep(insightsRoute); + hostInsights.name = 'hosts.edit.insights'; + + return Promise.all([ + hostTree + ]).then((generated) => { + return { + states: _.reduce(generated, (result, definition) => { + return result.concat(definition.states); + }, [ + stateExtender.buildDefinition(hostAnsibleFacts), + stateExtender.buildDefinition(hostInsights), + stateExtender.buildDefinition(hostGroupsRoute), + stateExtender.buildDefinition(hostGroupsAssociateRoute) + ]) + }; + }); + }; + + $stateProvider.state({ + name: 'hosts', + url: '/hosts', + lazyLoad: () => generateHostStates() + }); + } + ]); diff --git a/awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups-associate.route.js b/awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups-associate.route.js new file mode 100644 index 0000000000..169a9d6b7a --- /dev/null +++ b/awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups-associate.route.js @@ -0,0 +1,33 @@ +export default { + name: 'hosts.edit.groups.associate', + squashSearchUrl: true, + url: '/associate?inventory_id', + ncyBreadcrumb:{ + skip:true + }, + views: { + 'modal@hosts.edit': { + templateProvider: function() { + return ``; + }, + controller: function($scope, $q, GroupsService, $state){ + $scope.associateGroups = function(selectedItems){ + var deferred = $q.defer(); + return $q.all( _.map(selectedItems, (id) => GroupsService.associateHost({id: parseInt($state.params.host_id)}, id)) ) + .then( () =>{ + deferred.resolve(); + }, (error) => { + deferred.reject(error); + }); + }; + } + } + }, + onExit: function($state) { + if ($state.transition) { + $('#associate-groups-modal').modal('hide'); + $('.modal-backdrop').remove(); + $('body').removeClass('modal-open'); + } + }, +}; diff --git a/awx/ui/client/src/inventories/host-groups/host-groups.controller.js b/awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups.controller.js similarity index 83% rename from awx/ui/client/src/inventories/host-groups/host-groups.controller.js rename to awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups.controller.js index 31fe1d236d..bd32646dcc 100644 --- a/awx/ui/client/src/inventories/host-groups/host-groups.controller.js +++ b/awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups.controller.js @@ -4,14 +4,14 @@ * All Rights Reserved *************************************************/ export default - ['$scope', '$rootScope', '$state', '$stateParams', 'HostGroupsList', 'InventoryUpdate', - 'HostManageService', 'CancelSourceUpdate', 'rbacUiControlService', 'GetBasePath', - 'GetHostsStatusMsg', 'Dataset', 'Find', 'QuerySet', 'inventoryData', 'host', - function($scope, $rootScope, $state, $stateParams, HostGroupsList, InventoryUpdate, - HostManageService, CancelSourceUpdate, rbacUiControlService, GetBasePath, - GetHostsStatusMsg, Dataset, Find, qs, inventoryData, host){ + ['$scope', '$rootScope', '$state', '$stateParams', 'HostsRelatedGroupsList', 'InventoryUpdate', + 'CancelSourceUpdate', 'rbacUiControlService', 'GetBasePath', + 'GetHostsStatusMsg', 'Dataset', 'Find', 'QuerySet', 'inventoryData', 'host', 'GroupsService', + function($scope, $rootScope, $state, $stateParams, HostsRelatedGroupsList, InventoryUpdate, + CancelSourceUpdate, rbacUiControlService, GetBasePath, + GetHostsStatusMsg, Dataset, Find, qs, inventoryData, host, GroupsService){ - let list = HostGroupsList; + let list = HostsRelatedGroupsList; init(); @@ -73,7 +73,7 @@ $state.go('.', null, {reload: true}); }); - HostManageService.disassociateGroup(host, $scope.disassociateGroup.id).then(() => { + GroupsService.disassociateHost(host.id, $scope.disassociateGroup.id).then(() => { $state.go($state.current, null, {reload: true}); $('#host-disassociate-modal').modal('hide'); $('body').removeClass('modal-open'); diff --git a/awx/ui/client/src/inventories/host-groups/host-groups.list.js b/awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups.list.js similarity index 97% rename from awx/ui/client/src/inventories/host-groups/host-groups.list.js rename to awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups.list.js index 5bb9c85ee3..103eeca93f 100644 --- a/awx/ui/client/src/inventories/host-groups/host-groups.list.js +++ b/awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups.list.js @@ -49,7 +49,7 @@ export default { ngClick: "associateGroup()", awToolTip: "Associate this host with a new group", actionClass: 'btn List-buttonSubmit', - buttonContent: '+ ADD GROUP', + buttonContent: '+ ASSOCIATE GROUP', ngShow: 'canAdd', dataPlacement: "top", } diff --git a/awx/ui/client/src/inventories/host-groups/host-groups.partial.html b/awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups.partial.html similarity index 88% rename from awx/ui/client/src/inventories/host-groups/host-groups.partial.html rename to awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups.partial.html index 81d3a90e85..35d250f4c2 100644 --- a/awx/ui/client/src/inventories/host-groups/host-groups.partial.html +++ b/awx/ui/client/src/inventories-hosts/hosts/related/groups/hosts-related-groups.partial.html @@ -5,7 +5,7 @@