From b741354ad01a9dc34ddc8c934241c7d2f2b9a3ff Mon Sep 17 00:00:00 2001 From: Michael Abashian Date: Thu, 6 Apr 2017 15:20:55 -0400 Subject: [PATCH] Removed old inventories code. Cleaned up new inventories code --- awx/ui/client/src/app.js | 2 - .../add/inventory-add.controller.js | 2 +- awx/ui/client/src/inventories/add/main.js | 2 +- .../edit/inventory-edit.controller.js | 10 +- awx/ui/client/src/inventories/edit/main.js | 2 +- .../edit/build-groups-edit-state.factory.js | 93 +++++ .../nested-groups-list-state.factory.js | 85 ++++ .../nested-hosts-list.controller.js | 162 ++++++++ .../nested-hosts/nested-hosts.form.js} | 28 +- .../hosts/add/host-add.controller.js | 0 .../hosts/add/main.js | 2 +- .../hosts/edit/host-edit.controller.js | 0 .../hosts/edit/main.js | 2 +- .../hosts/host.form.js | 0 .../hosts/host.list.js | 1 + .../{manage => }/hosts/hosts.service.js | 0 .../hosts/list/host-list.controller.js | 13 +- .../hosts/list/main.js | 2 +- awx/ui/client/src/inventories/hosts/main.js | 26 ++ .../set-enabled-msg.factory.js | 0 .../factories => hosts}/set-status.factory.js | 0 .../inventories.partial.html | 6 +- .../client/src/inventories/inventory.list.js | 3 +- .../list/inventory-list.controller.js | 8 +- awx/ui/client/src/inventories/list/main.js | 2 +- awx/ui/client/src/inventories/main.js | 365 ++++-------------- .../manage/adhoc/adhoc.controller.js | 308 --------------- .../inventories/manage/adhoc/adhoc.form.js | 159 -------- .../manage/adhoc/adhoc.partial.html | 4 - .../inventories/manage/adhoc/adhoc.route.js | 28 -- .../src/inventories/manage/adhoc/main.js | 7 - .../manage/breadcrumbs/breadcrumbs.block.less | 25 -- .../breadcrumbs/breadcrumbs.controller.js | 38 -- .../breadcrumbs/breadcrumbs.partial.html | 22 -- .../manage/copy-move/copy-move-groups.list.js | 24 -- .../manage/copy-move/copy-move.block.less | 33 -- .../manage/copy-move/copy-move.partial.html | 21 - .../src/inventories/manage/copy-move/main.js | 15 - .../factories/get-hosts-status-msg.factory.js | 33 -- .../get-source-type-options.factory.js | 37 -- .../factories/get-sync-status-msg.factory.js | 77 ---- .../factories/groups-cancel-update.factory.js | 81 ---- .../factories/view-update-status.factory.js | 46 --- .../manage/groups/groups-list.partial.html | 79 ---- .../manage/groups/groups.block.less | 16 - .../inventories/manage/groups/groups.form.js | 360 ----------------- .../manage/groups/groups.service.js | 113 ------ .../manage/groups/inventory-groups.list.js | 167 -------- .../src/inventories/manage/groups/main.js | 27 -- .../manage/hosts/hosts-edit.controller.js | 84 ---- .../manage/hosts/hosts-list.controller.js | 120 ------ .../manage/hosts/inventory-hosts.list.js | 119 ------ .../src/inventories/manage/hosts/main.js | 21 - .../manage/inventory-manage.block.less | 3 - .../manage/inventory-manage.controller.js | 28 -- .../manage/inventory-manage.partial.html | 8 - awx/ui/client/src/inventories/manage/main.js | 24 -- .../edit/build-host-edit-state.factory.js | 73 ++++ .../add/inventory-add.controller.js | 104 ----- awx/ui/client/src/inventoriesnew/add/main.js | 11 - .../edit/inventory-edit.controller.js | 136 ------- awx/ui/client/src/inventoriesnew/edit/main.js | 11 - .../client/src/inventoriesnew/hosts/main.js | 20 - .../src/inventoriesnew/inventory.form.js | 135 ------- .../src/inventoriesnew/inventory.list.js | 98 ----- .../list/inventory-list.controller.js | 308 --------------- awx/ui/client/src/inventoriesnew/list/main.js | 11 - awx/ui/client/src/inventoriesnew/main.js | 236 ----------- .../src/main-menu/main-menu.partial.html | 17 - .../src/shared/stateDefinitions.factory.js | 2 +- awx/ui/templates/ui/index.html | 3 +- 71 files changed, 572 insertions(+), 3536 deletions(-) create mode 100644 awx/ui/client/src/inventories/groups/edit/build-groups-edit-state.factory.js create 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-hosts/nested-hosts-list.controller.js rename awx/ui/client/src/inventories/{manage/hosts/hosts.form.js => groups/nested-hosts/nested-hosts.form.js} (79%) rename awx/ui/client/src/{inventoriesnew => inventories}/hosts/add/host-add.controller.js (100%) rename awx/ui/client/src/{inventoriesnew => inventories}/hosts/add/main.js (83%) rename awx/ui/client/src/{inventoriesnew => inventories}/hosts/edit/host-edit.controller.js (100%) rename awx/ui/client/src/{inventoriesnew => inventories}/hosts/edit/main.js (82%) rename awx/ui/client/src/{inventoriesnew => inventories}/hosts/host.form.js (100%) rename awx/ui/client/src/{inventoriesnew => inventories}/hosts/host.list.js (99%) rename awx/ui/client/src/inventories/{manage => }/hosts/hosts.service.js (100%) rename awx/ui/client/src/{inventoriesnew => inventories}/hosts/list/host-list.controller.js (89%) rename awx/ui/client/src/{inventoriesnew => inventories}/hosts/list/main.js (82%) create mode 100644 awx/ui/client/src/inventories/hosts/main.js rename awx/ui/client/src/inventories/{manage/hosts/factories => hosts}/set-enabled-msg.factory.js (100%) rename awx/ui/client/src/inventories/{manage/hosts/factories => hosts}/set-status.factory.js (100%) rename awx/ui/client/src/{inventoriesnew => inventories}/inventories.partial.html (60%) delete mode 100644 awx/ui/client/src/inventories/manage/adhoc/adhoc.controller.js delete mode 100644 awx/ui/client/src/inventories/manage/adhoc/adhoc.form.js delete mode 100644 awx/ui/client/src/inventories/manage/adhoc/adhoc.partial.html delete mode 100644 awx/ui/client/src/inventories/manage/adhoc/adhoc.route.js delete mode 100644 awx/ui/client/src/inventories/manage/adhoc/main.js delete mode 100644 awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.block.less delete mode 100644 awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.controller.js delete mode 100644 awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.partial.html delete mode 100644 awx/ui/client/src/inventories/manage/copy-move/copy-move-groups.list.js delete mode 100644 awx/ui/client/src/inventories/manage/copy-move/copy-move.block.less delete mode 100644 awx/ui/client/src/inventories/manage/copy-move/copy-move.partial.html delete mode 100644 awx/ui/client/src/inventories/manage/copy-move/main.js delete mode 100644 awx/ui/client/src/inventories/manage/groups/factories/get-hosts-status-msg.factory.js delete mode 100644 awx/ui/client/src/inventories/manage/groups/factories/get-source-type-options.factory.js delete mode 100644 awx/ui/client/src/inventories/manage/groups/factories/get-sync-status-msg.factory.js delete mode 100644 awx/ui/client/src/inventories/manage/groups/factories/groups-cancel-update.factory.js delete mode 100644 awx/ui/client/src/inventories/manage/groups/factories/view-update-status.factory.js delete mode 100644 awx/ui/client/src/inventories/manage/groups/groups-list.partial.html delete mode 100644 awx/ui/client/src/inventories/manage/groups/groups.block.less delete mode 100644 awx/ui/client/src/inventories/manage/groups/groups.form.js delete mode 100644 awx/ui/client/src/inventories/manage/groups/groups.service.js delete mode 100644 awx/ui/client/src/inventories/manage/groups/inventory-groups.list.js delete mode 100644 awx/ui/client/src/inventories/manage/groups/main.js delete mode 100644 awx/ui/client/src/inventories/manage/hosts/hosts-edit.controller.js delete mode 100644 awx/ui/client/src/inventories/manage/hosts/hosts-list.controller.js delete mode 100644 awx/ui/client/src/inventories/manage/hosts/inventory-hosts.list.js delete mode 100644 awx/ui/client/src/inventories/manage/hosts/main.js delete mode 100644 awx/ui/client/src/inventories/manage/inventory-manage.block.less delete mode 100644 awx/ui/client/src/inventories/manage/inventory-manage.controller.js delete mode 100644 awx/ui/client/src/inventories/manage/inventory-manage.partial.html delete mode 100644 awx/ui/client/src/inventories/manage/main.js create mode 100644 awx/ui/client/src/inventories/related-hosts/edit/build-host-edit-state.factory.js delete mode 100644 awx/ui/client/src/inventoriesnew/add/inventory-add.controller.js delete mode 100644 awx/ui/client/src/inventoriesnew/add/main.js delete mode 100644 awx/ui/client/src/inventoriesnew/edit/inventory-edit.controller.js delete mode 100644 awx/ui/client/src/inventoriesnew/edit/main.js delete mode 100644 awx/ui/client/src/inventoriesnew/hosts/main.js delete mode 100644 awx/ui/client/src/inventoriesnew/inventory.form.js delete mode 100644 awx/ui/client/src/inventoriesnew/inventory.list.js delete mode 100644 awx/ui/client/src/inventoriesnew/list/inventory-list.controller.js delete mode 100644 awx/ui/client/src/inventoriesnew/list/main.js delete mode 100644 awx/ui/client/src/inventoriesnew/main.js diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index f5eaf2080b..0649023b54 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -40,7 +40,6 @@ if ($basePath) { import portalMode from './portal-mode/main'; import systemTracking from './system-tracking/main'; import inventories from './inventories/main'; -import inventorynew from './inventoriesnew/main'; import inventoryScripts from './inventory-scripts/main'; import credentialTypes from './credential-types/main'; import organizations from './organizations/main'; @@ -100,7 +99,6 @@ var tower = angular.module('Tower', [ configuration.name, systemTracking.name, inventories.name, - inventorynew.name, inventoryScripts.name, credentialTypes.name, organizations.name, diff --git a/awx/ui/client/src/inventories/add/inventory-add.controller.js b/awx/ui/client/src/inventories/add/inventory-add.controller.js index 4287cfb404..02e608af6c 100644 --- a/awx/ui/client/src/inventories/add/inventory-add.controller.js +++ b/awx/ui/client/src/inventories/add/inventory-add.controller.js @@ -77,7 +77,7 @@ function InventoriesAdd($scope, $location, .success(function(data) { var inventory_id = data.id; Wait('stop'); - $location.path('/inventories/' + inventory_id + '/manage'); + $location.path('/inventories/' + inventory_id); }) .error(function(data, status) { ProcessErrors($scope, data, status, form, { diff --git a/awx/ui/client/src/inventories/add/main.js b/awx/ui/client/src/inventories/add/main.js index fc9c82e6fd..2e477aa96c 100644 --- a/awx/ui/client/src/inventories/add/main.js +++ b/awx/ui/client/src/inventories/add/main.js @@ -7,5 +7,5 @@ import controller from './inventory-add.controller'; export default -angular.module('inventoryAdd', []) +angular.module('InventoryAdd', []) .controller('InventoryAddController', controller); 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 78d35d311f..c08f101ce0 100644 --- a/awx/ui/client/src/inventories/edit/inventory-edit.controller.js +++ b/awx/ui/client/src/inventories/edit/inventory-edit.controller.js @@ -11,13 +11,13 @@ */ function InventoriesEdit($scope, $location, - $stateParams, InventoryForm, Rest, ProcessErrors, + $stateParams, InventoriesForm, Rest, ProcessErrors, ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON, ParseVariableString, $state, OrgAdminLookup) { // Inject dynamic view var defaultUrl = GetBasePath('inventory'), - form = InventoryForm, + form = InventoriesForm, inventory_id = $stateParams.inventory_id, master = {}, fld, json_data, data; @@ -122,10 +122,6 @@ function InventoriesEdit($scope, $location, }); }; - $scope.manageInventory = function() { - $location.path($location.path() + '/manage'); - }; - $scope.formCancel = function() { $state.go('inventories'); }; @@ -133,7 +129,7 @@ function InventoriesEdit($scope, $location, } export default ['$scope', '$location', - '$stateParams', 'InventoryForm', 'Rest', + '$stateParams', 'InventoriesForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', '$state', 'OrgAdminLookup', InventoriesEdit, diff --git a/awx/ui/client/src/inventories/edit/main.js b/awx/ui/client/src/inventories/edit/main.js index f8792fe442..130a5e8b4b 100644 --- a/awx/ui/client/src/inventories/edit/main.js +++ b/awx/ui/client/src/inventories/edit/main.js @@ -7,5 +7,5 @@ import controller from './inventory-edit.controller'; export default - angular.module('inventoryEdit', []) + angular.module('InventoryEdit', []) .controller('InventoryEditController', 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 new file mode 100644 index 0000000000..3687face76 --- /dev/null +++ b/awx/ui/client/src/inventories/groups/edit/build-groups-edit-state.factory.js @@ -0,0 +1,93 @@ +/************************************************* +* 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/nested-groups/nested-groups-list-state.factory.js b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list-state.factory.js new file mode 100644 index 0000000000..7efd37c391 --- /dev/null +++ b/awx/ui/client/src/inventories/groups/nested-groups/nested-groups-list-state.factory.js @@ -0,0 +1,85 @@ +/************************************************* +* 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`]); + } + ], + inventoryData: ['InventoryManageService', '$stateParams', 'host', function(InventoryManageService, $stateParams, host) { + var id = ($stateParams.inventory_id) ? $stateParams.inventory_id : host.data.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-hosts/nested-hosts-list.controller.js b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-list.controller.js new file mode 100644 index 0000000000..20196b1647 --- /dev/null +++ b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts-list.controller.js @@ -0,0 +1,162 @@ +/************************************************* + * Copyright (c) 2017 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default ['$scope', 'NestedHostsListDefinition', '$rootScope', 'GetBasePath', + 'rbacUiControlService', 'Dataset', '$state', '$filter', 'Prompt', 'Wait', + 'HostManageService', 'SetStatus', + function($scope, NestedHostsListDefinition, $rootScope, GetBasePath, + rbacUiControlService, Dataset, $state, $filter, Prompt, Wait, + HostManageService, SetStatus) { + + let list = NestedHostsListDefinition; + + init(); + + function init(){ + $scope.canAdd = false; + $scope.enableSmartInventoryButton = false; + + rbacUiControlService.canAdd('hosts') + .then(function(canAdd) { + $scope.canAdd = canAdd; + }); + + // Search init + $scope.list = list; + $scope[`${list.iterator}_dataset`] = Dataset.data; + $scope[list.name] = $scope[`${list.iterator}_dataset`].results; + + $rootScope.flashMessage = null; + + $scope.$watchCollection(list.name, function() { + $scope[list.name] = _.map($scope.nested_hosts, function(value) { + value.inventory_name = value.summary_fields.inventory.name; + value.inventory_id = value.summary_fields.inventory.id; + return value; + }); + setJobStatus(); + }); + + $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams) { + if(toState.name === 'hosts.addSmartInventory') { + $scope.enableSmartInventoryButton = false; + } + else { + if(toParams && toParams.host_search) { + let hasMoreThanDefaultKeys = false; + angular.forEach(toParams.host_search, function(value, key) { + if(key !== 'order_by' && key !== 'page_size') { + hasMoreThanDefaultKeys = true; + } + }); + $scope.enableSmartInventoryButton = hasMoreThanDefaultKeys ? true : false; + } + else { + $scope.enableSmartInventoryButton = false; + } + } + }); + + $scope.$on('selectedOrDeselected', function(e, value) { + let item = value.value; + + if (value.isSelected) { + if(!$scope.hostsSelected) { + $scope.hostsSelected = []; + } + $scope.hostsSelected.push(item); + } else { + _.remove($scope.hostsSelected, { id: item.id }); + if($scope.hostsSelected.length === 0) { + $scope.hostsSelected = null; + } + } + + $scope.systemTrackingDisabled = ($scope.hostsSelected && $scope.hostsSelected.length > 2) ? true : false; + }); + + } + + function setJobStatus(){ + _.forEach($scope.hosts, function(value) { + SetStatus({ + scope: $scope, + host: value + }); + }); + } + + $scope.createHost = function(){ + $state.go('inventories.edit.groups.edit.nested_hosts.add'); + }; + $scope.editHost = function(id){ + $state.go('inventories.edit.groups.edit.nested_hosts.edit', {host_id: id}); + }; + $scope.deleteHost = function(id, name){ + var body = '
Are you sure you want to permanently delete the host below from the inventory?
' + $filter('sanitize')(name) + '
'; + var action = function(){ + delete $rootScope.promptActionBtnClass; + Wait('start'); + HostManageService.delete(id).then(() => { + $('#prompt-modal').modal('hide'); + if (parseInt($state.params.host_id) === id) { + $state.go("hosts", null, {reload: true}); + } else { + $state.go($state.current.name, null, {reload: true}); + } + Wait('stop'); + }); + }; + // Prompt depends on having $rootScope.promptActionBtnClass available... + Prompt({ + hdr: 'Delete Host', + body: body, + action: action, + actionText: 'DELETE', + }); + $rootScope.promptActionBtnClass = 'Modal-errorButton'; + }; + + $scope.toggleHost = function(event, host) { + try { + $(event.target).tooltip('hide'); + } catch (e) { + // ignore + } + + host.enabled = !host.enabled; + + HostManageService.put(host).then(function(){ + $state.go($state.current, null, {reload: true}); + }); + }; + + $scope.smartInventory = function() { + $state.go('inventories.addSmartInventory'); + }; + + $scope.systemTracking = function(){ + var hostIds = _.map($scope.hostsSelected, (host) => host.id); + $state.go('systemTracking', { + inventoryId: $state.params.inventory_id, + hosts: $scope.hostsSelected, + hostIds: hostIds + }); + }; + + $scope.setAdhocPattern = function(){ + var pattern = _($scope.hostsSelected) + .map(function(item){ + return item.name; + }).value().join(':'); + + $state.go('^.adhoc', {pattern: pattern}); + }; + + $scope.copyMoveHost = function(id) { + $state.go('inventories.edit.hosts.copyMoveHost', {host_id: id}); + }; +}]; diff --git a/awx/ui/client/src/inventories/manage/hosts/hosts.form.js b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.form.js similarity index 79% rename from awx/ui/client/src/inventories/manage/hosts/hosts.form.js rename to awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.form.js index efb64a4785..d2ffe33e05 100644 --- a/awx/ui/client/src/inventories/manage/hosts/hosts.form.js +++ b/awx/ui/client/src/inventories/groups/nested-hosts/nested-hosts.form.js @@ -10,7 +10,8 @@ * @description This form is for adding/editing a host on the inventory page */ -export default ['i18n', function(i18n) { +export default ['i18n', 'nestedGroupListState', +function(i18n, nestedGroupListState) { return { addTitle: i18n._('CREATE HOST'), @@ -21,6 +22,9 @@ export default ['i18n', function(i18n) { formLabelSize: 'col-lg-3', formFieldSize: 'col-lg-9', iterator: 'host', + // activeEditState: 'inventories.edit.hosts.edit', + activeEditState: 'inventories.edit.groups.edit.nested_hosts.edit', + stateTree: 'inventories.edit.groups.edit.nested_hosts', headerFields:{ enabled: { class: 'Form-header-field', @@ -99,5 +103,27 @@ export default ['i18n', function(i18n) { ngShow: '(host.summary_fields.user_capabilities.edit || canAdd)' } }, + + related: { + ansible_facts: { + name: 'ansible_facts', + title: i18n._('Facts'), + skipGenerator: true + }, + nested_groups: { + name: 'nested_groups', + ngClick: "$state.go('inventories.edit.groups.edit.nested_hosts.edit.nested_groups')", + include: "NestedGroupListDefinition", + includeForm: "NestedGroupFormDefinition", + title: i18n._('Groups'), + iterator: 'nested_group', + listState: nestedGroupListState + }, + insights: { + name: 'insights', + title: i18n._('Insights'), + skipGenerator: true + } + } }; }]; diff --git a/awx/ui/client/src/inventoriesnew/hosts/add/host-add.controller.js b/awx/ui/client/src/inventories/hosts/add/host-add.controller.js similarity index 100% rename from awx/ui/client/src/inventoriesnew/hosts/add/host-add.controller.js rename to awx/ui/client/src/inventories/hosts/add/host-add.controller.js diff --git a/awx/ui/client/src/inventoriesnew/hosts/add/main.js b/awx/ui/client/src/inventories/hosts/add/main.js similarity index 83% rename from awx/ui/client/src/inventoriesnew/hosts/add/main.js rename to awx/ui/client/src/inventories/hosts/add/main.js index 8205e986c6..9f1f083b96 100644 --- a/awx/ui/client/src/inventoriesnew/hosts/add/main.js +++ b/awx/ui/client/src/inventories/hosts/add/main.js @@ -8,4 +8,4 @@ import controller from './host-add.controller'; export default angular.module('hostsAdd', []) - .controller('NewHostAddController', controller); + .controller('HostAddController', controller); diff --git a/awx/ui/client/src/inventoriesnew/hosts/edit/host-edit.controller.js b/awx/ui/client/src/inventories/hosts/edit/host-edit.controller.js similarity index 100% rename from awx/ui/client/src/inventoriesnew/hosts/edit/host-edit.controller.js rename to awx/ui/client/src/inventories/hosts/edit/host-edit.controller.js diff --git a/awx/ui/client/src/inventoriesnew/hosts/edit/main.js b/awx/ui/client/src/inventories/hosts/edit/main.js similarity index 82% rename from awx/ui/client/src/inventoriesnew/hosts/edit/main.js rename to awx/ui/client/src/inventories/hosts/edit/main.js index 420e870e99..2f0c5aee39 100644 --- a/awx/ui/client/src/inventoriesnew/hosts/edit/main.js +++ b/awx/ui/client/src/inventories/hosts/edit/main.js @@ -8,4 +8,4 @@ import controller from './host-edit.controller'; export default angular.module('hostsEdit', []) - .controller('NewHostEditController', controller); + .controller('HostEditController', controller); diff --git a/awx/ui/client/src/inventoriesnew/hosts/host.form.js b/awx/ui/client/src/inventories/hosts/host.form.js similarity index 100% rename from awx/ui/client/src/inventoriesnew/hosts/host.form.js rename to awx/ui/client/src/inventories/hosts/host.form.js diff --git a/awx/ui/client/src/inventoriesnew/hosts/host.list.js b/awx/ui/client/src/inventories/hosts/host.list.js similarity index 99% rename from awx/ui/client/src/inventoriesnew/hosts/host.list.js rename to awx/ui/client/src/inventories/hosts/host.list.js index 283ce28779..ec70bb2716 100644 --- a/awx/ui/client/src/inventoriesnew/hosts/host.list.js +++ b/awx/ui/client/src/inventories/hosts/host.list.js @@ -17,6 +17,7 @@ export default ['i18n', function(i18n) { hasChildren: true, 'class': 'table-no-border', trackBy: 'host.id', + basePath: 'hosts', title: false, fields: { diff --git a/awx/ui/client/src/inventories/manage/hosts/hosts.service.js b/awx/ui/client/src/inventories/hosts/hosts.service.js similarity index 100% rename from awx/ui/client/src/inventories/manage/hosts/hosts.service.js rename to awx/ui/client/src/inventories/hosts/hosts.service.js diff --git a/awx/ui/client/src/inventoriesnew/hosts/list/host-list.controller.js b/awx/ui/client/src/inventories/hosts/list/host-list.controller.js similarity index 89% rename from awx/ui/client/src/inventoriesnew/hosts/list/host-list.controller.js rename to awx/ui/client/src/inventories/hosts/list/host-list.controller.js index 92c0f2befe..86d186ed74 100644 --- a/awx/ui/client/src/inventoriesnew/hosts/list/host-list.controller.js +++ b/awx/ui/client/src/inventories/hosts/list/host-list.controller.js @@ -4,11 +4,12 @@ * All Rights Reserved *************************************************/ -function HostsList($scope, HostsNewList, $rootScope, GetBasePath, + +function HostsList($scope, HostsList, $rootScope, GetBasePath, rbacUiControlService, Dataset, $state, $filter, Prompt, Wait, HostManageService, SetStatus) { - let list = HostsNewList; + let list = HostsList; init(); @@ -48,10 +49,10 @@ function HostsList($scope, HostsNewList, $rootScope, GetBasePath, } $scope.createHost = function(){ - $state.go('hostsnew.add'); + $state.go('hosts.add'); }; $scope.editHost = function(id){ - $state.go('hostsnew.edit', {host_id: id}); + $state.go('hosts.edit', {host_id: id}); }; $scope.deleteHost = function(id, name){ var body = '
Are you sure you want to permanently delete the host below from the inventory?
' + $filter('sanitize')(name) + '
'; @@ -61,7 +62,7 @@ function HostsList($scope, HostsNewList, $rootScope, GetBasePath, HostManageService.delete(id).then(() => { $('#prompt-modal').modal('hide'); if (parseInt($state.params.host_id) === id) { - $state.go("hostsnew", null, {reload: true}); + $state.go("hosts", null, {reload: true}); } else { $state.go($state.current.name, null, {reload: true}); } @@ -94,7 +95,7 @@ function HostsList($scope, HostsNewList, $rootScope, GetBasePath, } -export default ['$scope', 'HostsNewList', '$rootScope', 'GetBasePath', +export default ['$scope', 'HostsList', '$rootScope', 'GetBasePath', 'rbacUiControlService', 'Dataset', '$state', '$filter', 'Prompt', 'Wait', 'HostManageService', 'SetStatus', HostsList ]; diff --git a/awx/ui/client/src/inventoriesnew/hosts/list/main.js b/awx/ui/client/src/inventories/hosts/list/main.js similarity index 82% rename from awx/ui/client/src/inventoriesnew/hosts/list/main.js rename to awx/ui/client/src/inventories/hosts/list/main.js index 4e603ef45d..0682898494 100644 --- a/awx/ui/client/src/inventoriesnew/hosts/list/main.js +++ b/awx/ui/client/src/inventories/hosts/list/main.js @@ -8,4 +8,4 @@ import controller from './host-list.controller'; export default angular.module('hostsList', []) - .controller('NewHostListController', controller); + .controller('HostListController', controller); diff --git a/awx/ui/client/src/inventories/hosts/main.js b/awx/ui/client/src/inventories/hosts/main.js new file mode 100644 index 0000000000..d6fca96d15 --- /dev/null +++ b/awx/ui/client/src/inventories/hosts/main.js @@ -0,0 +1,26 @@ +/************************************************* + * Copyright (c) 2017 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + + import hostAdd from './add/main'; + import hostEdit from './edit/main'; + import hostList from './list/main'; + import HostsList from './host.list'; + import HostsForm from './host.form'; + import HostManageService from './hosts.service'; + import SetStatus from './set-status.factory'; + import SetEnabledMsg from './set-enabled-msg.factory'; + +export default +angular.module('host', [ + hostAdd.name, + hostEdit.name, + hostList.name + ]) + .factory('HostsForm', HostsForm) + .factory('HostsList', HostsList) + .factory('SetStatus', SetStatus) + .factory('SetEnabledMsg', SetEnabledMsg) + .service('HostManageService', HostManageService); diff --git a/awx/ui/client/src/inventories/manage/hosts/factories/set-enabled-msg.factory.js b/awx/ui/client/src/inventories/hosts/set-enabled-msg.factory.js similarity index 100% rename from awx/ui/client/src/inventories/manage/hosts/factories/set-enabled-msg.factory.js rename to awx/ui/client/src/inventories/hosts/set-enabled-msg.factory.js diff --git a/awx/ui/client/src/inventories/manage/hosts/factories/set-status.factory.js b/awx/ui/client/src/inventories/hosts/set-status.factory.js similarity index 100% rename from awx/ui/client/src/inventories/manage/hosts/factories/set-status.factory.js rename to awx/ui/client/src/inventories/hosts/set-status.factory.js diff --git a/awx/ui/client/src/inventoriesnew/inventories.partial.html b/awx/ui/client/src/inventories/inventories.partial.html similarity index 60% rename from awx/ui/client/src/inventoriesnew/inventories.partial.html rename to awx/ui/client/src/inventories/inventories.partial.html index 524ead4a7f..871367dcb9 100644 --- a/awx/ui/client/src/inventoriesnew/inventories.partial.html +++ b/awx/ui/client/src/inventories/inventories.partial.html @@ -1,11 +1,11 @@ -
+
-
INVENTORIES
-
HOSTS
+
INVENTORIES
+
HOSTS
diff --git a/awx/ui/client/src/inventories/inventory.list.js b/awx/ui/client/src/inventories/inventory.list.js index e5f0930a8c..38c6f91874 100644 --- a/awx/ui/client/src/inventories/inventory.list.js +++ b/awx/ui/client/src/inventories/inventory.list.js @@ -17,6 +17,7 @@ export default ['i18n', function(i18n) { index: false, hover: true, basePath: 'inventory', + title: false, fields: { status: { @@ -44,9 +45,9 @@ export default ['i18n', function(i18n) { label: i18n._('Name'), columnClass: 'col-md-5 col-sm-5 col-xs-8 List-staticColumnAdjacent', modalColumnClass: 'col-md-11', - linkTo: '/#/inventories/{{inventory.id}}/manage', awToolTip: "{{ inventory.description }}", awTipPlacement: "top" + linkTo: '/#/inventories/{{inventory.id}}' }, organization: { label: i18n._('Organization'), diff --git a/awx/ui/client/src/inventories/list/inventory-list.controller.js b/awx/ui/client/src/inventories/list/inventory-list.controller.js index d900048060..6a2f0e261b 100644 --- a/awx/ui/client/src/inventories/list/inventory-list.controller.js +++ b/awx/ui/client/src/inventories/list/inventory-list.controller.js @@ -11,10 +11,10 @@ */ function InventoriesList($scope, $rootScope, $location, - $compile, $filter, Rest, InventoryList, Prompt, + $compile, $filter, Rest, InventoriesList, Prompt, ProcessErrors, GetBasePath, Wait, Find, Empty, $state, rbacUiControlService, Dataset) { - let list = InventoryList, + let list = InventoriesList, defaultUrl = GetBasePath('inventory'); init(); @@ -250,7 +250,7 @@ function InventoriesList($scope, $rootScope, $location, }; $scope.addInventory = function () { - $state.go('inventoriesnew.add'); + $state.go('inventories.add'); }; $scope.editInventory = function (id) { @@ -303,6 +303,6 @@ function InventoriesList($scope, $rootScope, $location, } export default ['$scope', '$rootScope', '$location', - '$compile', '$filter', 'Rest', 'InventoryList', + '$compile', '$filter', 'Rest', 'InventoriesList', 'Prompt', 'ProcessErrors', 'GetBasePath', 'Wait', 'Find', 'Empty', '$state', 'rbacUiControlService', 'Dataset', InventoriesList ]; diff --git a/awx/ui/client/src/inventories/list/main.js b/awx/ui/client/src/inventories/list/main.js index e4514b6caf..11c6e4e694 100644 --- a/awx/ui/client/src/inventories/list/main.js +++ b/awx/ui/client/src/inventories/list/main.js @@ -7,5 +7,5 @@ import controller from './inventory-list.controller'; export default -angular.module('inventoryList', []) +angular.module('InventoryList', []) .controller('InventoryListController', controller); diff --git a/awx/ui/client/src/inventories/main.js b/awx/ui/client/src/inventories/main.js index 45207bcf7e..1cc57ff9a1 100644 --- a/awx/ui/client/src/inventories/main.js +++ b/awx/ui/client/src/inventories/main.js @@ -4,312 +4,101 @@ * All Rights Reserved *************************************************/ +import host from './hosts/main'; import inventoryAdd from './add/main'; import inventoryEdit from './edit/main'; import inventoryList from './list/main'; -import inventoryManage from './manage/main'; -import inventoryManageListRoute from './manage/inventory-manage.route'; -import { copyMoveGroupRoute, copyMoveHostRoute } from './manage/copy-move/copy-move.route'; -import adHocRoute from './manage/adhoc/adhoc.route'; import { templateUrl } from '../shared/template-url/template-url.factory'; import { N_ } from '../i18n'; - -// actual inventory list config object -import InventoryList from './inventory.list'; -import InventoryForm from './inventory.form'; - +import InventoriesList from './inventory.list'; +import InventoriesForm from './inventory.form'; export default angular.module('inventory', [ + host.name, inventoryAdd.name, inventoryEdit.name, - inventoryList.name, - inventoryManage.name, + inventoryList.name ]) - .factory('InventoryList', InventoryList) - .factory('InventoryForm', InventoryForm) - .config(['$stateProvider', '$stateExtenderProvider', 'stateDefinitionsProvider', - function($stateProvider, $stateExtenderProvider, stateDefinitionsProvider) { + .factory('InventoriesForm', InventoriesForm) + .factory('InventoriesList', InventoriesList) + .config(['$stateProvider', 'stateDefinitionsProvider', + function($stateProvider, stateDefinitionsProvider) { // When stateDefinition.lazyLoad() resolves, states matching name.** or /url** will be de-registered and replaced with resolved states // This means inventoryManage states will not be registered correctly on page refresh, unless they're registered at the same time as the inventories state tree - let stateTree, inventories, - addGroup, editGroup, addHost, editHost, - listSchedules, addSchedule, editSchedule, adhocCredentialLookup, - stateDefinitions = stateDefinitionsProvider.$get(), - stateExtender = $stateExtenderProvider.$get(); + let stateDefinitions = stateDefinitionsProvider.$get(); - function generateStateTree() { - - // inventories state node - inventories = stateDefinitions.generateTree({ - parent: 'inventories', // top-most node in the generated tree (will replace this state definition) - modes: ['add', 'edit'], - list: 'InventoryList', - form: 'InventoryForm', - controllers: { - list: 'InventoryListController', - add: 'InventoryAddController', - edit: 'InventoryEditController' - }, - data: { - activityStream: true, - activityStreamTarget: 'inventory' - }, - ncyBreadcrumb: { - label: N_('INVENTORIES') - } - }); - - // scheduler state nodes - listSchedules = { - name: 'inventoryManage.editGroup.schedules', - url: '/schedules', - searchPrefix: 'schedule', - ncyBreadcrumb: { - parent: 'inventoryManage({group_id: parentObject.id})', - label: N_('SCHEDULES') - }, - resolve: { - Dataset: ['ScheduleList', 'QuerySet', '$stateParams', 'GetBasePath', 'groupData', - function(list, qs, $stateParams, GetBasePath, groupData) { - let path = `${groupData.related.inventory_source}schedules`; - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ], - ParentObject: ['groupData', function(groupData) { - return groupData; - }], - 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', 'groupData', - (SchedulesList, groupData) => { - let list = _.cloneDeep(SchedulesList); - list.basePath = `${groupData.related.inventory_source}schedules`; - return list; - } - ] - }, - views: { - // clear form template when views render in this substate - 'form': { - templateProvider: () => '' + $stateProvider.state({ + name: 'inventories', + url: '/inventories', + lazyLoad: () => stateDefinitions.generateTree({ + parent: 'inventories', // top-most node in the generated tree (will replace this state definition) + modes: ['add', 'edit'], + list: 'InventoriesList', + form: 'InventoriesForm', + controllers: { + list: 'InventoryListController', + add: 'InventoryAddController', + edit: 'InventoryEditController' }, - // 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 + "
"; + urls: { + list: '/inventories' + }, + ncyBreadcrumb: { + label: N_('INVENTORIES') + }, + views: { + '@': { + templateUrl: templateUrl('inventories/inventories') }, - controller: 'schedulerListController' - } - } - }; - - addSchedule = { - name: 'inventoryManage.editGroup.schedules.add', - url: '/add', - ncyBreadcrumb: { - label: N_("CREATE SCHEDULE") - }, - views: { - 'form': { - controller: 'schedulerAddController', - templateUrl: templateUrl("scheduler/schedulerForm") - } - } - }; - - editSchedule = { - name: 'inventoryManage.editGroup.schedules.edit', - url: '/:schedule_id', - ncyBreadcrumb: { - label: "{{schedule_obj.name}}" - }, - views: { - 'form': { - templateUrl: templateUrl("scheduler/schedulerForm"), - controller: 'schedulerEditController', - } - } - }; - - // group state nodes - addGroup = stateDefinitions.generateTree({ - url: '/add-group', - name: 'inventoryManage.addGroup', - modes: ['add'], - form: 'GroupForm', - controllers: { - add: 'GroupAddController' - } - }); - - editGroup = stateDefinitions.generateTree({ - url: '/edit-group/:group_id', - name: 'inventoryManage.editGroup', - modes: ['edit'], - form: 'GroupForm', - controllers: { - edit: 'GroupEditController' - }, - resolve: { - edit: { - groupData: ['$stateParams', 'GroupManageService', function($stateParams, GroupManageService) { - return GroupManageService.get({ id: $stateParams.group_id }).then(res => res.data.results[0]); - }], - inventorySourceData: ['$stateParams', 'GroupManageService', function($stateParams, GroupManageService) { - return GroupManageService.getInventorySource({ group: $stateParams.group_id }).then(res => res.data.results[0]); - }] - } - }, - // concat boilerplate schedule state definitions with generated editGroup state definitions - }).then((generated) => { - let schedulerDefinitions = _.map([ - stateExtender.buildDefinition(listSchedules), - stateExtender.buildDefinition(addSchedule), - stateExtender.buildDefinition(editSchedule) - ], - (state) => stateExtender.buildDefinition(state)); - return { - states: _(generated.states) - .concat(schedulerDefinitions) - .value() - }; - }); - - // host state nodes - addHost = stateDefinitions.generateTree({ - url: '/add-host', - name: 'inventoryManage.addHost', - modes: ['add'], - form: 'HostForm', - controllers: { - add: 'HostsAddController' - } - }); - - editHost = stateDefinitions.generateTree({ - url: '/edit-host/:host_id', - name: 'inventoryManage.editHost', - modes: ['edit'], - form: 'HostForm', - controllers: { - edit: 'HostEditController' - }, - resolve: { - edit: { - host: ['$stateParams', 'HostManageService', function($stateParams, HostManageService) { - return HostManageService.get({ id: $stateParams.host_id }).then(function(res) { - return res.data.results[0]; - }); - }] - } - }, - ncyBreadcrumb: { - label: "{{host.name}}", - }, - }); - - adhocCredentialLookup = { - searchPrefix: 'credential', - name: 'inventoryManage.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}`; - + 'list@inventories': { + templateProvider: function(InventoriesList, generateList) { + let html = generateList.build({ + list: InventoriesList, + mode: 'edit' + }); + return html; + }, + controller: 'InventoryListController' } } - }, - 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'); - } - }, - }; - - return Promise.all([ - inventories, - addGroup, - editGroup, - addHost, - editHost, - ]).then((generated) => { - return { - states: _.reduce(generated, (result, definition) => { - return result.concat(definition.states); - }, [ - stateExtender.buildDefinition(inventoryManageListRoute), - stateExtender.buildDefinition(copyMoveGroupRoute), - stateExtender.buildDefinition(copyMoveHostRoute), - stateExtender.buildDefinition(adHocRoute), - stateExtender.buildDefinition(adhocCredentialLookup) - - ]) - }; + }) }); - } - stateTree = { - name: 'inventories', - url: '/inventories', - ncyBreadcrumb: { - label: N_("INVENTORIES") - }, - lazyLoad: () => generateStateTree() - }; - - $stateProvider.state(stateTree); + $stateProvider.state({ + name: 'hosts', + url: '/hosts', + lazyLoad: () => stateDefinitions.generateTree({ + parent: 'hosts', // top-most node in the generated tree (will replace this state definition) + modes: ['add', 'edit'], + list: 'HostsList', + form: 'HostsForm', + controllers: { + list: 'HostListController', + add: 'HostAddController', + edit: 'HostEditController' + }, + urls: { + list: '/hosts' + }, + ncyBreadcrumb: { + label: N_('HOSTS') + }, + views: { + '@': { + templateUrl: templateUrl('inventories/inventories') + }, + 'list@hosts': { + templateProvider: function(HostsList, generateList) { + let html = generateList.build({ + list: HostsList, + mode: 'edit' + }); + return html; + }, + controller: 'HostListController' + } + } + }) + }); } ]); diff --git a/awx/ui/client/src/inventories/manage/adhoc/adhoc.controller.js b/awx/ui/client/src/inventories/manage/adhoc/adhoc.controller.js deleted file mode 100644 index 4b8e25c051..0000000000 --- a/awx/ui/client/src/inventories/manage/adhoc/adhoc.controller.js +++ /dev/null @@ -1,308 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Adhoc - * @description This controller controls the adhoc form creation, command launching and navigating to standard out after command has been succesfully ran. -*/ -function adhocController($q, $scope, $stateParams, - $state, CheckPasswords, PromptForPasswords, CreateLaunchDialog, CreateSelect2, adhocForm, - GenerateForm, Rest, ProcessErrors, ClearScope, GetBasePath, GetChoices, - KindChange, Wait, ParseTypeChange) { - - ClearScope(); - - // this is done so that we can access private functions for testing, but - // we don't want to populate the "public" scope with these internal - // functions - var privateFn = {}; - this.privateFn = privateFn; - - var id = $stateParams.inventory_id, - hostPattern = $stateParams.pattern; - - // note: put any urls that the controller will use in here!!!! - privateFn.setAvailableUrls = function() { - return { - adhocUrl: GetBasePath('inventory') + id + '/ad_hoc_commands/', - inventoryUrl: GetBasePath('inventory') + id + '/', - machineCredentialUrl: GetBasePath('credentials') + '?kind=ssh' - }; - }; - - var urls = privateFn.setAvailableUrls(); - - // set the default options for the selects of the adhoc form - privateFn.setFieldDefaults = function(verbosity_options, forks_default) { - var verbosity; - for (verbosity in verbosity_options) { - if (verbosity_options[verbosity].isDefault) { - $scope.verbosity = verbosity_options[verbosity]; - } - } - $("#forks-number").spinner("value", forks_default); - $scope.forks = forks_default; - }; - - // set when "working" starts and stops - privateFn.setLoadingStartStop = function() { - var asyncHelper = {}, - formReadyPromise = 0; - - Wait('start'); - - if (asyncHelper.removeChoicesReady) { - asyncHelper.removeChoicesReady(); - } - asyncHelper.removeChoicesReady = $scope.$on('adhocFormReady', - isFormDone); - - // check to see if all requests have completed - function isFormDone() { - formReadyPromise++; - - if (formReadyPromise === 2) { - privateFn.setFieldDefaults($scope.adhoc_verbosity_options, - $scope.forks_field.default); - - CreateSelect2({ - element: '#adhoc_module_name', - multiple: false - }); - - CreateSelect2({ - element: '#adhoc_verbosity', - multiple: false - }); - - Wait('stop'); - } - } - }; - - // set the arguments help to watch on change of the module - privateFn.instantiateArgumentHelp = function() { - $scope.$watch('module_name', function(val) { - if (val) { - // give the docs for the selected module in the popover - $scope.argsPopOver = '

These arguments are used with the ' + - 'specified module. You can find information about the ' + - val.value + ' module here.

'; - } else { - // no module selected - $scope.argsPopOver = "

These arguments are used with the" + - " specified module.

"; - } - }, true); - - // initially set to the same as no module selected - $scope.argsPopOver = "

These arguments are used with the " + - "specified module.

"; - }; - - // pre-populate host patterns from the inventory page and - // delete the value off of rootScope - privateFn.instantiateHostPatterns = function(hostPattern) { - $scope.limit = hostPattern; - $scope.providedHostPatterns = $scope.limit; - }; - - // call helpers to initialize lookup and select fields through get - // requests - privateFn.initializeFields = function(machineCredentialUrl, adhocUrl) { - - // setup module name select - GetChoices({ - scope: $scope, - url: adhocUrl, - field: 'module_name', - variable: 'adhoc_module_options', - callback: 'adhocFormReady' - }); - - // setup verbosity options select - GetChoices({ - scope: $scope, - url: adhocUrl, - field: 'verbosity', - variable: 'adhoc_verbosity_options', - callback: 'adhocFormReady' - }); - }; - - // instantiate all variables on scope for display in the partial - privateFn.initializeForm = function(id, urls, hostPattern) { - // inject the adhoc command form - GenerateForm.inject(adhocForm, - { mode: 'add', related: true, scope: $scope }); - - // set when "working" starts and stops - privateFn.setLoadingStartStop(); - - // put the inventory id on scope for the partial to use - $scope.inv_id = id; - - // set the arguments help to watch on change of the module - privateFn.instantiateArgumentHelp(); - - // pre-populate host patterns from the inventory page and - // delete the value off of rootScope - privateFn.instantiateHostPatterns(hostPattern); - - privateFn.initializeFields(urls.machineCredentialUrl, urls.adhocUrl); - }; - - privateFn.initializeForm(id, urls, hostPattern); - - // init codemirror - $scope.extra_vars = '---'; - $scope.parseType = 'yaml'; - $scope.envParseType = 'yaml'; - ParseTypeChange({ scope: $scope, field_id: 'adhoc_extra_vars' , variable: "extra_vars"}); - - $scope.formCancel = function(){ - $state.go('inventoryManage'); - }; - - // remove all data input into the form and reset the form back to defaults - $scope.formReset = function () { - GenerateForm.reset(); - - // pre-populate host patterns from the inventory page and - // delete the value off of rootScope - privateFn.instantiateHostPatterns($scope.providedHostPatterns); - - KindChange({ scope: $scope, form: adhocForm, reset: false }); - - // set the default options for the selects of the adhoc form - privateFn.setFieldDefaults($scope.adhoc_verbosity_options, - $scope.forks_default); - }; - - // launch the job with the provided form data - $scope.launchJob = function () { - var adhocUrl = GetBasePath('inventory') + $stateParams.inventory_id + - '/ad_hoc_commands/', fld, data={}, html; - - html = '
'; - - // stub the payload with defaults from DRF - data = { - "job_type": "run", - "limit": "", - "credential": "", - "module_name": "command", - "module_args": "", - "forks": 0, - "verbosity": 0, - "extra_vars": "", - "privilege_escalation": "" - }; - - GenerateForm.clearApiErrors($scope); - - // populate data with the relevant form values - for (fld in adhocForm.fields) { - if (adhocForm.fields[fld].type === 'select') { - data[fld] = $scope[fld].value; - } else if ($scope[fld]) { - data[fld] = $scope[fld]; - } - } - - Wait('start'); - - if ($scope.removeStartAdhocRun) { - $scope.removeStartAdhocRun(); - } - $scope.removeStartAdhocRun = $scope.$on('StartAdhocRun', function() { - var password; - for (password in $scope.passwords) { - data[$scope.passwords[password]] = $scope[ - $scope.passwords[password] - ]; - } - // Launch the adhoc job - Rest.setUrl(GetBasePath('inventory') + - $stateParams.inventory_id + '/ad_hoc_commands/'); - Rest.post(data) - .success(function (data) { - Wait('stop'); - $state.go('adHocJobStdout', {id: data.id}); - }) - .error(function (data, status) { - ProcessErrors($scope, data, status, adhocForm, { - hdr: 'Error!', - msg: 'Failed to launch adhoc command. POST ' + - 'returned status: ' + status }); - }); - }); - - if ($scope.removeCreateLaunchDialog) { - $scope.removeCreateLaunchDialog(); - } - $scope.removeCreateLaunchDialog = $scope.$on('CreateLaunchDialog', - function(e, html, url) { - CreateLaunchDialog({ - scope: $scope, - html: html, - url: url, - callback: 'StartAdhocRun' - }); - }); - - if ($scope.removePromptForPasswords) { - $scope.removePromptForPasswords(); - } - $scope.removePromptForPasswords = $scope.$on('PromptForPasswords', - function(e, passwords_needed_to_start,html, url) { - PromptForPasswords({ scope: $scope, - passwords: passwords_needed_to_start, - callback: 'CreateLaunchDialog', - html: html, - url: url - }); - }); - - if ($scope.removeContinueCred) { - $scope.removeContinueCred(); - } - $scope.removeContinueCred = $scope.$on('ContinueCred', function(e, - passwords) { - if(passwords.length>0){ - $scope.passwords_needed_to_start = passwords; - // only go through the password prompting steps if there are - // passwords to prompt for - $scope.$emit('PromptForPasswords', passwords, html, adhocUrl); - } else { - // if not, go straight to trying to run the job. - $scope.$emit('StartAdhocRun', adhocUrl); - } - }); - - // start adhoc launching routine - CheckPasswords({ - scope: $scope, - credential: $scope.credential, - callback: 'ContinueCred' - }); - }; - - -} - -export default ['$q', '$scope', '$stateParams', - '$state', 'CheckPasswords', 'PromptForPasswords', 'CreateLaunchDialog', 'CreateSelect2', - 'adhocForm', 'GenerateForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath', - 'GetChoices', 'KindChange', 'Wait', 'ParseTypeChange', - adhocController]; diff --git a/awx/ui/client/src/inventories/manage/adhoc/adhoc.form.js b/awx/ui/client/src/inventories/manage/adhoc/adhoc.form.js deleted file mode 100644 index c58068deb6..0000000000 --- a/awx/ui/client/src/inventories/manage/adhoc/adhoc.form.js +++ /dev/null @@ -1,159 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - /** - * @ngdoc function - * @name forms.function:Adhoc - * @description This form is for executing an adhoc command -*/ - -export default ['i18n', function(i18n) { - return { - addTitle: 'EXECUTE COMMAND', - name: 'adhoc', - well: true, - forceListeners: true, - - fields: { - module_name: { - label: 'Module', - excludeModal: true, - type: 'select', - ngOptions: 'module.label for module in adhoc_module_options' + - ' track by module.value', - ngChange: 'moduleChange()', - required: true, - awPopOver:'

These are the modules that Tower supports ' + - 'running commands against.', - dataTitle: 'Module', - dataPlacement: 'right', - dataContainer: 'body' - }, - module_args: { - label: 'Arguments', - type: 'text', - awPopOverWatch: 'argsPopOver', - awPopOver: '{{ argsPopOver }}', - dataTitle: 'Arguments', - dataPlacement: 'right', - dataContainer: 'body', - autocomplete: false - }, - limit: { - label: 'Limit', - type: 'text', - - awPopOver: '

The pattern used to target hosts in the ' + - 'inventory. Leaving the field blank, all, and * will ' + - 'all target all hosts in the inventory. You can find ' + - 'more information about Ansible\'s host patterns ' + - 'here.

', - dataTitle: 'Limit', - dataPlacement: 'right', - dataContainer: 'body' - }, - credential: { - label: 'Machine Credential', - type: 'lookup', - list: 'CredentialList', - basePath: 'credentials', - sourceModel: 'credential', - sourceField: 'name', - class: 'squeeze', - awPopOver: '

Select the credential you want to use when ' + - 'accessing the remote hosts to run the command. ' + - 'Choose the credential containing ' + - 'the username and SSH key or password that Ansbile ' + - 'will need to log into the remote hosts.

', - dataTitle: 'Credential', - dataPlacement: 'right', - dataContainer: 'body', - awRequiredWhen: { - reqExpression: 'credRequired', - init: 'false' - } - }, - become_enabled: { - label: 'Enable Privilege Escalation', - type: 'checkbox', - - column: 2, - awPopOver: "

If enabled, run this playbook as an administrator. This is the equivalent of passing the --become option to the ansible command.

", - dataPlacement: 'right', - dataTitle: 'Become Privilege Escalation', - dataContainer: "body" - }, - verbosity: { - label: 'Verbosity', - excludeModal: true, - type: 'select', - ngOptions: 'verbosity.label for verbosity in ' + - 'adhoc_verbosity_options ' + - 'track by verbosity.value', - required: true, - awPopOver:'

These are the verbosity levels for standard ' + - 'out of the command run that are supported.', - dataTitle: 'Verbosity', - dataPlacement: 'right', - dataContainer: 'body', - "default": 1 - }, - forks: { - label: 'Forks', - id: 'forks-number', - type: 'number', - integer: true, - min: 0, - spinner: true, - "default": 0, - required: true, - 'class': "input-small", - column: 1, - awPopOver: '

The number of parallel or simultaneous processes to use while executing the command. 0 signifies ' + - 'the default value from the ansible configuration file.

', - dataTitle: 'Forks', - dataPlacement: 'right', - dataContainer: "body" - }, - extra_vars: { - label: i18n._('Extra Variables'), - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - "default": "---", - column: 2, - awPopOver: "

" + i18n.sprintf(i18n._("Pass extra command line variables. This is the %s or %s command line parameter " + - "for %s. Provide key/value pairs using either YAML or JSON."), '-e', '--extra-vars', 'ansible') + "

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n", - dataTitle: i18n._('Extra Variables'), - dataPlacement: 'right', - dataContainer: "body" - } - }, - buttons: { - reset: { - ngClick: 'formReset()', - ngDisabled: true, - label: 'Reset', - 'class': 'btn btn-sm Form-cancelButton' - }, - launch: { - label: 'Save', - ngClick: 'launchJob()', - ngDisabled: true, - 'class': 'btn btn-sm List-buttonSubmit launchButton' - } - }, - - related: {} - }; -}]; diff --git a/awx/ui/client/src/inventories/manage/adhoc/adhoc.partial.html b/awx/ui/client/src/inventories/manage/adhoc/adhoc.partial.html deleted file mode 100644 index eb25ec5b56..0000000000 --- a/awx/ui/client/src/inventories/manage/adhoc/adhoc.partial.html +++ /dev/null @@ -1,4 +0,0 @@ -
-
-
-
diff --git a/awx/ui/client/src/inventories/manage/adhoc/adhoc.route.js b/awx/ui/client/src/inventories/manage/adhoc/adhoc.route.js deleted file mode 100644 index 05a8d6dcad..0000000000 --- a/awx/ui/client/src/inventories/manage/adhoc/adhoc.route.js +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - import {templateUrl} from '../../../shared/template-url/template-url.factory'; - import { N_ } from '../../../i18n'; - -export default { - url: '/adhoc', - params:{ - pattern: { - value: 'all', - squash: true - } - }, - name: 'inventoryManage.adhoc', - views: { - 'form@inventoryManage': { - templateUrl: templateUrl('inventories/manage/adhoc/adhoc'), - controller: 'adhocController' - } - }, - ncyBreadcrumb: { - label: N_("RUN COMMAND") - } -}; diff --git a/awx/ui/client/src/inventories/manage/adhoc/main.js b/awx/ui/client/src/inventories/manage/adhoc/main.js deleted file mode 100644 index 1931e8f1d1..0000000000 --- a/awx/ui/client/src/inventories/manage/adhoc/main.js +++ /dev/null @@ -1,7 +0,0 @@ -import adhocController from './adhoc.controller'; -import form from './adhoc.form'; - -export default - angular.module('adhoc', []) - .controller('adhocController', adhocController) - .factory('adhocForm', form); diff --git a/awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.block.less b/awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.block.less deleted file mode 100644 index c87b1b3f52..0000000000 --- a/awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.block.less +++ /dev/null @@ -1,25 +0,0 @@ -.InventoryManageBreadCrumbs .BreadCrumb-list{ - padding-right: 0px; -} -.InventoryManageBreadCrumb-ncy.BreadCrumb-list{ - padding-left: 0px; -} -.InventoryManageBreadCrumbs-separator{ - content: "/"; - padding: 0 5px; - color: #B7B7B7; -} -.InventoryManageBreadCrumbs{ - position: relative; - height: auto; - top: -36px; - .BreadCrumb-list{ - margin-bottom: 0px; - } -} -.InventoryManage-breakWord{ - word-break: break-all; -} -ol.BreadCrumb-list{ - display: inline-block; -} diff --git a/awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.controller.js b/awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.controller.js deleted file mode 100644 index 0ace8e9dec..0000000000 --- a/awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.controller.js +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -export default - ['$state', '$stateParams', '$scope', '$rootScope', 'inventoryData', 'breadCrumbData', function($state, $stateParams, $scope, $rootScope, inventoryData, breadCrumbData){ - // process result data into the same order specified in the traversal path - $scope.groups = _.sortBy(breadCrumbData, function(item){ - var index = _.indexOf($stateParams.group, item.id); - return (index === -1) ? $stateParams.group.length : index; - }); - $scope.inventory = inventoryData; - $scope.currentState = $state.current.name; - // 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; - // slices the group stack at $index to supply new group params to $state.go() - $scope.goToGroup = function(index){ - var group = $stateParams.group.slice(0, index); - $state.go('inventoryManage', {group: group}, {reload: true}); - }; - $scope.goToInventory = function(){ - $state.go('inventoryManage', {group: undefined}, {reload: true}); - }; - - var cleanUpStateChangeListener = $rootScope.$on('$stateChangeSuccess', function(event, toState){ - $scope.currentState = toState.name; - }); - - // Remove the listener when the scope is destroyed to avoid a memory leak - $scope.$on('$destroy', function() { - cleanUpStateChangeListener(); - }); - }]; diff --git a/awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.partial.html b/awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.partial.html deleted file mode 100644 index 04777cc0f8..0000000000 --- a/awx/ui/client/src/inventories/manage/breadcrumbs/breadcrumbs.partial.html +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/awx/ui/client/src/inventories/manage/copy-move/copy-move-groups.list.js b/awx/ui/client/src/inventories/manage/copy-move/copy-move-groups.list.js deleted file mode 100644 index 5a98b24591..0000000000 --- a/awx/ui/client/src/inventories/manage/copy-move/copy-move-groups.list.js +++ /dev/null @@ -1,24 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - - - -export default { - name: 'groups', - iterator: 'copy', - selectTitle: 'Copy Groups', - index: false, - well: false, - emptyListText: 'PLEASE CREATE ADDITIONAL GROUPS / HOSTS TO PERFORM THIS ACTION', - fields: { - name: { - key: true, - label: 'Target Group Name' - } - }, - basePath: 'api/v1/inventories/{{$stateParams.inventory_id}}/groups' -}; diff --git a/awx/ui/client/src/inventories/manage/copy-move/copy-move.block.less b/awx/ui/client/src/inventories/manage/copy-move/copy-move.block.less deleted file mode 100644 index 608f59654a..0000000000 --- a/awx/ui/client/src/inventories/manage/copy-move/copy-move.block.less +++ /dev/null @@ -1,33 +0,0 @@ -@import "./client/src/shared/branding/colors.default.less"; - -#Inventory-copyMovePanel { - .List-searchRow { - width: 50%; - } - .Form-header { - width: 50%; - margin-top: -20px; - } - - .Form-saveButton { - &:disabled { - border-color: @default-icon-hov; - } - } -} -.copyMove-choices { - float: right; - width: 25%; - text-align: right; -} -.copyMove-buttons{ - height: 30px; - margin-top: 20px; - - button { - margin-left: 20px; - } -} -.copyMove-root{ - margin-top: 10px; -} diff --git a/awx/ui/client/src/inventories/manage/copy-move/copy-move.partial.html b/awx/ui/client/src/inventories/manage/copy-move/copy-move.partial.html deleted file mode 100644 index 030f0c7e3a..0000000000 --- a/awx/ui/client/src/inventories/manage/copy-move/copy-move.partial.html +++ /dev/null @@ -1,21 +0,0 @@ -
-
-
{{item.name}}
-
-
- - -
-
-
- Use the inventory root -
-
- - -
-
diff --git a/awx/ui/client/src/inventories/manage/copy-move/main.js b/awx/ui/client/src/inventories/manage/copy-move/main.js deleted file mode 100644 index a9fbd47660..0000000000 --- a/awx/ui/client/src/inventories/manage/copy-move/main.js +++ /dev/null @@ -1,15 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import CopyMoveGroupsController from './copy-move-groups.controller'; -import CopyMoveHostsController from './copy-move-hosts.controller'; -import CopyMoveGroupList from './copy-move-groups.list'; - -export default -angular.module('manageCopyMove', []) - .controller('CopyMoveGroupsController', CopyMoveGroupsController) - .controller('CopyMoveHostsController', CopyMoveHostsController) - .value('CopyMoveGroupList', CopyMoveGroupList); diff --git a/awx/ui/client/src/inventories/manage/groups/factories/get-hosts-status-msg.factory.js b/awx/ui/client/src/inventories/manage/groups/factories/get-hosts-status-msg.factory.js deleted file mode 100644 index 19a846c414..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/factories/get-hosts-status-msg.factory.js +++ /dev/null @@ -1,33 +0,0 @@ -export default - function GetHostsStatusMsg() { - return function(params) { - var active_failures = params.active_failures, - total_hosts = params.total_hosts, - tip, failures, html_class; - - // Return values for use on host status indicator - - if (active_failures > 0) { - tip = total_hosts + ((total_hosts === 1) ? ' host' : ' hosts') + '. ' + active_failures + ' with failed jobs.'; - html_class = 'error'; - failures = true; - } else { - failures = false; - if (total_hosts === 0) { - // no hosts - tip = "Contains 0 hosts."; - html_class = 'none'; - } else { - // many hosts with 0 failures - tip = total_hosts + ((total_hosts === 1) ? ' host' : ' hosts') + '. No job failures'; - html_class = 'success'; - } - } - - return { - tooltip: tip, - failures: failures, - 'class': html_class - }; - }; - } diff --git a/awx/ui/client/src/inventories/manage/groups/factories/get-source-type-options.factory.js b/awx/ui/client/src/inventories/manage/groups/factories/get-source-type-options.factory.js deleted file mode 100644 index befef8a499..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/factories/get-source-type-options.factory.js +++ /dev/null @@ -1,37 +0,0 @@ -export default - function GetSourceTypeOptions(Rest, ProcessErrors, GetBasePath) { - return function(params) { - var scope = params.scope, - variable = params.variable; - - if (scope[variable] === undefined) { - scope[variable] = []; - Rest.setUrl(GetBasePath('inventory_sources')); - Rest.options() - .success(function (data) { - var i, choices = data.actions.GET.source.choices; - for (i = 0; i < choices.length; i++) { - if (choices[i][0] !== 'file') { - scope[variable].push({ - label: choices[i][1], - value: choices[i][0] - }); - } - } - scope.cloudCredentialRequired = false; - scope.$emit('sourceTypeOptionsReady'); - }) - .error(function (data, status) { - ProcessErrors(scope, data, status, null, { hdr: 'Error!', - msg: 'Failed to retrieve options for inventory_sources.source. OPTIONS status: ' + status - }); - }); - } - }; - } - -GetSourceTypeOptions.$inject = - [ 'Rest', - 'ProcessErrors', - 'GetBasePath' - ]; diff --git a/awx/ui/client/src/inventories/manage/groups/factories/get-sync-status-msg.factory.js b/awx/ui/client/src/inventories/manage/groups/factories/get-sync-status-msg.factory.js deleted file mode 100644 index 2541abcc27..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/factories/get-sync-status-msg.factory.js +++ /dev/null @@ -1,77 +0,0 @@ -export default - function GetSyncStatusMsg(Empty) { - return function(params) { - var status = params.status, - source = params.source, - has_inventory_sources = params.has_inventory_sources, - launch_class = '', - launch_tip = 'Start sync process', - schedule_tip = 'Schedule future inventory syncs', - stat, stat_class, status_tip; - - stat = status; - stat_class = stat; - - switch (status) { - case 'never updated': - stat = 'never'; - stat_class = 'na'; - status_tip = 'Sync not performed. Click to start it now.'; - break; - case 'none': - case 'ok': - case '': - launch_class = 'btn-disabled'; - stat = 'n/a'; - stat_class = 'na'; - status_tip = 'Cloud source not configured. Click to update.'; - launch_tip = 'Cloud source not configured.'; - break; - case 'canceled': - status_tip = 'Sync canceled. Click to view log.'; - break; - case 'failed': - status_tip = 'Sync failed. Click to view log.'; - break; - case 'successful': - status_tip = 'Sync completed. Click to view log.'; - break; - case 'pending': - status_tip = 'Sync pending.'; - launch_class = "btn-disabled"; - launch_tip = "Sync pending"; - break; - case 'updating': - case 'running': - launch_class = "btn-disabled"; - launch_tip = "Sync running"; - status_tip = "Sync running. Click to view log."; - break; - } - - if (has_inventory_sources && Empty(source)) { - // parent has a source, therefore this group should not have a source - launch_class = "btn-disabled"; - status_tip = 'Managed by an external cloud source.'; - launch_tip = 'Can only be updated by running a sync on the parent group.'; - } - - if (has_inventory_sources === false && Empty(source)) { - launch_class = 'btn-disabled'; - status_tip = 'Cloud source not configured. Click to update.'; - launch_tip = 'Cloud source not configured.'; - } - - return { - "class": stat_class, - "tooltip": status_tip, - "status": stat, - "launch_class": launch_class, - "launch_tip": launch_tip, - "schedule_tip": schedule_tip - }; - }; - } - -GetSyncStatusMsg.$inject = - [ 'Empty' ]; diff --git a/awx/ui/client/src/inventories/manage/groups/factories/groups-cancel-update.factory.js b/awx/ui/client/src/inventories/manage/groups/factories/groups-cancel-update.factory.js deleted file mode 100644 index 1447d0aa1c..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/factories/groups-cancel-update.factory.js +++ /dev/null @@ -1,81 +0,0 @@ -export default - function GroupsCancelUpdate(Empty, Rest, ProcessErrors, Alert, Wait, Find) { - return function(params) { - var scope = params.scope, - id = params.id, - group = params.group; - - if (scope.removeCancelUpdate) { - scope.removeCancelUpdate(); - } - scope.removeCancelUpdate = scope.$on('CancelUpdate', function (e, url) { - // Cancel the update process - Rest.setUrl(url); - Rest.post() - .success(function () { - Wait('stop'); - //Alert('Inventory Sync Cancelled', 'Request to cancel the sync process was submitted to the task manger. ' + - // 'Click the button to monitor the status.', 'alert-info'); - }) - .error(function (data, status) { - ProcessErrors(scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. POST status: ' + status - }); - }); - }); - - if (scope.removeCheckCancel) { - scope.removeCheckCancel(); - } - scope.removeCheckCancel = scope.$on('CheckCancel', function (e, last_update, current_update) { - // Check that we have access to cancelling an update - var url = (current_update) ? current_update : last_update; - url += 'cancel/'; - Rest.setUrl(url); - Rest.get() - .success(function (data) { - if (data.can_cancel) { - scope.$emit('CancelUpdate', url); - //} else { - // Wait('stop'); - // Alert('Cancel Inventory Sync', 'The sync process completed. Click the button to view ' + - // 'the latest status.', 'alert-info'); - } - else { - Wait('stop'); - } - }) - .error(function (data, status) { - ProcessErrors(scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. GET status: ' + status - }); - }); - }); - - // Cancel the update process - if (Empty(group)) { - group = Find({ list: scope.groups, key: 'id', val: id }); - scope.selected_group_id = group.id; - } - - if (group && (group.status === 'running' || group.status === 'pending')) { - // We found the group, and there is a running update - Wait('start'); - Rest.setUrl(group.related.inventory_source); - Rest.get() - .success(function (data) { - scope.$emit('CheckCancel', data.related.last_update, data.related.current_update); - }) - .error(function (data, status) { - ProcessErrors(scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + group.related.inventory_source + ' failed. GET status: ' + status - }); - }); - } - }; - } - -GroupsCancelUpdate.$inject = - [ 'Empty', 'Rest', 'ProcessErrors', - 'Alert', 'Wait', 'Find' - ]; diff --git a/awx/ui/client/src/inventories/manage/groups/factories/view-update-status.factory.js b/awx/ui/client/src/inventories/manage/groups/factories/view-update-status.factory.js deleted file mode 100644 index 1f3280b51c..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/factories/view-update-status.factory.js +++ /dev/null @@ -1,46 +0,0 @@ -export default - function ViewUpdateStatus($state, Rest, ProcessErrors, Alert, Wait, Empty, Find) { - return function(params) { - var scope = params.scope, - group_id = params.group_id, - group = Find({ list: scope.groups, key: 'id', val: group_id }); - - if (scope.removeSourceReady) { - scope.removeSourceReady(); - } - scope.removeSourceReady = scope.$on('SourceReady', function(e, source) { - - // Get the ID from the correct summary field - var update_id = (source.summary_fields.current_update) ? source.summary_fields.current_update.id : source.summary_fields.last_update.id; - - $state.go('inventorySyncStdout', {id: update_id}); - - }); - - if (group) { - if (Empty(group.source)) { - // do nothing - } else if (Empty(group.status) || group.status === "never updated") { - Alert('No Status Available', '
An inventory sync has not been performed for the selected group. Start the process by ' + - 'clicking the button.
', 'alert-info', null, null, null, null, true); - } else { - Wait('start'); - Rest.setUrl(group.related.inventory_source); - Rest.get() - .success(function (data) { - scope.$emit('SourceReady', data); - }) - .error(function (data, status) { - ProcessErrors(scope, data, status, null, { hdr: 'Error!', - msg: 'Failed to retrieve inventory source: ' + group.related.inventory_source + - ' GET returned status: ' + status }); - }); - } - } - }; - } - -ViewUpdateStatus.$inject = - [ '$state', 'Rest', 'ProcessErrors', - 'Alert', 'Wait', 'Empty', 'Find' - ]; diff --git a/awx/ui/client/src/inventories/manage/groups/groups-list.partial.html b/awx/ui/client/src/inventories/manage/groups/groups-list.partial.html deleted file mode 100644 index 1a02f3a515..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/groups-list.partial.html +++ /dev/null @@ -1,79 +0,0 @@ - diff --git a/awx/ui/client/src/inventories/manage/groups/groups.block.less b/awx/ui/client/src/inventories/manage/groups/groups.block.less deleted file mode 100644 index e8387dcd10..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/groups.block.less +++ /dev/null @@ -1,16 +0,0 @@ -.select2-selection.select2-selection--multiple.Form-dropDown{ - height: auto !important; -} -.GroupDelete .Modal-header{ - margin-bottom: 20px; -} -.GroupDelete .modal-body{ - padding-top: 20px; -} -.Inventory-groupManage{ - // ugly hack to avoid the surface area of changing form generator's default classes - .checkbox-inline{ - display: block; - padding-bottom: 5px; - } -} diff --git a/awx/ui/client/src/inventories/manage/groups/groups.form.js b/awx/ui/client/src/inventories/manage/groups/groups.form.js deleted file mode 100644 index 16fee6017d..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/groups.form.js +++ /dev/null @@ -1,360 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - /** - * @ngdoc function - * @name forms.function:Groups - * @description This form is for adding/editing a Group on the inventory page -*/ - -export default ['NotificationsList', - function(NotificationsList) { - return function() { - var GroupFormObject = { - - addTitle: 'CREATE GROUP', - editTitle: '{{ name }}', - showTitle: true, - name: 'group', - basePath: 'groups', - // the parent node this generated state definition tree expects to attach to - stateTree: 'inventoryManage', - // form generator inspects the current state name to determine whether or not to set an active (.is-selected) class on a form tab - // this setting is optional on most forms, except where the form's edit state name is not parentStateName.edit - activeEditState: 'inventoryManage.editGroup', - detailsClick: "$state.go('inventoryManage.editGroup')", - well: false, - fields: { - name: { - label: 'Name', - type: 'text', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - required: true, - tab: 'properties' - }, - description: { - label: 'Description', - type: 'text', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - tab: 'properties' - }, - variables: { - label: 'Variables', - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - dataTitle: 'Group Variables', - dataPlacement: 'right', - parseTypeName: 'parseType', - awPopOver: "

Variables defined here apply to all child groups and hosts.

" + - "

Enter variables using either JSON or YAML syntax. Use the " + - "radio button to toggle between the two.

" + - "JSON:
\n" + - "
{
  \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body', - tab: 'properties' - }, - source: { - label: 'Source', - type: 'select', - ngOptions: 'source.label for source in source_type_options track by source.value', - ngChange: 'sourceChange(source)', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - ngModel: 'source' - }, - credential: { - // initializes a default value for this search param - // search params with default values set will not generate user-interactable search tags - search: { - kind: null - }, - label: 'Cloud Credential', - type: 'lookup', - list: 'CredentialList', - basePath: 'credentials', - ngShow: "source && source.value !== '' && source.value !== 'custom'", - sourceModel: 'credential', - sourceField: 'name', - ngClick: 'lookupCredential()', - awRequiredWhen: { - reqExpression: "cloudCredentialRequired", - init: "false" - }, - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - watchBasePath: "credentialBasePath" - }, - source_regions: { - label: 'Regions', - type: 'select', - ngOptions: 'source.label for source in source_region_choices track by source.value', - multiSelect: true, - ngShow: "source && (source.value == 'rax' || source.value == 'ec2' || source.value == 'gce' || source.value == 'azure' || source.value == 'azure_rm')", - - - dataTitle: 'Source Regions', - dataPlacement: 'right', - awPopOver: "

Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " + - "or choose All to include all regions. Tower will only be updated with Hosts associated with the selected regions." + - "

", - dataContainer: 'body', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - instance_filters: { - label: 'Instance Filters', - type: 'text', - ngShow: "source && source.value == 'ec2'", - dataTitle: 'Instance Filters', - dataPlacement: 'right', - awPopOver: "

Provide a comma-separated list of filter expressions. " + - "Hosts are imported to Tower when ANY of the filters match.

" + - "Limit to hosts having a tag:
\n" + - "
tag-key=TowerManaged
\n" + - "Limit to hosts using either key pair:
\n" + - "
key-name=staging, key-name=production
\n" + - "Limit to hosts where the Name tag begins with test:
\n" + - "
tag:Name=test*
\n" + - "

View the Describe Instances documentation " + - "for a complete list of supported filters.

", - dataContainer: 'body', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - group_by: { - label: 'Only Group By', - type: 'select', - ngShow: "source && source.value == 'ec2'", - ngOptions: 'source.label for source in group_by_choices track by source.value', - multiSelect: true, - dataTitle: 'Only Group By', - dataPlacement: 'right', - awPopOver: "

Select which groups to create automatically. " + - "Tower will create group names similar to the following examples based on the options selected:

    " + - "
  • Availability Zone: zones » us-east-1b
  • " + - "
  • Image ID: images » ami-b007ab1e
  • " + - "
  • Instance ID: instances » i-ca11ab1e
  • " + - "
  • Instance Type: types » type_m1_medium
  • " + - "
  • Key Name: keys » key_testing
  • " + - "
  • Region: regions » us-east-1
  • " + - "
  • Security Group: security_groups » security_group_default
  • " + - "
  • Tags: tags » tag_Name » tag_Name_host1
  • " + - "
  • VPC ID: vpcs » vpc-5ca1ab1e
  • " + - "
  • Tag None: tags » tag_none
  • " + - "

If blank, all groups above are created except Instance ID.

", - dataContainer: 'body', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - inventory_script: { - label : "Custom Inventory Script", - type: 'lookup', - basePath: 'inventory_scripts', - list: 'InventoryScriptsList', - ngShow: "source && source.value === 'custom'", - sourceModel: 'inventory_script', - sourceField: 'name', - awRequiredWhen: { - reqExpression: "source && source.value === 'custom'", - init: "false" - }, - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - }, - custom_variables: { - id: 'custom_variables', - label: 'Environment Variables', //"{{vars_label}}" , - ngShow: "source && source.value=='custom' ", - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - parseTypeName: 'envParseType', - dataTitle: "Environment Variables", - dataPlacement: 'right', - awPopOver: "

Provide environment variables to pass to the custom inventory script.

" + - "

Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body' - }, - ec2_variables: { - id: 'ec2_variables', - label: 'Source Variables', //"{{vars_label}}" , - ngShow: "source && source.value == 'ec2'", - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - parseTypeName: 'envParseType', - dataTitle: "Source Variables", - dataPlacement: 'right', - awPopOver: "

Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables " + - "" + - "view ec2.ini in the Ansible github repo.

" + - "

Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body' - }, - vmware_variables: { - id: 'vmware_variables', - label: 'Source Variables', //"{{vars_label}}" , - ngShow: "source && source.value == 'vmware'", - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - parseTypeName: 'envParseType', - dataTitle: "Source Variables", - dataPlacement: 'right', - awPopOver: "

Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables " + - "" + - "view vmware_inventory.ini in the Ansible github repo.

" + - "

Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body' - }, - openstack_variables: { - id: 'openstack_variables', - label: 'Source Variables', //"{{vars_label}}" , - ngShow: "source && source.value == 'openstack'", - type: 'textarea', - class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 6, - 'default': '---', - parseTypeName: 'envParseType', - dataTitle: "Source Variables", - dataPlacement: 'right', - awPopOver: "

Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration " + - "" + - "view openstack.yml in the Ansible github repo.

" + - "

Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

View JSON examples at www.json.org

' + - '

View YAML examples at docs.ansible.com

', - dataContainer: 'body' - }, - checkbox_group: { - label: 'Update Options', - type: 'checkbox_group', - ngShow: "source && (source.value !== '' && source.value !== null)", - class: 'Form-checkbox--stacked', - fields: [{ - name: 'overwrite', - label: 'Overwrite', - type: 'checkbox', - ngShow: "source.value !== '' && source.value !== null", - - - awPopOver: '

If checked, all child groups and hosts not found on the external source will be deleted from ' + - 'the local inventory.

When not checked, local child hosts and groups not found on the external source will ' + - 'remain untouched by the inventory update process.

', - dataTitle: 'Overwrite', - dataContainer: 'body', - dataPlacement: 'right', - labelClass: 'checkbox-options', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, { - name: 'overwrite_vars', - label: 'Overwrite Variables', - type: 'checkbox', - ngShow: "source.value !== '' && source.value !== null", - - - awPopOver: '

If checked, all variables for child groups and hosts will be removed and replaced by those ' + - 'found on the external source.

When not checked, a merge will be performed, combining local variables with ' + - 'those found on the external source.

', - dataTitle: 'Overwrite Variables', - dataContainer: 'body', - dataPlacement: 'right', - labelClass: 'checkbox-options', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, { - name: 'update_on_launch', - label: 'Update on Launch', - type: 'checkbox', - ngShow: "source.value !== '' && source.value !== null", - awPopOver: '

Each time a job runs using this inventory, refresh the inventory from the selected source before ' + - 'executing job tasks.

', - dataTitle: 'Update on Launch', - dataContainer: 'body', - dataPlacement: 'right', - labelClass: 'checkbox-options', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }] - }, - update_cache_timeout: { - label: "Cache Timeout (seconds)", - id: 'source-cache-timeout', - type: 'number', - ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)', - integer: true, - min: 0, - ngShow: "source && source.value !== '' && update_on_launch", - spinner: true, - "default": 0, - awPopOver: '

Time in seconds to consider an inventory sync to be current. During job runs and callbacks the task system will ' + - 'evaluate the timestamp of the latest sync. If it is older than Cache Timeout, it is not considered current, ' + - 'and a new inventory sync will be performed.

', - dataTitle: 'Cache Timeout', - dataPlacement: 'right', - dataContainer: "body" - } - }, - - buttons: { - cancel: { - ngClick: 'formCancel()', - ngShow: '(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - close: { - ngClick: 'formCancel()', - ngShow: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - save: { - ngClick: 'formSave()', - ngDisabled: true, - ngShow: '(group_obj.summary_fields.user_capabilities.edit || canAdd)' - } - }, - - related: { - "notifications": { - include: "NotificationsList" - } - } - - }; - var itm; - - for (itm in GroupFormObject.related) { - if (GroupFormObject.related[itm].include === "NotificationsList") { - GroupFormObject.related[itm] = angular.copy(NotificationsList); - GroupFormObject.related[itm].generateList = true; - GroupFormObject.related[itm].disabled = "source === undefined || source.value === ''"; - GroupFormObject.related[itm].ngClick = "$state.go('inventoryManage.editGroup.notifications')"; - } - } - return GroupFormObject; - }; - }]; diff --git a/awx/ui/client/src/inventories/manage/groups/groups.service.js b/awx/ui/client/src/inventories/manage/groups/groups.service.js deleted file mode 100644 index 54ed90dfc7..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/groups.service.js +++ /dev/null @@ -1,113 +0,0 @@ -export default - ['$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', 'Wait', function($rootScope, Rest, GetBasePath, ProcessErrors, Wait){ - return { - stringifyParams: function(params){ - return _.reduce(params, (result, value, key) => { - return result + key + '=' + value + '&'; - }, ''); - }, - // cute abstractions via fn.bind() - url: function(){ - return ''; - }, - error: function(data, status) { - ProcessErrors($rootScope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + this.url + '. GET returned: ' + status }); - }, - success: function(data){ - return data; - }, - // HTTP methods - get: function(params){ - Wait('start'); - this.url = GetBasePath('groups') + '?' + this.stringifyParams(params); - Rest.setUrl(this.url); - return Rest.get() - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - }, - post: function(group){ - Wait('start'); - this.url = GetBasePath('groups'); - Rest.setUrl(this.url); - return Rest.post(group) - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - }, - put: function(group){ - Wait('start'); - this.url = GetBasePath('groups') + group.id; - Rest.setUrl(this.url); - return Rest.put(group) - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - }, - delete: function(id){ - Wait('start'); - this.url = GetBasePath('groups') + id; - Rest.setUrl(this.url); - return Rest.destroy() - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - }, - getCredential: function(id){ - Wait('start'); - this.url = GetBasePath('credentials') + id; - Rest.setUrl(this.url); - return Rest.get() - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - }, - getInventorySource: function(params){ - Wait('start'); - this.url = GetBasePath('inventory_sources') + '?' + this.stringifyParams(params); - Rest.setUrl(this.url); - return Rest.get() - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - }, - putInventorySource: function(params, url){ - Wait('start'); - this.url = url; - Rest.setUrl(this.url); - return Rest.put(params) - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - }, - // these relationship setters could be consolidated, but verbosity makes the operation feel more clear @ controller level - associateGroup: function(group, target){ - Wait('start'); - this.url = GetBasePath('groups') + target + '/children/'; - Rest.setUrl(this.url); - return Rest.post(group) - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - }, - disassociateGroup: function(group, parent){ - Wait('start'); - this.url = GetBasePath('groups') + parent + '/children/'; - Rest.setUrl(this.url); - return Rest.post({id: group, disassociate: 1}) - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - }, - promote: function(group, inventory){ - Wait('start'); - this.url = GetBasePath('inventory') + inventory + '/groups/'; - Rest.setUrl(this.url); - return Rest.post({id: group, disassociate: 1}) - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); - } - }; - }]; diff --git a/awx/ui/client/src/inventories/manage/groups/inventory-groups.list.js b/awx/ui/client/src/inventories/manage/groups/inventory-groups.list.js deleted file mode 100644 index 3c4c12c9c1..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/inventory-groups.list.js +++ /dev/null @@ -1,167 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -export default { - name: 'groups', - iterator: 'group', - editTitle: '{{ inventory.name }}', - listTitle: 'GROUPS', - searchSize: 'col-lg-12 col-md-12 col-sm-12 col-xs-12', - showTitle: false, - well: true, - index: false, - hover: true, - 'class': 'table-no-border', - multiSelect: true, - trackBy: 'group.id', - - fields: { - sync_status: { - label: '', - nosort: true, - mode: 'all', - iconOnly: true, - ngClick: 'viewUpdateStatus(group.id)', - awToolTip: "{{ group.status_tooltip }}", - dataTipWatch: "group.status_tooltip", - icon: "{{ 'fa icon-cloud-' + group.status_class }}", - ngClass: "group.status_class", - dataPlacement: "top", - columnClass: 'status-column List-staticColumn--smallStatus' - }, - failed_hosts: { - label: '', - nosort: true, - mode: 'all', - iconOnly: true, - awToolTip: "{{ group.hosts_status_tip }}", - dataPlacement: "top", - ngClick: "showFailedHosts(group)", - icon: "{{ 'fa icon-job-' + group.hosts_status_class }}", - columnClass: 'status-column List-staticColumn--smallStatus' - }, - name: { - label: 'Groups', - key: true, - ngClick: "groupSelect(group.id)", - columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6', - class: 'InventoryManage-breakWord', - }, - total_groups: { - nosort: true, - label: '', - type: 'badgeCount', - ngHide: 'group.total_groups == 0', - noLink: true, - awToolTip: "{{group.name | sanitize}} contains {{group.total_groups}} {{group.total_groups === 1 ? 'child' : 'children'}}" - } - }, - - actions: { - refresh: { - mode: 'all', - awToolTip: "Refresh the page", - ngClick: "refreshGroups()", - ngShow: "socketStatus == 'error'", - actionClass: 'btn List-buttonDefault', - buttonContent: 'REFRESH' - }, - launch: { - mode: 'all', - // $scope.$parent is governed by InventoryManageController, - ngDisabled: '!$parent.groupsSelected && !$parent.hostsSelected', - ngClick: '$parent.setAdhocPattern()', - awToolTip: "Select an inventory source by clicking the check box beside it. The inventory source can be a single group or host, a selection of multiple hosts, or a selection of multiple groups.", - dataTipWatch: "adhocCommandTooltip", - actionClass: 'btn List-buttonDefault', - buttonContent: 'RUN COMMANDS', - showTipWhenDisabled: true, - tooltipInnerClass: "Tooltip-wide", - ngShow: 'canAdhoc' - // TODO: set up a tip watcher and change text based on when - // things are selected/not selected. This is started and - // commented out in the inventory controller within the watchers. - // awToolTip: "{{ adhocButtonTipContents }}", - // dataTipWatch: "adhocButtonTipContents" - }, - create: { - mode: 'all', - ngClick: "createGroup()", - awToolTip: "Create a new group", - actionClass: 'btn List-buttonSubmit', - buttonContent: '+ ADD GROUP', - ngShow: 'canAdd', - dataPlacement: "top", - } - }, - - fieldActions: { - - columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6 text-right', - - group_update: { - //label: 'Sync', - mode: 'all', - ngClick: 'updateGroup(group)', - awToolTip: "{{ group.launch_tooltip }}", - dataTipWatch: "group.launch_tooltip", - ngShow: "(group.status !== 'running' && group.status " + - "!== 'pending' && group.status !== 'updating') && group.summary_fields.user_capabilities.start", - ngClass: "group.launch_class", - dataPlacement: "top", - }, - cancel: { - //label: 'Cancel', - mode: 'all', - ngClick: "cancelUpdate(group.id)", - awToolTip: "Cancel sync process", - 'class': 'red-txt', - ngShow: "(group.status == 'running' || group.status == 'pending' " + - "|| group.status == 'updating') && group.summary_fields.user_capabilities.start", - dataPlacement: "top", - iconClass: "fa fa-minus-circle" - }, - copy: { - mode: 'all', - ngClick: "copyMoveGroup(group.id)", - awToolTip: 'Copy or move group', - ngShow: "group.id > 0 && group.summary_fields.user_capabilities.copy", - dataPlacement: "top" - }, - schedule: { - mode: 'all', - ngClick: "scheduleGroup(group.id)", - awToolTip: "{{ group.group_schedule_tooltip }}", - ngClass: "group.scm_type_class", - dataPlacement: 'top', - ngShow: "!(group.summary_fields.inventory_source.source === '')" - }, - edit: { - //label: 'Edit', - mode: 'all', - ngClick: "editGroup(group.id)", - awToolTip: 'Edit group', - dataPlacement: "top", - ngShow: "group.summary_fields.user_capabilities.edit" - }, - view: { - //label: 'Edit', - mode: 'all', - ngClick: "editGroup(group.id)", - awToolTip: 'View group', - dataPlacement: "top", - ngShow: "!group.summary_fields.user_capabilities.edit" - }, - "delete": { - //label: 'Delete', - mode: 'all', - ngClick: "deleteGroup(group)", - awToolTip: 'Delete group', - dataPlacement: "top", - ngShow: "group.summary_fields.user_capabilities.delete" - } - } -}; diff --git a/awx/ui/client/src/inventories/manage/groups/main.js b/awx/ui/client/src/inventories/manage/groups/main.js deleted file mode 100644 index 9423ed0c81..0000000000 --- a/awx/ui/client/src/inventories/manage/groups/main.js +++ /dev/null @@ -1,27 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import GroupAddController from './groups-add.controller'; -import GroupEditController from './groups-edit.controller'; -import GetHostsStatusMsg from './factories/get-hosts-status-msg.factory'; -import GetSourceTypeOptions from './factories/get-source-type-options.factory'; -import GetSyncStatusMsg from './factories/get-sync-status-msg.factory'; -import GroupsCancelUpdate from './factories/groups-cancel-update.factory'; -import ViewUpdateStatus from './factories/view-update-status.factory'; -import InventoryGroups from './inventory-groups.list'; -import GroupForm from './groups.form'; - -export default -angular.module('manageGroups', []) - .factory('GetHostsStatusMsg', GetHostsStatusMsg) - .factory('GetSourceTypeOptions', GetSourceTypeOptions) - .factory('GetSyncStatusMsg', GetSyncStatusMsg) - .factory('GroupsCancelUpdate', GroupsCancelUpdate) - .factory('ViewUpdateStatus', ViewUpdateStatus) - .factory('GroupForm', GroupForm) - .value('InventoryGroups', InventoryGroups) - .controller('GroupAddController', GroupAddController) - .controller('GroupEditController', GroupEditController); diff --git a/awx/ui/client/src/inventories/manage/hosts/hosts-edit.controller.js b/awx/ui/client/src/inventories/manage/hosts/hosts-edit.controller.js deleted file mode 100644 index 47ac724664..0000000000 --- a/awx/ui/client/src/inventories/manage/hosts/hosts-edit.controller.js +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - export default - ['$state', '$stateParams', '$scope', 'HostForm', 'ParseTypeChange', 'HostManageService', 'host', 'ToJSON', - function($state, $stateParams, $scope, HostForm, ParseTypeChange, HostManageService, host, ToJSON){ - - init(); - - function init(){ - $scope.$watch('host.summary_fields.user_capabilities.edit', function(val) { - if (val === false) { - $scope.canAdd = false; - } - }); - - $scope.parseType = 'yaml'; - $scope.host = host; - $scope.variables = getVars(host.variables); - $scope.name = host.name; - $scope.description = host.description; - - ParseTypeChange({ - scope: $scope, - field_id: 'host_variables', - }); - } - - // Adding this function b/c sometimes extra vars are returned to the - // UI as a string (ex: "foo: bar"), and other times as a - // json-object-string (ex: "{"foo": "bar"}"). CodeMirror wouldn't know - // how to prettify the latter. The latter occurs when host vars were - // system generated and not user-input (such as adding a cloud host); - function getVars(str){ - - // Quick function to test if the host vars are a json-object-string, - // by testing if they can be converted to a JSON object w/o error. - function IsJsonString(str) { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; - } - - if(str === ''){ - return '---'; - } - else if(IsJsonString(str)){ - str = JSON.parse(str); - return jsyaml.safeDump(str); - } - else if(!IsJsonString(str)){ - return str; - } - } - - $scope.formCancel = function(){ - $state.go('^'); - }; - $scope.toggleHostEnabled = function(){ - if ($scope.host.has_inventory_sources){ - return; - } - $scope.host.enabled = !$scope.host.enabled; - }; - $scope.formSave = function(){ - var json_data = ToJSON($scope.parseType, $scope.variables, true), - host = { - id: $scope.host.id, - variables: json_data, - name: $scope.name, - description: $scope.description, - enabled: $scope.host.enabled - }; - HostManageService.put(host).then(function(){ - $state.go($state.current, null, {reload: true}); - }); - }; - }]; diff --git a/awx/ui/client/src/inventories/manage/hosts/hosts-list.controller.js b/awx/ui/client/src/inventories/manage/hosts/hosts-list.controller.js deleted file mode 100644 index 278022e002..0000000000 --- a/awx/ui/client/src/inventories/manage/hosts/hosts-list.controller.js +++ /dev/null @@ -1,120 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - export default - ['$scope', '$rootScope', '$state', '$stateParams', 'InventoryHosts', 'HostManageService', - 'hostsUrl', 'SetStatus', 'Prompt', 'Wait', 'inventoryData', '$filter', 'hostsDataset', 'GetBasePath', 'rbacUiControlService', 'QuerySet', - function($scope, $rootScope, $state, $stateParams, InventoryHosts, HostManageService, - hostsUrl, SetStatus, Prompt, Wait, inventoryData, $filter, hostsDataset, GetBasePath, rbacUiControlService, qs){ - var list = InventoryHosts; - - init(); - function init(){ - $scope.inventory_id = $stateParams.inventory_id; - - $scope.canAdd = false; - - rbacUiControlService.canAdd(GetBasePath('inventory') + $scope.inventory_id + "/hosts") - .then(function(params) { - $scope.canAdd = params.canAdd; - }); - - // Search init - $scope.list = list; - $scope[`${list.iterator}_dataset`] = hostsDataset.data; - $scope[list.name] = $scope[`${list.iterator}_dataset`].results; - - $scope.$watch(`${list.iterator}_dataset`, () => { - $scope.hosts - .forEach((host) => SetStatus({scope: $scope, - host: host})); - }); - - $scope.$on(`ws-jobs`, function(e, data){ - if(data.status === 'failed' || data.status === 'successful'){ - let path = hostsUrl; - qs.search(path, $state.params[`${list.iterator}_search`]) - .then(function(searchResponse) { - $scope[`${list.iterator}_dataset`] = searchResponse.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 === "inventoryManage.editHost") { - $scope.rowBeingEdited = $state.params.host_id; - $scope.listBeingEdited = "hosts"; - } - } - - $scope.createHost = function(){ - $state.go('inventoryManage.addHost'); - }; - $scope.editHost = function(id){ - $state.go('inventoryManage.editHost', {host_id: id}); - }; - $scope.deleteHost = function(id, name){ - var body = '
Are you sure you want to permanently delete the host below from the inventory?
' + $filter('sanitize')(name) + '
'; - var action = function(){ - delete $rootScope.promptActionBtnClass; - Wait('start'); - HostManageService.delete(id).then(() => { - $('#prompt-modal').modal('hide'); - if (parseInt($state.params.host_id) === id) { - $state.go("inventoryManage", null, {reload: true}); - } else { - $state.go($state.current.name, null, {reload: true}); - } - Wait('stop'); - }); - }; - // Prompt depends on having $rootScope.promptActionBtnClass available... - Prompt({ - hdr: 'Delete Host', - body: body, - action: action, - actionText: 'DELETE', - }); - $rootScope.promptActionBtnClass = 'Modal-errorButton'; - }; - $scope.copyMoveHost = function(id){ - $state.go('inventoryManage.copyMoveHost', {host_id: id}); - }; - $scope.systemTracking = function(){ - var hostIds = _.map($scope.$parent.hostsSelectedItems, (host) => host.id); - $state.go('systemTracking', { - inventory: inventoryData, - inventoryId: $stateParams.inventory_id, - hosts: $scope.$parent.hostsSelectedItems, - hostIds: hostIds - }); - }; - // $scope.$parent governed by InventoryManageController, for unified multiSelect options - $scope.$on('multiSelectList.selectionChanged', (event, selection) => { - $scope.$parent.hostsSelected = selection.length > 0 ? true : false; - $scope.$parent.hostsSelectedItems = selection.selectedItems; - $scope.$parent.systemTrackingDisabled = selection.length > 0 && selection.length < 3 ? false : true; - $scope.$parent.systemTrackingTooltip = selection.length > 0 && selection.length < 3 ? "Compare host facts over time" : "Select one or two hosts by clicking the checkbox beside the host. System tracking offers the ability to compare the results of two scan runs from different dates on one host or the same date on two hosts."; - }); - var cleanUpStateChangeListener = $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams) { - if (toState.name === "inventoryManage.editHost") { - $scope.rowBeingEdited = toParams.host_id; - $scope.listBeingEdited = "hosts"; - } - else { - delete $scope.rowBeingEdited; - delete $scope.listBeingEdited; - } - }); - // Remove the listener when the scope is destroyed to avoid a memory leak - $scope.$on('$destroy', function() { - cleanUpStateChangeListener(); - }); - }]; diff --git a/awx/ui/client/src/inventories/manage/hosts/inventory-hosts.list.js b/awx/ui/client/src/inventories/manage/hosts/inventory-hosts.list.js deleted file mode 100644 index a2793638a3..0000000000 --- a/awx/ui/client/src/inventories/manage/hosts/inventory-hosts.list.js +++ /dev/null @@ -1,119 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -export default { - name: 'hosts', - iterator: 'host', - editTitle: '{{ selected_group }}', - listTitle: 'HOSTS', - searchSize: 'col-lg-12 col-md-12 col-sm-12 col-xs-12', - showTitle: false, - well: true, - index: false, - hover: true, - hasChildren: true, - 'class': 'table-no-border', - multiSelect: true, - trackBy: 'host.id', - - fields: { - active_failures: { - label: '', - iconOnly: true, - nosort: true, - // do not remove this ng-click directive - // the list generator case to handle fields without ng-click - // cannot handle the aw-* directives - ngClick: 'noop()', - awPopOver: "{{ host.job_status_html }}", - dataTitle: "{{ host.job_status_title }}", - awToolTip: "{{ host.badgeToolTip }}", - dataPlacement: 'top', - icon: "{{ 'fa icon-job-' + host.active_failures }}", - id: 'active-failures-action', - columnClass: 'status-column List-staticColumn--smallStatus' - }, - name: { - key: true, - label: 'Hosts', - ngClick: "editHost(host.id)", - ngClass: "{ 'host-disabled-label': !host.enabled }", - columnClass: 'col-lg-6 col-md-8 col-sm-8 col-xs-7', - dataHostId: "{{ host.id }}", - dataType: "host", - class: 'InventoryManage-breakWord' - } - }, - - fieldActions: { - - columnClass: 'col-lg-6 col-md-4 col-sm-4 col-xs-5 text-right', - copy: { - mode: 'all', - ngClick: "copyMoveHost(host.id)", - awToolTip: 'Copy or move host to another group', - dataPlacement: "top", - ngShow: 'host.summary_fields.user_capabilities.edit' - }, - edit: { - //label: 'Edit', - ngClick: "editHost(host.id)", - icon: 'icon-edit', - awToolTip: 'Edit host', - dataPlacement: 'top', - ngShow: 'host.summary_fields.user_capabilities.edit' - }, - view: { - //label: 'Edit', - ngClick: "editHost(host.id)", - awToolTip: 'View host', - dataPlacement: 'top', - ngShow: '!host.summary_fields.user_capabilities.edit' - }, - "delete": { - //label: 'Delete', - ngClick: "deleteHost(host.id, host.name)", - icon: 'icon-trash', - awToolTip: 'Delete host', - dataPlacement: 'top', - ngShow: 'host.summary_fields.user_capabilities.delete' - } - }, - - actions: { - system_tracking: { - buttonContent: 'System Tracking', - ngClick: 'systemTracking()', - awToolTip: "Select one or two hosts by clicking the checkbox beside the host. System tracking offers the ability to compare the results of two scan runs from different dates on one host or the same date on two hosts.", - dataTipWatch: "systemTrackingTooltip", - dataPlacement: 'top', - awFeature: 'system_tracking', - actionClass: 'btn List-buttonDefault system-tracking', - ngDisabled: 'systemTrackingDisabled || !hostsSelected', - showTipWhenDisabled: true, - tooltipInnerClass: "Tooltip-wide", - ngShow: true - }, - refresh: { - mode: 'all', - awToolTip: "Refresh the page", - ngClick: "refreshGroups()", - ngShow: "socketStatus == 'error'", - actionClass: 'btn List-buttonDefault', - buttonContent: 'REFRESH' - }, - create: { - mode: 'all', - ngClick: "createHost()", - awToolTip: "Create a new host", - actionClass: 'btn List-buttonSubmit', - buttonContent: '+ ADD HOST', - ngShow: 'canAdd', - dataPlacement: "top", - } - } - -}; diff --git a/awx/ui/client/src/inventories/manage/hosts/main.js b/awx/ui/client/src/inventories/manage/hosts/main.js deleted file mode 100644 index b3d514a4f4..0000000000 --- a/awx/ui/client/src/inventories/manage/hosts/main.js +++ /dev/null @@ -1,21 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import HostsAddController from './hosts-add.controller'; -import HostsEditController from './hosts-edit.controller'; -import SetStatus from './factories/set-status.factory'; -import SetEnabledMsg from './factories/set-enabled-msg.factory'; -import InventoryHosts from './inventory-hosts.list'; -import HostForm from './hosts.form'; - -export default -angular.module('manageHosts', []) - .factory('SetStatus', SetStatus) - .factory('SetEnabledMsg', SetEnabledMsg) - .factory('HostForm', HostForm) - .value('InventoryHosts', InventoryHosts) - .controller('HostsAddController', HostsAddController) - .controller('HostEditController', HostsEditController); diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.block.less b/awx/ui/client/src/inventories/manage/inventory-manage.block.less deleted file mode 100644 index caaf039058..0000000000 --- a/awx/ui/client/src/inventories/manage/inventory-manage.block.less +++ /dev/null @@ -1,3 +0,0 @@ -.InventoryManage-container{ - margin-top: -36px; -} diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js deleted file mode 100644 index f3201d475a..0000000000 --- a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ -export default - ['$scope', '$state', 'inventoryData', function($scope, $state, inventoryData){ - $scope.groupsSelected = false; - $scope.hostsSelected = false; - $scope.hostsSelectedItems = []; - $scope.groupsSelectedItems = []; - - $scope.canAdhoc = inventoryData.summary_fields.user_capabilities.adhoc; - - $scope.setAdhocPattern = function(){ - var pattern = _($scope.groupsSelectedItems) - .concat($scope.hostsSelectedItems) - .map(function(item){ - return item.name; - }).value().join(':'); - - $state.go('inventoryManage.adhoc', {pattern: pattern}); - }; - - $scope.$watchGroup(['groupsSelected', 'hostsSelected'], function(newVals) { - $scope.adhocCommandTooltip = (newVals[0] || newVals[1]) ? "Run a command on the selected inventory" : "Select an inventory source by clicking the check box beside it. The inventory source can be a single group or host, a selection of multiple hosts, or a selection of multiple groups."; - }); - }]; diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.partial.html b/awx/ui/client/src/inventories/manage/inventory-manage.partial.html deleted file mode 100644 index 80a4bc2707..0000000000 --- a/awx/ui/client/src/inventories/manage/inventory-manage.partial.html +++ /dev/null @@ -1,8 +0,0 @@ -
-
-
-
-
-
-
-
diff --git a/awx/ui/client/src/inventories/manage/main.js b/awx/ui/client/src/inventories/manage/main.js deleted file mode 100644 index 79925117ec..0000000000 --- a/awx/ui/client/src/inventories/manage/main.js +++ /dev/null @@ -1,24 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import InventoryManageService from './inventory-manage.service'; -import HostManageService from './hosts/hosts.service'; -import GroupManageService from './groups/groups.service'; -import hosts from './hosts/main'; -import groups from './groups/main'; -import adhoc from './adhoc/main'; -import copyMove from './copy-move/main'; - -export default -angular.module('inventoryManage', [ - hosts.name, - groups.name, - copyMove.name, - adhoc.name - ]) - .service('InventoryManageService', InventoryManageService) - .service('HostManageService', HostManageService) - .service('GroupManageService', GroupManageService); 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 new file mode 100644 index 0000000000..7dfbd5d819 --- /dev/null +++ b/awx/ui/client/src/inventories/related-hosts/edit/build-host-edit-state.factory.js @@ -0,0 +1,73 @@ +/************************************************* +* 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/inventoriesnew/add/inventory-add.controller.js b/awx/ui/client/src/inventoriesnew/add/inventory-add.controller.js deleted file mode 100644 index 17f42276d0..0000000000 --- a/awx/ui/client/src/inventoriesnew/add/inventory-add.controller.js +++ /dev/null @@ -1,104 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Inventories - * @description This controller's for the Inventory page - */ - -function InventoriesAdd($scope, $location, - GenerateForm, InventoryForm, rbacUiControlService, Rest, Alert, ProcessErrors, - ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON, - $state) { - - $scope.canAdd = false; - rbacUiControlService.canAdd(GetBasePath('inventory')) - .then(function(canAdd) { - $scope.canAdd = canAdd; - }); - - Rest.setUrl(GetBasePath('inventory')); - Rest.options() - .success(function(data) { - if (!data.actions.POST) { - $state.go("^"); - Alert('Permission Error', 'You do not have permission to add an inventory.', 'alert-info'); - } - }); - - ClearScope(); - - // Inject dynamic view - var defaultUrl = GetBasePath('inventory'), - form = InventoryForm; - - init(); - - function init() { - $scope.canEditOrg = true; - form.formLabelSize = null; - form.formFieldSize = null; - - // apply form definition's default field values - GenerateForm.applyDefaults(form, $scope); - - $scope.parseType = 'yaml'; - ParseTypeChange({ - scope: $scope, - variable: 'variables', - parse_variable: 'parseType', - field_id: 'inventory_variables' - }); - } - - // Save - $scope.formSave = function() { - Wait('start'); - try { - var fld, json_data, data; - - json_data = ToJSON($scope.parseType, $scope.variables, true); - - data = {}; - for (fld in form.fields) { - if (form.fields[fld].realName) { - data[form.fields[fld].realName] = $scope[fld]; - } else { - data[fld] = $scope[fld]; - } - } - - Rest.setUrl(defaultUrl); - Rest.post(data) - .success(function(data) { - var inventory_id = data.id; - Wait('stop'); - $location.path('/inventoriesnew/' + inventory_id); - }) - .error(function(data, status) { - ProcessErrors($scope, data, status, form, { - hdr: 'Error!', - msg: 'Failed to add new inventory. Post returned status: ' + status - }); - }); - } catch (err) { - Wait('stop'); - Alert("Error", "Error parsing inventory variables. Parser returned: " + err); - } - - }; - - $scope.formCancel = function() { - $state.go('inventoriesnew'); - }; -} - -export default ['$scope', '$location', - 'GenerateForm', 'InventoryForm', 'rbacUiControlService', 'Rest', 'Alert', - 'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange', - 'Wait', 'ToJSON', '$state', InventoriesAdd -]; diff --git a/awx/ui/client/src/inventoriesnew/add/main.js b/awx/ui/client/src/inventoriesnew/add/main.js deleted file mode 100644 index 2d3c391495..0000000000 --- a/awx/ui/client/src/inventoriesnew/add/main.js +++ /dev/null @@ -1,11 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import controller from './inventory-add.controller'; - -export default -angular.module('newInventoryAdd', []) - .controller('NewInventoryAddController', controller); diff --git a/awx/ui/client/src/inventoriesnew/edit/inventory-edit.controller.js b/awx/ui/client/src/inventoriesnew/edit/inventory-edit.controller.js deleted file mode 100644 index 98c1549499..0000000000 --- a/awx/ui/client/src/inventoriesnew/edit/inventory-edit.controller.js +++ /dev/null @@ -1,136 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Inventories - * @description This controller's for the Inventory page - */ - -function InventoriesEdit($scope, $location, - $stateParams, InventoriesNewForm, Rest, ProcessErrors, - ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON, - ParseVariableString, $state, OrgAdminLookup) { - - // Inject dynamic view - var defaultUrl = GetBasePath('inventory'), - form = InventoriesNewForm, - inventory_id = $stateParams.inventory_id, - master = {}, - fld, json_data, data; - - ClearScope(); - init(); - - function init() { - ClearScope(); - form.formLabelSize = null; - form.formFieldSize = null; - $scope.inventory_id = inventory_id; - - $scope.$watch('inventory_obj.summary_fields.user_capabilities.edit', function(val) { - if (val === false) { - $scope.canAdd = false; - } - }); - } - - - Wait('start'); - Rest.setUrl(GetBasePath('inventory') + inventory_id + '/'); - Rest.get() - .success(function(data) { - var fld; - for (fld in form.fields) { - if (fld === 'variables') { - $scope.variables = ParseVariableString(data.variables); - master.variables = $scope.variables; - } else if (fld === 'inventory_name') { - $scope[fld] = data.name; - master[fld] = $scope[fld]; - } else if (fld === 'inventory_description') { - $scope[fld] = data.description; - master[fld] = $scope[fld]; - } else if (data[fld]) { - $scope[fld] = data[fld]; - master[fld] = $scope[fld]; - } - if (form.fields[fld].sourceModel && data.summary_fields && - data.summary_fields[form.fields[fld].sourceModel]) { - $scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = - data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; - master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] = - data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField]; - } - } - - Wait('stop'); - $scope.parseType = 'yaml'; - ParseTypeChange({ - scope: $scope, - variable: 'variables', - parse_variable: 'parseType', - field_id: 'inventory_variables' - }); - - OrgAdminLookup.checkForAdminAccess({organization: data.organization}) - .then(function(canEditOrg){ - $scope.canEditOrg = canEditOrg; - }); - - $scope.inventory_obj = data; - $scope.name = data.name; - - $scope.$emit('inventoryLoaded'); - }) - .error(function(data, status) { - ProcessErrors($scope, data, status, null, { - hdr: 'Error!', - msg: 'Failed to get inventory: ' + inventory_id + '. GET returned: ' + status - }); - }); - // Save - $scope.formSave = function() { - Wait('start'); - - // Make sure we have valid variable data - json_data = ToJSON($scope.parseType, $scope.variables); - - data = {}; - for (fld in form.fields) { - if (form.fields[fld].realName) { - data[form.fields[fld].realName] = $scope[fld]; - } else { - data[fld] = $scope[fld]; - } - } - - Rest.setUrl(defaultUrl + inventory_id + '/'); - Rest.put(data) - .success(function() { - Wait('stop'); - $state.go($state.current, {}, { reload: true }); - }) - .error(function(data, status) { - ProcessErrors($scope, data, status, form, { - hdr: 'Error!', - msg: 'Failed to update inventory. PUT returned status: ' + status - }); - }); - }; - - $scope.formCancel = function() { - $state.go('inventoriesnew'); - }; - -} - -export default ['$scope', '$location', - '$stateParams', 'InventoriesNewForm', 'Rest', - 'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange', 'Wait', - 'ToJSON', 'ParseVariableString', - '$state', 'OrgAdminLookup', InventoriesEdit, -]; diff --git a/awx/ui/client/src/inventoriesnew/edit/main.js b/awx/ui/client/src/inventoriesnew/edit/main.js deleted file mode 100644 index a6a404a869..0000000000 --- a/awx/ui/client/src/inventoriesnew/edit/main.js +++ /dev/null @@ -1,11 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import controller from './inventory-edit.controller'; - -export default - angular.module('newInventoryEdit', []) - .controller('NewInventoryEditController', controller); diff --git a/awx/ui/client/src/inventoriesnew/hosts/main.js b/awx/ui/client/src/inventoriesnew/hosts/main.js deleted file mode 100644 index 7363b267f9..0000000000 --- a/awx/ui/client/src/inventoriesnew/hosts/main.js +++ /dev/null @@ -1,20 +0,0 @@ -/************************************************* - * Copyright (c) 2017 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - import hostAdd from './add/main'; - import hostEdit from './edit/main'; - import hostList from './list/main'; - import HostsNewList from './host.list'; - import HostsNewForm from './host.form'; - -export default -angular.module('hostnew', [ - hostAdd.name, - hostEdit.name, - hostList.name - ]) - .factory('HostsNewForm', HostsNewForm) - .factory('HostsNewList', HostsNewList); diff --git a/awx/ui/client/src/inventoriesnew/inventory.form.js b/awx/ui/client/src/inventoriesnew/inventory.form.js deleted file mode 100644 index a138461f49..0000000000 --- a/awx/ui/client/src/inventoriesnew/inventory.form.js +++ /dev/null @@ -1,135 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name forms.function:Inventories - * @description This form is for adding/editing an inventory - */ - -export default ['i18n', function(i18n) { - return { - - addTitle: i18n._('NEW INVENTORY'), - editTitle: '{{ inventory_name }}', - name: 'inventory', - basePath: 'inventory', - // the top-most node of this generated state tree - stateTree: 'inventoriesnew', - tabs: true, - - fields: { - inventory_name: { - realName: 'name', - label: i18n._('Name'), - type: 'text', - required: true, - capitalize: false, - ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - inventory_description: { - realName: 'description', - label: i18n._('Description'), - type: 'text', - ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - organization: { - label: i18n._('Organization'), - type: 'lookup', - basePath: 'organizations', - list: 'OrganizationList', - sourceModel: 'organization', - sourceField: 'name', - awRequiredWhen: { - reqExpression: "organizationrequired", - init: "true" - }, - ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd) || !canEditOrg', - awLookupWhen: '(inventory_obj.summary_fields.user_capabilities.edit || canAdd) && canEditOrg' - }, - variables: { - label: i18n._('Variables'), - type: 'textarea', - class: 'Form-formGroup--fullWidth', - rows: 6, - "default": "---", - awPopOver: "

" + i18n._("Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.") + "

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\n" + - '

' + i18n.sprintf(i18n._('View JSON examples at %s'), 'www.json.org') + '

' + - '

' + i18n.sprintf(i18n._('View YAML examples at %s'), 'docs.ansible.com') + '

', - dataTitle: i18n._('Inventory Variables'), - dataPlacement: 'right', - dataContainer: 'body', - ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' // TODO: get working - } - }, - - buttons: { - cancel: { - ngClick: 'formCancel()', - ngShow: '(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - close: { - ngClick: 'formCancel()', - ngShow: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' - }, - save: { - ngClick: 'formSave()', - ngDisabled: true, - ngShow: '(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' - } - }, - related: { - permissions: { - name: 'permissions', - awToolTip: i18n._('Please save before assigning permissions'), - dataPlacement: 'top', - basePath: 'api/v1/inventories/{{$stateParams.inventory_id}}/access_list/', - type: 'collection', - title: i18n._('Permissions'), - iterator: 'permission', - index: false, - open: false, - search: { - order_by: 'username' - }, - actions: { - add: { - label: i18n._('Add'), - ngClick: "$state.go('.add')", - awToolTip: i18n._('Add a permission'), - actionClass: 'btn List-buttonSubmit', - buttonContent: '+ ADD', - ngShow: '(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' - - } - }, - fields: { - username: { - label: i18n._('User'), - linkBase: 'users', - class: 'col-lg-3 col-md-3 col-sm-3 col-xs-4' - }, - role: { - label: i18n._('Role'), - type: 'role', - nosort: true, - class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4', - }, - team_roles: { - label: i18n._('Team Roles'), - type: 'team_roles', - nosort: true, - class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4', - } - } - } - } - - };}]; diff --git a/awx/ui/client/src/inventoriesnew/inventory.list.js b/awx/ui/client/src/inventoriesnew/inventory.list.js deleted file mode 100644 index c06f3703ec..0000000000 --- a/awx/ui/client/src/inventoriesnew/inventory.list.js +++ /dev/null @@ -1,98 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - -export default ['i18n', function(i18n) { - return { - - name: 'inventoriesnew', - iterator: 'inventory', - selectTitle: i18n._('Add Inventories'), - editTitle: i18n._('INVENTORIES'), - listTitle: i18n._('INVENTORIES'), - selectInstructions: i18n.sprintf(i18n._("Click on a row to select it, and click Finished when done. Click the %s button to create a new inventory."), " "), - index: false, - hover: true, - basePath: 'inventory', - title: false, - - fields: { - status: { - label: '', - columnClass: 'List-staticColumn--mediumStatus', - nosort: true, - ngClick: "null", - iconOnly: true, - excludeModal: true, - icons: [{ - icon: "{{ 'icon-cloud-' + inventory.syncStatus }}", - awToolTip: "{{ inventory.syncTip }}", - awTipPlacement: "right", - ngClick: "showGroupSummary($event, inventory.id)", - ngClass: "inventory.launch_class" - },{ - icon: "{{ 'icon-job-' + inventory.hostsStatus }}", - awToolTip: false, - ngClick: "showHostSummary($event, inventory.id)", - ngClass: "" - }] - }, - name: { - key: true, - label: i18n._('Name'), - columnClass: 'col-md-5 col-sm-5 col-xs-8 List-staticColumnAdjacent', - modalColumnClass: 'col-md-11', - linkTo: '/#/inventoriesnew/{{inventory.id}}' - }, - organization: { - label: i18n._('Organization'), - ngBind: 'inventory.summary_fields.organization.name', - linkTo: '/#/organizations/{{ inventory.organization }}', - sourceModel: 'organization', - sourceField: 'name', - excludeModal: true, - columnClass: 'col-md-5 col-sm-3 hidden-xs' - } - }, - - actions: { - add: { - mode: 'all', // One of: edit, select, all - ngClick: 'addInventory()', - awToolTip: i18n._('Create a new inventory'), - actionClass: 'btn List-buttonSubmit', - buttonContent: '+ ' + i18n._('ADD'), - ngShow: 'canAdd' - } - }, - - fieldActions: { - - columnClass: 'col-md-2 col-sm-4 col-xs-4', - - edit: { - label: i18n._('Edit'), - ngClick: 'editInventory(inventory.id)', - awToolTip: i18n._('Edit inventory'), - dataPlacement: 'top', - ngShow: 'inventory.summary_fields.user_capabilities.edit' - }, - view: { - label: i18n._('View'), - ngClick: 'editInventory(inventory.id)', - awToolTip: i18n._('View inventory'), - dataPlacement: 'top', - ngShow: '!inventory.summary_fields.user_capabilities.edit' - }, - "delete": { - label: i18n._('Delete'), - ngClick: "deleteInventory(inventory.id, inventory.name)", - awToolTip: i18n._('Delete inventory'), - dataPlacement: 'top', - ngShow: 'inventory.summary_fields.user_capabilities.delete' - } - } - };}]; diff --git a/awx/ui/client/src/inventoriesnew/list/inventory-list.controller.js b/awx/ui/client/src/inventoriesnew/list/inventory-list.controller.js deleted file mode 100644 index e37f9ab6e8..0000000000 --- a/awx/ui/client/src/inventoriesnew/list/inventory-list.controller.js +++ /dev/null @@ -1,308 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Inventories - * @description This controller's for the Inventory page - */ - -function InventoriesList($scope, $rootScope, $location, - $compile, $filter, Rest, InventoriesNewList, Prompt, - ProcessErrors, GetBasePath, Wait, Find, Empty, $state, rbacUiControlService, Dataset) { - - let list = InventoriesNewList, - defaultUrl = GetBasePath('inventory'); - - init(); - - function init(){ - $scope.canAdd = false; - - rbacUiControlService.canAdd('inventory') - .then(function(canAdd) { - $scope.canAdd = canAdd; - }); - - $scope.$watchCollection(list.name, function(){ - _.forEach($scope[list.name], buildStatusIndicators); - }); - - // Search init - $scope.list = list; - $scope[`${list.iterator}_dataset`] = Dataset.data; - $scope[list.name] = $scope[`${list.iterator}_dataset`].results; - - $rootScope.flashMessage = null; - - } - - function buildStatusIndicators(inventory){ - inventory.launch_class = ""; - if (inventory.has_inventory_sources) { - if (inventory.inventory_sources_with_failures > 0) { - inventory.syncStatus = 'error'; - inventory.syncTip = inventory.inventory_sources_with_failures + ' groups with sync failures. Click for details'; - } - else { - inventory.syncStatus = 'successful'; - inventory.syncTip = 'No inventory sync failures. Click for details.'; - } - } - else { - inventory.syncStatus = 'na'; - inventory.syncTip = 'Not configured for inventory sync.'; - inventory.launch_class = "btn-disabled"; - } - if (inventory.has_active_failures) { - inventory.hostsStatus = 'error'; - inventory.hostsTip = inventory.hosts_with_active_failures + ' hosts with failures. Click for details.'; - } - else if (inventory.total_hosts) { - inventory.hostsStatus = 'successful'; - inventory.hostsTip = 'No hosts with failures. Click for details.'; - } - else { - inventory.hostsStatus = 'none'; - inventory.hostsTip = 'Inventory contains 0 hosts.'; - } - } - - function ellipsis(a) { - if (a.length > 20) { - return a.substr(0,20) + '...'; - } - return a; - } - - function attachElem(event, html, title) { - var elem = $(event.target).parent(); - try { - elem.tooltip('hide'); - elem.popover('destroy'); - } - catch(err) { - //ignore - } - $('.popover').each(function() { - // remove lingering popover
. Seems to be a bug in TB3 RC1 - $(this).remove(); - }); - $('.tooltip').each( function() { - // close any lingering tool tipss - $(this).hide(); - }); - elem.attr({ - "aw-pop-over": html, - "data-popover-title": title, - "data-placement": "right" }); - elem.removeAttr('ng-click'); - $compile(elem)($scope); - $scope.triggerPopover(event); - } - if ($scope.removeHostSummaryReady) { - $scope.removeHostSummaryReady(); - } - $scope.removeHostSummaryReady = $scope.$on('HostSummaryReady', function(e, event, data) { - - var html, title = "Recent Jobs"; - Wait('stop'); - if (data.count > 0) { - html = "\n"; - html += "\n"; - html += ""; - html += ""; - html += ""; - html += ""; - html += "\n"; - html += "\n"; - html += "\n"; - - data.results.forEach(function(row) { - html += "\n"; - html += "\n"; - html += ""; - html += ""; - html += "\n"; - }); - html += "\n"; - html += "
StatusFinishedName
" + ($filter('longDate')(row.finished)).replace(/ /,'
') + "
" + $filter('sanitize')(ellipsis(row.name)) + "
\n"; - } - else { - html = "

No recent job data available for this inventory.

\n"; - } - attachElem(event, html, title); - }); - - if ($scope.removeGroupSummaryReady) { - $scope.removeGroupSummaryReady(); - } - $scope.removeGroupSummaryReady = $scope.$on('GroupSummaryReady', function(e, event, inventory, data) { - var html, title; - - Wait('stop'); - - // Build the html for our popover - html = "\n"; - html += "\n"; - html += ""; - html += ""; - html += ""; - html += ""; - html += ""; - html += "\n"; - html += "\n"; - data.results.forEach( function(row) { - if (row.related.last_update) { - html += ""; - html += ``; - html += ""; - html += ""; - html += "\n"; - } - else { - html += ""; - html += ""; - html += ""; - html += ""; - html += "\n"; - } - }); - html += "\n"; - html += "
StatusLast SyncGroup
" + ($filter('longDate')(row.last_updated)).replace(/ /,'
') + "
" + $filter('sanitize')(ellipsis(row.summary_fields.group.name)) + "
NA" + $filter('sanitize')(ellipsis(row.summary_fields.group.name)) + "
\n"; - title = "Sync Status"; - attachElem(event, html, title); - }); - - $scope.showGroupSummary = function(event, id) { - try{ - var elem = $(event.target).parent(); - // if the popover is visible already, then exit the function here - if(elem.data()['bs.popover'].tip().hasClass('in')){ - return; - } - } - catch(err){ - var inventory; - if (!Empty(id)) { - inventory = Find({ list: $scope.inventories, key: 'id', val: id }); - if (inventory.syncStatus !== 'na') { - Wait('start'); - Rest.setUrl(inventory.related.inventory_sources + '?or__source=ec2&or__source=rax&order_by=-last_job_run&page_size=5'); - Rest.get() - .success(function(data) { - $scope.$emit('GroupSummaryReady', event, inventory, data); - }) - .error(function(data, status) { - ProcessErrors( $scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + inventory.related.inventory_sources + ' failed. GET returned status: ' + status - }); - }); - } - } - } - }; - - $scope.showHostSummary = function(event, id) { - try{ - var elem = $(event.target).parent(); - // if the popover is visible already, then exit the function here - if(elem.data()['bs.popover'].tip().hasClass('in')){ - return; - } - } - catch(err){ - var url, inventory; - if (!Empty(id)) { - inventory = Find({ list: $scope.inventories, key: 'id', val: id }); - if (inventory.total_hosts > 0) { - Wait('start'); - url = GetBasePath('jobs') + "?type=job&inventory=" + id + "&failed="; - url += (inventory.has_active_failures) ? 'true' : "false"; - url += "&order_by=-finished&page_size=5"; - Rest.setUrl(url); - Rest.get() - .success( function(data) { - $scope.$emit('HostSummaryReady', event, data); - }) - .error( function(data, status) { - ProcessErrors( $scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. GET returned: ' + status - }); - }); - } - } - } - }; - - $scope.viewJob = function(url) { - - // Pull the id out of the URL - var id = url.replace(/^\//, '').split('/')[3]; - - $state.go('inventorySyncStdout', {id: id}); - - }; - - $scope.addInventory = function () { - $state.go('inventoriesnew.add'); - }; - - $scope.editInventory = function (id) { - $state.go('inventoriesnew.edit', {inventory_id: id}); - }; - - $scope.manageInventory = function(id){ - $location.path($location.path() + '/' + id + '/manage'); - }; - - $scope.deleteInventory = function (id, name) { - - var action = function () { - var url = defaultUrl + id + '/'; - Wait('start'); - $('#prompt-modal').modal('hide'); - Rest.setUrl(url); - Rest.destroy() - .success(function () { - if (parseInt($state.params.inventory_id) === id) { - $state.go("^", null, {reload: true}); - } else { - $state.go('.', null, {reload: true}); - Wait('stop'); - } - }) - .error(function (data, status) { - ProcessErrors( $scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status - }); - }); - }; - - Prompt({ - hdr: 'Delete', - body: '
Are you sure you want to delete the inventory below?
' + $filter('sanitize')(name) + '
', - action: action, - actionText: 'DELETE' - }); - }; - - // Failed jobs link. Go to the jobs tabs, find all jobs for the inventory and sort by status - $scope.viewJobs = function (id) { - $location.url('/jobs/?inventory__int=' + id); - }; - - $scope.viewFailedJobs = function (id) { - $location.url('/jobs/?inventory__int=' + id + '&status=failed'); - }; -} - -export default ['$scope', '$rootScope', '$location', - '$compile', '$filter', 'Rest', 'InventoriesNewList', - 'Prompt', 'ProcessErrors', 'GetBasePath', 'Wait', 'Find', 'Empty', '$state', 'rbacUiControlService', 'Dataset', InventoriesList -]; diff --git a/awx/ui/client/src/inventoriesnew/list/main.js b/awx/ui/client/src/inventoriesnew/list/main.js deleted file mode 100644 index 09550f45ca..0000000000 --- a/awx/ui/client/src/inventoriesnew/list/main.js +++ /dev/null @@ -1,11 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import controller from './inventory-list.controller'; - -export default -angular.module('newInventoryList', []) - .controller('NewInventoryListController', controller); diff --git a/awx/ui/client/src/inventoriesnew/main.js b/awx/ui/client/src/inventoriesnew/main.js deleted file mode 100644 index 4e736caf9a..0000000000 --- a/awx/ui/client/src/inventoriesnew/main.js +++ /dev/null @@ -1,236 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import hostnew from './hosts/main'; -import inventoryAdd from './add/main'; -import inventoryEdit from './edit/main'; -import inventoryList from './list/main'; -import { templateUrl } from '../shared/template-url/template-url.factory'; -import { N_ } from '../i18n'; -// import inventoriesnewRoute from './inventories.route'; -import InventoriesNewList from './inventory.list'; -import InventoriesNewForm from './inventory.form'; -export default -angular.module('inventorynew', [ - hostnew.name, - inventoryAdd.name, - inventoryEdit.name, - inventoryList.name - ]) - .factory('InventoriesNewForm', InventoriesNewForm) - .factory('InventoriesNewList', InventoriesNewList) - .config(['$stateProvider', '$stateExtenderProvider', 'stateDefinitionsProvider', - function($stateProvider, $stateExtenderProvider, stateDefinitionsProvider) { - // When stateDefinition.lazyLoad() resolves, states matching name.** or /url** will be de-registered and replaced with resolved states - // This means inventoryManage states will not be registered correctly on page refresh, unless they're registered at the same time as the inventories state tree - let stateDefinitions = stateDefinitionsProvider.$get(); - - $stateProvider.state({ - name: 'inventoriesnew', - url: '/inventoriesnew', - lazyLoad: () => stateDefinitions.generateTree({ - parent: 'inventoriesnew', // top-most node in the generated tree (will replace this state definition) - modes: ['add', 'edit'], - list: 'InventoriesNewList', - form: 'InventoriesNewForm', - controllers: { - list: 'NewInventoryListController', - add: 'NewInventoryAddController', - edit: 'NewInventoryEditController' - }, - ncyBreadcrumb: { - label: N_('INVENTORIESNEW') - }, - views: { - '@': { - templateUrl: templateUrl('inventoriesnew/inventories') - }, - 'list@inventoriesnew': { - templateProvider: function(InventoriesNewList, generateList) { - let html = generateList.build({ - list: InventoriesNewList, - mode: 'edit' - }); - return html; - }, - controller: 'NewInventoryListController' - } - } - }) - }); - - $stateProvider.state({ - name: 'hostsnew', - url: '/hostsnew', - lazyLoad: () => stateDefinitions.generateTree({ - parent: 'hostsnew', // top-most node in the generated tree (will replace this state definition) - modes: ['add', 'edit'], - list: 'HostsNewList', - form: 'HostsNewForm', - controllers: { - list: 'NewHostListController', - add: 'NewHostAddController', - edit: 'NewHostEditController' - }, - ncyBreadcrumb: { - label: N_('HOSTSNEW') - }, - views: { - '@': { - templateUrl: templateUrl('inventoriesnew/inventories') - }, - 'list@hostsnew': { - templateProvider: function(HostsNewList, generateList) { - let html = generateList.build({ - list: HostsNewList, - mode: 'edit' - }); - return html; - }, - controller: 'NewHostListController' - } - } - }) - }); - - - - // function generateInvAddStateTree() { - // - // let addInventory = stateDefinitions.generateTree({ - // url: '/add', - // name: 'inventoriesnew.add', - // modes: ['add'], - // form: 'InventoriesNewForm', - // controllers: { - // add: 'NewInventoryAddController' - // } - // }); - // - // return Promise.all([ - // addInventory, - // ]).then((generated) => { - // return { - // states: _.reduce(generated, (result, definition) => { - // return result.concat(definition.states); - // }, []) - // }; - // }); - // } - // - // function generateInvEditStateTree() { - // - // let editInventory = stateDefinitions.generateTree({ - // url: '/:inventory_id', - // name: 'inventoriesnew.edit', - // modes: ['edit'], - // form: 'InventoriesNewForm', - // controllers: { - // edit: 'NewInventoryEditController' - // } - // }); - // - // return Promise.all([ - // editInventory, - // ]).then((generated) => { - // return { - // states: _.reduce(generated, (result, definition) => { - // return result.concat(definition.states); - // }, []) - // }; - // }); - // } - // - // let inventoriesnew = { - // name: 'inventoriesnew', - // route: '/inventoriesnew', - // ncyBreadcrumb: { - // label: N_("INVENTORIESNEW") - // }, - // params: { - // inventory_search: { - // value: {order_by: 'name', page_size: '20', role_level: 'admin_role'}, - // dynamic: true - // } - // }, - // resolve: { - // Dataset: ['InventoriesNewList', 'QuerySet', '$stateParams', 'GetBasePath', (list, qs, $stateParams, GetBasePath) => { - // let path = GetBasePath(list.basePath) || GetBasePath(list.name); - // return qs.search(path, $stateParams[`${list.iterator}_search`]); - // }], - // ListDefinition: ['InventoriesNewList', (list) => { - // return list; - // }] - // }, - // views: { - // '@': { - // templateUrl: templateUrl('inventoriesnew/inventories') - // }, - // 'list@inventoriesnew': { - // templateProvider: function(InventoriesNewList, generateList) { - // let html = generateList.build({ - // list: InventoriesNewList, - // mode: 'edit' - // }); - // return html; - // }, - // controller: 'NewInventoryListController' - // } - // } - // }; - // stateExtender.addState(inventoriesnew); - // - // let hostsnew = { - // name: 'inventoriesnew.hosts', - // route: '/hosts', - // ncyBreadcrumb: { - // label: N_("HOSTS") - // }, - // params: { - // host_search: { - // value: {order_by: 'name', page_size: '20'}, - // dynamic: true - // } - // }, - // resolve: { - // Dataset: ['HostsNewList', 'QuerySet', '$stateParams', 'GetBasePath', (list, qs, $stateParams, GetBasePath) => { - // let path = GetBasePath(list.basePath) || GetBasePath(list.name); - // return qs.search(path, $stateParams[`${list.iterator}_search`]); - // }], - // ListDefinition: ['HostsNewList', (list) => { - // return list; - // }] - // }, - // views: { - // 'list@inventoriesnew': { - // templateProvider: function(HostsNewList, generateList) { - // let html = generateList.build({ - // list: HostsNewList, - // mode: 'edit' - // }); - // return html; - // }, - // controller: 'NewHostListController' - // } - // } - // }; - // stateExtender.addState(hostsnew); - // - // let addInventoryTree = { - // name: 'inventoriesnew.add', - // url: '/add', - // lazyLoad: () => generateInvAddStateTree() - // }; - // $stateProvider.state(addInventoryTree); - // - // let editInventoryTree = { - // name: 'inventoriesnew.edit', - // url: '/:inventory_id', - // lazyLoad: () => generateInvEditStateTree() - // }; - // $stateProvider.state(editInventoryTree); - } - ]); diff --git a/awx/ui/client/src/main-menu/main-menu.partial.html b/awx/ui/client/src/main-menu/main-menu.partial.html index 4d28ea22e8..398488add7 100644 --- a/awx/ui/client/src/main-menu/main-menu.partial.html +++ b/awx/ui/client/src/main-menu/main-menu.partial.html @@ -27,14 +27,6 @@ INVENTORIES - - - INVENTORIES NEW - - INVENTORIES - - - INVENTORIES NEW - - - -
+