From b0acb590e6c373de248b52489170bd4c4a635925 Mon Sep 17 00:00:00 2001 From: Michael Abashian Date: Tue, 9 May 2017 20:55:06 -0400 Subject: [PATCH] Breadcrumb fixes and nested groups/hosts state refactoring --- awx/ui/client/src/app.js | 2 + .../adhoc/adhoc-credential.route.js | 53 +++ .../ansible_facts/ansible_facts.route.js | 27 ++ ...-inventory-completed-jobs-state.factory.js | 80 ----- .../completed_jobs/completed_jobs.route.js | 57 ++++ .../src/inventories/completed_jobs/main.js | 4 +- .../copy-move/copy-move-groups.controller.js | 5 +- .../copy-move/copy-move-hosts.controller.js | 5 +- .../inventories/copy-move/copy-move.route.js | 2 +- .../edit/inventory-edit.controller.js | 5 +- .../add/build-groups-add-state.factory.js | 46 --- .../groups/add/groups-add.route.js | 22 ++ .../client/src/inventories/groups/add/main.js | 2 - .../edit/build-groups-edit-state.factory.js | 93 ----- .../groups/edit/groups-edit.controller.js | 6 +- .../groups/edit/groups-edit.route.js | 25 ++ .../src/inventories/groups/edit/main.js | 2 - .../src/inventories/groups/groups.form.js | 13 +- .../list/build-groups-list-state.factory.js | 82 ----- .../groups/list/groups-list.controller.js | 5 - .../groups/list/groups-list.route.js | 63 ++++ .../src/inventories/groups/list/main.js | 2 - .../inventories/groups/nested-groups/main.js | 4 - .../nested-groups-add-state.factory.js | 46 --- .../nested-groups/nested-groups-add.route.js | 22 ++ .../nested-groups-list-state.factory.js | 92 ----- .../nested-groups-list.controller.js | 5 - .../nested-groups/nested-groups.form.js | 7 +- .../nested-groups/nested-groups.route.js | 64 ++++ .../inventories/groups/nested-hosts/main.js | 2 - .../nested-hosts/nested-hosts-add.route.js | 22 ++ .../nested-hosts/nested-hosts-edit.route.js | 30 ++ .../nested-hosts-list-state.factory.js | 79 ----- .../groups/nested-hosts/nested-hosts.form.js | 7 +- .../groups/nested-hosts/nested-hosts.route.js | 58 ++++ .../hosts/edit/host-edit.controller.js | 6 +- .../client/src/inventories/hosts/host.form.js | 9 +- .../smart-inventory/smart-inventory.form.js | 7 +- .../inventories/insights/insights.route.js | 27 ++ .../src/inventories/inventories.route.js | 34 ++ .../client/src/inventories/inventory.form.js | 25 +- awx/ui/client/src/inventories/main.js | 321 +++++------------- .../add/build-host-add-state.factory.js | 46 --- .../related-hosts/add/host-add.route.js | 22 ++ .../src/inventories/related-hosts/add/main.js | 2 - .../edit/build-host-edit-state.factory.js | 73 ---- .../related-hosts/edit/host-edit.route.js | 30 ++ .../inventories/related-hosts/edit/main.js | 2 - .../list/build-host-list-state.factory.js | 89 ----- .../inventories/related-hosts/list/main.js | 2 - .../related-hosts/related-host.form.js | 7 +- .../related-hosts/related-host.route.js | 69 ++++ .../add/build-sources-add-state.factory.js | 46 --- .../src/inventories/sources/add/main.js | 2 - .../sources/add/sources-add.route.js | 22 ++ .../edit/build-sources-edit-state.factory.js | 49 --- .../src/inventories/sources/edit/main.js | 2 - .../sources/edit/sources-edit.route.js | 27 ++ .../list/build-sources-list-state.factory.js | 82 ----- .../src/inventories/sources/list/main.js | 2 - .../schedule/sources-schedule-add.route.js | 16 + .../schedule/sources-schedule-edit.route.js | 15 + .../list/schedule/sources-schedule.route.js | 60 ++++ .../sources/list/sources-list.controller.js | 6 - .../sources/list/sources-list.route.js | 62 ++++ .../src/shared/stateDefinitions.factory.js | 33 +- 66 files changed, 964 insertions(+), 1270 deletions(-) create mode 100644 awx/ui/client/src/inventories/adhoc/adhoc-credential.route.js create mode 100644 awx/ui/client/src/inventories/ansible_facts/ansible_facts.route.js delete mode 100644 awx/ui/client/src/inventories/completed_jobs/build-inventory-completed-jobs-state.factory.js create mode 100644 awx/ui/client/src/inventories/completed_jobs/completed_jobs.route.js delete mode 100644 awx/ui/client/src/inventories/groups/add/build-groups-add-state.factory.js create mode 100644 awx/ui/client/src/inventories/groups/add/groups-add.route.js delete mode 100644 awx/ui/client/src/inventories/groups/edit/build-groups-edit-state.factory.js create mode 100644 awx/ui/client/src/inventories/groups/edit/groups-edit.route.js delete mode 100644 awx/ui/client/src/inventories/groups/list/build-groups-list-state.factory.js create mode 100644 awx/ui/client/src/inventories/groups/list/groups-list.route.js delete mode 100644 awx/ui/client/src/inventories/groups/nested-groups/nested-groups-add-state.factory.js create mode 100644 awx/ui/client/src/inventories/groups/nested-groups/nested-groups-add.route.js delete mode 100644 awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list-state.factory.js create mode 100644 awx/ui/client/src/inventories/groups/nested-groups/nested-groups.route.js create mode 100644 awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-add.route.js create mode 100644 awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-edit.route.js delete mode 100644 awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-list-state.factory.js create mode 100644 awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.route.js create mode 100644 awx/ui/client/src/inventories/insights/insights.route.js create mode 100644 awx/ui/client/src/inventories/inventories.route.js delete mode 100644 awx/ui/client/src/inventories/related-hosts/add/build-host-add-state.factory.js create mode 100644 awx/ui/client/src/inventories/related-hosts/add/host-add.route.js delete mode 100644 awx/ui/client/src/inventories/related-hosts/edit/build-host-edit-state.factory.js create mode 100644 awx/ui/client/src/inventories/related-hosts/edit/host-edit.route.js delete mode 100644 awx/ui/client/src/inventories/related-hosts/list/build-host-list-state.factory.js create mode 100644 awx/ui/client/src/inventories/related-hosts/related-host.route.js delete mode 100644 awx/ui/client/src/inventories/sources/add/build-sources-add-state.factory.js create mode 100644 awx/ui/client/src/inventories/sources/add/sources-add.route.js delete mode 100644 awx/ui/client/src/inventories/sources/edit/build-sources-edit-state.factory.js create mode 100644 awx/ui/client/src/inventories/sources/edit/sources-edit.route.js delete mode 100644 awx/ui/client/src/inventories/sources/list/build-sources-list-state.factory.js create mode 100644 awx/ui/client/src/inventories/sources/list/schedule/sources-schedule-add.route.js create mode 100644 awx/ui/client/src/inventories/sources/list/schedule/sources-schedule-edit.route.js create mode 100644 awx/ui/client/src/inventories/sources/list/schedule/sources-schedule.route.js create mode 100644 awx/ui/client/src/inventories/sources/list/sources-list.route.js diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index 0649023b54..11e5aca889 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -218,6 +218,8 @@ var tower = angular.module('Tower', [ $state.go('.', null, {reload: true}); }; + $rootScope.breadcrumb = {}; + function activateTab() { // Make the correct tab active var base = $location.path().replace(/^\//, '').split('/')[0]; diff --git a/awx/ui/client/src/inventories/adhoc/adhoc-credential.route.js b/awx/ui/client/src/inventories/adhoc/adhoc-credential.route.js new file mode 100644 index 0000000000..457e6288bb --- /dev/null +++ b/awx/ui/client/src/inventories/adhoc/adhoc-credential.route.js @@ -0,0 +1,53 @@ +export default { + searchPrefix: 'credential', + name: 'inventories.edit.adhoc.credential', + url: '/credential', + data: { + formChildState: true + }, + params: { + credential_search: { + value: { + page_size: '5' + }, + squash: true, + dynamic: true + } + }, + ncyBreadcrumb: { + skip: true + }, + views: { + 'related': { + templateProvider: function(ListDefinition, generateList) { + let list_html = generateList.build({ + mode: 'lookup', + list: ListDefinition, + input_type: 'radio' + }); + return `${list_html}`; + + } + } + }, + resolve: { + ListDefinition: ['CredentialList', function(CredentialList) { + let list = _.cloneDeep(CredentialList); + list.lookupConfirmText = 'SELECT'; + return list; + }], + Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', + (list, qs, $stateParams, GetBasePath) => { + let path = GetBasePath(list.name) || GetBasePath(list.basePath); + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ] + }, + onExit: function($state) { + if ($state.transition) { + $('#form-modal').modal('hide'); + $('.modal-backdrop').remove(); + $('body').removeClass('modal-open'); + } + } +}; diff --git a/awx/ui/client/src/inventories/ansible_facts/ansible_facts.route.js b/awx/ui/client/src/inventories/ansible_facts/ansible_facts.route.js new file mode 100644 index 0000000000..9ce2a18672 --- /dev/null +++ b/awx/ui/client/src/inventories/ansible_facts/ansible_facts.route.js @@ -0,0 +1,27 @@ +import {templateUrl} from '../../shared/template-url/template-url.factory'; +import { N_ } from '../../i18n'; + +export default { + 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; + }); + } + ] + } +}; diff --git a/awx/ui/client/src/inventories/completed_jobs/build-inventory-completed-jobs-state.factory.js b/awx/ui/client/src/inventories/completed_jobs/build-inventory-completed-jobs-state.factory.js deleted file mode 100644 index df06c8ede9..0000000000 --- a/awx/ui/client/src/inventories/completed_jobs/build-inventory-completed-jobs-state.factory.js +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ -import JobsListController from '../../jobs/jobs-list.controller'; -export default ['InventoryCompletedJobsList', '$stateExtender', 'templateUrl', '$injector', - function(InventoryCompletedJobsList, $stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - // searchPrefix: `${list.iterator}`, - name: `${formStateDefinition.name}.${list.iterator}s`, - url: `/${list.iterator}s`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - params: { - completed_job_search: { - value: { - or__job__inventory: '', - or__adhoccommand__inventory: '', - or__inventoryupdate__inventory_source__inventory: '' - }, - squash: '' - } - }, - views: { - 'related': { - templateProvider: function(FormDefinition, GenerateForm) { - let html = GenerateForm.buildCollection({ - mode: 'edit', - related: `${list.iterator}s`, - form: typeof(FormDefinition) === 'function' ? - FormDefinition() : FormDefinition - }); - return html; - }, - controller: JobsListController - } - }, - resolve: { - ListDefinition: () => { - return list; - }, - Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', - (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { - // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field - let path, interpolator; - if (GetBasePath(list.basePath)) { - path = GetBasePath(list.basePath); - } else { - interpolator = $interpolate(list.basePath); - path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); - } - - $stateParams[`${list.iterator}_search`].or__job__inventory = $stateParams.inventory_id; - $stateParams[`${list.iterator}_search`].or__adhoccommand__inventory = $stateParams.inventory_id; - $stateParams[`${list.iterator}_search`].or__inventoryupdate__inventory_source__inventory = $stateParams.inventory_id; - - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - // appy any default search parameters in form definition - if (field.search) { - state.params[`${field.iterator}_search`].value = _.merge(state.params[`${field.iterator}_search`].value, field.search); - } - - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/completed_jobs/completed_jobs.route.js b/awx/ui/client/src/inventories/completed_jobs/completed_jobs.route.js new file mode 100644 index 0000000000..62e2eec282 --- /dev/null +++ b/awx/ui/client/src/inventories/completed_jobs/completed_jobs.route.js @@ -0,0 +1,57 @@ +import { N_ } from '../../i18n'; + +export default { + name: "inventories.edit.completed_jobs", + url: "/completed_jobs", + params: { + completed_job_search: { + value: { + or__job__inventory:"", + or__adhoccommand__inventory:"", + or__inventoryupdate__inventory_source__inventory:"" + }, + squash:"" + } + }, + ncyBreadcrumb: { + parent: "inventories.edit", + label: N_("COMPLETED JOBS") + }, + views: { + 'related': { + templateProvider: function(FormDefinition, GenerateForm) { + let html = GenerateForm.buildCollection({ + mode: 'edit', + related: 'completed_jobs', + form: typeof(FormDefinition) === 'function' ? + FormDefinition() : FormDefinition + }); + return html; + }, + controller: 'JobsList' + } + }, + resolve: { + ListDefinition: ['InventoryCompletedJobsList', (InventoryCompletedJobsList) => { + return InventoryCompletedJobsList; + }], + Dataset: ['InventoryCompletedJobsList', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', + (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { + // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field + let path, interpolator; + if (GetBasePath(list.basePath)) { + path = GetBasePath(list.basePath); + } else { + interpolator = $interpolate(list.basePath); + path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); + } + + $stateParams[`${list.iterator}_search`].or__job__inventory = $stateParams.inventory_id; + $stateParams[`${list.iterator}_search`].or__adhoccommand__inventory = $stateParams.inventory_id; + $stateParams[`${list.iterator}_search`].or__inventoryupdate__inventory_source__inventory = $stateParams.inventory_id; + + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ] + } +}; diff --git a/awx/ui/client/src/inventories/completed_jobs/main.js b/awx/ui/client/src/inventories/completed_jobs/main.js index b34f919a78..50c073719e 100644 --- a/awx/ui/client/src/inventories/completed_jobs/main.js +++ b/awx/ui/client/src/inventories/completed_jobs/main.js @@ -5,9 +5,7 @@ *************************************************/ import list from './completed_jobs.list'; -import buildInventoryCompletedJobsState from './build-inventory-completed-jobs-state.factory'; export default angular.module('inventoryCompletedJobs', []) - .factory('InventoryCompletedJobsList', list) - .factory('buildInventoryCompletedJobsState', buildInventoryCompletedJobsState); + .factory('InventoryCompletedJobsList', list); diff --git a/awx/ui/client/src/inventories/copy-move/copy-move-groups.controller.js b/awx/ui/client/src/inventories/copy-move/copy-move-groups.controller.js index 2ebf91cc93..d982560725 100644 --- a/awx/ui/client/src/inventories/copy-move/copy-move-groups.controller.js +++ b/awx/ui/client/src/inventories/copy-move/copy-move-groups.controller.js @@ -5,11 +5,12 @@ *************************************************/ export default - ['$scope', '$state', '$stateParams', 'GroupManageService', 'CopyMoveGroupList', 'group', 'Dataset', - function($scope, $state, $stateParams, GroupManageService, CopyMoveGroupList, group, Dataset){ + ['$scope', '$state', '$stateParams', 'GroupManageService', 'CopyMoveGroupList', 'group', 'Dataset', '$rootScope', + function($scope, $state, $stateParams, GroupManageService, CopyMoveGroupList, group, Dataset, $rootScope){ var list = CopyMoveGroupList; $scope.item = group; + $rootScope.breadcrumb.copyMoveName = group.name; $scope.submitMode = $stateParams.groups === undefined ? 'move' : 'copy'; $scope.toggle_row = function(id){ // toggle off anything else currently selected diff --git a/awx/ui/client/src/inventories/copy-move/copy-move-hosts.controller.js b/awx/ui/client/src/inventories/copy-move/copy-move-hosts.controller.js index 8e347dc2c8..47120e472a 100644 --- a/awx/ui/client/src/inventories/copy-move/copy-move-hosts.controller.js +++ b/awx/ui/client/src/inventories/copy-move/copy-move-hosts.controller.js @@ -5,11 +5,12 @@ *************************************************/ export default - ['$scope', '$state', '$stateParams', 'HostManageService', 'CopyMoveGroupList', 'host', 'Dataset', - function($scope, $state, $stateParams, HostManageService, CopyMoveGroupList, host, Dataset){ + ['$scope', '$state', '$stateParams', 'HostManageService', 'CopyMoveGroupList', 'host', 'Dataset', '$rootScope', + function($scope, $state, $stateParams, HostManageService, CopyMoveGroupList, host, Dataset, $rootScope){ var list = CopyMoveGroupList; $scope.item = host; + $rootScope.breadcrumb.copyMoveName = host.name; $scope.submitMode = 'copy'; $scope.toggle_row = function(id){ // toggle off anything else currently selected diff --git a/awx/ui/client/src/inventories/copy-move/copy-move.route.js b/awx/ui/client/src/inventories/copy-move/copy-move.route.js index e68c6de633..bce74939c9 100644 --- a/awx/ui/client/src/inventories/copy-move/copy-move.route.js +++ b/awx/ui/client/src/inventories/copy-move/copy-move.route.js @@ -26,7 +26,7 @@ var copyMoveGroupRoute = { } }, ncyBreadcrumb: { - label: N_("COPY OR MOVE") + " {{item.name}}" + label: N_("COPY OR MOVE") + " {{breadcrumb.copyMoveName}}" }, resolve: { Dataset: ['CopyMoveGroupList', 'QuerySet', '$stateParams', 'GetBasePath', 'group', diff --git a/awx/ui/client/src/inventories/edit/inventory-edit.controller.js b/awx/ui/client/src/inventories/edit/inventory-edit.controller.js index 0558be203a..355b20735e 100644 --- a/awx/ui/client/src/inventories/edit/inventory-edit.controller.js +++ b/awx/ui/client/src/inventories/edit/inventory-edit.controller.js @@ -13,7 +13,7 @@ function InventoriesEdit($scope, $location, $stateParams, InventoryForm, Rest, ProcessErrors, ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON, - ParseVariableString, $state, OrgAdminLookup) { + ParseVariableString, $state, OrgAdminLookup, $rootScope) { // Inject dynamic view var defaultUrl = GetBasePath('inventory'), @@ -82,6 +82,7 @@ function InventoriesEdit($scope, $location, }); $scope.inventory_obj = data; + $rootScope.breadcrumb.inventory_name = data.name; $scope.name = data.name; }) .error(function(data, status) { @@ -127,5 +128,5 @@ export default ['$scope', '$location', '$stateParams', 'InventoryForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', - '$state', 'OrgAdminLookup', InventoriesEdit, + '$state', 'OrgAdminLookup', '$rootScope', InventoriesEdit, ]; diff --git a/awx/ui/client/src/inventories/groups/add/build-groups-add-state.factory.js b/awx/ui/client/src/inventories/groups/add/build-groups-add-state.factory.js deleted file mode 100644 index e44130ce22..0000000000 --- a/awx/ui/client/src/inventories/groups/add/build-groups-add-state.factory.js +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ - -import GroupAddController from './groups-add.controller'; - -export default ['$stateExtender', 'templateUrl', '$injector', - function($stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition, params) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - name: `${formStateDefinition.name}.${list.iterator}s.add`, - url: `/add`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - views: { - 'groupForm@inventories': { - templateProvider: function(GenerateForm, GroupForm) { - let form = GroupForm; - return GenerateForm.buildHTML(form, { - mode: 'add', - related: false - }); - }, - controller: GroupAddController - } - }, - resolve: { - 'FormDefinition': [params.form, function(definition) { - return definition; - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/groups/add/groups-add.route.js b/awx/ui/client/src/inventories/groups/add/groups-add.route.js new file mode 100644 index 0000000000..6e4a3ba974 --- /dev/null +++ b/awx/ui/client/src/inventories/groups/add/groups-add.route.js @@ -0,0 +1,22 @@ +import { N_ } from '../../../i18n'; + +export default { + name: "inventories.edit.groups.add", + url: "/add", + ncyBreadcrumb: { + parent: "inventories.edit.groups", + label: N_("CREATE GROUP") + }, + views: { + 'groupForm@inventories': { + templateProvider: function(GenerateForm, GroupForm) { + let form = GroupForm; + return GenerateForm.buildHTML(form, { + mode: 'add', + related: false + }); + }, + controller: 'GroupAddController' + } + }, +}; diff --git a/awx/ui/client/src/inventories/groups/add/main.js b/awx/ui/client/src/inventories/groups/add/main.js index 4cbb4e5c66..8de2bc98de 100644 --- a/awx/ui/client/src/inventories/groups/add/main.js +++ b/awx/ui/client/src/inventories/groups/add/main.js @@ -4,10 +4,8 @@ * All Rights Reserved *************************************************/ -import buildGroupAddState from './build-groups-add-state.factory'; import controller from './groups-add.controller'; export default angular.module('groupAdd', []) - .factory('buildGroupsAddState', buildGroupAddState) .controller('GroupAddController', controller); diff --git a/awx/ui/client/src/inventories/groups/edit/build-groups-edit-state.factory.js b/awx/ui/client/src/inventories/groups/edit/build-groups-edit-state.factory.js deleted file mode 100644 index 3687face76..0000000000 --- a/awx/ui/client/src/inventories/groups/edit/build-groups-edit-state.factory.js +++ /dev/null @@ -1,93 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ - -import GroupEditController from './groups-edit.controller'; - -export default ['$stateExtender', 'templateUrl', '$injector', - 'stateDefinitions','GroupForm','nestedGroupListState', - 'nestedHostsListState', 'buildHostAddState', 'buildHostEditState', - 'nestedGroupAddState', - function($stateExtender, templateUrl, $injector, stateDefinitions, GroupForm, - nestedGroupListState, nestedHostsListState, buildHostAddState, - buildHostEditState, nestedGroupAddState){ - var val = function(field, formStateDefinition, params) { - let state, states = [], - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - name: `${formStateDefinition.name}.${list.iterator}s.edit`, - url: `/edit/:group_id`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - views: { - 'groupForm@inventories': { - templateProvider: function(GenerateForm, GroupForm) { - let form = GroupForm; - return GenerateForm.buildHTML(form, { - mode: 'edit', - related: false - }); - }, - controller: GroupEditController - } - }, - resolve: { - 'FormDefinition': [params.form, function(definition) { - return definition; - }], - groupData: ['$stateParams', 'GroupManageService', function($stateParams, GroupManageService) { - return GroupManageService.get({ id: $stateParams.group_id }).then(res => res.data.results[0]); - }] - } - }; - state = $stateExtender.buildDefinition(stateConfig); - - let relatedGroupListState = nestedGroupListState(GroupForm.related.nested_groups, state, params); - let relatedGroupsAddState = nestedGroupAddState(GroupForm.related.nested_groups, state, params); - relatedGroupListState = $stateExtender.buildDefinition(relatedGroupListState); - relatedGroupsAddState = $stateExtender.buildDefinition(relatedGroupsAddState); - - let relatedHostsListState = nestedHostsListState(GroupForm.related.nested_hosts, state, params); - let relatedHostsAddState = buildHostAddState(GroupForm.related.nested_hosts, state, params); - let relatedHostsEditState = buildHostEditState(GroupForm.related.nested_hosts, state, params); - relatedHostsListState = $stateExtender.buildDefinition(relatedHostsListState); - relatedHostsAddState = $stateExtender.buildDefinition(relatedHostsAddState); - if(Array.isArray(relatedHostsEditState)) - { - relatedHostsEditState[0] = $stateExtender.buildDefinition(relatedHostsEditState[0]); - relatedHostsEditState[1] = $stateExtender.buildDefinition(relatedHostsEditState[1]); - states.push(state, - relatedGroupListState, - relatedGroupsAddState, - relatedHostsListState, - relatedHostsAddState, - relatedHostsEditState[0], - relatedHostsEditState[1]); - } - else { - relatedHostsEditState = $stateExtender.buildDefinition(relatedHostsEditState); - states.push(state, - relatedGroupListState, - relatedGroupsAddState, - relatedHostsListState, - relatedHostsAddState, - relatedHostsEditState); - } - - // states.push(state, - // relatedGroupListState, - // relatedGroupsAddState, - // relatedHostsListState, - // relatedHostsAddState, - // relatedHostsEditState[0], - // relatedHostsEditState[1]); - return states; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/groups/edit/groups-edit.controller.js b/awx/ui/client/src/inventories/groups/edit/groups-edit.controller.js index 1335b4bb80..794df0daad 100644 --- a/awx/ui/client/src/inventories/groups/edit/groups-edit.controller.js +++ b/awx/ui/client/src/inventories/groups/edit/groups-edit.controller.js @@ -5,9 +5,9 @@ *************************************************/ export default ['$state', '$stateParams', '$scope', 'ParseVariableString', 'rbacUiControlService', 'ToJSON', - 'ParseTypeChange', 'GroupManageService', 'GetChoices', 'GetBasePath', 'CreateSelect2', 'groupData', + 'ParseTypeChange', 'GroupManageService', 'GetChoices', 'GetBasePath', 'CreateSelect2', 'groupData', '$rootScope', function($state, $stateParams, $scope, ParseVariableString, rbacUiControlService, ToJSON, - ParseTypeChange, GroupManageService, GetChoices, GetBasePath, CreateSelect2, groupData) { + ParseTypeChange, GroupManageService, GetChoices, GetBasePath, CreateSelect2, groupData, $rootScope) { init(); @@ -19,6 +19,8 @@ export default ['$state', '$stateParams', '$scope', 'ParseVariableString', 'rbac $scope = angular.extend($scope, groupData); + $rootScope.breadcrumb.group_name = groupData.name; + $scope.$watch('summary_fields.user_capabilities.edit', function(val) { $scope.canAdd = val; }); diff --git a/awx/ui/client/src/inventories/groups/edit/groups-edit.route.js b/awx/ui/client/src/inventories/groups/edit/groups-edit.route.js new file mode 100644 index 0000000000..6fe46593ad --- /dev/null +++ b/awx/ui/client/src/inventories/groups/edit/groups-edit.route.js @@ -0,0 +1,25 @@ +export default { + name: "inventories.edit.groups.edit", + url: "/edit/:group_id", + ncyBreadcrumb: { + parent: "inventories.edit.groups", + label: "{{breadcrumb.group_name}}" + }, + views: { + 'groupForm@inventories': { + templateProvider: function(GenerateForm, GroupForm) { + let form = GroupForm; + return GenerateForm.buildHTML(form, { + mode: 'edit', + related: false + }); + }, + controller: 'GroupEditController' + } + }, + resolve: { + groupData: ['$stateParams', 'GroupManageService', function($stateParams, GroupManageService) { + return GroupManageService.get({ id: $stateParams.group_id }).then(res => res.data.results[0]); + }] + } +}; diff --git a/awx/ui/client/src/inventories/groups/edit/main.js b/awx/ui/client/src/inventories/groups/edit/main.js index 532d4b03ba..0c52e2d6b9 100644 --- a/awx/ui/client/src/inventories/groups/edit/main.js +++ b/awx/ui/client/src/inventories/groups/edit/main.js @@ -4,10 +4,8 @@ * All Rights Reserved *************************************************/ -import buildGroupsEditState from './build-groups-edit-state.factory'; import controller from './groups-edit.controller'; export default angular.module('groupEdit', []) - .factory('buildGroupsEditState', buildGroupsEditState) .controller('GroupEditController', controller); diff --git a/awx/ui/client/src/inventories/groups/groups.form.js b/awx/ui/client/src/inventories/groups/groups.form.js index 6a15edd02e..b8a378c733 100644 --- a/awx/ui/client/src/inventories/groups/groups.form.js +++ b/awx/ui/client/src/inventories/groups/groups.form.js @@ -10,9 +10,8 @@ * @description This form is for adding/editing a Group on the inventory page */ -export default ['i18n', 'nestedGroupListState', 'nestedHostsListState', - 'buildHostAddState', -function(i18n, nestedGroupListState, nestedHostsListState, buildHostAddState){ +export default ['i18n', +function(i18n){ return { addTitle: 'CREATE GROUP', editTitle: '{{ name }}', @@ -89,8 +88,7 @@ function(i18n, nestedGroupListState, nestedHostsListState, buildHostAddState){ include: "NestedGroupListDefinition", includeForm: "NestedGroupFormDefinition", title: i18n._('Groups'), - iterator: 'nested_group', - listState: nestedGroupListState + iterator: 'nested_group' }, nested_hosts: { name: 'nested_hosts', @@ -99,10 +97,7 @@ function(i18n, nestedGroupListState, nestedHostsListState, buildHostAddState){ ngClick: "$state.go('inventories.edit.groups.edit.nested_hosts')", include: "NestedHostsListDefinition", title: i18n._('Hosts'), - iterator: 'nested_hosts', - listState: nestedHostsListState, - addState: buildHostAddState, - // editState: buildGroupsEditState + iterator: 'nested_hosts' }, } diff --git a/awx/ui/client/src/inventories/groups/list/build-groups-list-state.factory.js b/awx/ui/client/src/inventories/groups/list/build-groups-list-state.factory.js deleted file mode 100644 index db175bf3eb..0000000000 --- a/awx/ui/client/src/inventories/groups/list/build-groups-list-state.factory.js +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ -import GroupsListController from './groups-list.controller'; -export default ['GroupList', '$stateExtender', 'templateUrl', '$injector', - function(GroupList, $stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - searchPrefix: `${list.iterator}`, - name: `${formStateDefinition.name}.${list.iterator}s`, - url: `/${list.iterator}s`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - params: { - [list.iterator + '_search']: { - value: { order_by: field.order_by ? field.order_by : 'name' } - }, - }, - views: { - 'related': { - templateProvider: function(GroupList, generateList, $templateRequest, $stateParams, GetBasePath) { - let list = _.cloneDeep(GroupList); - if($stateParams && $stateParams.group) { - list.basePath = GetBasePath('groups') + _.last($stateParams.group) + '/children'; - } - else { - //reaches here if the user is on the root level group - list.basePath = GetBasePath('inventory') + $stateParams.inventory_id + '/root_groups'; - } - - let html = generateList.build({ - list: list, - mode: 'edit' - }); - // Include the custom group delete modal template - return $templateRequest(templateUrl('inventories/groups/list/groups-list')).then((template) => { - return html.concat(template); - }); - }, - controller: GroupsListController - } - }, - resolve: { - ListDefinition: () => { - return list; - }, - Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', - (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { - // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field - let path, interpolator; - if (GetBasePath(list.basePath)) { - path = GetBasePath(list.basePath); - } else { - interpolator = $interpolate(list.basePath); - path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); - } - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ], - inventoryData: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { - return InventoryManageService.getInventory($stateParams.inventory_id).then(res => res.data); - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - // appy any default search parameters in form definition - if (field.search) { - state.params[`${field.iterator}_search`].value = _.merge(state.params[`${field.iterator}_search`].value, field.search); - } - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/groups/list/groups-list.controller.js b/awx/ui/client/src/inventories/groups/list/groups-list.controller.js index 7cfd4cdb01..01995f48bb 100644 --- a/awx/ui/client/src/inventories/groups/list/groups-list.controller.js +++ b/awx/ui/client/src/inventories/groups/list/groups-list.controller.js @@ -30,11 +30,6 @@ $scope[`${list.iterator}_dataset`] = Dataset.data; $scope[list.name] = $scope[`${list.iterator}_dataset`].results; - // The ncy breadcrumb directive will look at this attribute when attempting to bind to the correct scope. - // In this case, we don't want to incidentally bind to this scope when editing a host or a group. See: - // https://github.com/ncuillery/angular-breadcrumb/issues/42 for a little more information on the - // problem that this solves. - $scope.ncyBreadcrumbIgnore = true; if($state.current.name === "inventories.edit.groups") { $scope.rowBeingEdited = $state.params.group_id; $scope.listBeingEdited = "groups"; diff --git a/awx/ui/client/src/inventories/groups/list/groups-list.route.js b/awx/ui/client/src/inventories/groups/list/groups-list.route.js new file mode 100644 index 0000000000..fb9ef19167 --- /dev/null +++ b/awx/ui/client/src/inventories/groups/list/groups-list.route.js @@ -0,0 +1,63 @@ +import { N_ } from '../../../i18n'; +import {templateUrl} from '../../../shared/template-url/template-url.factory'; + +export default { + name: "inventories.edit.groups", + url: "/groups?{group_search:queryset}", + resolve: { + Dataset: ['GroupList', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', + (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { + // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field + let path, interpolator; + if (GetBasePath(list.basePath)) { + path = GetBasePath(list.basePath); + } else { + interpolator = $interpolate(list.basePath); + path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); + } + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + inventoryData: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { + return InventoryManageService.getInventory($stateParams.inventory_id).then(res => res.data); + }] + }, + params: { + group_search: { + value: { + page_size: "20", + order_by: "name" + }, + dynamic: true, + squash: "" + } + }, + ncyBreadcrumb: { + parent: "inventories.edit", + label: N_("GROUPS") + }, + views: { + 'related': { + templateProvider: function(GroupList, generateList, $templateRequest, $stateParams, GetBasePath) { + let list = _.cloneDeep(GroupList); + if($stateParams && $stateParams.group) { + list.basePath = GetBasePath('groups') + _.last($stateParams.group) + '/children'; + } + else { + //reaches here if the user is on the root level group + list.basePath = GetBasePath('inventory') + $stateParams.inventory_id + '/root_groups'; + } + + let html = generateList.build({ + list: list, + mode: 'edit' + }); + // Include the custom group delete modal template + return $templateRequest(templateUrl('inventories/groups/list/groups-list')).then((template) => { + return html.concat(template); + }); + }, + controller: 'GroupsListController' + } + } +}; diff --git a/awx/ui/client/src/inventories/groups/list/main.js b/awx/ui/client/src/inventories/groups/list/main.js index 37e4c974fa..6c030c9869 100644 --- a/awx/ui/client/src/inventories/groups/list/main.js +++ b/awx/ui/client/src/inventories/groups/list/main.js @@ -4,10 +4,8 @@ * All Rights Reserved *************************************************/ -import buildGroupsListState from './build-groups-list-state.factory'; import controller from './groups-list.controller'; export default angular.module('groupsList', []) - .factory('buildGroupsListState', buildGroupsListState) .controller('GroupsListController', controller); diff --git a/awx/ui/client/src/inventories/groups/nested-groups/main.js b/awx/ui/client/src/inventories/groups/nested-groups/main.js index 0c02775e75..9146e87664 100644 --- a/awx/ui/client/src/inventories/groups/nested-groups/main.js +++ b/awx/ui/client/src/inventories/groups/nested-groups/main.js @@ -4,16 +4,12 @@ * All Rights Reserved *************************************************/ -import nestedGroupListState from './nested-groups-list-state.factory'; -import nestedGroupAddState from './nested-groups-add-state.factory'; import nestedGroupListDefinition from './nested-groups.list'; import nestedGroupFormDefinition from './nested-groups.form'; import controller from './nested-groups-list.controller'; export default angular.module('nestedGroups', []) - .factory('nestedGroupListState', nestedGroupListState) - .factory('nestedGroupAddState', nestedGroupAddState) .value('NestedGroupListDefinition', nestedGroupListDefinition) .factory('NestedGroupFormDefinition', nestedGroupFormDefinition) .controller('NestedGroupsListController', controller); diff --git a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-add-state.factory.js b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-add-state.factory.js deleted file mode 100644 index b376436149..0000000000 --- a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-add-state.factory.js +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ - -import GroupAddController from '../add/groups-add.controller'; - -export default ['$stateExtender', 'templateUrl', '$injector', - function($stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition, params) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - name: `${formStateDefinition.name}.${list.iterator}s.add`, - url: `/add`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - views: { - 'nestedGroupForm@inventories': { - templateProvider: function(GenerateForm, GroupForm) { - let form = GroupForm; - return GenerateForm.buildHTML(form, { - mode: 'add', - related: false - }); - }, - controller: GroupAddController - } - }, - resolve: { - 'FormDefinition': [params.form, function(definition) { - return definition; - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-add.route.js b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-add.route.js new file mode 100644 index 0000000000..e524d445fb --- /dev/null +++ b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-add.route.js @@ -0,0 +1,22 @@ +import { N_ } from '../../../i18n'; + +export default { + name: "inventories.edit.groups.edit.nested_groups.add", + url: "/add", + ncyBreadcrumb: { + parent: "inventories.edit.groups.edit.nested_groups", + label: N_("CREATE GROUP") + }, + views: { + 'nestedGroupForm@inventories': { + templateProvider: function(GenerateForm, GroupForm) { + let form = GroupForm; + return GenerateForm.buildHTML(form, { + mode: 'add', + related: false + }); + }, + controller: 'GroupAddController' + } + } +}; diff --git a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list-state.factory.js b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list-state.factory.js deleted file mode 100644 index 26763ee007..0000000000 --- a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list-state.factory.js +++ /dev/null @@ -1,92 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ -import NestedGroupsListController from './nested-groups-list.controller'; -export default ['$stateExtender', 'templateUrl', '$injector', - function($stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - searchPrefix: `${list.iterator}`, - squash: '', - name: `${formStateDefinition.name}.nested_groups`, - url: `/${list.iterator}s`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - params: { - [list.iterator + '_search']: { - value: { order_by: field.order_by ? field.order_by : 'name' } - }, - }, - views: { - // 'related@inventories.edit.groups.edit': { - 'related': { - templateProvider: function(NestedGroupListDefinition, generateList) { - let list = _.cloneDeep(NestedGroupListDefinition); - - let html = generateList.build({ - list: list, - mode: 'edit' - }); - // Include the custom group delete modal template - // return $templateRequest(templateUrl('inventories/groups/list/groups-list')).then((template) => { - // return html.concat(template); - // }); - return html; - }, - controller: NestedGroupsListController - } - }, - resolve: { - ListDefinition: () => { - return list; - }, - Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', - (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { - // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field - let path, interpolator; - if (GetBasePath(list.basePath)) { - path = GetBasePath(list.basePath); - } else { - interpolator = $interpolate(list.basePath); - path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); - } - if($stateParams.group_id){ - path = `api/v2/groups/${$stateParams.group_id}/children`; - } - else if($stateParams.host_id){ - path = GetBasePath('hosts') + $stateParams.host_id + '/all_groups'; - } - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ], - host: ['$stateParams', 'HostManageService', function($stateParams, HostManageService) { - if($stateParams.host_id){ - return HostManageService.get({ id: $stateParams.host_id }).then(function(res) { - return res.data.results[0]; - }); - } - }], - inventoryData: ['InventoryManageService', '$stateParams', 'host', function(InventoryManageService, $stateParams, host) { - var id = ($stateParams.inventory_id) ? $stateParams.inventory_id : host.summary_fields.inventory.id; - return InventoryManageService.getInventory(id).then(res => res.data); - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - // appy any default search parameters in form definition - if (field.search) { - state.params[`${field.iterator}_search`].value = _.merge(state.params[`${field.iterator}_search`].value, field.search); - } - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list.controller.js b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list.controller.js index 1bcf0824c6..a8d5492e5b 100644 --- a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list.controller.js +++ b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list.controller.js @@ -30,11 +30,6 @@ $scope[`${list.iterator}_dataset`] = Dataset.data; $scope[list.name] = $scope[`${list.iterator}_dataset`].results; - // The ncy breadcrumb directive will look at this attribute when attempting to bind to the correct scope. - // In this case, we don't want to incidentally bind to this scope when editing a host or a group. See: - // https://github.com/ncuillery/angular-breadcrumb/issues/42 for a little more information on the - // problem that this solves. - $scope.ncyBreadcrumbIgnore = true; if($state.current.name === "inventories.edit.groups.edit.nested_groups.edit") { $scope.rowBeingEdited = $state.params.group_id; $scope.listBeingEdited = "groups"; diff --git a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups.form.js b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups.form.js index 955d25e462..7b5d7cc77e 100644 --- a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups.form.js +++ b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups.form.js @@ -10,8 +10,8 @@ * @description This form is for adding/editing a Group on the inventory page */ -export default ['i18n', 'nestedGroupListState', -function(i18n, nestedGroupListState){ +export default ['i18n', +function(i18n){ return { addTitle: 'CREATE GROUP', editTitle: '{{ name }}', @@ -87,8 +87,7 @@ function(i18n, nestedGroupListState){ include: "RelatedGroupListDefinition", includeForm: "RelatedGroupFormDefinition", title: i18n._('Groups'), - iterator: 'related_group', - listState: nestedGroupListState + iterator: 'related_group' }, } diff --git a/awx/ui/client/src/inventories/groups/nested-groups/nested-groups.route.js b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups.route.js new file mode 100644 index 0000000000..433cabf0e9 --- /dev/null +++ b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups.route.js @@ -0,0 +1,64 @@ +export default { + url: "/nested_groups?{nested_group_search:queryset}", + params: { + nested_group_search: { + value: { + page_size: "20", + order_by: "name" + }, + dynamic: true, + squash: "" + } + }, + views: { + // 'related@inventories.edit.groups.edit': { + 'related': { + templateProvider: function(NestedGroupListDefinition, generateList) { + let list = _.cloneDeep(NestedGroupListDefinition); + + let html = generateList.build({ + list: list, + mode: 'edit' + }); + // Include the custom group delete modal template + // return $templateRequest(templateUrl('inventories/groups/list/groups-list')).then((template) => { + // return html.concat(template); + // }); + return html; + }, + controller: 'NestedGroupsListController' + } + }, + resolve: { + Dataset: ['NestedGroupListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', + (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { + // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field + let path, interpolator; + if (GetBasePath(list.basePath)) { + path = GetBasePath(list.basePath); + } else { + interpolator = $interpolate(list.basePath); + path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); + } + if($stateParams.group_id){ + path = `api/v2/groups/${$stateParams.group_id}/children`; + } + else if($stateParams.host_id){ + path = GetBasePath('hosts') + $stateParams.host_id + '/all_groups'; + } + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + host: ['$stateParams', 'HostManageService', function($stateParams, HostManageService) { + if($stateParams.host_id){ + return HostManageService.get({ id: $stateParams.host_id }).then(function(res) { + return res.data.results[0]; + }); + } + }], + inventoryData: ['InventoryManageService', '$stateParams', 'host', function(InventoryManageService, $stateParams, host) { + var id = ($stateParams.inventory_id) ? $stateParams.inventory_id : host.summary_fields.inventory.id; + return InventoryManageService.getInventory(id).then(res => res.data); + }] + } +}; diff --git a/awx/ui/client/src/inventories/groups/nested-hosts/main.js b/awx/ui/client/src/inventories/groups/nested-hosts/main.js index 0d1ef630e9..450a20e290 100644 --- a/awx/ui/client/src/inventories/groups/nested-hosts/main.js +++ b/awx/ui/client/src/inventories/groups/nested-hosts/main.js @@ -4,14 +4,12 @@ * All Rights Reserved *************************************************/ -import nestedHostsListState from './nested-hosts-list-state.factory'; import nestedHostsListDefinition from './nested-hosts.list'; import nestedHostsFormDefinition from './nested-hosts.form'; import controller from './nested-hosts-list.controller'; export default angular.module('nestedHosts', []) - .factory('nestedHostsListState', nestedHostsListState) .value('NestedHostsListDefinition', nestedHostsListDefinition) .factory('NestedHostsFormDefinition', nestedHostsFormDefinition) .controller('NestedHostsListController', controller); diff --git a/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-add.route.js b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-add.route.js new file mode 100644 index 0000000000..2006735dde --- /dev/null +++ b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-add.route.js @@ -0,0 +1,22 @@ +import { N_ } from '../../../i18n'; + +export default { + name: "inventories.edit.groups.edit.nested_hosts.add", + url: "/add", + ncyBreadcrumb: { + parent: "inventories.edit.groups.edit.nested_hosts", + label: N_("CREATE HOST") + }, + views: { + 'hostForm@inventories': { + templateProvider: function(GenerateForm, RelatedHostsFormDefinition) { + let form = RelatedHostsFormDefinition; + return GenerateForm.buildHTML(form, { + mode: 'add', + related: false + }); + }, + controller: 'RelatedHostAddController' + } + } +}; diff --git a/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-edit.route.js b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-edit.route.js new file mode 100644 index 0000000000..63b65d648c --- /dev/null +++ b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-edit.route.js @@ -0,0 +1,30 @@ +export default { + name: "inventories.edit.groups.edit.nested_hosts.edit", + url: "/edit/:host_id", + ncyBreadcrumb: { + parent: "inventories.edit.groups.edit", + label: "ASSOCIATED HOSTS" + }, + views: { + 'hostForm@inventories': { + templateProvider: function(GenerateForm, RelatedHostsFormDefinition, NestedHostsFormDefinition, $stateParams) { + let form = RelatedHostsFormDefinition; + if($stateParams.group_id){ + form = NestedHostsFormDefinition; + } + return GenerateForm.buildHTML(form, { + mode: 'edit', + related: false + }); + }, + controller: 'RelatedHostEditController' + } + }, + resolve: { + host: ['$stateParams', 'HostManageService', function($stateParams, HostManageService) { + return HostManageService.get({ id: $stateParams.host_id }).then(function(res) { + return res.data.results[0]; + }); + }] + } +}; diff --git a/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-list-state.factory.js b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-list-state.factory.js deleted file mode 100644 index 96b7402292..0000000000 --- a/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-list-state.factory.js +++ /dev/null @@ -1,79 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ -import NestedHostsListController from './nested-hosts-list.controller'; -export default ['NestedHostsListDefinition', '$stateExtender', 'templateUrl', '$injector', - function(NestedHostsListDefinition, $stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - searchPrefix: `${list.iterator}`, - squash: '', - name: `${formStateDefinition.name}.nested_hosts`, - url: `/${list.iterator}s`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - params: { - [list.iterator + '_search']: { - value: { order_by: field.order_by ? field.order_by : 'name' } - }, - }, - views: { - // 'related@inventories.edit.groups.edit': { - 'related': { - templateProvider: function(NestedHostsListDefinition, generateList) { - let list = _.cloneDeep(NestedHostsListDefinition); - - let html = generateList.build({ - list: list, - mode: 'edit' - }); - // Include the custom group delete modal template - // return $templateRequest(templateUrl('inventories/groups/list/groups-list')).then((template) => { - // return html.concat(template); - // }); - return html; - }, - controller: NestedHostsListController - } - }, - resolve: { - ListDefinition: () => { - return list; - }, - Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', - (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { - // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field - let path, interpolator; - if (GetBasePath(list.basePath)) { - path = GetBasePath(list.basePath); - } else { - interpolator = $interpolate(list.basePath); - path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); - } - path = `api/v2/groups/${$stateParams.group_id}/all_hosts`; - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ], - inventoryData: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { - return InventoryManageService.getInventory($stateParams.inventory_id).then(res => res.data); - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - // appy any default search parameters in form definition - if (field.search) { - state.params[`${field.iterator}_search`].value = _.merge(state.params[`${field.iterator}_search`].value, field.search); - } - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.form.js b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.form.js index 56fe871d7a..780df59dcf 100644 --- a/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.form.js +++ b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.form.js @@ -10,8 +10,8 @@ * @description This form is for adding/editing a host on the inventory page */ -export default ['i18n', 'nestedGroupListState', -function(i18n, nestedGroupListState) { +export default ['i18n', +function(i18n) { return { addTitle: i18n._('CREATE HOST'), @@ -120,8 +120,7 @@ function(i18n, nestedGroupListState) { include: "NestedGroupListDefinition", includeForm: "NestedGroupFormDefinition", title: i18n._('Groups'), - iterator: 'nested_group', - listState: nestedGroupListState + iterator: 'nested_group' }, insights: { name: 'insights', diff --git a/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.route.js b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.route.js new file mode 100644 index 0000000000..bbfa7d8a79 --- /dev/null +++ b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.route.js @@ -0,0 +1,58 @@ +import { N_ } from '../../../i18n'; + +export default { + name: "inventories.edit.groups.edit.nested_hosts", + url: "/nested_hosts?{nested_host_search:queryset}", + params: { + nested_host_search: { + value: { + page_size: "20", + order_by: "name" + }, + dynamic: true, + squash: "" + } + }, + ncyBreadcrumb: { + parent: "inventories.edit.groups.edit", + label: N_("ASSOCIATED HOSTS") + }, + views: { + // 'related@inventories.edit.groups.edit': { + 'related': { + templateProvider: function(NestedHostsListDefinition, generateList) { + let list = _.cloneDeep(NestedHostsListDefinition); + + let html = generateList.build({ + list: list, + mode: 'edit' + }); + // Include the custom group delete modal template + // return $templateRequest(templateUrl('inventories/groups/list/groups-list')).then((template) => { + // return html.concat(template); + // }); + return html; + }, + controller: 'NestedHostsListController' + } + }, + resolve: { + Dataset: ['NestedHostsListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', + (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { + // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field + let path, interpolator; + if (GetBasePath(list.basePath)) { + path = GetBasePath(list.basePath); + } else { + interpolator = $interpolate(list.basePath); + path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); + } + path = `api/v2/groups/${$stateParams.group_id}/all_hosts`; + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + inventoryData: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { + return InventoryManageService.getInventory($stateParams.inventory_id).then(res => res.data); + }] + } +}; diff --git a/awx/ui/client/src/inventories/hosts/edit/host-edit.controller.js b/awx/ui/client/src/inventories/hosts/edit/host-edit.controller.js index ab4ab233e4..35586ade34 100644 --- a/awx/ui/client/src/inventories/hosts/edit/host-edit.controller.js +++ b/awx/ui/client/src/inventories/hosts/edit/host-edit.controller.js @@ -5,8 +5,8 @@ *************************************************/ export default - ['$scope', '$state', '$stateParams', 'DashboardHostsForm', 'GenerateForm', 'ParseTypeChange', 'DashboardHostService', 'host', - function($scope, $state, $stateParams, DashboardHostsForm, GenerateForm, ParseTypeChange, DashboardHostService, host){ + ['$scope', '$state', '$stateParams', 'DashboardHostsForm', 'GenerateForm', 'ParseTypeChange', 'DashboardHostService', 'host', '$rootScope', + function($scope, $state, $stateParams, DashboardHostsForm, GenerateForm, ParseTypeChange, DashboardHostService, host, $rootScope){ $scope.parseType = 'yaml'; $scope.formCancel = function(){ $state.go('^', null, {reload: true}); @@ -39,7 +39,7 @@ }; var init = function(){ $scope.host = host.data; - $scope.name = host.data.name; + $rootScope.breadcrumb.host_name = host.data.name; $scope.description = host.data.description; $scope.variables = getVars(host.data.variables); ParseTypeChange({ diff --git a/awx/ui/client/src/inventories/hosts/host.form.js b/awx/ui/client/src/inventories/hosts/host.form.js index 93f381c1f3..474121457a 100644 --- a/awx/ui/client/src/inventories/hosts/host.form.js +++ b/awx/ui/client/src/inventories/hosts/host.form.js @@ -10,8 +10,8 @@ * @description This form is for adding/editing a host on the inventory page */ -export default ['i18n', 'nestedGroupListState', -function(i18n, nestedGroupListState) { +export default ['i18n', +function(i18n) { return { addTitle: i18n._('CREATE HOST'), @@ -115,12 +115,11 @@ function(i18n, nestedGroupListState) { name: 'nested_groups', awToolTip: i18n._('Please save before defining groups'), dataPlacement: 'top', - ngClick: "groupsTab()", + ngClick: "$state.go('hosts.edit.nested_groups')", include: "NestedGroupListDefinition", includeForm: "NestedGroupFormDefinition", title: i18n._('Groups'), - iterator: 'nested_group', - listState: nestedGroupListState + iterator: 'nested_group' }, insights: { name: 'insights', diff --git a/awx/ui/client/src/inventories/hosts/smart-inventory/smart-inventory.form.js b/awx/ui/client/src/inventories/hosts/smart-inventory/smart-inventory.form.js index 7be1881920..0ba2c72899 100644 --- a/awx/ui/client/src/inventories/hosts/smart-inventory/smart-inventory.form.js +++ b/awx/ui/client/src/inventories/hosts/smart-inventory/smart-inventory.form.js @@ -4,7 +4,7 @@ * All Rights Reserved *************************************************/ -export default ['i18n', 'buildHostListState', function(i18n, buildHostListState) { +export default ['i18n', function(i18n) { return { addTitle: i18n._('NEW SMART INVENTORY'), @@ -139,10 +139,7 @@ export default ['i18n', 'buildHostListState', function(i18n, buildHostListState) name: 'hosts', include: "RelatedHostsListDefinition", title: i18n._('Hosts'), - iterator: 'host', - listState: buildHostListState, - // addState: buildGroupsAddState, - // editState: buildGroupsEditState + iterator: 'host' }, //this is a placeholder for when we're ready for completed jobs completed_jobs: { diff --git a/awx/ui/client/src/inventories/insights/insights.route.js b/awx/ui/client/src/inventories/insights/insights.route.js new file mode 100644 index 0000000000..1bba477d18 --- /dev/null +++ b/awx/ui/client/src/inventories/insights/insights.route.js @@ -0,0 +1,27 @@ +import {templateUrl} from '../../shared/template-url/template-url.factory'; +import { N_ } from '../../i18n'; + +export default { + url: '/insights', + ncyBreadcrumb: { + label: N_("INSIGHTS") + }, + views: { + 'related': { + controller: 'InsightsController', + templateUrl: templateUrl('inventories/insights/insights') + } + }, + 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; + }); + } + ] + } +}; diff --git a/awx/ui/client/src/inventories/inventories.route.js b/awx/ui/client/src/inventories/inventories.route.js new file mode 100644 index 0000000000..694f68e274 --- /dev/null +++ b/awx/ui/client/src/inventories/inventories.route.js @@ -0,0 +1,34 @@ +import {templateUrl} from '../shared/template-url/template-url.factory'; +import { N_ } from '../i18n'; + +export default { + name: 'inventories', // top-most node in the generated tree (will replace this state definition) + route: '/inventories', + ncyBreadcrumb: { + label: N_('INVENTORIES') + }, + views: { + '@': { + templateUrl: templateUrl('inventories/inventories') + }, + 'list@inventories': { + templateProvider: function(InventoryList, generateList) { + let html = generateList.build({ + list: InventoryList, + mode: 'edit' + }); + return html; + }, + controller: 'InventoryListController' + } + }, + searchPrefix: 'inventory', + resolve: { + Dataset: ['InventoryList', 'QuerySet', '$stateParams', 'GetBasePath', + function(list, qs, $stateParams, GetBasePath) { + let path = GetBasePath(list.basePath) || GetBasePath(list.name); + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ] + } +}; diff --git a/awx/ui/client/src/inventories/inventory.form.js b/awx/ui/client/src/inventories/inventory.form.js index 270511f06c..5e2535205d 100644 --- a/awx/ui/client/src/inventories/inventory.form.js +++ b/awx/ui/client/src/inventories/inventory.form.js @@ -10,15 +10,8 @@ * @description This form is for adding/editing an inventory */ -export default ['i18n', 'buildGroupsListState', 'buildGroupsAddState', - 'buildGroupsEditState', 'buildHostListState', 'buildHostAddState', - 'buildHostEditState', 'buildSourcesListState', 'buildSourcesAddState', - 'buildSourcesEditState', 'buildInventoryCompletedJobsState', - 'InventoryCompletedJobsList', -function(i18n, buildGroupsListState, buildGroupsAddState, buildGroupsEditState, - buildHostListState, buildHostAddState, buildHostEditState, - buildSourcesListState, buildSourcesAddState,buildSourcesEditState, - buildInventoryCompletedJobsState, InventoryCompletedJobsList) { +export default ['i18n', 'InventoryCompletedJobsList', +function(i18n, InventoryCompletedJobsList) { var completed_jobs_object = { name: 'completed_jobs', @@ -28,7 +21,7 @@ function(i18n, buildGroupsListState, buildGroupsAddState, buildGroupsEditState, title: i18n._('Completed Jobs'), iterator: 'completed_job', generateList: true, - listState: buildInventoryCompletedJobsState, + skipGenerator: true, search: { "or__job__inventory": '' } @@ -164,9 +157,7 @@ function(i18n, buildGroupsListState, buildGroupsAddState, buildGroupsEditState, include: "GroupList", title: i18n._('Groups'), iterator: 'group', - listState: buildGroupsListState, - addState: buildGroupsAddState, - editState: buildGroupsEditState + skipGenerator: true }, hosts: { name: 'hosts', @@ -175,9 +166,7 @@ function(i18n, buildGroupsListState, buildGroupsAddState, buildGroupsEditState, include: "RelatedHostsListDefinition", title: i18n._('Hosts'), iterator: 'host', - listState: buildHostListState, - addState: buildHostAddState, - editState: buildHostEditState + skipGenerator: true }, inventory_sources: { name: 'inventory_sources', @@ -187,9 +176,7 @@ function(i18n, buildGroupsListState, buildGroupsAddState, buildGroupsEditState, includeForm: "SourcesFormDefinition", title: i18n._('Sources'), iterator: 'inventory_source', - listState: buildSourcesListState, - addState: buildSourcesAddState, - editState: buildSourcesEditState + skipGenerator: true }, completed_jobs: completed_jobs_object } diff --git a/awx/ui/client/src/inventories/main.js b/awx/ui/client/src/inventories/main.js index 8db43d4af6..e3362436c7 100644 --- a/awx/ui/client/src/inventories/main.js +++ b/awx/ui/client/src/inventories/main.js @@ -23,6 +23,29 @@ import ansibleFacts from './ansible_facts/main'; import insights from './insights/main'; import { copyMoveGroupRoute, copyMoveHostRoute } from './copy-move/copy-move.route'; import copyMove from './copy-move/main'; +import inventoryCompletedJobsRoute from './completed_jobs/completed_jobs.route'; +import inventorySourceEditRoute from './sources/edit/sources-edit.route'; +import inventorySourceAddRoute from './sources/add/sources-add.route'; +import inventorySourceListRoute from './sources/list/sources-list.route'; +import inventorySourceListScheduleRoute from './sources/list/schedule/sources-schedule.route'; +import inventorySourceListScheduleAddRoute from './sources/list/schedule/sources-schedule-add.route'; +import inventorySourceListScheduleEditRoute from './sources/list/schedule/sources-schedule-edit.route'; +import inventoryAdhocCredential from './adhoc/adhoc-credential.route'; +import inventoryGroupsList from './groups/list/groups-list.route'; +import inventoryGroupsAdd from './groups/add/groups-add.route'; +import inventoryGroupsEdit from './groups/edit/groups-edit.route'; +import nestedGroups from './groups/nested-groups/nested-groups.route'; +import nestedGroupsAdd from './groups/nested-groups/nested-groups-add.route'; +import nestedHosts from './groups/nested-hosts/nested-hosts.route'; +import inventoryHosts from './related-hosts/related-host.route'; +import inventoriesList from './inventories.route'; +import inventoryHostsAdd from './related-hosts/add/host-add.route'; +import inventoryHostsEdit from './related-hosts/edit/host-edit.route'; +import nestedHostsAdd from './groups/nested-hosts/nested-hosts-add.route'; +import nestedHostsEdit from './groups/nested-hosts/nested-hosts-edit.route'; +import ansibleFactsRoute from './ansible_facts/ansible_facts.route'; +import insightsRoute from './insights/insights.route'; + export default angular.module('inventory', [ adhoc.name, @@ -46,62 +69,6 @@ angular.module('inventory', [ let stateDefinitions = stateDefinitionsProvider.$get(), stateExtender = $stateExtenderProvider.$get(); - function factsConfig(stateName) { - return { - name: stateName, - 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; - }); - } - ] - } - }; - } - - function insightsConfig(stateName) { - return { - name: stateName, - url: '/insights', - ncyBreadcrumb: { - label: N_("INSIGHTS") - }, - views: { - 'related': { - controller: 'InsightsController', - templateUrl: templateUrl('inventories/insights/insights') - } - }, - 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; - }); - } - ] - } - }; - } - function generateInventoryStates() { let basicInventoryAdd = stateDefinitions.generateTree({ @@ -121,6 +88,9 @@ angular.module('inventory', [ form: 'InventoryForm', controllers: { edit: 'InventoryEditController' + }, + breadcrumbs: { + edit: '{{breadcrumb.inventory_name}}' } }); @@ -144,151 +114,38 @@ angular.module('inventory', [ } }); - let adhocCredentialLookup = { - searchPrefix: 'credential', - name: 'inventories.edit.adhoc.credential', - url: '/credential', - data: { - formChildState: true - }, - params: { - credential_search: { - value: { - page_size: '5' - }, - squash: true, - dynamic: true - } - }, - ncyBreadcrumb: { - skip: true - }, - views: { - 'related': { - templateProvider: function(ListDefinition, generateList) { - let list_html = generateList.build({ - mode: 'lookup', - list: ListDefinition, - input_type: 'radio' - }); - return `${list_html}`; - - } - } - }, - resolve: { - ListDefinition: ['CredentialList', function(CredentialList) { - let list = _.cloneDeep(CredentialList); - list.lookupConfirmText = 'SELECT'; - return list; - }], - Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', - (list, qs, $stateParams, GetBasePath) => { - let path = GetBasePath(list.name) || GetBasePath(list.basePath); - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ] - }, - onExit: function($state) { - if ($state.transition) { - $('#form-modal').modal('hide'); - $('.modal-backdrop').remove(); - $('body').removeClass('modal-open'); - } - } + let inventoryGroupsEditNestedGroups = _.cloneDeep(nestedGroups); + inventoryGroupsEditNestedGroups.name = "inventories.edit.groups.edit.nested_groups"; + inventoryGroupsEditNestedGroups.ncyBreadcrumb = { + parent: "inventories.edit.groups.edit", + label: "ASSOCIATED GROUPS" }; - let listSchedules = { - name: 'inventories.edit.inventory_sources.edit.schedules', - url: '/schedules', - searchPrefix: 'schedule', - ncyBreadcrumb: { - label: N_('SCHEDULES') - }, - resolve: { - Dataset: ['ScheduleList', 'QuerySet', '$stateParams', 'GetBasePath', 'inventorySourceData', - function(list, qs, $stateParams, GetBasePath, inventorySourceData) { - let path = `${inventorySourceData.related.schedules}`; - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ], - ParentObject: ['inventorySourceData', function(inventorySourceData) { - return inventorySourceData; - }], - UnifiedJobsOptions: ['Rest', 'GetBasePath', '$stateParams', '$q', - function(Rest, GetBasePath, $stateParams, $q) { - Rest.setUrl(GetBasePath('unified_jobs')); - var val = $q.defer(); - Rest.options() - .then(function(data) { - val.resolve(data.data); - }, function(data) { - val.reject(data); - }); - return val.promise; - }], - ScheduleList: ['SchedulesList', 'inventorySourceData', - (SchedulesList, inventorySourceData) => { - let list = _.cloneDeep(SchedulesList); - list.basePath = `${inventorySourceData.related.schedules}`; - return list; - } - ] - }, - views: { - // clear form template when views render in this substate - 'form': { - templateProvider: () => '' - }, - // target the un-named ui-view @ root level - '@': { - templateProvider: function(ScheduleList, generateList, ParentObject) { - // include name of parent resource in listTitle - ScheduleList.listTitle = `${ParentObject.name}
` + N_('SCHEDULES'); - let html = generateList.build({ - list: ScheduleList, - mode: 'edit' - }); - html = generateList.wrapPanel(html); - return "
" + generateList.insertFormView() + html + "
"; - }, - controller: 'schedulerListController' - } - } + let inventoryGroupsEditNestedHostsEditGroups = _.cloneDeep(nestedGroups); + inventoryGroupsEditNestedHostsEditGroups.name = "inventories.edit.groups.edit.nested_hosts.edit.nested_groups"; + inventoryGroupsEditNestedHostsEditGroups.ncyBreadcrumb = { + parent: "inventories.edit.groups.edit.nested_hosts.edit", + label: "ASSOCIATED GROUPS" }; - let addSchedule = { - name: 'inventories.edit.inventory_sources.edit.schedules.add', - url: '/add', - ncyBreadcrumb: { - label: N_("CREATE SCHEDULE") - }, - views: { - 'form': { - controller: 'schedulerAddController', - templateUrl: templateUrl("scheduler/schedulerForm") - } - } + let inventoryHostsEditGroups = _.cloneDeep(nestedGroups); + inventoryHostsEditGroups.name = "inventories.edit.hosts.edit.nested_groups"; + inventoryHostsEditGroups.ncyBreadcrumb = { + parent: "inventories.edit.hosts.edit", + label: "ASSOCIATED GROUPS" }; - let editSchedule = { - name: 'inventories.edit.inventory_sources.edit.schedules.edit', - url: '/:schedule_id', - ncyBreadcrumb: { - label: "{{schedule_obj.name}}" - }, - views: { - 'form': { - templateUrl: templateUrl("scheduler/schedulerForm"), - controller: 'schedulerEditController', - } - } - }; + let relatedHostsAnsibleFacts = _.cloneDeep(ansibleFactsRoute); + relatedHostsAnsibleFacts.name = 'inventories.edit.hosts.edit.ansible_facts'; - let relatedHostsAnsibleFacts = factsConfig('inventories.edit.hosts.edit.ansible_facts'); - let nestedHostsAnsibleFacts = factsConfig('inventories.edit.groups.edit.nested_hosts.edit.ansible_facts'); - let relatedHostsInsights = insightsConfig('inventories.edit.hosts.edit.insights'); - let nestedHostsInsights = insightsConfig('inventories.edit.groups.edit.nested_hosts.edit.insights'); + let nestedHostsAnsibleFacts = _.cloneDeep(ansibleFactsRoute); + nestedHostsAnsibleFacts.name = 'inventories.edit.groups.edit.nested_hosts.edit.ansible_facts'; + + let relatedHostsInsights = _.cloneDeep(insightsRoute); + relatedHostsInsights.name = 'inventories.edit.hosts.edit.insights'; + + let nestedHostsInsights = _.cloneDeep(insightsRoute); + nestedHostsInsights.name = 'inventories.edit.groups.edit.nested_hosts.edit.insights'; return Promise.all([ basicInventoryAdd, @@ -300,48 +157,35 @@ angular.module('inventory', [ states: _.reduce(generated, (result, definition) => { return result.concat(definition.states); }, [ - stateExtender.buildDefinition({ - name: 'inventories', // top-most node in the generated tree (will replace this state definition) - route: '/inventories', - ncyBreadcrumb: { - label: N_('INVENTORIES') - }, - views: { - '@': { - templateUrl: templateUrl('inventories/inventories') - }, - 'list@inventories': { - templateProvider: function(InventoryList, generateList) { - let html = generateList.build({ - list: InventoryList, - mode: 'edit' - }); - return html; - }, - controller: 'InventoryListController' - } - }, - searchPrefix: 'inventory', - resolve: { - Dataset: ['InventoryList', 'QuerySet', '$stateParams', 'GetBasePath', - function(list, qs, $stateParams, GetBasePath) { - let path = GetBasePath(list.basePath) || GetBasePath(list.name); - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ] - } - }), + stateExtender.buildDefinition(inventoriesList), stateExtender.buildDefinition(adHocRoute), - stateExtender.buildDefinition(adhocCredentialLookup), - stateExtender.buildDefinition(listSchedules), - stateExtender.buildDefinition(addSchedule), - stateExtender.buildDefinition(editSchedule), + stateExtender.buildDefinition(inventoryAdhocCredential), + stateExtender.buildDefinition(inventorySourceListScheduleRoute), + stateExtender.buildDefinition(inventorySourceListScheduleAddRoute), + stateExtender.buildDefinition(inventorySourceListScheduleEditRoute), stateExtender.buildDefinition(relatedHostsAnsibleFacts), stateExtender.buildDefinition(nestedHostsAnsibleFacts), stateExtender.buildDefinition(relatedHostsInsights), stateExtender.buildDefinition(nestedHostsInsights), stateExtender.buildDefinition(copyMoveGroupRoute), - stateExtender.buildDefinition(copyMoveHostRoute) + stateExtender.buildDefinition(copyMoveHostRoute), + stateExtender.buildDefinition(inventoryGroupsList), + stateExtender.buildDefinition(inventoryGroupsAdd), + stateExtender.buildDefinition(inventoryGroupsEdit), + stateExtender.buildDefinition(inventoryGroupsEditNestedGroups), + stateExtender.buildDefinition(nestedGroupsAdd), + stateExtender.buildDefinition(nestedHosts), + stateExtender.buildDefinition(nestedHostsAdd), + stateExtender.buildDefinition(nestedHostsEdit), + stateExtender.buildDefinition(inventoryGroupsEditNestedHostsEditGroups), + stateExtender.buildDefinition(inventoryHosts), + stateExtender.buildDefinition(inventoryHostsAdd), + stateExtender.buildDefinition(inventoryHostsEdit), + stateExtender.buildDefinition(inventoryHostsEditGroups), + stateExtender.buildDefinition(inventorySourceListRoute), + stateExtender.buildDefinition(inventorySourceAddRoute), + stateExtender.buildDefinition(inventorySourceEditRoute), + stateExtender.buildDefinition(inventoryCompletedJobsRoute) ]) }; }); @@ -358,6 +202,9 @@ angular.module('inventory', [ list: 'HostListController', edit: 'HostEditController' }, + breadcrumbs: { + edit: '{{breadcrumb.host_name}}' + }, urls: { list: '/hosts' }, @@ -392,8 +239,18 @@ angular.module('inventory', [ } }); - let hostAnsibleFacts = factsConfig('hosts.edit.ansible_facts'); - let hostInsights = insightsConfig('hosts.edit.insights'); + let hostAnsibleFacts = _.cloneDeep(ansibleFactsRoute); + hostAnsibleFacts.name = 'hosts.edit.ansible_facts'; + + let hostInsights = _.cloneDeep(insightsRoute); + hostInsights.name = 'hosts.edit.insights'; + + let hostsEditGroups = _.cloneDeep(nestedGroups); + hostsEditGroups.name = "hosts.edit.nested_groups"; + hostsEditGroups.ncyBreadcrumb = { + parent: "hosts.edit", + label: "ASSOCIATED GROUPS" + }; return Promise.all([ hostTree diff --git a/awx/ui/client/src/inventories/related-hosts/add/build-host-add-state.factory.js b/awx/ui/client/src/inventories/related-hosts/add/build-host-add-state.factory.js deleted file mode 100644 index 4a1ed4c9d7..0000000000 --- a/awx/ui/client/src/inventories/related-hosts/add/build-host-add-state.factory.js +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ - -import RelatedHostAddController from './host-add.controller'; - -export default ['$stateExtender', 'templateUrl', '$injector', - function($stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition, params) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - name: `${formStateDefinition.name}.${list.iterator}s.add`, - url: `/add`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - views: { - 'hostForm@inventories': { - templateProvider: function(GenerateForm, RelatedHostsFormDefinition) { - let form = RelatedHostsFormDefinition; - return GenerateForm.buildHTML(form, { - mode: 'add', - related: false - }); - }, - controller: RelatedHostAddController - } - }, - resolve: { - 'FormDefinition': [params.form, function(definition) { - return definition; - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/related-hosts/add/host-add.route.js b/awx/ui/client/src/inventories/related-hosts/add/host-add.route.js new file mode 100644 index 0000000000..456089f51f --- /dev/null +++ b/awx/ui/client/src/inventories/related-hosts/add/host-add.route.js @@ -0,0 +1,22 @@ +import { N_ } from '../../../i18n'; + +export default { + name: "inventories.edit.hosts.add", + url: "/add", + ncyBreadcrumb: { + parent: "inventories.edit.hosts", + label: N_("CREATE HOST") + }, + views: { + 'hostForm@inventories': { + templateProvider: function(GenerateForm, RelatedHostsFormDefinition) { + let form = RelatedHostsFormDefinition; + return GenerateForm.buildHTML(form, { + mode: 'add', + related: false + }); + }, + controller: 'RelatedHostAddController' + } + }, +}; diff --git a/awx/ui/client/src/inventories/related-hosts/add/main.js b/awx/ui/client/src/inventories/related-hosts/add/main.js index 48128f9a38..7a55327c9f 100644 --- a/awx/ui/client/src/inventories/related-hosts/add/main.js +++ b/awx/ui/client/src/inventories/related-hosts/add/main.js @@ -4,10 +4,8 @@ * All Rights Reserved *************************************************/ -import buildHostAddState from './build-host-add-state.factory'; import controller from './host-add.controller'; export default angular.module('relatedHostsAdd', []) - .factory('buildHostAddState', buildHostAddState) .controller('RelatedHostAddController', controller); diff --git a/awx/ui/client/src/inventories/related-hosts/edit/build-host-edit-state.factory.js b/awx/ui/client/src/inventories/related-hosts/edit/build-host-edit-state.factory.js deleted file mode 100644 index 7dfbd5d819..0000000000 --- a/awx/ui/client/src/inventories/related-hosts/edit/build-host-edit-state.factory.js +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ - -import RelatedHostEditController from './host-edit.controller'; - -export default ['$stateExtender', 'templateUrl', '$injector', - 'RelatedHostsFormDefinition', 'NestedHostsFormDefinition', - 'nestedGroupListState', - function($stateExtender, templateUrl, $injector, - RelatedHostsFormDefinition, NestedHostsFormDefinition, - nestedGroupListState){ - var val = function(field, formStateDefinition, params) { - let state, states = [], - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - name: `${formStateDefinition.name}.${list.iterator}s.edit`, - url: `/edit/:host_id`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - views: { - 'hostForm@inventories': { - templateProvider: function(GenerateForm, RelatedHostsFormDefinition, NestedHostsFormDefinition, $stateParams) { - let form = RelatedHostsFormDefinition; - if($stateParams.group_id){ - form = NestedHostsFormDefinition; - } - return GenerateForm.buildHTML(form, { - mode: 'edit', - related: false - }); - }, - controller: RelatedHostEditController - } - }, - resolve: { - 'FormDefinition': [params.form, function(definition) { - return definition; - }], - host: ['$stateParams', 'HostManageService', function($stateParams, HostManageService) { - return HostManageService.get({ id: $stateParams.host_id }).then(function(res) { - return res.data.results[0]; - }); - }] - } - }; - var relatedGroupListState; - state = $stateExtender.buildDefinition(stateConfig); - if(stateConfig.name === "inventories.edit.groups.edit.nested_hosts.edit"){ - relatedGroupListState = nestedGroupListState(NestedHostsFormDefinition.related.nested_groups, state, params); - relatedGroupListState = $stateExtender.buildDefinition(relatedGroupListState); - states.push(state, relatedGroupListState); - return states; - } - if(stateConfig.name === "inventories.edit.hosts.edit"){ - relatedGroupListState = nestedGroupListState(RelatedHostsFormDefinition.related.nested_groups, state, params); - relatedGroupListState = $stateExtender.buildDefinition(relatedGroupListState); - states.push(state, relatedGroupListState); - return states; - } - else { - return state; - } - - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/related-hosts/edit/host-edit.route.js b/awx/ui/client/src/inventories/related-hosts/edit/host-edit.route.js new file mode 100644 index 0000000000..f44066c625 --- /dev/null +++ b/awx/ui/client/src/inventories/related-hosts/edit/host-edit.route.js @@ -0,0 +1,30 @@ +export default { + name: "inventories.edit.hosts.edit", + url: "/edit/:host_id", + ncyBreadcrumb: { + parent: "inventories.edit.hosts", + label: "HOSTS" + }, + views: { + 'hostForm@inventories': { + templateProvider: function(GenerateForm, RelatedHostsFormDefinition, NestedHostsFormDefinition, $stateParams) { + let form = RelatedHostsFormDefinition; + if($stateParams.group_id){ + form = NestedHostsFormDefinition; + } + return GenerateForm.buildHTML(form, { + mode: 'edit', + related: false + }); + }, + controller: 'RelatedHostEditController' + } + }, + resolve: { + host: ['$stateParams', 'HostManageService', function($stateParams, HostManageService) { + return HostManageService.get({ id: $stateParams.host_id }).then(function(res) { + return res.data.results[0]; + }); + }] + } +}; diff --git a/awx/ui/client/src/inventories/related-hosts/edit/main.js b/awx/ui/client/src/inventories/related-hosts/edit/main.js index 731113f6e5..9536f686dc 100644 --- a/awx/ui/client/src/inventories/related-hosts/edit/main.js +++ b/awx/ui/client/src/inventories/related-hosts/edit/main.js @@ -3,10 +3,8 @@ * * All Rights Reserved *************************************************/ -import buildHostEditState from './build-host-edit-state.factory'; import controller from './host-edit.controller'; export default angular.module('relatedHostEdit', []) - .factory('buildHostEditState', buildHostEditState) .controller('RelatedHostEditController', controller); diff --git a/awx/ui/client/src/inventories/related-hosts/list/build-host-list-state.factory.js b/awx/ui/client/src/inventories/related-hosts/list/build-host-list-state.factory.js deleted file mode 100644 index 8ad2d71c3d..0000000000 --- a/awx/ui/client/src/inventories/related-hosts/list/build-host-list-state.factory.js +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ -import RelatedHostListController from './host-list.controller'; -export default ['RelatedHostsListDefinition', '$stateExtender', 'templateUrl', '$injector', - function(RelatedHostsListDefinition, $stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - searchPrefix: `${list.iterator}`, - name: `${formStateDefinition.name}.${list.iterator}s`, - url: `/${list.iterator}s`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - params: { - [list.iterator + '_search']: { - value: { order_by: field.order_by ? field.order_by : 'name' } - }, - }, - views: { - 'related': { - templateProvider: function(RelatedHostsListDefinition, generateList, $stateParams, GetBasePath) { - let list = _.cloneDeep(RelatedHostsListDefinition); - if($stateParams && $stateParams.group) { - list.basePath = GetBasePath('groups') + _.last($stateParams.group) + '/all_hosts'; - } - else { - //reaches here if the user is on the root level group - list.basePath = GetBasePath('inventory') + $stateParams.inventory_id + '/hosts'; - } - let html = generateList.build({ - list: list, - mode: 'edit' - }); - return html; - }, - controller: RelatedHostListController - } - }, - resolve: { - ListDefinition: () => { - return list; - }, - Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', - (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { - // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field - let path, interpolator; - if (GetBasePath(list.basePath)) { - path = GetBasePath(list.basePath); - } else { - interpolator = $interpolate(list.basePath); - path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); - } - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ], - hostsUrl: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { - return $stateParams.group && $stateParams.group.length > 0 ? - // nested context - provide all hosts managed by nodes - InventoryManageService.childHostsUrl(_.last($stateParams.group)) : - // root context - provide all hosts in an inventory - InventoryManageService.rootHostsUrl($stateParams.inventory_id); - }], - hostsDataset: ['RelatedHostsListDefinition', 'QuerySet', '$stateParams', 'hostsUrl', (list, qs, $stateParams, hostsUrl) => { - let path = hostsUrl; - return qs.search(path, $stateParams[`${list.iterator}_search`]); - }], - inventoryData: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { - return InventoryManageService.getInventory($stateParams.inventory_id).then(res => res.data); - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - // appy any default search parameters in form definition - if (field.search) { - state.params[`${field.iterator}_search`].value = _.merge(state.params[`${field.iterator}_search`].value, field.search); - } - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/related-hosts/list/main.js b/awx/ui/client/src/inventories/related-hosts/list/main.js index 5bdc8f2bc8..6cb8d2dda5 100644 --- a/awx/ui/client/src/inventories/related-hosts/list/main.js +++ b/awx/ui/client/src/inventories/related-hosts/list/main.js @@ -4,10 +4,8 @@ * All Rights Reserved *************************************************/ -import buildHostListState from './build-host-list-state.factory'; import RelatedHostListController from './host-list.controller'; export default angular.module('relatedHostList', []) - .factory('buildHostListState', buildHostListState) .controller('RelatedHostListController', RelatedHostListController); 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 0e71a6f0bb..9dc29daf31 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 @@ -10,8 +10,8 @@ * @description This form is for adding/editing a host on the inventory page */ -export default ['i18n', 'nestedGroupListState', -function(i18n,nestedGroupListState) { +export default ['i18n', +function(i18n) { return { addTitle: i18n._('CREATE HOST'), @@ -120,8 +120,7 @@ function(i18n,nestedGroupListState) { include: "NestedGroupListDefinition", includeForm: "NestedGroupFormDefinition", title: i18n._('Groups'), - iterator: 'nested_group', - listState: nestedGroupListState + iterator: 'nested_group' }, insights: { name: 'insights', diff --git a/awx/ui/client/src/inventories/related-hosts/related-host.route.js b/awx/ui/client/src/inventories/related-hosts/related-host.route.js new file mode 100644 index 0000000000..a9bb70695d --- /dev/null +++ b/awx/ui/client/src/inventories/related-hosts/related-host.route.js @@ -0,0 +1,69 @@ +import { N_ } from '../../i18n'; + +export default { + name: "inventories.edit.hosts", + url: "/hosts?{host_search:queryset}", + params: { + host_search: { + value: { + page_size: "20", + order_by: "name" + }, + dynamic: true, + squash:"" + } + }, + ncyBreadcrumb: { + parent: "inventories.edit", + label: N_("HOSTS") + }, + views: { + 'related': { + templateProvider: function(RelatedHostsListDefinition, generateList, $stateParams, GetBasePath) { + let list = _.cloneDeep(RelatedHostsListDefinition); + if($stateParams && $stateParams.group) { + list.basePath = GetBasePath('groups') + _.last($stateParams.group) + '/all_hosts'; + } + else { + //reaches here if the user is on the root level group + list.basePath = GetBasePath('inventory') + $stateParams.inventory_id + '/hosts'; + } + let html = generateList.build({ + list: list, + mode: 'edit' + }); + return html; + }, + controller: 'RelatedHostListController' + } + }, + resolve: { + Dataset: ['RelatedHostsListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', + (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { + // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field + let path, interpolator; + if (GetBasePath(list.basePath)) { + path = GetBasePath(list.basePath); + } else { + interpolator = $interpolate(list.basePath); + path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); + } + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + hostsUrl: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { + return $stateParams.group && $stateParams.group.length > 0 ? + // nested context - provide all hosts managed by nodes + InventoryManageService.childHostsUrl(_.last($stateParams.group)) : + // root context - provide all hosts in an inventory + InventoryManageService.rootHostsUrl($stateParams.inventory_id); + }], + hostsDataset: ['RelatedHostsListDefinition', 'QuerySet', '$stateParams', 'hostsUrl', (list, qs, $stateParams, hostsUrl) => { + let path = hostsUrl; + return qs.search(path, $stateParams[`${list.iterator}_search`]); + }], + inventoryData: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { + return InventoryManageService.getInventory($stateParams.inventory_id).then(res => res.data); + }] + } +}; diff --git a/awx/ui/client/src/inventories/sources/add/build-sources-add-state.factory.js b/awx/ui/client/src/inventories/sources/add/build-sources-add-state.factory.js deleted file mode 100644 index 234fa72bf7..0000000000 --- a/awx/ui/client/src/inventories/sources/add/build-sources-add-state.factory.js +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ - -import SourcesAddController from './sources-add.controller'; - -export default ['$stateExtender', 'templateUrl', '$injector', - function($stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition, params) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - name: `${formStateDefinition.name}.${list.iterator}s.add`, - url: `/add`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - views: { - 'sourcesForm@inventories': { - templateProvider: function(GenerateForm, SourcesFormDefinition) { - let form = SourcesFormDefinition; - return GenerateForm.buildHTML(form, { - mode: 'add', - related: false - }); - }, - controller: SourcesAddController - } - }, - resolve: { - 'FormDefinition': [params.form, function(definition) { - return definition; - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/sources/add/main.js b/awx/ui/client/src/inventories/sources/add/main.js index 134eaf5214..04cfc8ba9a 100644 --- a/awx/ui/client/src/inventories/sources/add/main.js +++ b/awx/ui/client/src/inventories/sources/add/main.js @@ -4,10 +4,8 @@ * All Rights Reserved *************************************************/ -import buildSourcesAddState from './build-sources-add-state.factory'; import controller from './sources-add.controller'; export default angular.module('sourcesAdd', []) - .factory('buildSourcesAddState', buildSourcesAddState) .controller('SourcesAddController', controller); diff --git a/awx/ui/client/src/inventories/sources/add/sources-add.route.js b/awx/ui/client/src/inventories/sources/add/sources-add.route.js new file mode 100644 index 0000000000..40b8bdcc75 --- /dev/null +++ b/awx/ui/client/src/inventories/sources/add/sources-add.route.js @@ -0,0 +1,22 @@ +import { N_ } from '../../../i18n'; + +export default { + name: "inventories.edit.inventory_sources.add", + url: "/add", + ncyBreadcrumb: { + parent: "inventories.edit.inventory_sources", + label: N_("CREATE INVENTORY SOURCE") + }, + views: { + 'sourcesForm@inventories': { + templateProvider: function(GenerateForm, SourcesFormDefinition) { + let form = SourcesFormDefinition; + return GenerateForm.buildHTML(form, { + mode: 'add', + related: false + }); + }, + controller: 'SourcesAddController' + } + }, +}; diff --git a/awx/ui/client/src/inventories/sources/edit/build-sources-edit-state.factory.js b/awx/ui/client/src/inventories/sources/edit/build-sources-edit-state.factory.js deleted file mode 100644 index 5862650f27..0000000000 --- a/awx/ui/client/src/inventories/sources/edit/build-sources-edit-state.factory.js +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ - -import SourcesEditController from './sources-edit.controller'; - -export default ['$stateExtender', 'templateUrl', '$injector', - function($stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition, params) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - name: `${formStateDefinition.name}.${list.iterator}s.edit`, - url: `/edit/:inventory_source_id`, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - views: { - 'groupForm@inventories': { - templateProvider: function(GenerateForm, SourcesFormDefinition) { - let form = SourcesFormDefinition; - return GenerateForm.buildHTML(form, { - mode: 'edit', - related: false - }); - }, - controller: SourcesEditController - } - }, - resolve: { - 'FormDefinition': [params.form, function(definition) { - return definition; - }], - inventorySourceData: ['$stateParams', 'SourcesService', function($stateParams, SourcesService) { - return SourcesService.get({id: $stateParams.inventory_source_id }).then(res => res.data.results[0]); - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/sources/edit/main.js b/awx/ui/client/src/inventories/sources/edit/main.js index eb130001d5..8c68bc5544 100644 --- a/awx/ui/client/src/inventories/sources/edit/main.js +++ b/awx/ui/client/src/inventories/sources/edit/main.js @@ -4,10 +4,8 @@ * All Rights Reserved *************************************************/ -import buildSourcesEditState from './build-sources-edit-state.factory'; import controller from './sources-edit.controller'; export default angular.module('sourcesEdit', []) - .factory('buildSourcesEditState', buildSourcesEditState) .controller('SourcesEditController', controller); diff --git a/awx/ui/client/src/inventories/sources/edit/sources-edit.route.js b/awx/ui/client/src/inventories/sources/edit/sources-edit.route.js new file mode 100644 index 0000000000..03904159da --- /dev/null +++ b/awx/ui/client/src/inventories/sources/edit/sources-edit.route.js @@ -0,0 +1,27 @@ +import { N_ } from '../../../i18n'; + +export default { + name: "inventories.edit.inventory_sources.edit", + url: "/edit/:inventory_source_id", + ncyBreadcrumb: { + parent: "inventories.edit.inventory_sources", + label: N_("INVENTORY SOURCES") + }, + views: { + 'groupForm@inventories': { + templateProvider: function(GenerateForm, SourcesFormDefinition) { + let form = SourcesFormDefinition; + return GenerateForm.buildHTML(form, { + mode: 'edit', + related: false + }); + }, + controller: 'SourcesEditController' + } + }, + resolve: { + inventorySourceData: ['$stateParams', 'SourcesService', function($stateParams, SourcesService) { + return SourcesService.get({id: $stateParams.inventory_source_id }).then(res => res.data.results[0]); + }] + } +}; diff --git a/awx/ui/client/src/inventories/sources/list/build-sources-list-state.factory.js b/awx/ui/client/src/inventories/sources/list/build-sources-list-state.factory.js deleted file mode 100644 index 71792e273d..0000000000 --- a/awx/ui/client/src/inventories/sources/list/build-sources-list-state.factory.js +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************* -* Copyright (c) 2017 Ansible, Inc. -* -* All Rights Reserved -*************************************************/ -import SourcesListController from './sources-list.controller'; -export default ['SourcesListDefinition', '$stateExtender', 'templateUrl', '$injector', - function(SourcesListDefinition, $stateExtender, templateUrl, $injector){ - var val = function(field, formStateDefinition) { - let state, - list = field.include ? $injector.get(field.include) : field, - breadcrumbLabel = (field.iterator.replace('_', ' ') + 's').toUpperCase(), - stateConfig = { - searchPrefix: `${list.iterator}`, - name: `${formStateDefinition.name}.${list.iterator}s`, - url: `/${list.iterator}s`, - data: { - socket: { - "groups": { - "jobs": ["status_changed"] - } - } - }, - ncyBreadcrumb: { - parent: `${formStateDefinition.name}`, - label: `${breadcrumbLabel}` - }, - params: { - [list.iterator + '_search']: { - value: { order_by: field.order_by ? field.order_by : 'name' } - }, - }, - views: { - 'related': { - templateProvider: function(SourcesListDefinition, generateList) { - let list = _.cloneDeep(SourcesListDefinition); - let html = generateList.build({ - list: list, - mode: 'edit' - }); - // Include the custom group delete modal template - // return $templateRequest(templateUrl('inventories/groups/list/groups-list')).then((template) => { - // return html.concat(template); - // }); - return html; - }, - controller: SourcesListController - } - }, - resolve: { - ListDefinition: () => { - return list; - }, - Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', - (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { - // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field - let path, interpolator; - if (GetBasePath(list.basePath)) { - path = GetBasePath(list.basePath); - } else { - interpolator = $interpolate(list.basePath); - path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); - } - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ], - inventoryData: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { - return InventoryManageService.getInventory($stateParams.inventory_id).then(res => res.data); - }] - } - }; - - state = $stateExtender.buildDefinition(stateConfig); - // appy any default search parameters in form definition - // if (field.search) { - // state.params[`${field.iterator}_search`].value = _.merge(state.params[`${field.iterator}_search`].value, field.search); - // } - return state; - }; - return val; - } -]; diff --git a/awx/ui/client/src/inventories/sources/list/main.js b/awx/ui/client/src/inventories/sources/list/main.js index c33538ab1f..2c7c3b62f8 100644 --- a/awx/ui/client/src/inventories/sources/list/main.js +++ b/awx/ui/client/src/inventories/sources/list/main.js @@ -4,10 +4,8 @@ * All Rights Reserved *************************************************/ -import buildSourcesListState from './build-sources-list-state.factory'; import controller from './sources-list.controller'; export default angular.module('sourcesList', []) - .factory('buildSourcesListState', buildSourcesListState) .controller('SourcesListController', controller); diff --git a/awx/ui/client/src/inventories/sources/list/schedule/sources-schedule-add.route.js b/awx/ui/client/src/inventories/sources/list/schedule/sources-schedule-add.route.js new file mode 100644 index 0000000000..27faa728ed --- /dev/null +++ b/awx/ui/client/src/inventories/sources/list/schedule/sources-schedule-add.route.js @@ -0,0 +1,16 @@ +import { N_ } from '../../../../i18n'; +import {templateUrl} from '../../../../shared/template-url/template-url.factory'; + +export default { + name: 'inventories.edit.inventory_sources.edit.schedules.add', + url: '/add', + ncyBreadcrumb: { + label: N_("CREATE SCHEDULE") + }, + views: { + 'form': { + controller: 'schedulerAddController', + templateUrl: templateUrl("scheduler/schedulerForm") + } + } +}; diff --git a/awx/ui/client/src/inventories/sources/list/schedule/sources-schedule-edit.route.js b/awx/ui/client/src/inventories/sources/list/schedule/sources-schedule-edit.route.js new file mode 100644 index 0000000000..f43c9b3def --- /dev/null +++ b/awx/ui/client/src/inventories/sources/list/schedule/sources-schedule-edit.route.js @@ -0,0 +1,15 @@ +import {templateUrl} from '../../../../shared/template-url/template-url.factory'; + +export default { + name: 'inventories.edit.inventory_sources.edit.schedules.edit', + url: '/:schedule_id', + ncyBreadcrumb: { + label: "{{schedule_obj.name}}" + }, + views: { + 'form': { + templateUrl: templateUrl("scheduler/schedulerForm"), + controller: 'schedulerEditController', + } + } +}; diff --git a/awx/ui/client/src/inventories/sources/list/schedule/sources-schedule.route.js b/awx/ui/client/src/inventories/sources/list/schedule/sources-schedule.route.js new file mode 100644 index 0000000000..3edae958d1 --- /dev/null +++ b/awx/ui/client/src/inventories/sources/list/schedule/sources-schedule.route.js @@ -0,0 +1,60 @@ +import { N_ } from '../../../../i18n'; + +export default { + name: 'inventories.edit.inventory_sources.edit.schedules', + url: '/schedules', + searchPrefix: 'schedule', + ncyBreadcrumb: { + label: N_('SCHEDULES') + }, + resolve: { + Dataset: ['ScheduleList', 'QuerySet', '$stateParams', 'GetBasePath', 'inventorySourceData', + function(list, qs, $stateParams, GetBasePath, inventorySourceData) { + let path = `${inventorySourceData.related.schedules}`; + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + ParentObject: ['inventorySourceData', function(inventorySourceData) { + return inventorySourceData; + }], + UnifiedJobsOptions: ['Rest', 'GetBasePath', '$stateParams', '$q', + function(Rest, GetBasePath, $stateParams, $q) { + Rest.setUrl(GetBasePath('unified_jobs')); + var val = $q.defer(); + Rest.options() + .then(function(data) { + val.resolve(data.data); + }, function(data) { + val.reject(data); + }); + return val.promise; + }], + ScheduleList: ['SchedulesList', 'inventorySourceData', + (SchedulesList, inventorySourceData) => { + let list = _.cloneDeep(SchedulesList); + list.basePath = `${inventorySourceData.related.schedules}`; + return list; + } + ] + }, + views: { + // clear form template when views render in this substate + 'form': { + templateProvider: () => '' + }, + // target the un-named ui-view @ root level + '@': { + templateProvider: function(ScheduleList, generateList, ParentObject) { + // include name of parent resource in listTitle + ScheduleList.listTitle = `${ParentObject.name}
` + N_('SCHEDULES'); + let html = generateList.build({ + list: ScheduleList, + mode: 'edit' + }); + html = generateList.wrapPanel(html); + return "
" + generateList.insertFormView() + html + "
"; + }, + controller: 'schedulerListController' + } + } +}; diff --git a/awx/ui/client/src/inventories/sources/list/sources-list.controller.js b/awx/ui/client/src/inventories/sources/list/sources-list.controller.js index 8e260c0590..0e09051f16 100644 --- a/awx/ui/client/src/inventories/sources/list/sources-list.controller.js +++ b/awx/ui/client/src/inventories/sources/list/sources-list.controller.js @@ -34,12 +34,6 @@ $scope[`${list.iterator}_dataset`] = Dataset.data; $scope[list.name] = $scope[`${list.iterator}_dataset`].results; - // The ncy breadcrumb directive will look at this attribute when attempting to bind to the correct scope. - // In this case, we don't want to incidentally bind to this scope when editing a host or a group. See: - // https://github.com/ncuillery/angular-breadcrumb/issues/42 for a little more information on the - // problem that this solves. - $scope.ncyBreadcrumbIgnore = true; - $scope.inventory_id = $stateParams.inventory_id; _.forEach($scope[list.name], buildStatusIndicators); diff --git a/awx/ui/client/src/inventories/sources/list/sources-list.route.js b/awx/ui/client/src/inventories/sources/list/sources-list.route.js new file mode 100644 index 0000000000..73e7a1ffc9 --- /dev/null +++ b/awx/ui/client/src/inventories/sources/list/sources-list.route.js @@ -0,0 +1,62 @@ +import { N_ } from '../../../i18n'; + +export default { + name: "inventories.edit.inventory_sources", + url: "/inventory_sources?{inventory_source_search:queryset}", + params: { + inventory_source_search: { + value: { + page_size: "20", + order_by: "name" + }, + dynamic: true, + squash: "" + } + }, + data: { + socket: { + groups: { + jobs: ["status_changed"] + } + } + }, + ncyBreadcrumb: { + parent: "inventories.edit", + label: N_("SOURCES") + }, + views: { + 'related': { + templateProvider: function(SourcesListDefinition, generateList) { + let list = _.cloneDeep(SourcesListDefinition); + let html = generateList.build({ + list: list, + mode: 'edit' + }); + // Include the custom group delete modal template + // return $templateRequest(templateUrl('inventories/groups/list/groups-list')).then((template) => { + // return html.concat(template); + // }); + return html; + }, + controller: 'SourcesListController' + } + }, + resolve: { + Dataset: ['SourcesListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope', + (list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => { + // allow related list definitions to use interpolated $rootScope / $stateParams in basePath field + let path, interpolator; + if (GetBasePath(list.basePath)) { + path = GetBasePath(list.basePath); + } else { + interpolator = $interpolate(list.basePath); + path = interpolator({ $rootScope: $rootScope, $stateParams: $stateParams }); + } + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + inventoryData: ['InventoryManageService', '$stateParams', function(InventoryManageService, $stateParams) { + return InventoryManageService.getInventory($stateParams.inventory_id).then(res => res.data); + }] + } +}; diff --git a/awx/ui/client/src/shared/stateDefinitions.factory.js b/awx/ui/client/src/shared/stateDefinitions.factory.js index 14395fc024..7d0e07953d 100644 --- a/awx/ui/client/src/shared/stateDefinitions.factory.js +++ b/awx/ui/client/src/shared/stateDefinitions.factory.js @@ -181,12 +181,13 @@ function($injector, $stateExtender, $log, i18n) { break; case 'edit': url = params.urls && params.urls.edit ? params.urls.edit : (params.url ? params.url : `/:${form.name}_id`); + let breadcrumbLabel = params.breadcrumbs && params.breadcrumbs.edit ? params.breadcrumbs.edit : '{{parentObject.name || name}}'; let formNodeState = { name: params.name || `${params.parent}.edit`, url: url, ncyBreadcrumb: { [params.parent ? 'parent' : null]: `${params.parent}`, - label: '{{parentObject.name || name}}' + label: breadcrumbLabel }, views: { 'form': { @@ -246,7 +247,6 @@ function($injector, $stateExtender, $log, i18n) { * @returns {array} Array of state definitions [{...}, {...}, ...] */ generateFormListDefinitions: function(form, formStateDefinition, params) { - var that = this; function buildRbacUserTeamDirective(){ let states = []; @@ -553,34 +553,7 @@ function($injector, $stateExtender, $log, i18n) { function buildListNodes(field) { let states = []; 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 below 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 below 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'){ + if(field.iterator === 'notification'){ states.push(buildNotificationState(field)); states = _.flatten(states); }