diff --git a/awx/ui/client/src/inventories/ansible_facts/ansible_facts.controller.js b/awx/ui/client/src/inventories/ansible_facts/ansible_facts.controller.js new file mode 100644 index 0000000000..0fea8b1772 --- /dev/null +++ b/awx/ui/client/src/inventories/ansible_facts/ansible_facts.controller.js @@ -0,0 +1,27 @@ +/************************************************* + * Copyright (c) 2017 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +function AnsibleFacts($scope, Facts, ParseTypeChange, ParseVariableString) { + + function init() { + $scope.facts = ParseVariableString(Facts.data); + + $scope.parseType = 'yaml'; + ParseTypeChange({ + scope: $scope, + variable: 'facts', + parse_variable: 'parseType', + field_id: 'host_facts', + readOnly: true + }); + } + + init(); + +} + +export default ['$scope', 'Facts', 'ParseTypeChange', 'ParseVariableString', AnsibleFacts +]; diff --git a/awx/ui/client/src/inventories/ansible_facts/ansible_facts.partial.html b/awx/ui/client/src/inventories/ansible_facts/ansible_facts.partial.html new file mode 100644 index 0000000000..3a8cbce18b --- /dev/null +++ b/awx/ui/client/src/inventories/ansible_facts/ansible_facts.partial.html @@ -0,0 +1,10 @@ +
diff --git a/awx/ui/client/src/inventories/ansible_facts/main.js b/awx/ui/client/src/inventories/ansible_facts/main.js new file mode 100644 index 0000000000..dffa3f9c69 --- /dev/null +++ b/awx/ui/client/src/inventories/ansible_facts/main.js @@ -0,0 +1,11 @@ +/************************************************* + * Copyright (c) 2017 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import controller from './ansible_facts.controller'; + +export default +angular.module('AnsibleFacts', []) + .controller('AnsibleFactsController', controller); diff --git a/awx/ui/client/src/inventories/hosts/host.form.js b/awx/ui/client/src/inventories/hosts/host.form.js index efb64a4785..350e2c11cf 100644 --- a/awx/ui/client/src/inventories/hosts/host.form.js +++ b/awx/ui/client/src/inventories/hosts/host.form.js @@ -21,6 +21,8 @@ export default ['i18n', function(i18n) { formLabelSize: 'col-lg-3', formFieldSize: 'col-lg-9', iterator: 'host', + activeEditState: 'hosts.edit', + stateTree: 'hosts', headerFields:{ enabled: { class: 'Form-header-field', @@ -99,5 +101,13 @@ export default ['i18n', function(i18n) { ngShow: '(host.summary_fields.user_capabilities.edit || canAdd)' } }, + + related: { + ansible_facts: { + name: 'ansible_facts', + title: i18n._('Facts'), + skipGenerator: true + } + } }; }]; diff --git a/awx/ui/client/src/inventories/main.js b/awx/ui/client/src/inventories/main.js index f2dc2fc58e..d753bc8cd5 100644 --- a/awx/ui/client/src/inventories/main.js +++ b/awx/ui/client/src/inventories/main.js @@ -19,6 +19,7 @@ import InventoryList from './inventory.list'; import InventoryForm from './inventory.form'; import InventoryManageService from './inventory-manage.service'; import adHocRoute from './adhoc/adhoc.route'; +import ansibleFacts from './ansible_facts/main'; export default angular.module('inventory', [ adhoc.name, @@ -29,7 +30,8 @@ angular.module('inventory', [ inventoryCompletedJobs.name, inventoryAdd.name, inventoryEdit.name, - inventoryList.name + inventoryList.name, + ansibleFacts.name ]) .factory('InventoryForm', InventoryForm) .factory('InventoryList', InventoryList) @@ -222,6 +224,32 @@ angular.module('inventory', [ } }; + let relatedHostsAnsibleFacts = { + name: 'inventories.edit.hosts.edit.ansible_facts', + url: '/ansible_facts', + ncyBreadcrumb: { + label: N_("FACTS") + }, + views: { + 'related': { + controller: 'AnsibleFactsController', + templateUrl: templateUrl('inventories/ansible_facts/ansible_facts') + } + }, + resolve: { + Facts: ['$stateParams', 'GetBasePath', 'Rest', + function($stateParams, GetBasePath, Rest) { + let ansibleFactsUrl = GetBasePath('hosts') + $stateParams.host_id + '/ansible_facts'; + Rest.setUrl(ansibleFactsUrl); + return Rest.get() + .success(function(data) { + return data; + }); + } + ] + } + }; + return Promise.all([ basicInventoryAdd, basicInventoryEdit, @@ -267,64 +295,107 @@ angular.module('inventory', [ stateExtender.buildDefinition(adhocCredentialLookup), stateExtender.buildDefinition(listSchedules), stateExtender.buildDefinition(addSchedule), - stateExtender.buildDefinition(editSchedule) + stateExtender.buildDefinition(editSchedule), + stateExtender.buildDefinition(relatedHostsAnsibleFacts) ]) }; }); } - $stateProvider.state({ - name: 'hosts', - url: '/hosts', - lazyLoad: () => stateDefinitions.generateTree({ - parent: 'hosts', // top-most node in the generated tree (will replace this state definition) - modes: ['edit'], - list: 'HostsList', - form: 'HostsForm', - controllers: { - list: 'HostListController', - edit: 'HostEditController' - }, - urls: { - list: '/hosts' - }, - resolve: { - edit: { - host: ['Rest', '$stateParams', 'GetBasePath', - function(Rest, $stateParams, GetBasePath) { - let path = GetBasePath('hosts') + $stateParams.host_id; - Rest.setUrl(path); - return Rest.get(); - } - ] - } - }, - ncyBreadcrumb: { - label: N_('HOSTS') - }, - views: { - '@': { - templateUrl: templateUrl('inventories/inventories') - }, - 'list@hosts': { - templateProvider: function(HostsList, generateList) { - let html = generateList.build({ - list: HostsList, - mode: 'edit' - }); - return html; - }, - controller: 'HostListController' - } + 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: { + list: 'HostListController', + edit: 'HostEditController' + }, + urls: { + list: '/hosts' + }, + resolve: { + edit: { + host: ['Rest', '$stateParams', 'GetBasePath', + function(Rest, $stateParams, GetBasePath) { + let path = GetBasePath('hosts') + $stateParams.host_id; + Rest.setUrl(path); + return Rest.get(); + } + ] } - }) + }, + ncyBreadcrumb: { + label: N_('HOSTS') + }, + views: { + '@': { + templateUrl: templateUrl('inventories/inventories') + }, + 'list@hosts': { + templateProvider: function(HostsList, generateList) { + let html = generateList.build({ + list: HostsList, + mode: 'edit' + }); + return html; + }, + controller: 'HostListController' + } + } }); - $stateProvider.state({ - name: 'inventories', - url: '/inventories', - lazyLoad: () => generateInventoryStates() + let hostAnsibleFacts = { + name: 'hosts.edit.ansible_facts', + url: '/ansible_facts', + ncyBreadcrumb: { + label: N_("FACTS") + }, + views: { + 'related': { + controller: 'AnsibleFactsController', + templateUrl: templateUrl('inventories/ansible_facts/ansible_facts') + } + }, + resolve: { + Facts: ['$stateParams', 'GetBasePath', 'Rest', + function($stateParams, GetBasePath, Rest) { + let ansibleFactsUrl = GetBasePath('hosts') + $stateParams.host_id + '/ansible_facts'; + Rest.setUrl(ansibleFactsUrl); + return Rest.get() + .success(function(data) { + return data; + }); + } + ] + } + }; + + return Promise.all([ + hostTree + ]).then((generated) => { + return { + states: _.reduce(generated, (result, definition) => { + return result.concat(definition.states); + }, [ + stateExtender.buildDefinition(hostAnsibleFacts) + ]) + }; }); + }; + + $stateProvider.state({ + name: 'hosts', + url: '/hosts', + lazyLoad: () => generateHostStates() + }); + + $stateProvider.state({ + name: 'inventories', + url: '/inventories', + lazyLoad: () => generateInventoryStates() + }); } ]); diff --git a/awx/ui/client/src/inventories/related-hosts/related-host.form.js b/awx/ui/client/src/inventories/related-hosts/related-host.form.js index efb64a4785..07f6798e11 100644 --- a/awx/ui/client/src/inventories/related-hosts/related-host.form.js +++ b/awx/ui/client/src/inventories/related-hosts/related-host.form.js @@ -21,6 +21,8 @@ export default ['i18n', function(i18n) { formLabelSize: 'col-lg-3', formFieldSize: 'col-lg-9', iterator: 'host', + activeEditState: 'inventories.edit.hosts.edit', + stateTree: 'inventories.edit.hosts', headerFields:{ enabled: { class: 'Form-header-field', @@ -99,5 +101,13 @@ export default ['i18n', function(i18n) { ngShow: '(host.summary_fields.user_capabilities.edit || canAdd)' } }, + + related: { + ansible_facts: { + name: 'ansible_facts', + title: i18n._('Facts'), + skipGenerator: true + } + } }; }]; diff --git a/awx/ui/client/src/shared/stateDefinitions.factory.js b/awx/ui/client/src/shared/stateDefinitions.factory.js index 9b9ce3dbf5..f1bc9ba79c 100644 --- a/awx/ui/client/src/shared/stateDefinitions.factory.js +++ b/awx/ui/client/src/shared/stateDefinitions.factory.js @@ -554,53 +554,56 @@ function($injector, $stateExtender, $log, i18n) { function buildListNodes(field) { let states = []; - if(field && (field.listState || field.addState || field.editState)){ - if(field && field.listState){ - states.push(field.listState(field, formStateDefinition)); + if(!field.skipGenerator) { + if(field && (field.listState || field.addState || field.editState)){ + if(field && field.listState){ + states.push(field.listState(field, formStateDefinition)); + states = _.flatten(states); + } + if(field && field.addState){ + let formState = field.addState(field, formStateDefinition, params); + states.push(formState); + // intent here is to add lookup states for any add-forms + if(field.includeForm){ + let form = field.includeForm ? $injector.get(field.includeForm) : field; + states.push(that.generateLookupNodes(form, formState)); + } + states = _.flatten(states); + } + if(field && field.editState){ + let formState = field.editState(field, formStateDefinition, params); + states.push(formState); + // intent here is to add lookup states for any edit-forms + if(field.includeForm){ + let form = field.includeForm ? $injector.get(field.includeForm) : field; + states.push(that.generateLookupNodes(form, formState)); + states.push(that.generateFormListDefinitions(form, formState, params)); + } + states = _.flatten(states); + } + } + else if(field.iterator === 'notification'){ + states.push(buildNotificationState(field)); states = _.flatten(states); } - if(field && field.addState){ - let formState = field.addState(field, formStateDefinition, params); - states.push(formState); - // intent here is to add lookup states for any add-forms - if(field.includeForm){ - let form = field.includeForm ? $injector.get(field.includeForm) : field; - states.push(that.generateLookupNodes(form, formState)); + else{ + states.push(buildListDefinition(field)); + if (field.iterator === 'permission' && field.actions && field.actions.add) { + if (form.name === 'user' || form.name === 'team'){ + states.push(buildRbacUserTeamDirective()); + } + else { + states.push(buildRbacResourceDirective()); + } } - states = _.flatten(states); - } - if(field && field.editState){ - let formState = field.editState(field, formStateDefinition, params); - states.push(formState); - // intent here is to add lookup states for any edit-forms - if(field.includeForm){ - let form = field.includeForm ? $injector.get(field.includeForm) : field; - states.push(that.generateLookupNodes(form, formState)); - states.push(that.generateFormListDefinitions(form, formState, params)); - } - states = _.flatten(states); - } - } - else if(field.iterator === 'notification'){ - states.push(buildNotificationState(field)); - states = _.flatten(states); - } - else{ - states.push(buildListDefinition(field)); - if (field.iterator === 'permission' && field.actions && field.actions.add) { - if (form.name === 'user' || form.name === 'team'){ - states.push(buildRbacUserTeamDirective()); - } - else { - states.push(buildRbacResourceDirective()); - } - } - else if (field.iterator === 'user' && field.actions && field.actions.add) { - if(form.name === 'team' || form.name === 'organization') { - states.push(buildRbacUserDirective()); + else if (field.iterator === 'user' && field.actions && field.actions.add) { + if(form.name === 'team' || form.name === 'organization') { + states.push(buildRbacUserDirective()); + } } } } + states = _.flatten(states); return states; } @@ -679,7 +682,7 @@ function($injector, $stateExtender, $log, i18n) { if (field.search) { state.params[`${field.iterator}_search`].value = _.merge(state.params[`${field.iterator}_search`].value, field.search); } - + return state; } return _(form.related).map(buildListNodes).flatten().value();