From 989cf4d1aeccae13467840fa01260eaaeff910b1 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Mon, 14 Mar 2016 16:13:01 -0400 Subject: [PATCH 01/11] Set up inventory module and split apart controllers/inventory.js into more manageable chunks. --- awx/ui/client/src/app.js | 6 +- awx/ui/client/src/controllers/Inventories.js | 1296 ----------------- .../src/inventory/inventory-add.controller.js | 98 ++ .../inventory/inventory-edit.controller.js | 332 +++++ .../inventory/inventory-list.controller.js | 371 +++++ .../inventory/inventory-manage.controller.js | 532 +++++++ awx/ui/client/src/inventory/main.js | 10 + 7 files changed, 1348 insertions(+), 1297 deletions(-) delete mode 100644 awx/ui/client/src/controllers/Inventories.js create mode 100644 awx/ui/client/src/inventory/inventory-add.controller.js create mode 100644 awx/ui/client/src/inventory/inventory-edit.controller.js create mode 100644 awx/ui/client/src/inventory/inventory-list.controller.js create mode 100644 awx/ui/client/src/inventory/inventory-manage.controller.js create mode 100644 awx/ui/client/src/inventory/main.js diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index e207eab59b..2a3367805c 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -26,6 +26,7 @@ import {CredentialsAdd, CredentialsEdit, CredentialsList} from './controllers/Cr import {JobsListController} from './controllers/Jobs'; import {PortalController} from './controllers/Portal'; import systemTracking from './system-tracking/main'; +import inventory from './inventory/main'; import inventoryScripts from './inventory-scripts/main'; import organizations from './organizations/main'; import permissions from './permissions/main'; @@ -54,7 +55,10 @@ import {ProjectsList, ProjectsAdd, ProjectsEdit} from './controllers/Projects'; import OrganizationsList from './organizations/list/organizations-list.controller'; import OrganizationsAdd from './organizations/add/organizations-add.controller'; import OrganizationsEdit from './organizations/edit/organizations-edit.controller'; -import {InventoriesList, InventoriesAdd, InventoriesEdit, InventoriesManage} from './controllers/Inventories'; +import InventoriesAdd from './inventory/inventory-add.controller'; +import InventoriesEdit from './inventory/inventory-edit.controller'; +import InventoriesList from './inventory/inventory-list.controller'; +import InventoriesManage from './inventory/inventory-manage.controller'; import {AdminsList} from './controllers/Admins'; import {UsersList, UsersAdd, UsersEdit} from './controllers/Users'; import {TeamsList, TeamsAdd, TeamsEdit} from './controllers/Teams'; diff --git a/awx/ui/client/src/controllers/Inventories.js b/awx/ui/client/src/controllers/Inventories.js deleted file mode 100644 index 62dfb5b03b..0000000000 --- a/awx/ui/client/src/controllers/Inventories.js +++ /dev/null @@ -1,1296 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Inventories - * @description This controller's for the Inventory page -*/ - -import '../job-templates/main'; - -export function InventoriesList($scope, $rootScope, $location, $log, - $stateParams, $compile, $filter, sanitizeFilter, Rest, Alert, InventoryList, - generateList, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, Wait, - EditInventoryProperties, Find, Empty, $state) { - - var list = InventoryList, - defaultUrl = GetBasePath('inventory'), - view = generateList, - paths = $location.path().replace(/^\//, '').split('/'), - mode = (paths[0] === 'inventories') ? 'edit' : 'select'; - - 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" }); - $compile(elem)($scope); - elem.on('shown.bs.popover', function() { - $('.popover').each(function() { - $compile($(this))($scope); //make nested directives work! - }); - $('.popover-content, .popover-title').click(function() { - elem.popover('hide'); - }); - }); - elem.popover('show'); - } - - view.inject(InventoryList, { mode: mode, scope: $scope }); - $rootScope.flashMessage = null; - - SearchInit({ - scope: $scope, - set: 'inventories', - list: list, - url: defaultUrl - }); - - PaginateInit({ - scope: $scope, - list: list, - url: defaultUrl - }); - - if ($stateParams.name) { - $scope[InventoryList.iterator + 'InputDisable'] = false; - $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.name; - $scope[InventoryList.iterator + 'SearchField'] = 'name'; - $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.name.label; - $scope[InventoryList.iterator + 'SearchSelectValue'] = null; - } - - if ($stateParams.has_active_failures) { - $scope[InventoryList.iterator + 'InputDisable'] = true; - $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_active_failures; - $scope[InventoryList.iterator + 'SearchField'] = 'has_active_failures'; - $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_active_failures.label; - $scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_active_failures === 'true') ? { - value: 1 - } : { - value: 0 - }; - } - - if ($stateParams.has_inventory_sources) { - $scope[InventoryList.iterator + 'InputDisable'] = true; - $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_inventory_sources; - $scope[InventoryList.iterator + 'SearchField'] = 'has_inventory_sources'; - $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_inventory_sources.label; - $scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_inventory_sources === 'true') ? { - value: 1 - } : { - value: 0 - }; - } - - if ($stateParams.inventory_sources_with_failures) { - // pass a value of true, however this field actually contains an integer value - $scope[InventoryList.iterator + 'InputDisable'] = true; - $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.inventory_sources_with_failures; - $scope[InventoryList.iterator + 'SearchField'] = 'inventory_sources_with_failures'; - $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.inventory_sources_with_failures.label; - $scope[InventoryList.iterator + 'SearchType'] = 'gtzero'; - } - - $scope.search(list.iterator); - - if ($scope.removePostRefresh) { - $scope.removePostRefresh(); - } - $scope.removePostRefresh = $scope.$on('PostRefresh', function () { - //If we got here by deleting an inventory, stop the spinner and cleanup events - Wait('stop'); - try { - $('#prompt-modal').modal('hide'); - } - catch(e) { - // ignore - } - $scope.inventories.forEach(function(inventory, idx) { - $scope.inventories[idx].launch_class = ""; - if (inventory.has_inventory_sources) { - if (inventory.inventory_sources_with_failures > 0) { - $scope.inventories[idx].syncStatus = 'error'; - $scope.inventories[idx].syncTip = inventory.inventory_sources_with_failures + ' groups with sync failures. Click for details'; - } - else { - $scope.inventories[idx].syncStatus = 'successful'; - $scope.inventories[idx].syncTip = 'No inventory sync failures. Click for details.'; - } - } - else { - $scope.inventories[idx].syncStatus = 'na'; - $scope.inventories[idx].syncTip = 'Not configured for inventory sync.'; - $scope.inventories[idx].launch_class = "btn-disabled"; - } - if (inventory.has_active_failures) { - $scope.inventories[idx].hostsStatus = 'error'; - $scope.inventories[idx].hostsTip = inventory.hosts_with_active_failures + ' hosts with failures. Click for details.'; - } - else if (inventory.total_hosts) { - $scope.inventories[idx].hostsStatus = 'successful'; - $scope.inventories[idx].hostsTip = 'No hosts with failures. Click for details.'; - } - else { - $scope.inventories[idx].hostsStatus = 'none'; - $scope.inventories[idx].hostsTip = 'Inventory contains 0 hosts.'; - } - }); - }); - - if ($scope.removeRefreshInventories) { - $scope.removeRefreshInventories(); - } - $scope.removeRefreshInventories = $scope.$on('RefreshInventories', function () { - // Reflect changes after inventory properties edit completes - $scope.search(list.iterator); - }); - - 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(/ /,'
') + "
" + 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(/ /,'
') + "
" + ellipsis(row.summary_fields.group.name) + "
NA" + ellipsis(row.summary_fields.group.name) + "
\n"; - title = "Sync Status"; - attachElem(event, html, title); - }); - - $scope.showGroupSummary = function(event, id) { - 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) { - 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.editInventoryProperties = function (inventory_id) { - EditInventoryProperties({ scope: $scope, inventory_id: inventory_id }); - }; - - $scope.addInventory = function () { - $state.go('inventories.add'); - }; - - $scope.editInventory = function (id) { - $state.go('inventories.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 () { - $scope.search(list.iterator); - }) - .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' - }); - }; - - $scope.lookupOrganization = function (organization_id) { - Rest.setUrl(GetBasePath('organizations') + organization_id + '/'); - Rest.get() - .success(function (data) { - return data.name; - }); - }; - - - // 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'); - }; -} - -InventoriesList.$inject = ['$scope', '$rootScope', '$location', '$log', '$stateParams', '$compile', '$filter', 'sanitizeFilter', 'Rest', 'Alert', 'InventoryList', 'generateList', - 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'GetBasePath', 'Wait', 'EditInventoryProperties', 'Find', 'Empty', '$state' -]; - - -export function InventoriesAdd($scope, $rootScope, $compile, $location, $log, - $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, - ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, - PaginateInit, LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, - $state) { - - ClearScope(); - - // Inject dynamic view - var defaultUrl = GetBasePath('inventory'), - form = InventoryForm(), - generator = GenerateForm; - - form.well = true; - form.formLabelSize = null; - form.formFieldSize = null; - - generator.inject(form, { mode: 'add', related: false, scope: $scope }); - - generator.reset(); - - $scope.parseType = 'yaml'; - ParseTypeChange({ - scope: $scope, - variable: 'variables', - parse_variable: 'parseType', - field_id: 'inventory_variables' - }); - - LookUpInit({ - scope: $scope, - form: form, - current_item: ($stateParams.organization_id) ? $stateParams.organization_id : null, - list: OrganizationList, - field: 'organization', - input_type: 'radio' - }); - - // Save - $scope.formSave = function () { - generator.clearApiErrors(); - 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('/inventories/' + inventory_id + '/manage'); - }) - .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.transitionTo('inventories'); - }; -} - -InventoriesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', - '$log', '$stateParams', 'InventoryForm', 'GenerateForm', 'Rest', 'Alert', - 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'generateList', - 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', - 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', '$state' -]; - -export function InventoriesEdit($scope, $rootScope, $compile, $location, - $log, $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, - ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, - PaginateInit, LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, - ParseVariableString, RelatedSearchInit, RelatedPaginateInit, - Prompt, PlaybookRun, CreateDialog, deleteJobTemplate, $state) { - - ClearScope(); - - // Inject dynamic view - var defaultUrl = GetBasePath('inventory'), - form = InventoryForm(), - generator = GenerateForm, - inventory_id = $stateParams.inventory_id, - master = {}, - fld, json_data, data, - relatedSets = {}; - - form.well = true; - form.formLabelSize = null; - form.formFieldSize = null; - $scope.inventory_id = inventory_id; - generator.inject(form, { mode: 'edit', related: true, scope: $scope }); - - generator.reset(); - - - // After the project is loaded, retrieve each related set - if ($scope.inventoryLoadedRemove) { - $scope.inventoryLoadedRemove(); - } - $scope.projectLoadedRemove = $scope.$on('inventoryLoaded', function () { - var set; - for (set in relatedSets) { - $scope.search(relatedSets[set].iterator); - } - }); - - 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]; - } - } - relatedSets = form.relatedSets(data.related); - - // Initialize related search functions. Doing it here to make sure relatedSets object is populated. - RelatedSearchInit({ - scope: $scope, - form: form, - relatedSets: relatedSets - }); - RelatedPaginateInit({ - scope: $scope, - relatedSets: relatedSets - }); - - Wait('stop'); - $scope.parseType = 'yaml'; - ParseTypeChange({ - scope: $scope, - variable: 'variables', - parse_variable: 'parseType', - field_id: 'inventory_variables' - }); - LookUpInit({ - scope: $scope, - form: form, - current_item: $scope.organization, - list: OrganizationList, - field: 'organization', - input_type: 'radio' - }); - $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'); - $location.path('/inventories/'); - }) - .error(function (data, status) { - ProcessErrors($scope, data, status, form, { hdr: 'Error!', - msg: 'Failed to update inventory. PUT returned status: ' + status }); - }); - }; - - $scope.manageInventory = function(){ - $location.path($location.path() + '/manage'); - }; - - $scope.formCancel = function () { - $state.transitionTo('inventories'); - }; - - $scope.addScanJob = function(){ - $location.path($location.path()+'/job_templates/add'); - }; - - $scope.launchScanJob = function(){ - PlaybookRun({ scope: $scope, id: this.scan_job_template.id }); - }; - - $scope.scheduleScanJob = function(){ - $location.path('/job_templates/'+this.scan_job_template.id+'/schedules'); - }; - - $scope.editScanJob = function(){ - $location.path($location.path()+'/job_templates/'+this.scan_job_template.id); - }; - - $scope.copyScanJobTemplate = function(){ - var id = this.scan_job_template.id, - name = this.scan_job_template.name, - element, - buttons = [{ - "label": "Cancel", - "onClick": function() { - $(this).dialog('close'); - }, - "icon": "fa-times", - "class": "btn btn-default", - "id": "copy-close-button" - },{ - "label": "Copy", - "onClick": function() { - copyAction(); - }, - "icon": "fa-copy", - "class": "btn btn-primary", - "id": "job-copy-button" - }], - copyAction = function () { - // retrieve the copy of the job template object from the api, then overwrite the name and throw away the id - Wait('start'); - var url = GetBasePath('job_templates')+id; - Rest.setUrl(url); - Rest.get() - .success(function (data) { - data.name = $scope.new_copy_name; - delete data.id; - $scope.$emit('GoToCopy', data); - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; - - - CreateDialog({ - id: 'copy-job-modal' , - title: "Copy", - scope: $scope, - buttons: buttons, - width: 500, - height: 300, - minWidth: 200, - callback: 'CopyDialogReady' - }); - - $('#job_name').text(name); - $('#copy-job-modal').show(); - - - if ($scope.removeCopyDialogReady) { - $scope.removeCopyDialogReady(); - } - $scope.removeCopyDialogReady = $scope.$on('CopyDialogReady', function() { - //clear any old remaining text - $scope.new_copy_name = "" ; - $scope.copy_form.$setPristine(); - $('#copy-job-modal').dialog('open'); - $('#job-copy-button').attr('ng-disabled', "!copy_form.$valid"); - element = angular.element(document.getElementById('job-copy-button')); - $compile(element)($scope); - - }); - - if ($scope.removeGoToCopy) { - $scope.removeGoToCopy(); - } - $scope.removeGoToCopy = $scope.$on('GoToCopy', function(e, data) { - var url = GetBasePath('job_templates'), - old_survey_url = (data.related.survey_spec) ? data.related.survey_spec : "" ; - Rest.setUrl(url); - Rest.post(data) - .success(function (data) { - if(data.survey_enabled===true){ - $scope.$emit("CopySurvey", data, old_survey_url); - } - else { - $('#copy-job-modal').dialog('close'); - Wait('stop'); - $location.path($location.path() + '/job_templates/' + data.id); - } - - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }); - - if ($scope.removeCopySurvey) { - $scope.removeCopySurvey(); - } - $scope.removeCopySurvey = $scope.$on('CopySurvey', function(e, new_data, old_url) { - // var url = data.related.survey_spec; - Rest.setUrl(old_url); - Rest.get() - .success(function (survey_data) { - - Rest.setUrl(new_data.related.survey_spec); - Rest.post(survey_data) - .success(function () { - $('#copy-job-modal').dialog('close'); - Wait('stop'); - $location.path($location.path() + '/job_templates/' + new_data.id); - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + new_data.related.survey_spec + ' failed. DELETE returned status: ' + status }); - }); - - - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + old_url + ' failed. DELETE returned status: ' + status }); - }); - - }); - - }; - - $scope.deleteScanJob = function () { - var id = this.scan_job_template.id , - action = function () { - $('#prompt-modal').modal('hide'); - Wait('start'); - deleteJobTemplate(id) - .success(function () { - $('#prompt-modal').modal('hide'); - $scope.search(form.related.scan_job_templates.iterator); - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'DELETE returned status: ' + status }); - }); - }; - - Prompt({ - hdr: 'Delete', - body: '
Are you sure you want to delete the job template below?
' + this.scan_job_template.name + '
', - action: action, - actionText: 'DELETE' - }); - - }; - -} - -InventoriesEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', - '$log', '$stateParams', 'InventoryForm', 'GenerateForm', 'Rest', 'Alert', - 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'generateList', - 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', - 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', - 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', - 'PlaybookRun', 'CreateDialog', 'deleteJobTemplate', '$state' -]; - - - -export function InventoriesManage ($log, $scope, $rootScope, $location, - $state, $compile, generateList, ClearScope, Empty, Wait, Rest, Alert, - GetBasePath, ProcessErrors, InventoryGroups, - InjectHosts, Find, HostsReload, SearchInit, PaginateInit, GetSyncStatusMsg, - GetHostsStatusMsg, GroupsEdit, InventoryUpdate, GroupsCancelUpdate, - ViewUpdateStatus, GroupsDelete, Store, HostsEdit, HostsDelete, - EditInventoryProperties, ToggleHostEnabled, ShowJobSummary, - InventoryGroupsHelp, HelpDialog, - GroupsCopy, HostsCopy, $stateParams) { - - var PreviousSearchParams, - url, - hostScope = $scope.$new(); - - ClearScope(); - - // TODO: only display adhoc button if the user has permission to use it. - // TODO: figure out how to get the action-list partial to update so that - // the tooltip can be changed based off things being selected or not. - $scope.adhocButtonTipContents = "Launch adhoc command for the inventory"; - - // watcher for the group list checkbox changes - $scope.$on('multiSelectList.selectionChanged', function(e, selection) { - if (selection.length > 0) { - $scope.groupsSelected = true; - // $scope.adhocButtonTipContents = "Launch adhoc command for the " - // + "selected groups and hosts."; - } else { - $scope.groupsSelected = false; - // $scope.adhocButtonTipContents = "Launch adhoc command for the " - // + "inventory."; - } - $scope.groupsSelectedItems = selection.selectedItems; - }); - - // watcher for the host list checkbox changes - hostScope.$on('multiSelectList.selectionChanged', function(e, selection) { - // you need this so that the event doesn't bubble to the watcher above - // for the host list - e.stopPropagation(); - if (selection.length === 0) { - $scope.hostsSelected = false; - } else if (selection.length === 1) { - $scope.systemTrackingTooltip = "Compare host over time"; - $scope.hostsSelected = true; - $scope.systemTrackingDisabled = false; - } else if (selection.length === 2) { - $scope.systemTrackingTooltip = "Compare hosts against each other"; - $scope.hostsSelected = true; - $scope.systemTrackingDisabled = false; - } else { - $scope.hostsSelected = true; - $scope.systemTrackingDisabled = true; - } - $scope.hostsSelectedItems = selection.selectedItems; - }); - - $scope.systemTracking = function() { - var hostIds = _.map($scope.hostsSelectedItems, function(x){ - return x.id; - }); - $state.transitionTo('systemTracking', - { inventory: $scope.inventory, - inventoryId: $scope.inventory.id, - hosts: $scope.hostsSelectedItems, - hostIds: hostIds - }); - }; - - // populates host patterns based on selected hosts/groups - $scope.populateAdhocForm = function() { - var host_patterns = "all"; - if ($scope.hostsSelected || $scope.groupsSelected) { - var allSelectedItems = []; - if ($scope.groupsSelectedItems) { - allSelectedItems = allSelectedItems.concat($scope.groupsSelectedItems); - } - if ($scope.hostsSelectedItems) { - allSelectedItems = allSelectedItems.concat($scope.hostsSelectedItems); - } - if (allSelectedItems) { - host_patterns = _.pluck(allSelectedItems, "name").join(":"); - } - } - $rootScope.hostPatterns = host_patterns; - $state.go('inventoryManage.adhoc'); - }; - - $scope.refreshHostsOnGroupRefresh = false; - $scope.selected_group_id = null; - - Wait('start'); - - - if ($scope.removeHostReloadComplete) { - $scope.removeHostReloadComplete(); - } - $scope.removeHostReloadComplete = $scope.$on('HostReloadComplete', function() { - if ($scope.initial_height) { - var host_height = $('#hosts-container .well').height(), - group_height = $('#group-list-container .well').height(), - new_height; - - if (host_height > group_height) { - new_height = host_height - (host_height - group_height); - } - else if (host_height < group_height) { - new_height = host_height + (group_height - host_height); - } - if (new_height) { - $('#hosts-container .well').height(new_height); - } - $scope.initial_height = null; - } - }); - - if ($scope.removeRowCountReady) { - $scope.removeRowCountReady(); - } - $scope.removeRowCountReady = $scope.$on('RowCountReady', function(e, rows) { - // Add hosts view - $scope.show_failures = false; - InjectHosts({ - group_scope: $scope, - host_scope: hostScope, - inventory_id: $scope.inventory.id, - tree_id: null, - group_id: null, - pageSize: rows - }); - - SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: $scope.inventory.related.root_groups }); - PaginateInit({ scope: $scope, list: InventoryGroups , url: $scope.inventory.related.root_groups, pageSize: rows }); - $scope.search(InventoryGroups.iterator, null, true); - }); - - if ($scope.removeInventoryLoaded) { - $scope.removeInventoryLoaded(); - } - $scope.removeInventoryLoaded = $scope.$on('InventoryLoaded', function() { - var rows; - - // Add groups view - generateList.inject(InventoryGroups, { - mode: 'edit', - id: 'group-list-container', - searchSize: 'col-lg-6 col-md-6 col-sm-6 col-xs-12', - scope: $scope - }); - - rows = 20; - hostScope.host_page_size = rows; - $scope.group_page_size = rows; - - $scope.show_failures = false; - InjectHosts({ - group_scope: $scope, - host_scope: hostScope, - inventory_id: $scope.inventory.id, - tree_id: null, - group_id: null, - pageSize: rows - }); - - // Load data - SearchInit({ - scope: $scope, - set: 'groups', - list: InventoryGroups, - url: $scope.inventory.related.root_groups - }); - - PaginateInit({ - scope: $scope, - list: InventoryGroups , - url: $scope.inventory.related.root_groups, - pageSize: rows - }); - - $scope.search(InventoryGroups.iterator, null, true); - - $scope.$emit('WatchUpdateStatus'); // init socket io conneciton and start watching for status updates - }); - - if ($scope.removePostRefresh) { - $scope.removePostRefresh(); - } - $scope.removePostRefresh = $scope.$on('PostRefresh', function(e, set) { - if (set === 'groups') { - $scope.groups.forEach( function(group, idx) { - var stat, hosts_status; - stat = GetSyncStatusMsg({ - status: group.summary_fields.inventory_source.status, - has_inventory_sources: group.has_inventory_sources, - source: ( (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null ) - }); // from helpers/Groups.js - $scope.groups[idx].status_class = stat['class']; - $scope.groups[idx].status_tooltip = stat.tooltip; - $scope.groups[idx].launch_tooltip = stat.launch_tip; - $scope.groups[idx].launch_class = stat.launch_class; - hosts_status = GetHostsStatusMsg({ - active_failures: group.hosts_with_active_failures, - total_hosts: group.total_hosts, - inventory_id: $scope.inventory.id, - group_id: group.id - }); // from helpers/Groups.js - $scope.groups[idx].hosts_status_tip = hosts_status.tooltip; - $scope.groups[idx].show_failures = hosts_status.failures; - $scope.groups[idx].hosts_status_class = hosts_status['class']; - - $scope.groups[idx].source = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null; - $scope.groups[idx].status = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.status : null; - - }); - if ($scope.refreshHostsOnGroupRefresh) { - $scope.refreshHostsOnGroupRefresh = false; - HostsReload({ - scope: hostScope, - group_id: $scope.selected_group_id, - inventory_id: $scope.inventory.id, - pageSize: hostScope.host_page_size - }); - } - else { - Wait('stop'); - } - } - }); - - // Load Inventory - url = GetBasePath('inventory') + $stateParams.inventory_id + '/'; - Rest.setUrl(url); - Rest.get() - .success(function (data) { - $scope.inventory = data; - $scope.$emit('InventoryLoaded'); - }) - .error(function (data, status) { - ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve inventory: ' + $stateParams.inventory_id + - ' GET returned status: ' + status }); - }); - - // start watching for real-time updates - if ($rootScope.removeWatchUpdateStatus) { - $rootScope.removeWatchUpdateStatus(); - } - $rootScope.removeWatchUpdateStatus = $rootScope.$on('JobStatusChange-inventory', function(e, data) { - var stat, group; - if (data.group_id) { - group = Find({ list: $scope.groups, key: 'id', val: data.group_id }); - if (data.status === "failed" || data.status === "successful") { - if (data.group_id === $scope.selected_group_id || group) { - // job completed, fefresh all groups - $log.debug('Update completed. Refreshing the tree.'); - $scope.refreshGroups(); - } - } - else if (group) { - // incremental update, just update - $log.debug('Status of group: ' + data.group_id + ' changed to: ' + data.status); - stat = GetSyncStatusMsg({ - status: data.status, - has_inventory_sources: group.has_inventory_sources, - source: group.source - }); - $log.debug('changing tooltip to: ' + stat.tooltip); - group.status = data.status; - group.status_class = stat['class']; - group.status_tooltip = stat.tooltip; - group.launch_tooltip = stat.launch_tip; - group.launch_class = stat.launch_class; - } - } - }); - - // Load group on selection - function loadGroups(url) { - SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: url }); - PaginateInit({ scope: $scope, list: InventoryGroups , url: url, pageSize: $scope.group_page_size }); - $scope.search(InventoryGroups.iterator, null, true, false, true); - } - - $scope.refreshHosts = function() { - HostsReload({ - scope: hostScope, - group_id: $scope.selected_group_id, - inventory_id: $scope.inventory.id, - pageSize: hostScope.host_page_size - }); - }; - - $scope.refreshGroups = function() { - $scope.refreshHostsOnGroupRefresh = true; - $scope.search(InventoryGroups.iterator, null, true, false, true); - }; - - $scope.restoreSearch = function() { - // Restore search params and related stuff, plus refresh - // groups and hosts lists - SearchInit({ - scope: $scope, - set: PreviousSearchParams.set, - list: PreviousSearchParams.list, - url: PreviousSearchParams.defaultUrl, - iterator: PreviousSearchParams.iterator, - sort_order: PreviousSearchParams.sort_order, - setWidgets: false - }); - $scope.refreshHostsOnGroupRefresh = true; - $scope.search(InventoryGroups.iterator, null, true, false, true); - }; - - $scope.groupSelect = function(id) { - var groups = [], group = Find({ list: $scope.groups, key: 'id', val: id }); - if($state.params.groups){ - groups.push($state.params.groups); - } - groups.push(group.id); - groups = groups.join(); - $state.transitionTo('inventoryManage', {inventory_id: $state.params.inventory_id, groups: groups}, { notify: false }); - loadGroups(group.related.children, group.id); - }; - - $scope.createGroup = function () { - PreviousSearchParams = Store('group_current_search_params'); - GroupsEdit({ - scope: $scope, - inventory_id: $scope.inventory.id, - group_id: $scope.selected_group_id, - mode: 'add' - }); - }; - - $scope.editGroup = function (id) { - PreviousSearchParams = Store('group_current_search_params'); - GroupsEdit({ - scope: $scope, - inventory_id: $scope.inventory.id, - group_id: id, - mode: 'edit' - }); - }; - - // Launch inventory sync - $scope.updateGroup = function (id) { - var group = Find({ list: $scope.groups, key: 'id', val: id }); - if (group) { - if (Empty(group.source)) { - // if no source, do nothing. - } else if (group.status === 'updating') { - Alert('Update in Progress', 'The inventory update process is currently running for group ' + - group.name + ' Click the button to monitor the status.', 'alert-info', null, null, null, null, true); - } else { - Wait('start'); - Rest.setUrl(group.related.inventory_source); - Rest.get() - .success(function (data) { - InventoryUpdate({ - scope: $scope, - url: data.related.update, - group_name: data.summary_fields.group.name, - group_source: data.source, - group_id: group.id, - }); - }) - .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 }); - }); - } - } - }; - - $scope.cancelUpdate = function (id) { - GroupsCancelUpdate({ scope: $scope, id: id }); - }; - - $scope.viewUpdateStatus = function (id) { - ViewUpdateStatus({ - scope: $scope, - group_id: id - }); - }; - - $scope.copyGroup = function(id) { - PreviousSearchParams = Store('group_current_search_params'); - GroupsCopy({ - scope: $scope, - group_id: id - }); - }; - - $scope.deleteGroup = function (id) { - GroupsDelete({ - scope: $scope, - group_id: id, - inventory_id: $scope.inventory.id - }); - }; - - $scope.editInventoryProperties = function () { - // EditInventoryProperties({ scope: $scope, inventory_id: $scope.inventory.id }); - $location.path('/inventories/' + $scope.inventory.id + '/'); - }; - - hostScope.createHost = function () { - HostsEdit({ - host_scope: hostScope, - group_scope: $scope, - mode: 'add', - host_id: null, - selected_group_id: $scope.selected_group_id, - inventory_id: $scope.inventory.id - }); - }; - - hostScope.editHost = function (host_id) { - HostsEdit({ - host_scope: hostScope, - group_scope: $scope, - mode: 'edit', - host_id: host_id, - inventory_id: $scope.inventory.id - }); - }; - - hostScope.deleteHost = function (host_id, host_name) { - HostsDelete({ - parent_scope: $scope, - host_scope: hostScope, - host_id: host_id, - host_name: host_name - }); - }; - - hostScope.copyHost = function(id) { - PreviousSearchParams = Store('group_current_search_params'); - HostsCopy({ - group_scope: $scope, - host_scope: hostScope, - host_id: id - }); - }; - - /*hostScope.restoreSearch = function() { - SearchInit({ - scope: hostScope, - set: PreviousSearchParams.set, - list: PreviousSearchParams.list, - url: PreviousSearchParams.defaultUrl, - iterator: PreviousSearchParams.iterator, - sort_order: PreviousSearchParams.sort_order, - setWidgets: false - }); - hostScope.search('host'); - };*/ - - hostScope.toggleHostEnabled = function (host_id, external_source) { - ToggleHostEnabled({ - parent_scope: $scope, - host_scope: hostScope, - host_id: host_id, - external_source: external_source - }); - }; - - hostScope.showJobSummary = function (job_id) { - ShowJobSummary({ - job_id: job_id - }); - }; - - $scope.showGroupHelp = function (params) { - var opts = { - defn: InventoryGroupsHelp - }; - if (params) { - opts.autoShow = params.autoShow || false; - } - HelpDialog(opts); - } -; - $scope.showHosts = function (group_id, show_failures) { - // Clicked on group - if (group_id !== null) { - Wait('start'); - hostScope.show_failures = show_failures; - $scope.groupSelect(group_id); - hostScope.hosts = []; - $scope.show_failures = show_failures; // turn on failed hosts - // filter in hosts view - } else { - Wait('stop'); - } - }; - - if ($scope.removeGroupDeleteCompleted) { - $scope.removeGroupDeleteCompleted(); - } - $scope.removeGroupDeleteCompleted = $scope.$on('GroupDeleteCompleted', - function() { - $scope.refreshGroups(); - } - ); -} - - -InventoriesManage.$inject = ['$log', '$scope', '$rootScope', '$location', - '$state', '$compile', 'generateList', 'ClearScope', 'Empty', 'Wait', - 'Rest', 'Alert', 'GetBasePath', 'ProcessErrors', - 'InventoryGroups', 'InjectHosts', 'Find', 'HostsReload', - 'SearchInit', 'PaginateInit', 'GetSyncStatusMsg', 'GetHostsStatusMsg', - 'GroupsEdit', 'InventoryUpdate', 'GroupsCancelUpdate', 'ViewUpdateStatus', - 'GroupsDelete', 'Store', 'HostsEdit', 'HostsDelete', - 'EditInventoryProperties', 'ToggleHostEnabled', 'ShowJobSummary', - 'InventoryGroupsHelp', 'HelpDialog', 'GroupsCopy', - 'HostsCopy', '$stateParams' -]; diff --git a/awx/ui/client/src/inventory/inventory-add.controller.js b/awx/ui/client/src/inventory/inventory-add.controller.js new file mode 100644 index 0000000000..a0903f4fab --- /dev/null +++ b/awx/ui/client/src/inventory/inventory-add.controller.js @@ -0,0 +1,98 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/** + * @ngdoc function + * @name controllers.function:Inventories + * @description This controller's for the Inventory page + */ + +import '../job-templates/main'; + +function InventoriesAdd($scope, $rootScope, $compile, $location, $log, + $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, + ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, + PaginateInit, LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, + $state) { + + ClearScope(); + + // Inject dynamic view + var defaultUrl = GetBasePath('inventory'), + form = InventoryForm(), + generator = GenerateForm; + + form.well = true; + form.formLabelSize = null; + form.formFieldSize = null; + + generator.inject(form, { mode: 'add', related: false, scope: $scope }); + + generator.reset(); + + $scope.parseType = 'yaml'; + ParseTypeChange({ + scope: $scope, + variable: 'variables', + parse_variable: 'parseType', + field_id: 'inventory_variables' + }); + + LookUpInit({ + scope: $scope, + form: form, + current_item: ($stateParams.organization_id) ? $stateParams.organization_id : null, + list: OrganizationList, + field: 'organization', + input_type: 'radio' + }); + + // Save + $scope.formSave = function () { + generator.clearApiErrors(); + 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('/inventories/' + inventory_id + '/manage'); + }) + .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.transitionTo('inventories'); + }; +} + +export default['$scope', '$rootScope', '$compile', '$location', + '$log', '$stateParams', 'InventoryForm', 'GenerateForm', 'Rest', 'Alert', + 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'generateList', + 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', + 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', '$state', InventoriesAdd] diff --git a/awx/ui/client/src/inventory/inventory-edit.controller.js b/awx/ui/client/src/inventory/inventory-edit.controller.js new file mode 100644 index 0000000000..dd45a566ac --- /dev/null +++ b/awx/ui/client/src/inventory/inventory-edit.controller.js @@ -0,0 +1,332 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/** + * @ngdoc function + * @name controllers.function:Inventories + * @description This controller's for the Inventory page + */ + +import '../job-templates/main'; + +function InventoriesEdit($scope, $rootScope, $compile, $location, + $log, $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, + ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, + PaginateInit, LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, + ParseVariableString, RelatedSearchInit, RelatedPaginateInit, + Prompt, PlaybookRun, CreateDialog, deleteJobTemplate, $state) { + + ClearScope(); + + // Inject dynamic view + var defaultUrl = GetBasePath('inventory'), + form = InventoryForm(), + generator = GenerateForm, + inventory_id = $stateParams.inventory_id, + master = {}, + fld, json_data, data, + relatedSets = {}; + + form.well = true; + form.formLabelSize = null; + form.formFieldSize = null; + $scope.inventory_id = inventory_id; + generator.inject(form, { mode: 'edit', related: true, scope: $scope }); + + generator.reset(); + + + // After the project is loaded, retrieve each related set + if ($scope.inventoryLoadedRemove) { + $scope.inventoryLoadedRemove(); + } + $scope.projectLoadedRemove = $scope.$on('inventoryLoaded', function () { + var set; + for (set in relatedSets) { + $scope.search(relatedSets[set].iterator); + } + }); + + 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]; + } + } + relatedSets = form.relatedSets(data.related); + + // Initialize related search functions. Doing it here to make sure relatedSets object is populated. + RelatedSearchInit({ + scope: $scope, + form: form, + relatedSets: relatedSets + }); + RelatedPaginateInit({ + scope: $scope, + relatedSets: relatedSets + }); + + Wait('stop'); + $scope.parseType = 'yaml'; + ParseTypeChange({ + scope: $scope, + variable: 'variables', + parse_variable: 'parseType', + field_id: 'inventory_variables' + }); + LookUpInit({ + scope: $scope, + form: form, + current_item: $scope.organization, + list: OrganizationList, + field: 'organization', + input_type: 'radio' + }); + $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'); + $location.path('/inventories/'); + }) + .error(function (data, status) { + ProcessErrors($scope, data, status, form, { hdr: 'Error!', + msg: 'Failed to update inventory. PUT returned status: ' + status }); + }); + }; + + $scope.manageInventory = function(){ + $location.path($location.path() + '/manage'); + }; + + $scope.formCancel = function () { + $state.transitionTo('inventories'); + }; + + $scope.addScanJob = function(){ + $location.path($location.path()+'/job_templates/add'); + }; + + $scope.launchScanJob = function(){ + PlaybookRun({ scope: $scope, id: this.scan_job_template.id }); + }; + + $scope.scheduleScanJob = function(){ + $location.path('/job_templates/'+this.scan_job_template.id+'/schedules'); + }; + + $scope.editScanJob = function(){ + $location.path($location.path()+'/job_templates/'+this.scan_job_template.id); + }; + + $scope.copyScanJobTemplate = function(){ + var id = this.scan_job_template.id, + name = this.scan_job_template.name, + element, + buttons = [{ + "label": "Cancel", + "onClick": function() { + $(this).dialog('close'); + }, + "icon": "fa-times", + "class": "btn btn-default", + "id": "copy-close-button" + },{ + "label": "Copy", + "onClick": function() { + copyAction(); + }, + "icon": "fa-copy", + "class": "btn btn-primary", + "id": "job-copy-button" + }], + copyAction = function () { + // retrieve the copy of the job template object from the api, then overwrite the name and throw away the id + Wait('start'); + var url = GetBasePath('job_templates')+id; + Rest.setUrl(url); + Rest.get() + .success(function (data) { + data.name = $scope.new_copy_name; + delete data.id; + $scope.$emit('GoToCopy', data); + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + }; + + + CreateDialog({ + id: 'copy-job-modal' , + title: "Copy", + scope: $scope, + buttons: buttons, + width: 500, + height: 300, + minWidth: 200, + callback: 'CopyDialogReady' + }); + + $('#job_name').text(name); + $('#copy-job-modal').show(); + + + if ($scope.removeCopyDialogReady) { + $scope.removeCopyDialogReady(); + } + $scope.removeCopyDialogReady = $scope.$on('CopyDialogReady', function() { + //clear any old remaining text + $scope.new_copy_name = "" ; + $scope.copy_form.$setPristine(); + $('#copy-job-modal').dialog('open'); + $('#job-copy-button').attr('ng-disabled', "!copy_form.$valid"); + element = angular.element(document.getElementById('job-copy-button')); + $compile(element)($scope); + + }); + + if ($scope.removeGoToCopy) { + $scope.removeGoToCopy(); + } + $scope.removeGoToCopy = $scope.$on('GoToCopy', function(e, data) { + var url = GetBasePath('job_templates'), + old_survey_url = (data.related.survey_spec) ? data.related.survey_spec : "" ; + Rest.setUrl(url); + Rest.post(data) + .success(function (data) { + if(data.survey_enabled===true){ + $scope.$emit("CopySurvey", data, old_survey_url); + } + else { + $('#copy-job-modal').dialog('close'); + Wait('stop'); + $location.path($location.path() + '/job_templates/' + data.id); + } + + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + }); + + if ($scope.removeCopySurvey) { + $scope.removeCopySurvey(); + } + $scope.removeCopySurvey = $scope.$on('CopySurvey', function(e, new_data, old_url) { + // var url = data.related.survey_spec; + Rest.setUrl(old_url); + Rest.get() + .success(function (survey_data) { + + Rest.setUrl(new_data.related.survey_spec); + Rest.post(survey_data) + .success(function () { + $('#copy-job-modal').dialog('close'); + Wait('stop'); + $location.path($location.path() + '/job_templates/' + new_data.id); + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + new_data.related.survey_spec + ' failed. DELETE returned status: ' + status }); + }); + + + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + old_url + ' failed. DELETE returned status: ' + status }); + }); + + }); + + }; + + $scope.deleteScanJob = function () { + var id = this.scan_job_template.id , + action = function () { + $('#prompt-modal').modal('hide'); + Wait('start'); + deleteJobTemplate(id) + .success(function () { + $('#prompt-modal').modal('hide'); + $scope.search(form.related.scan_job_templates.iterator); + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'DELETE returned status: ' + status }); + }); + }; + + Prompt({ + hdr: 'Delete', + body: '
Are you sure you want to delete the job template below?
' + this.scan_job_template.name + '
', + action: action, + actionText: 'DELETE' + }); + + }; + +} + +export default ['$scope', '$rootScope', '$compile', '$location', + '$log', '$stateParams', 'InventoryForm', 'GenerateForm', 'Rest', 'Alert', + 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'generateList', + 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', + 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', + 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', + 'PlaybookRun', 'CreateDialog', 'deleteJobTemplate', '$state', + InventoriesEdit, +]; diff --git a/awx/ui/client/src/inventory/inventory-list.controller.js b/awx/ui/client/src/inventory/inventory-list.controller.js new file mode 100644 index 0000000000..98f02df918 --- /dev/null +++ b/awx/ui/client/src/inventory/inventory-list.controller.js @@ -0,0 +1,371 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/** + * @ngdoc function + * @name controllers.function:Inventories + * @description This controller's for the Inventory page + */ + +import '../job-templates/main'; + +function InventoriesList($scope, $rootScope, $location, $log, + $stateParams, $compile, $filter, sanitizeFilter, Rest, Alert, InventoryList, + generateList, Prompt, SearchInit, PaginateInit, ReturnToCaller, + ClearScope, ProcessErrors, GetBasePath, Wait, + EditInventoryProperties, Find, Empty, $state) { + + var list = InventoryList, + defaultUrl = GetBasePath('inventory'), + view = generateList, + paths = $location.path().replace(/^\//, '').split('/'), + mode = (paths[0] === 'inventories') ? 'edit' : 'select'; + + 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" }); + $compile(elem)($scope); + elem.on('shown.bs.popover', function() { + $('.popover').each(function() { + $compile($(this))($scope); //make nested directives work! + }); + $('.popover-content, .popover-title').click(function() { + elem.popover('hide'); + }); + }); + elem.popover('show'); + } + + view.inject(InventoryList, { mode: mode, scope: $scope }); + $rootScope.flashMessage = null; + + SearchInit({ + scope: $scope, + set: 'inventories', + list: list, + url: defaultUrl + }); + + PaginateInit({ + scope: $scope, + list: list, + url: defaultUrl + }); + + if ($stateParams.name) { + $scope[InventoryList.iterator + 'InputDisable'] = false; + $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.name; + $scope[InventoryList.iterator + 'SearchField'] = 'name'; + $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.name.label; + $scope[InventoryList.iterator + 'SearchSelectValue'] = null; + } + + if ($stateParams.has_active_failures) { + $scope[InventoryList.iterator + 'InputDisable'] = true; + $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_active_failures; + $scope[InventoryList.iterator + 'SearchField'] = 'has_active_failures'; + $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_active_failures.label; + $scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_active_failures === 'true') ? { + value: 1 + } : { + value: 0 + }; + } + + if ($stateParams.has_inventory_sources) { + $scope[InventoryList.iterator + 'InputDisable'] = true; + $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_inventory_sources; + $scope[InventoryList.iterator + 'SearchField'] = 'has_inventory_sources'; + $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_inventory_sources.label; + $scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_inventory_sources === 'true') ? { + value: 1 + } : { + value: 0 + }; + } + + if ($stateParams.inventory_sources_with_failures) { + // pass a value of true, however this field actually contains an integer value + $scope[InventoryList.iterator + 'InputDisable'] = true; + $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.inventory_sources_with_failures; + $scope[InventoryList.iterator + 'SearchField'] = 'inventory_sources_with_failures'; + $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.inventory_sources_with_failures.label; + $scope[InventoryList.iterator + 'SearchType'] = 'gtzero'; + } + + $scope.search(list.iterator); + + if ($scope.removePostRefresh) { + $scope.removePostRefresh(); + } + $scope.removePostRefresh = $scope.$on('PostRefresh', function () { + //If we got here by deleting an inventory, stop the spinner and cleanup events + Wait('stop'); + try { + $('#prompt-modal').modal('hide'); + } + catch(e) { + // ignore + } + $scope.inventories.forEach(function(inventory, idx) { + $scope.inventories[idx].launch_class = ""; + if (inventory.has_inventory_sources) { + if (inventory.inventory_sources_with_failures > 0) { + $scope.inventories[idx].syncStatus = 'error'; + $scope.inventories[idx].syncTip = inventory.inventory_sources_with_failures + ' groups with sync failures. Click for details'; + } + else { + $scope.inventories[idx].syncStatus = 'successful'; + $scope.inventories[idx].syncTip = 'No inventory sync failures. Click for details.'; + } + } + else { + $scope.inventories[idx].syncStatus = 'na'; + $scope.inventories[idx].syncTip = 'Not configured for inventory sync.'; + $scope.inventories[idx].launch_class = "btn-disabled"; + } + if (inventory.has_active_failures) { + $scope.inventories[idx].hostsStatus = 'error'; + $scope.inventories[idx].hostsTip = inventory.hosts_with_active_failures + ' hosts with failures. Click for details.'; + } + else if (inventory.total_hosts) { + $scope.inventories[idx].hostsStatus = 'successful'; + $scope.inventories[idx].hostsTip = 'No hosts with failures. Click for details.'; + } + else { + $scope.inventories[idx].hostsStatus = 'none'; + $scope.inventories[idx].hostsTip = 'Inventory contains 0 hosts.'; + } + }); + }); + + if ($scope.removeRefreshInventories) { + $scope.removeRefreshInventories(); + } + $scope.removeRefreshInventories = $scope.$on('RefreshInventories', function () { + // Reflect changes after inventory properties edit completes + $scope.search(list.iterator); + }); + + 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(/ /,'
') + "
" + 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(/ /,'
') + "
" + ellipsis(row.summary_fields.group.name) + "
NA" + ellipsis(row.summary_fields.group.name) + "
\n"; + title = "Sync Status"; + attachElem(event, html, title); + }); + + $scope.showGroupSummary = function(event, id) { + 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) { + 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.editInventoryProperties = function (inventory_id) { + EditInventoryProperties({ scope: $scope, inventory_id: inventory_id }); + }; + + $scope.addInventory = function () { + $state.go('inventories.add'); + }; + + $scope.editInventory = function (id) { + $state.go('inventories.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 () { + $scope.search(list.iterator); + }) + .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' + }); + }; + + $scope.lookupOrganization = function (organization_id) { + Rest.setUrl(GetBasePath('organizations') + organization_id + '/'); + Rest.get() + .success(function (data) { + return data.name; + }); + }; + + + // 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', '$log', + '$stateParams', '$compile', '$filter', 'sanitizeFilter', 'Rest', 'Alert', 'InventoryList', + 'generateList', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', + 'ClearScope', 'ProcessErrors', 'GetBasePath', 'Wait', + 'EditInventoryProperties', 'Find', 'Empty', '$state', InventoriesList]; diff --git a/awx/ui/client/src/inventory/inventory-manage.controller.js b/awx/ui/client/src/inventory/inventory-manage.controller.js new file mode 100644 index 0000000000..651547894e --- /dev/null +++ b/awx/ui/client/src/inventory/inventory-manage.controller.js @@ -0,0 +1,532 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/** + * @ngdoc function + * @name controllers.function:Inventories + * @description This controller's for the Inventory page + */ + +import '../job-templates/main'; + +function InventoriesManage($log, $scope, $rootScope, $location, + $state, $compile, generateList, ClearScope, Empty, Wait, Rest, Alert, + GetBasePath, ProcessErrors, InventoryGroups, + InjectHosts, Find, HostsReload, SearchInit, PaginateInit, GetSyncStatusMsg, + GetHostsStatusMsg, GroupsEdit, InventoryUpdate, GroupsCancelUpdate, + ViewUpdateStatus, GroupsDelete, Store, HostsEdit, HostsDelete, + EditInventoryProperties, ToggleHostEnabled, ShowJobSummary, + InventoryGroupsHelp, HelpDialog, + GroupsCopy, HostsCopy, $stateParams) { + + var PreviousSearchParams, + url, + hostScope = $scope.$new(); + + ClearScope(); + + // TODO: only display adhoc button if the user has permission to use it. + // TODO: figure out how to get the action-list partial to update so that + // the tooltip can be changed based off things being selected or not. + $scope.adhocButtonTipContents = "Launch adhoc command for the inventory"; + + // watcher for the group list checkbox changes + $scope.$on('multiSelectList.selectionChanged', function(e, selection) { + if (selection.length > 0) { + $scope.groupsSelected = true; + // $scope.adhocButtonTipContents = "Launch adhoc command for the " + // + "selected groups and hosts."; + } else { + $scope.groupsSelected = false; + // $scope.adhocButtonTipContents = "Launch adhoc command for the " + // + "inventory."; + } + $scope.groupsSelectedItems = selection.selectedItems; + }); + + // watcher for the host list checkbox changes + hostScope.$on('multiSelectList.selectionChanged', function(e, selection) { + // you need this so that the event doesn't bubble to the watcher above + // for the host list + e.stopPropagation(); + if (selection.length === 0) { + $scope.hostsSelected = false; + } else if (selection.length === 1) { + $scope.systemTrackingTooltip = "Compare host over time"; + $scope.hostsSelected = true; + $scope.systemTrackingDisabled = false; + } else if (selection.length === 2) { + $scope.systemTrackingTooltip = "Compare hosts against each other"; + $scope.hostsSelected = true; + $scope.systemTrackingDisabled = false; + } else { + $scope.hostsSelected = true; + $scope.systemTrackingDisabled = true; + } + $scope.hostsSelectedItems = selection.selectedItems; + }); + + $scope.systemTracking = function() { + var hostIds = _.map($scope.hostsSelectedItems, function(x){ + return x.id; + }); + $state.transitionTo('systemTracking', + { inventory: $scope.inventory, + inventoryId: $scope.inventory.id, + hosts: $scope.hostsSelectedItems, + hostIds: hostIds + }); + }; + + // populates host patterns based on selected hosts/groups + $scope.populateAdhocForm = function() { + var host_patterns = "all"; + if ($scope.hostsSelected || $scope.groupsSelected) { + var allSelectedItems = []; + if ($scope.groupsSelectedItems) { + allSelectedItems = allSelectedItems.concat($scope.groupsSelectedItems); + } + if ($scope.hostsSelectedItems) { + allSelectedItems = allSelectedItems.concat($scope.hostsSelectedItems); + } + if (allSelectedItems) { + host_patterns = _.pluck(allSelectedItems, "name").join(":"); + } + } + $rootScope.hostPatterns = host_patterns; + $state.go('inventoryManage.adhoc'); + }; + + $scope.refreshHostsOnGroupRefresh = false; + $scope.selected_group_id = null; + + Wait('start'); + + + if ($scope.removeHostReloadComplete) { + $scope.removeHostReloadComplete(); + } + $scope.removeHostReloadComplete = $scope.$on('HostReloadComplete', function() { + if ($scope.initial_height) { + var host_height = $('#hosts-container .well').height(), + group_height = $('#group-list-container .well').height(), + new_height; + + if (host_height > group_height) { + new_height = host_height - (host_height - group_height); + } + else if (host_height < group_height) { + new_height = host_height + (group_height - host_height); + } + if (new_height) { + $('#hosts-container .well').height(new_height); + } + $scope.initial_height = null; + } + }); + + if ($scope.removeRowCountReady) { + $scope.removeRowCountReady(); + } + $scope.removeRowCountReady = $scope.$on('RowCountReady', function(e, rows) { + // Add hosts view + $scope.show_failures = false; + InjectHosts({ + group_scope: $scope, + host_scope: hostScope, + inventory_id: $scope.inventory.id, + tree_id: null, + group_id: null, + pageSize: rows + }); + + SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: $scope.inventory.related.root_groups }); + PaginateInit({ scope: $scope, list: InventoryGroups , url: $scope.inventory.related.root_groups, pageSize: rows }); + $scope.search(InventoryGroups.iterator, null, true); + }); + + if ($scope.removeInventoryLoaded) { + $scope.removeInventoryLoaded(); + } + $scope.removeInventoryLoaded = $scope.$on('InventoryLoaded', function() { + var rows; + + // Add groups view + generateList.inject(InventoryGroups, { + mode: 'edit', + id: 'group-list-container', + searchSize: 'col-lg-6 col-md-6 col-sm-6 col-xs-12', + scope: $scope + }); + + rows = 20; + hostScope.host_page_size = rows; + $scope.group_page_size = rows; + + $scope.show_failures = false; + InjectHosts({ + group_scope: $scope, + host_scope: hostScope, + inventory_id: $scope.inventory.id, + tree_id: null, + group_id: null, + pageSize: rows + }); + + // Load data + SearchInit({ + scope: $scope, + set: 'groups', + list: InventoryGroups, + url: $scope.inventory.related.root_groups + }); + + PaginateInit({ + scope: $scope, + list: InventoryGroups , + url: $scope.inventory.related.root_groups, + pageSize: rows + }); + + $scope.search(InventoryGroups.iterator, null, true); + + $scope.$emit('WatchUpdateStatus'); // init socket io conneciton and start watching for status updates + }); + + if ($scope.removePostRefresh) { + $scope.removePostRefresh(); + } + $scope.removePostRefresh = $scope.$on('PostRefresh', function(e, set) { + if (set === 'groups') { + $scope.groups.forEach( function(group, idx) { + var stat, hosts_status; + stat = GetSyncStatusMsg({ + status: group.summary_fields.inventory_source.status, + has_inventory_sources: group.has_inventory_sources, + source: ( (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null ) + }); // from helpers/Groups.js + $scope.groups[idx].status_class = stat['class']; + $scope.groups[idx].status_tooltip = stat.tooltip; + $scope.groups[idx].launch_tooltip = stat.launch_tip; + $scope.groups[idx].launch_class = stat.launch_class; + hosts_status = GetHostsStatusMsg({ + active_failures: group.hosts_with_active_failures, + total_hosts: group.total_hosts, + inventory_id: $scope.inventory.id, + group_id: group.id + }); // from helpers/Groups.js + $scope.groups[idx].hosts_status_tip = hosts_status.tooltip; + $scope.groups[idx].show_failures = hosts_status.failures; + $scope.groups[idx].hosts_status_class = hosts_status['class']; + + $scope.groups[idx].source = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null; + $scope.groups[idx].status = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.status : null; + + }); + if ($scope.refreshHostsOnGroupRefresh) { + $scope.refreshHostsOnGroupRefresh = false; + HostsReload({ + scope: hostScope, + group_id: $scope.selected_group_id, + inventory_id: $scope.inventory.id, + pageSize: hostScope.host_page_size + }); + } + else { + Wait('stop'); + } + } + }); + + // Load Inventory + url = GetBasePath('inventory') + $stateParams.inventory_id + '/'; + Rest.setUrl(url); + Rest.get() + .success(function (data) { + $scope.inventory = data; + $scope.$emit('InventoryLoaded'); + }) + .error(function (data, status) { + ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve inventory: ' + $stateParams.inventory_id + + ' GET returned status: ' + status }); + }); + + // start watching for real-time updates + if ($rootScope.removeWatchUpdateStatus) { + $rootScope.removeWatchUpdateStatus(); + } + $rootScope.removeWatchUpdateStatus = $rootScope.$on('JobStatusChange-inventory', function(e, data) { + var stat, group; + if (data.group_id) { + group = Find({ list: $scope.groups, key: 'id', val: data.group_id }); + if (data.status === "failed" || data.status === "successful") { + if (data.group_id === $scope.selected_group_id || group) { + // job completed, fefresh all groups + $log.debug('Update completed. Refreshing the tree.'); + $scope.refreshGroups(); + } + } + else if (group) { + // incremental update, just update + $log.debug('Status of group: ' + data.group_id + ' changed to: ' + data.status); + stat = GetSyncStatusMsg({ + status: data.status, + has_inventory_sources: group.has_inventory_sources, + source: group.source + }); + $log.debug('changing tooltip to: ' + stat.tooltip); + group.status = data.status; + group.status_class = stat['class']; + group.status_tooltip = stat.tooltip; + group.launch_tooltip = stat.launch_tip; + group.launch_class = stat.launch_class; + } + } + }); + + // Load group on selection + function loadGroups(url) { + SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: url }); + PaginateInit({ scope: $scope, list: InventoryGroups , url: url, pageSize: $scope.group_page_size }); + $scope.search(InventoryGroups.iterator, null, true, false, true); + } + + $scope.refreshHosts = function() { + HostsReload({ + scope: hostScope, + group_id: $scope.selected_group_id, + inventory_id: $scope.inventory.id, + pageSize: hostScope.host_page_size + }); + }; + + $scope.refreshGroups = function() { + $scope.refreshHostsOnGroupRefresh = true; + $scope.search(InventoryGroups.iterator, null, true, false, true); + }; + + $scope.restoreSearch = function() { + // Restore search params and related stuff, plus refresh + // groups and hosts lists + SearchInit({ + scope: $scope, + set: PreviousSearchParams.set, + list: PreviousSearchParams.list, + url: PreviousSearchParams.defaultUrl, + iterator: PreviousSearchParams.iterator, + sort_order: PreviousSearchParams.sort_order, + setWidgets: false + }); + $scope.refreshHostsOnGroupRefresh = true; + $scope.search(InventoryGroups.iterator, null, true, false, true); + }; + + $scope.groupSelect = function(id) { + var groups = [], group = Find({ list: $scope.groups, key: 'id', val: id }); + if($state.params.groups){ + groups.push($state.params.groups); + } + groups.push(group.id); + groups = groups.join(); + $state.transitionTo('inventoryManage', {inventory_id: $state.params.inventory_id, groups: groups}, { notify: false }); + loadGroups(group.related.children, group.id); + }; + + $scope.createGroup = function () { + PreviousSearchParams = Store('group_current_search_params'); + GroupsEdit({ + scope: $scope, + inventory_id: $scope.inventory.id, + group_id: $scope.selected_group_id, + mode: 'add' + }); + }; + + $scope.editGroup = function (id) { + PreviousSearchParams = Store('group_current_search_params'); + GroupsEdit({ + scope: $scope, + inventory_id: $scope.inventory.id, + group_id: id, + mode: 'edit' + }); + }; + + // Launch inventory sync + $scope.updateGroup = function (id) { + var group = Find({ list: $scope.groups, key: 'id', val: id }); + if (group) { + if (Empty(group.source)) { + // if no source, do nothing. + } else if (group.status === 'updating') { + Alert('Update in Progress', 'The inventory update process is currently running for group ' + + group.name + ' Click the button to monitor the status.', 'alert-info', null, null, null, null, true); + } else { + Wait('start'); + Rest.setUrl(group.related.inventory_source); + Rest.get() + .success(function (data) { + InventoryUpdate({ + scope: $scope, + url: data.related.update, + group_name: data.summary_fields.group.name, + group_source: data.source, + group_id: group.id, + }); + }) + .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 }); + }); + } + } + }; + + $scope.cancelUpdate = function (id) { + GroupsCancelUpdate({ scope: $scope, id: id }); + }; + + $scope.viewUpdateStatus = function (id) { + ViewUpdateStatus({ + scope: $scope, + group_id: id + }); + }; + + $scope.copyGroup = function(id) { + PreviousSearchParams = Store('group_current_search_params'); + GroupsCopy({ + scope: $scope, + group_id: id + }); + }; + + $scope.deleteGroup = function (id) { + GroupsDelete({ + scope: $scope, + group_id: id, + inventory_id: $scope.inventory.id + }); + }; + + $scope.editInventoryProperties = function () { + // EditInventoryProperties({ scope: $scope, inventory_id: $scope.inventory.id }); + $location.path('/inventories/' + $scope.inventory.id + '/'); + }; + + hostScope.createHost = function () { + HostsEdit({ + host_scope: hostScope, + group_scope: $scope, + mode: 'add', + host_id: null, + selected_group_id: $scope.selected_group_id, + inventory_id: $scope.inventory.id + }); + }; + + hostScope.editHost = function (host_id) { + HostsEdit({ + host_scope: hostScope, + group_scope: $scope, + mode: 'edit', + host_id: host_id, + inventory_id: $scope.inventory.id + }); + }; + + hostScope.deleteHost = function (host_id, host_name) { + HostsDelete({ + parent_scope: $scope, + host_scope: hostScope, + host_id: host_id, + host_name: host_name + }); + }; + + hostScope.copyHost = function(id) { + PreviousSearchParams = Store('group_current_search_params'); + HostsCopy({ + group_scope: $scope, + host_scope: hostScope, + host_id: id + }); + }; + + /*hostScope.restoreSearch = function() { + SearchInit({ + scope: hostScope, + set: PreviousSearchParams.set, + list: PreviousSearchParams.list, + url: PreviousSearchParams.defaultUrl, + iterator: PreviousSearchParams.iterator, + sort_order: PreviousSearchParams.sort_order, + setWidgets: false + }); + hostScope.search('host'); + };*/ + + hostScope.toggleHostEnabled = function (host_id, external_source) { + ToggleHostEnabled({ + parent_scope: $scope, + host_scope: hostScope, + host_id: host_id, + external_source: external_source + }); + }; + + hostScope.showJobSummary = function (job_id) { + ShowJobSummary({ + job_id: job_id + }); + }; + + $scope.showGroupHelp = function (params) { + var opts = { + defn: InventoryGroupsHelp + }; + if (params) { + opts.autoShow = params.autoShow || false; + } + HelpDialog(opts); + } +; + $scope.showHosts = function (group_id, show_failures) { + // Clicked on group + if (group_id !== null) { + Wait('start'); + hostScope.show_failures = show_failures; + $scope.groupSelect(group_id); + hostScope.hosts = []; + $scope.show_failures = show_failures; // turn on failed hosts + // filter in hosts view + } else { + Wait('stop'); + } + }; + + if ($scope.removeGroupDeleteCompleted) { + $scope.removeGroupDeleteCompleted(); + } + $scope.removeGroupDeleteCompleted = $scope.$on('GroupDeleteCompleted', + function() { + $scope.refreshGroups(); + } + ); +} + +export default [ + '$log', '$scope', '$rootScope', '$location', + '$state', '$compile', 'generateList', 'ClearScope', 'Empty', 'Wait', + 'Rest', 'Alert', 'GetBasePath', 'ProcessErrors', + 'InventoryGroups', 'InjectHosts', 'Find', 'HostsReload', + 'SearchInit', 'PaginateInit', 'GetSyncStatusMsg', 'GetHostsStatusMsg', + 'GroupsEdit', 'InventoryUpdate', 'GroupsCancelUpdate', 'ViewUpdateStatus', + 'GroupsDelete', 'Store', 'HostsEdit', 'HostsDelete', + 'EditInventoryProperties', 'ToggleHostEnabled', 'ShowJobSummary', + 'InventoryGroupsHelp', 'HelpDialog', 'GroupsCopy', + 'HostsCopy', '$stateParams', InventoriesManage, +]; diff --git a/awx/ui/client/src/inventory/main.js b/awx/ui/client/src/inventory/main.js new file mode 100644 index 0000000000..0689a2d726 --- /dev/null +++ b/awx/ui/client/src/inventory/main.js @@ -0,0 +1,10 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + + +export default +angular.module('inventory', [ +]) From b0b416341d314c4434cc0dc86a046fac4b2a45b4 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Wed, 16 Mar 2016 09:23:05 -0400 Subject: [PATCH 02/11] Further modularization. --- awx/ui/client/src/app.js | 43 ++++++++++++++++++- .../add}/inventory-add.controller.js | 2 +- .../inventories/add/inventory-add.route.js | 24 +++++++++++ awx/ui/client/src/inventories/add/main.js | 14 ++++++ .../edit}/inventory-edit.controller.js | 2 +- .../inventories/edit/inventory-edit.route.js | 26 +++++++++++ awx/ui/client/src/inventories/edit/main.js | 14 ++++++ .../inventories.partial.html} | 0 .../list}/inventory-list.controller.js | 2 +- .../inventories/list/inventory-list.route.js | 27 ++++++++++++ awx/ui/client/src/inventories/list/main.js | 14 ++++++ awx/ui/client/src/inventories/main.js | 18 ++++++++ .../manage}/inventory-manage.controller.js | 2 +- .../manage/inventory-manage.partial.html} | 0 .../manage/inventory-manage.route.js | 28 ++++++++++++ awx/ui/client/src/inventories/manage/main.js | 14 ++++++ awx/ui/client/src/inventory/main.js | 10 ----- 17 files changed, 225 insertions(+), 15 deletions(-) rename awx/ui/client/src/{inventory => inventories/add}/inventory-add.controller.js (98%) create mode 100644 awx/ui/client/src/inventories/add/inventory-add.route.js create mode 100644 awx/ui/client/src/inventories/add/main.js rename awx/ui/client/src/{inventory => inventories/edit}/inventory-edit.controller.js (99%) create mode 100644 awx/ui/client/src/inventories/edit/inventory-edit.route.js create mode 100644 awx/ui/client/src/inventories/edit/main.js rename awx/ui/client/src/{partials/inventories.html => inventories/inventories.partial.html} (100%) rename awx/ui/client/src/{inventory => inventories/list}/inventory-list.controller.js (99%) create mode 100644 awx/ui/client/src/inventories/list/inventory-list.route.js create mode 100644 awx/ui/client/src/inventories/list/main.js create mode 100644 awx/ui/client/src/inventories/main.js rename awx/ui/client/src/{inventory => inventories/manage}/inventory-manage.controller.js (99%) rename awx/ui/client/src/{partials/inventory-manage.html => inventories/manage/inventory-manage.partial.html} (100%) create mode 100644 awx/ui/client/src/inventories/manage/inventory-manage.route.js create mode 100644 awx/ui/client/src/inventories/manage/main.js delete mode 100644 awx/ui/client/src/inventory/main.js diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index 2a3367805c..55753b9f40 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -26,7 +26,7 @@ import {CredentialsAdd, CredentialsEdit, CredentialsList} from './controllers/Cr import {JobsListController} from './controllers/Jobs'; import {PortalController} from './controllers/Portal'; import systemTracking from './system-tracking/main'; -import inventory from './inventory/main'; +import inventories from './inventories/main'; import inventoryScripts from './inventory-scripts/main'; import organizations from './organizations/main'; import permissions from './permissions/main'; @@ -91,6 +91,7 @@ var tower = angular.module('Tower', [ RestServices.name, browserData.name, systemTracking.name, + inventories.name, inventoryScripts.name, organizations.name, permissions.name, @@ -372,6 +373,7 @@ var tower = angular.module('Tower', [ } }). +<<<<<<< 3e32787490a4faf3899b1a5d125475e73521ef35 state('inventories', { url: '/inventories', templateUrl: urlPrefix + 'partials/inventories.html', @@ -382,6 +384,22 @@ var tower = angular.module('Tower', [ }, ncyBreadcrumb: { label: "INVENTORIES" +======= + state('organizations', { + url: '/organizations', + templateUrl: urlPrefix + 'partials/organizations.html', + controller: OrganizationsList, + data: { + activityStream: true, + activityStreamTarget: 'organization' + }, + ncyBreadcrumb: { + parent: function($scope) { + $scope.$parent.$emit("ReloadOrgListView"); + return "setup"; + }, + label: "ORGANIZATIONS" +>>>>>>> Further modularization. }, resolve: { features: ['FeaturesService', function(FeaturesService) { @@ -390,6 +408,7 @@ var tower = angular.module('Tower', [ } }). +<<<<<<< 3e32787490a4faf3899b1a5d125475e73521ef35 state('inventories.add', { url: '/add', templateUrl: urlPrefix + 'partials/inventories.html', @@ -397,6 +416,15 @@ var tower = angular.module('Tower', [ ncyBreadcrumb: { parent: "inventories", label: "CREATE INVENTORY" +======= + state('organizations.add', { + url: '/add', + templateUrl: urlPrefix + 'partials/organizations.crud.html', + controller: OrganizationsAdd, + ncyBreadcrumb: { + parent: "organizations", + label: "CREATE ORGANIZATION" +>>>>>>> Further modularization. }, resolve: { features: ['FeaturesService', function(FeaturesService) { @@ -405,6 +433,7 @@ var tower = angular.module('Tower', [ } }). +<<<<<<< 3e32787490a4faf3899b1a5d125475e73521ef35 state('inventories.edit', { url: '/:inventory_id', templateUrl: urlPrefix + 'partials/inventories.html', @@ -427,6 +456,18 @@ var tower = angular.module('Tower', [ activityStream: true, activityStreamTarget: 'inventory', activityStreamId: 'inventory_id' +======= + state('organizations.edit', { + url: '/:organization_id', + templateUrl: urlPrefix + 'partials/organizations.crud.html', + controller: OrganizationsEdit, + data: { + activityStreamId: 'organization_id' + }, + ncyBreadcrumb: { + parent: "organizations", + label: "{{name}}" +>>>>>>> Further modularization. }, resolve: { features: ['FeaturesService', function(FeaturesService) { diff --git a/awx/ui/client/src/inventory/inventory-add.controller.js b/awx/ui/client/src/inventories/add/inventory-add.controller.js similarity index 98% rename from awx/ui/client/src/inventory/inventory-add.controller.js rename to awx/ui/client/src/inventories/add/inventory-add.controller.js index a0903f4fab..befcc1d14e 100644 --- a/awx/ui/client/src/inventory/inventory-add.controller.js +++ b/awx/ui/client/src/inventories/add/inventory-add.controller.js @@ -10,7 +10,7 @@ * @description This controller's for the Inventory page */ -import '../job-templates/main'; +import '../../job-templates/main'; function InventoriesAdd($scope, $rootScope, $compile, $location, $log, $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, diff --git a/awx/ui/client/src/inventories/add/inventory-add.route.js b/awx/ui/client/src/inventories/add/inventory-add.route.js new file mode 100644 index 0000000000..50ba5b26a6 --- /dev/null +++ b/awx/ui/client/src/inventories/add/inventory-add.route.js @@ -0,0 +1,24 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import {templateUrl} from '../../shared/template-url/template-url.factory'; +import InventoriesAdd from './inventory-add.controller'; + +export default { + name: 'inventories.add', + route: '/add', + templateUrl: templateUrl('inventories/inventories'), + controller: InventoriesAdd, + ncyBreadcrumb: { + parent: "inventories", + label: "CREATE INVENTORY" + }, + resolve: { + features: ['FeaturesService', function(FeaturesService) { + return FeaturesService.get(); + }] + } +}; diff --git a/awx/ui/client/src/inventories/add/main.js b/awx/ui/client/src/inventories/add/main.js new file mode 100644 index 0000000000..e12ff940ac --- /dev/null +++ b/awx/ui/client/src/inventories/add/main.js @@ -0,0 +1,14 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import route from './inventory-add.route'; +import controller from './inventory-add.controller'; + +export default + angular.module('inventoryAdd', []) + .run(['$stateExtender', function($stateExtender) { + $stateExtender.addState(route); + }]); diff --git a/awx/ui/client/src/inventory/inventory-edit.controller.js b/awx/ui/client/src/inventories/edit/inventory-edit.controller.js similarity index 99% rename from awx/ui/client/src/inventory/inventory-edit.controller.js rename to awx/ui/client/src/inventories/edit/inventory-edit.controller.js index dd45a566ac..3876f67c20 100644 --- a/awx/ui/client/src/inventory/inventory-edit.controller.js +++ b/awx/ui/client/src/inventories/edit/inventory-edit.controller.js @@ -10,7 +10,7 @@ * @description This controller's for the Inventory page */ -import '../job-templates/main'; +import '../../job-templates/main'; function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, diff --git a/awx/ui/client/src/inventories/edit/inventory-edit.route.js b/awx/ui/client/src/inventories/edit/inventory-edit.route.js new file mode 100644 index 0000000000..d721ba92a4 --- /dev/null +++ b/awx/ui/client/src/inventories/edit/inventory-edit.route.js @@ -0,0 +1,26 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import {templateUrl} from '../../shared/template-url/template-url.factory'; +import InventoriesEdit from './inventory-edit.controller'; + +export default { + name: 'inventories.edit', + route: '/:inventory_id', + templateUrl: templateUrl('inventories/inventories'), + controller: InventoriesEdit, + data: { + activityStreamId: 'inventory_id' + }, + ncyBreadcrumb: { + label: "INVENTORY EDIT" + }, + resolve: { + features: ['FeaturesService', function(FeaturesService) { + return FeaturesService.get(); + }] + } +}; diff --git a/awx/ui/client/src/inventories/edit/main.js b/awx/ui/client/src/inventories/edit/main.js new file mode 100644 index 0000000000..28c99819b7 --- /dev/null +++ b/awx/ui/client/src/inventories/edit/main.js @@ -0,0 +1,14 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import route from './inventory-edit.route'; +import controller from './inventory-edit.controller'; + +export default + angular.module('inventoryEdit', []) + .run(['$stateExtender', function($stateExtender) { + $stateExtender.addState(route); + }]); diff --git a/awx/ui/client/src/partials/inventories.html b/awx/ui/client/src/inventories/inventories.partial.html similarity index 100% rename from awx/ui/client/src/partials/inventories.html rename to awx/ui/client/src/inventories/inventories.partial.html diff --git a/awx/ui/client/src/inventory/inventory-list.controller.js b/awx/ui/client/src/inventories/list/inventory-list.controller.js similarity index 99% rename from awx/ui/client/src/inventory/inventory-list.controller.js rename to awx/ui/client/src/inventories/list/inventory-list.controller.js index 98f02df918..c535187925 100644 --- a/awx/ui/client/src/inventory/inventory-list.controller.js +++ b/awx/ui/client/src/inventories/list/inventory-list.controller.js @@ -10,7 +10,7 @@ * @description This controller's for the Inventory page */ -import '../job-templates/main'; +import '../../job-templates/main'; function InventoriesList($scope, $rootScope, $location, $log, $stateParams, $compile, $filter, sanitizeFilter, Rest, Alert, InventoryList, diff --git a/awx/ui/client/src/inventories/list/inventory-list.route.js b/awx/ui/client/src/inventories/list/inventory-list.route.js new file mode 100644 index 0000000000..2804370249 --- /dev/null +++ b/awx/ui/client/src/inventories/list/inventory-list.route.js @@ -0,0 +1,27 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import {templateUrl} from '../../shared/template-url/template-url.factory'; +import InventoriesList from './inventory-list.controller'; + +export default { + name: 'inventories', + route: '/inventories', + templateUrl: templateUrl('inventories/inventories'), + controller: InventoriesList, + data: { + activityStream: true, + activityStreamTarget: 'inventory' + }, + ncyBreadcrumb: { + label: "INVENTORIES" + }, + resolve: { + features: ['FeaturesService', function(FeaturesService) { + return FeaturesService.get(); + }] + } +}; diff --git a/awx/ui/client/src/inventories/list/main.js b/awx/ui/client/src/inventories/list/main.js new file mode 100644 index 0000000000..4d67816cd7 --- /dev/null +++ b/awx/ui/client/src/inventories/list/main.js @@ -0,0 +1,14 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import route from './inventory-list.route'; +import controller from './inventory-list.controller'; + +export default + angular.module('inventoryList', []) + .run(['$stateExtender', function($stateExtender) { + $stateExtender.addState(route); + }]); diff --git a/awx/ui/client/src/inventories/main.js b/awx/ui/client/src/inventories/main.js new file mode 100644 index 0000000000..52f9986ef3 --- /dev/null +++ b/awx/ui/client/src/inventories/main.js @@ -0,0 +1,18 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import inventoryAdd from './add/main'; +import inventoryEdit from './edit/main'; +import inventoryList from './list/main'; +import inventoryManage from './manage/main'; + +export default +angular.module('inventory', [ + inventoryAdd.name, + inventoryEdit.name, + inventoryList.name, + inventoryManage.name, +]); diff --git a/awx/ui/client/src/inventory/inventory-manage.controller.js b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js similarity index 99% rename from awx/ui/client/src/inventory/inventory-manage.controller.js rename to awx/ui/client/src/inventories/manage/inventory-manage.controller.js index 651547894e..3b1d3b4625 100644 --- a/awx/ui/client/src/inventory/inventory-manage.controller.js +++ b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js @@ -10,7 +10,7 @@ * @description This controller's for the Inventory page */ -import '../job-templates/main'; +import '../../job-templates/main'; function InventoriesManage($log, $scope, $rootScope, $location, $state, $compile, generateList, ClearScope, Empty, Wait, Rest, Alert, diff --git a/awx/ui/client/src/partials/inventory-manage.html b/awx/ui/client/src/inventories/manage/inventory-manage.partial.html similarity index 100% rename from awx/ui/client/src/partials/inventory-manage.html rename to awx/ui/client/src/inventories/manage/inventory-manage.partial.html diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.route.js b/awx/ui/client/src/inventories/manage/inventory-manage.route.js new file mode 100644 index 0000000000..1cfc9176ac --- /dev/null +++ b/awx/ui/client/src/inventories/manage/inventory-manage.route.js @@ -0,0 +1,28 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import {templateUrl} from '../../shared/template-url/template-url.factory'; +import InventoriesManage from './inventory-manage.controller'; + +export default { + name: 'inventoryManage', + route: '/inventories/:inventory_id/manage', + templateUrl: templateUrl('inventories/manage/inventory-manage'), + controller: InventoriesManage, + data: { + activityStream: true, + activityStreamTarget: 'inventory', + activityStreamId: 'inventory_id' + }, + ncyBreadcrumb: { + label: "INVENTORY MANAGE" + }, + resolve: { + features: ['FeaturesService', function(FeaturesService) { + return FeaturesService.get(); + }] + } +}; diff --git a/awx/ui/client/src/inventories/manage/main.js b/awx/ui/client/src/inventories/manage/main.js new file mode 100644 index 0000000000..7bd839ecc1 --- /dev/null +++ b/awx/ui/client/src/inventories/manage/main.js @@ -0,0 +1,14 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import route from './inventory-manage.route'; +import controller from './inventory-manage.controller'; + +export default + angular.module('inventoryManage', []) + .run(['$stateExtender', function($stateExtender) { + $stateExtender.addState(route); + }]); diff --git a/awx/ui/client/src/inventory/main.js b/awx/ui/client/src/inventory/main.js deleted file mode 100644 index 0689a2d726..0000000000 --- a/awx/ui/client/src/inventory/main.js +++ /dev/null @@ -1,10 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - -export default -angular.module('inventory', [ -]) From 6ee654c879f85897899e9f5530a9992e1e1f7ef3 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Wed, 16 Mar 2016 11:35:23 -0400 Subject: [PATCH 03/11] Removed unused job templates import from some controllers --- awx/ui/client/src/inventories/list/inventory-list.controller.js | 2 -- .../src/inventories/manage/inventory-manage.controller.js | 2 -- 2 files changed, 4 deletions(-) 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 c535187925..a55529491c 100644 --- a/awx/ui/client/src/inventories/list/inventory-list.controller.js +++ b/awx/ui/client/src/inventories/list/inventory-list.controller.js @@ -10,8 +10,6 @@ * @description This controller's for the Inventory page */ -import '../../job-templates/main'; - function InventoriesList($scope, $rootScope, $location, $log, $stateParams, $compile, $filter, sanitizeFilter, Rest, Alert, InventoryList, generateList, Prompt, SearchInit, PaginateInit, ReturnToCaller, diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js index 3b1d3b4625..58c50dfbe2 100644 --- a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js +++ b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js @@ -10,8 +10,6 @@ * @description This controller's for the Inventory page */ -import '../../job-templates/main'; - function InventoriesManage($log, $scope, $rootScope, $location, $state, $compile, generateList, ClearScope, Empty, Wait, Rest, Alert, GetBasePath, ProcessErrors, InventoryGroups, From d24ab43c9941223934438710eb447370b2d25433 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Mon, 14 Mar 2016 16:13:01 -0400 Subject: [PATCH 04/11] Set up inventory module and split apart controllers/inventory.js into more manageable chunks. --- awx/ui/client/src/app.js | 40 -- .../src/inventory/inventory-add.controller.js | 98 ++++ .../inventory/inventory-edit.controller.js | 332 +++++++++++ .../inventory/inventory-list.controller.js | 371 ++++++++++++ .../inventory/inventory-manage.controller.js | 532 ++++++++++++++++++ awx/ui/client/src/inventory/main.js | 10 + 6 files changed, 1343 insertions(+), 40 deletions(-) create mode 100644 awx/ui/client/src/inventory/inventory-add.controller.js create mode 100644 awx/ui/client/src/inventory/inventory-edit.controller.js create mode 100644 awx/ui/client/src/inventory/inventory-list.controller.js create mode 100644 awx/ui/client/src/inventory/inventory-manage.controller.js create mode 100644 awx/ui/client/src/inventory/main.js diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index 55753b9f40..aabeec0f4c 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -373,7 +373,6 @@ var tower = angular.module('Tower', [ } }). -<<<<<<< 3e32787490a4faf3899b1a5d125475e73521ef35 state('inventories', { url: '/inventories', templateUrl: urlPrefix + 'partials/inventories.html', @@ -384,22 +383,6 @@ var tower = angular.module('Tower', [ }, ncyBreadcrumb: { label: "INVENTORIES" -======= - state('organizations', { - url: '/organizations', - templateUrl: urlPrefix + 'partials/organizations.html', - controller: OrganizationsList, - data: { - activityStream: true, - activityStreamTarget: 'organization' - }, - ncyBreadcrumb: { - parent: function($scope) { - $scope.$parent.$emit("ReloadOrgListView"); - return "setup"; - }, - label: "ORGANIZATIONS" ->>>>>>> Further modularization. }, resolve: { features: ['FeaturesService', function(FeaturesService) { @@ -408,7 +391,6 @@ var tower = angular.module('Tower', [ } }). -<<<<<<< 3e32787490a4faf3899b1a5d125475e73521ef35 state('inventories.add', { url: '/add', templateUrl: urlPrefix + 'partials/inventories.html', @@ -416,15 +398,6 @@ var tower = angular.module('Tower', [ ncyBreadcrumb: { parent: "inventories", label: "CREATE INVENTORY" -======= - state('organizations.add', { - url: '/add', - templateUrl: urlPrefix + 'partials/organizations.crud.html', - controller: OrganizationsAdd, - ncyBreadcrumb: { - parent: "organizations", - label: "CREATE ORGANIZATION" ->>>>>>> Further modularization. }, resolve: { features: ['FeaturesService', function(FeaturesService) { @@ -433,7 +406,6 @@ var tower = angular.module('Tower', [ } }). -<<<<<<< 3e32787490a4faf3899b1a5d125475e73521ef35 state('inventories.edit', { url: '/:inventory_id', templateUrl: urlPrefix + 'partials/inventories.html', @@ -456,18 +428,6 @@ var tower = angular.module('Tower', [ activityStream: true, activityStreamTarget: 'inventory', activityStreamId: 'inventory_id' -======= - state('organizations.edit', { - url: '/:organization_id', - templateUrl: urlPrefix + 'partials/organizations.crud.html', - controller: OrganizationsEdit, - data: { - activityStreamId: 'organization_id' - }, - ncyBreadcrumb: { - parent: "organizations", - label: "{{name}}" ->>>>>>> Further modularization. }, resolve: { features: ['FeaturesService', function(FeaturesService) { diff --git a/awx/ui/client/src/inventory/inventory-add.controller.js b/awx/ui/client/src/inventory/inventory-add.controller.js new file mode 100644 index 0000000000..a0903f4fab --- /dev/null +++ b/awx/ui/client/src/inventory/inventory-add.controller.js @@ -0,0 +1,98 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/** + * @ngdoc function + * @name controllers.function:Inventories + * @description This controller's for the Inventory page + */ + +import '../job-templates/main'; + +function InventoriesAdd($scope, $rootScope, $compile, $location, $log, + $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, + ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, + PaginateInit, LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, + $state) { + + ClearScope(); + + // Inject dynamic view + var defaultUrl = GetBasePath('inventory'), + form = InventoryForm(), + generator = GenerateForm; + + form.well = true; + form.formLabelSize = null; + form.formFieldSize = null; + + generator.inject(form, { mode: 'add', related: false, scope: $scope }); + + generator.reset(); + + $scope.parseType = 'yaml'; + ParseTypeChange({ + scope: $scope, + variable: 'variables', + parse_variable: 'parseType', + field_id: 'inventory_variables' + }); + + LookUpInit({ + scope: $scope, + form: form, + current_item: ($stateParams.organization_id) ? $stateParams.organization_id : null, + list: OrganizationList, + field: 'organization', + input_type: 'radio' + }); + + // Save + $scope.formSave = function () { + generator.clearApiErrors(); + 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('/inventories/' + inventory_id + '/manage'); + }) + .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.transitionTo('inventories'); + }; +} + +export default['$scope', '$rootScope', '$compile', '$location', + '$log', '$stateParams', 'InventoryForm', 'GenerateForm', 'Rest', 'Alert', + 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'generateList', + 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', + 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', '$state', InventoriesAdd] diff --git a/awx/ui/client/src/inventory/inventory-edit.controller.js b/awx/ui/client/src/inventory/inventory-edit.controller.js new file mode 100644 index 0000000000..dd45a566ac --- /dev/null +++ b/awx/ui/client/src/inventory/inventory-edit.controller.js @@ -0,0 +1,332 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/** + * @ngdoc function + * @name controllers.function:Inventories + * @description This controller's for the Inventory page + */ + +import '../job-templates/main'; + +function InventoriesEdit($scope, $rootScope, $compile, $location, + $log, $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, + ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, + PaginateInit, LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, + ParseVariableString, RelatedSearchInit, RelatedPaginateInit, + Prompt, PlaybookRun, CreateDialog, deleteJobTemplate, $state) { + + ClearScope(); + + // Inject dynamic view + var defaultUrl = GetBasePath('inventory'), + form = InventoryForm(), + generator = GenerateForm, + inventory_id = $stateParams.inventory_id, + master = {}, + fld, json_data, data, + relatedSets = {}; + + form.well = true; + form.formLabelSize = null; + form.formFieldSize = null; + $scope.inventory_id = inventory_id; + generator.inject(form, { mode: 'edit', related: true, scope: $scope }); + + generator.reset(); + + + // After the project is loaded, retrieve each related set + if ($scope.inventoryLoadedRemove) { + $scope.inventoryLoadedRemove(); + } + $scope.projectLoadedRemove = $scope.$on('inventoryLoaded', function () { + var set; + for (set in relatedSets) { + $scope.search(relatedSets[set].iterator); + } + }); + + 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]; + } + } + relatedSets = form.relatedSets(data.related); + + // Initialize related search functions. Doing it here to make sure relatedSets object is populated. + RelatedSearchInit({ + scope: $scope, + form: form, + relatedSets: relatedSets + }); + RelatedPaginateInit({ + scope: $scope, + relatedSets: relatedSets + }); + + Wait('stop'); + $scope.parseType = 'yaml'; + ParseTypeChange({ + scope: $scope, + variable: 'variables', + parse_variable: 'parseType', + field_id: 'inventory_variables' + }); + LookUpInit({ + scope: $scope, + form: form, + current_item: $scope.organization, + list: OrganizationList, + field: 'organization', + input_type: 'radio' + }); + $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'); + $location.path('/inventories/'); + }) + .error(function (data, status) { + ProcessErrors($scope, data, status, form, { hdr: 'Error!', + msg: 'Failed to update inventory. PUT returned status: ' + status }); + }); + }; + + $scope.manageInventory = function(){ + $location.path($location.path() + '/manage'); + }; + + $scope.formCancel = function () { + $state.transitionTo('inventories'); + }; + + $scope.addScanJob = function(){ + $location.path($location.path()+'/job_templates/add'); + }; + + $scope.launchScanJob = function(){ + PlaybookRun({ scope: $scope, id: this.scan_job_template.id }); + }; + + $scope.scheduleScanJob = function(){ + $location.path('/job_templates/'+this.scan_job_template.id+'/schedules'); + }; + + $scope.editScanJob = function(){ + $location.path($location.path()+'/job_templates/'+this.scan_job_template.id); + }; + + $scope.copyScanJobTemplate = function(){ + var id = this.scan_job_template.id, + name = this.scan_job_template.name, + element, + buttons = [{ + "label": "Cancel", + "onClick": function() { + $(this).dialog('close'); + }, + "icon": "fa-times", + "class": "btn btn-default", + "id": "copy-close-button" + },{ + "label": "Copy", + "onClick": function() { + copyAction(); + }, + "icon": "fa-copy", + "class": "btn btn-primary", + "id": "job-copy-button" + }], + copyAction = function () { + // retrieve the copy of the job template object from the api, then overwrite the name and throw away the id + Wait('start'); + var url = GetBasePath('job_templates')+id; + Rest.setUrl(url); + Rest.get() + .success(function (data) { + data.name = $scope.new_copy_name; + delete data.id; + $scope.$emit('GoToCopy', data); + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + }; + + + CreateDialog({ + id: 'copy-job-modal' , + title: "Copy", + scope: $scope, + buttons: buttons, + width: 500, + height: 300, + minWidth: 200, + callback: 'CopyDialogReady' + }); + + $('#job_name').text(name); + $('#copy-job-modal').show(); + + + if ($scope.removeCopyDialogReady) { + $scope.removeCopyDialogReady(); + } + $scope.removeCopyDialogReady = $scope.$on('CopyDialogReady', function() { + //clear any old remaining text + $scope.new_copy_name = "" ; + $scope.copy_form.$setPristine(); + $('#copy-job-modal').dialog('open'); + $('#job-copy-button').attr('ng-disabled', "!copy_form.$valid"); + element = angular.element(document.getElementById('job-copy-button')); + $compile(element)($scope); + + }); + + if ($scope.removeGoToCopy) { + $scope.removeGoToCopy(); + } + $scope.removeGoToCopy = $scope.$on('GoToCopy', function(e, data) { + var url = GetBasePath('job_templates'), + old_survey_url = (data.related.survey_spec) ? data.related.survey_spec : "" ; + Rest.setUrl(url); + Rest.post(data) + .success(function (data) { + if(data.survey_enabled===true){ + $scope.$emit("CopySurvey", data, old_survey_url); + } + else { + $('#copy-job-modal').dialog('close'); + Wait('stop'); + $location.path($location.path() + '/job_templates/' + data.id); + } + + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + }); + + if ($scope.removeCopySurvey) { + $scope.removeCopySurvey(); + } + $scope.removeCopySurvey = $scope.$on('CopySurvey', function(e, new_data, old_url) { + // var url = data.related.survey_spec; + Rest.setUrl(old_url); + Rest.get() + .success(function (survey_data) { + + Rest.setUrl(new_data.related.survey_spec); + Rest.post(survey_data) + .success(function () { + $('#copy-job-modal').dialog('close'); + Wait('stop'); + $location.path($location.path() + '/job_templates/' + new_data.id); + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + new_data.related.survey_spec + ' failed. DELETE returned status: ' + status }); + }); + + + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + old_url + ' failed. DELETE returned status: ' + status }); + }); + + }); + + }; + + $scope.deleteScanJob = function () { + var id = this.scan_job_template.id , + action = function () { + $('#prompt-modal').modal('hide'); + Wait('start'); + deleteJobTemplate(id) + .success(function () { + $('#prompt-modal').modal('hide'); + $scope.search(form.related.scan_job_templates.iterator); + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'DELETE returned status: ' + status }); + }); + }; + + Prompt({ + hdr: 'Delete', + body: '
Are you sure you want to delete the job template below?
' + this.scan_job_template.name + '
', + action: action, + actionText: 'DELETE' + }); + + }; + +} + +export default ['$scope', '$rootScope', '$compile', '$location', + '$log', '$stateParams', 'InventoryForm', 'GenerateForm', 'Rest', 'Alert', + 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'generateList', + 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', + 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', + 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', + 'PlaybookRun', 'CreateDialog', 'deleteJobTemplate', '$state', + InventoriesEdit, +]; diff --git a/awx/ui/client/src/inventory/inventory-list.controller.js b/awx/ui/client/src/inventory/inventory-list.controller.js new file mode 100644 index 0000000000..98f02df918 --- /dev/null +++ b/awx/ui/client/src/inventory/inventory-list.controller.js @@ -0,0 +1,371 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/** + * @ngdoc function + * @name controllers.function:Inventories + * @description This controller's for the Inventory page + */ + +import '../job-templates/main'; + +function InventoriesList($scope, $rootScope, $location, $log, + $stateParams, $compile, $filter, sanitizeFilter, Rest, Alert, InventoryList, + generateList, Prompt, SearchInit, PaginateInit, ReturnToCaller, + ClearScope, ProcessErrors, GetBasePath, Wait, + EditInventoryProperties, Find, Empty, $state) { + + var list = InventoryList, + defaultUrl = GetBasePath('inventory'), + view = generateList, + paths = $location.path().replace(/^\//, '').split('/'), + mode = (paths[0] === 'inventories') ? 'edit' : 'select'; + + 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" }); + $compile(elem)($scope); + elem.on('shown.bs.popover', function() { + $('.popover').each(function() { + $compile($(this))($scope); //make nested directives work! + }); + $('.popover-content, .popover-title').click(function() { + elem.popover('hide'); + }); + }); + elem.popover('show'); + } + + view.inject(InventoryList, { mode: mode, scope: $scope }); + $rootScope.flashMessage = null; + + SearchInit({ + scope: $scope, + set: 'inventories', + list: list, + url: defaultUrl + }); + + PaginateInit({ + scope: $scope, + list: list, + url: defaultUrl + }); + + if ($stateParams.name) { + $scope[InventoryList.iterator + 'InputDisable'] = false; + $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.name; + $scope[InventoryList.iterator + 'SearchField'] = 'name'; + $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.name.label; + $scope[InventoryList.iterator + 'SearchSelectValue'] = null; + } + + if ($stateParams.has_active_failures) { + $scope[InventoryList.iterator + 'InputDisable'] = true; + $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_active_failures; + $scope[InventoryList.iterator + 'SearchField'] = 'has_active_failures'; + $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_active_failures.label; + $scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_active_failures === 'true') ? { + value: 1 + } : { + value: 0 + }; + } + + if ($stateParams.has_inventory_sources) { + $scope[InventoryList.iterator + 'InputDisable'] = true; + $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_inventory_sources; + $scope[InventoryList.iterator + 'SearchField'] = 'has_inventory_sources'; + $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_inventory_sources.label; + $scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_inventory_sources === 'true') ? { + value: 1 + } : { + value: 0 + }; + } + + if ($stateParams.inventory_sources_with_failures) { + // pass a value of true, however this field actually contains an integer value + $scope[InventoryList.iterator + 'InputDisable'] = true; + $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.inventory_sources_with_failures; + $scope[InventoryList.iterator + 'SearchField'] = 'inventory_sources_with_failures'; + $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.inventory_sources_with_failures.label; + $scope[InventoryList.iterator + 'SearchType'] = 'gtzero'; + } + + $scope.search(list.iterator); + + if ($scope.removePostRefresh) { + $scope.removePostRefresh(); + } + $scope.removePostRefresh = $scope.$on('PostRefresh', function () { + //If we got here by deleting an inventory, stop the spinner and cleanup events + Wait('stop'); + try { + $('#prompt-modal').modal('hide'); + } + catch(e) { + // ignore + } + $scope.inventories.forEach(function(inventory, idx) { + $scope.inventories[idx].launch_class = ""; + if (inventory.has_inventory_sources) { + if (inventory.inventory_sources_with_failures > 0) { + $scope.inventories[idx].syncStatus = 'error'; + $scope.inventories[idx].syncTip = inventory.inventory_sources_with_failures + ' groups with sync failures. Click for details'; + } + else { + $scope.inventories[idx].syncStatus = 'successful'; + $scope.inventories[idx].syncTip = 'No inventory sync failures. Click for details.'; + } + } + else { + $scope.inventories[idx].syncStatus = 'na'; + $scope.inventories[idx].syncTip = 'Not configured for inventory sync.'; + $scope.inventories[idx].launch_class = "btn-disabled"; + } + if (inventory.has_active_failures) { + $scope.inventories[idx].hostsStatus = 'error'; + $scope.inventories[idx].hostsTip = inventory.hosts_with_active_failures + ' hosts with failures. Click for details.'; + } + else if (inventory.total_hosts) { + $scope.inventories[idx].hostsStatus = 'successful'; + $scope.inventories[idx].hostsTip = 'No hosts with failures. Click for details.'; + } + else { + $scope.inventories[idx].hostsStatus = 'none'; + $scope.inventories[idx].hostsTip = 'Inventory contains 0 hosts.'; + } + }); + }); + + if ($scope.removeRefreshInventories) { + $scope.removeRefreshInventories(); + } + $scope.removeRefreshInventories = $scope.$on('RefreshInventories', function () { + // Reflect changes after inventory properties edit completes + $scope.search(list.iterator); + }); + + 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(/ /,'
') + "
" + 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(/ /,'
') + "
" + ellipsis(row.summary_fields.group.name) + "
NA" + ellipsis(row.summary_fields.group.name) + "
\n"; + title = "Sync Status"; + attachElem(event, html, title); + }); + + $scope.showGroupSummary = function(event, id) { + 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) { + 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.editInventoryProperties = function (inventory_id) { + EditInventoryProperties({ scope: $scope, inventory_id: inventory_id }); + }; + + $scope.addInventory = function () { + $state.go('inventories.add'); + }; + + $scope.editInventory = function (id) { + $state.go('inventories.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 () { + $scope.search(list.iterator); + }) + .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' + }); + }; + + $scope.lookupOrganization = function (organization_id) { + Rest.setUrl(GetBasePath('organizations') + organization_id + '/'); + Rest.get() + .success(function (data) { + return data.name; + }); + }; + + + // 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', '$log', + '$stateParams', '$compile', '$filter', 'sanitizeFilter', 'Rest', 'Alert', 'InventoryList', + 'generateList', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', + 'ClearScope', 'ProcessErrors', 'GetBasePath', 'Wait', + 'EditInventoryProperties', 'Find', 'Empty', '$state', InventoriesList]; diff --git a/awx/ui/client/src/inventory/inventory-manage.controller.js b/awx/ui/client/src/inventory/inventory-manage.controller.js new file mode 100644 index 0000000000..651547894e --- /dev/null +++ b/awx/ui/client/src/inventory/inventory-manage.controller.js @@ -0,0 +1,532 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/** + * @ngdoc function + * @name controllers.function:Inventories + * @description This controller's for the Inventory page + */ + +import '../job-templates/main'; + +function InventoriesManage($log, $scope, $rootScope, $location, + $state, $compile, generateList, ClearScope, Empty, Wait, Rest, Alert, + GetBasePath, ProcessErrors, InventoryGroups, + InjectHosts, Find, HostsReload, SearchInit, PaginateInit, GetSyncStatusMsg, + GetHostsStatusMsg, GroupsEdit, InventoryUpdate, GroupsCancelUpdate, + ViewUpdateStatus, GroupsDelete, Store, HostsEdit, HostsDelete, + EditInventoryProperties, ToggleHostEnabled, ShowJobSummary, + InventoryGroupsHelp, HelpDialog, + GroupsCopy, HostsCopy, $stateParams) { + + var PreviousSearchParams, + url, + hostScope = $scope.$new(); + + ClearScope(); + + // TODO: only display adhoc button if the user has permission to use it. + // TODO: figure out how to get the action-list partial to update so that + // the tooltip can be changed based off things being selected or not. + $scope.adhocButtonTipContents = "Launch adhoc command for the inventory"; + + // watcher for the group list checkbox changes + $scope.$on('multiSelectList.selectionChanged', function(e, selection) { + if (selection.length > 0) { + $scope.groupsSelected = true; + // $scope.adhocButtonTipContents = "Launch adhoc command for the " + // + "selected groups and hosts."; + } else { + $scope.groupsSelected = false; + // $scope.adhocButtonTipContents = "Launch adhoc command for the " + // + "inventory."; + } + $scope.groupsSelectedItems = selection.selectedItems; + }); + + // watcher for the host list checkbox changes + hostScope.$on('multiSelectList.selectionChanged', function(e, selection) { + // you need this so that the event doesn't bubble to the watcher above + // for the host list + e.stopPropagation(); + if (selection.length === 0) { + $scope.hostsSelected = false; + } else if (selection.length === 1) { + $scope.systemTrackingTooltip = "Compare host over time"; + $scope.hostsSelected = true; + $scope.systemTrackingDisabled = false; + } else if (selection.length === 2) { + $scope.systemTrackingTooltip = "Compare hosts against each other"; + $scope.hostsSelected = true; + $scope.systemTrackingDisabled = false; + } else { + $scope.hostsSelected = true; + $scope.systemTrackingDisabled = true; + } + $scope.hostsSelectedItems = selection.selectedItems; + }); + + $scope.systemTracking = function() { + var hostIds = _.map($scope.hostsSelectedItems, function(x){ + return x.id; + }); + $state.transitionTo('systemTracking', + { inventory: $scope.inventory, + inventoryId: $scope.inventory.id, + hosts: $scope.hostsSelectedItems, + hostIds: hostIds + }); + }; + + // populates host patterns based on selected hosts/groups + $scope.populateAdhocForm = function() { + var host_patterns = "all"; + if ($scope.hostsSelected || $scope.groupsSelected) { + var allSelectedItems = []; + if ($scope.groupsSelectedItems) { + allSelectedItems = allSelectedItems.concat($scope.groupsSelectedItems); + } + if ($scope.hostsSelectedItems) { + allSelectedItems = allSelectedItems.concat($scope.hostsSelectedItems); + } + if (allSelectedItems) { + host_patterns = _.pluck(allSelectedItems, "name").join(":"); + } + } + $rootScope.hostPatterns = host_patterns; + $state.go('inventoryManage.adhoc'); + }; + + $scope.refreshHostsOnGroupRefresh = false; + $scope.selected_group_id = null; + + Wait('start'); + + + if ($scope.removeHostReloadComplete) { + $scope.removeHostReloadComplete(); + } + $scope.removeHostReloadComplete = $scope.$on('HostReloadComplete', function() { + if ($scope.initial_height) { + var host_height = $('#hosts-container .well').height(), + group_height = $('#group-list-container .well').height(), + new_height; + + if (host_height > group_height) { + new_height = host_height - (host_height - group_height); + } + else if (host_height < group_height) { + new_height = host_height + (group_height - host_height); + } + if (new_height) { + $('#hosts-container .well').height(new_height); + } + $scope.initial_height = null; + } + }); + + if ($scope.removeRowCountReady) { + $scope.removeRowCountReady(); + } + $scope.removeRowCountReady = $scope.$on('RowCountReady', function(e, rows) { + // Add hosts view + $scope.show_failures = false; + InjectHosts({ + group_scope: $scope, + host_scope: hostScope, + inventory_id: $scope.inventory.id, + tree_id: null, + group_id: null, + pageSize: rows + }); + + SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: $scope.inventory.related.root_groups }); + PaginateInit({ scope: $scope, list: InventoryGroups , url: $scope.inventory.related.root_groups, pageSize: rows }); + $scope.search(InventoryGroups.iterator, null, true); + }); + + if ($scope.removeInventoryLoaded) { + $scope.removeInventoryLoaded(); + } + $scope.removeInventoryLoaded = $scope.$on('InventoryLoaded', function() { + var rows; + + // Add groups view + generateList.inject(InventoryGroups, { + mode: 'edit', + id: 'group-list-container', + searchSize: 'col-lg-6 col-md-6 col-sm-6 col-xs-12', + scope: $scope + }); + + rows = 20; + hostScope.host_page_size = rows; + $scope.group_page_size = rows; + + $scope.show_failures = false; + InjectHosts({ + group_scope: $scope, + host_scope: hostScope, + inventory_id: $scope.inventory.id, + tree_id: null, + group_id: null, + pageSize: rows + }); + + // Load data + SearchInit({ + scope: $scope, + set: 'groups', + list: InventoryGroups, + url: $scope.inventory.related.root_groups + }); + + PaginateInit({ + scope: $scope, + list: InventoryGroups , + url: $scope.inventory.related.root_groups, + pageSize: rows + }); + + $scope.search(InventoryGroups.iterator, null, true); + + $scope.$emit('WatchUpdateStatus'); // init socket io conneciton and start watching for status updates + }); + + if ($scope.removePostRefresh) { + $scope.removePostRefresh(); + } + $scope.removePostRefresh = $scope.$on('PostRefresh', function(e, set) { + if (set === 'groups') { + $scope.groups.forEach( function(group, idx) { + var stat, hosts_status; + stat = GetSyncStatusMsg({ + status: group.summary_fields.inventory_source.status, + has_inventory_sources: group.has_inventory_sources, + source: ( (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null ) + }); // from helpers/Groups.js + $scope.groups[idx].status_class = stat['class']; + $scope.groups[idx].status_tooltip = stat.tooltip; + $scope.groups[idx].launch_tooltip = stat.launch_tip; + $scope.groups[idx].launch_class = stat.launch_class; + hosts_status = GetHostsStatusMsg({ + active_failures: group.hosts_with_active_failures, + total_hosts: group.total_hosts, + inventory_id: $scope.inventory.id, + group_id: group.id + }); // from helpers/Groups.js + $scope.groups[idx].hosts_status_tip = hosts_status.tooltip; + $scope.groups[idx].show_failures = hosts_status.failures; + $scope.groups[idx].hosts_status_class = hosts_status['class']; + + $scope.groups[idx].source = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null; + $scope.groups[idx].status = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.status : null; + + }); + if ($scope.refreshHostsOnGroupRefresh) { + $scope.refreshHostsOnGroupRefresh = false; + HostsReload({ + scope: hostScope, + group_id: $scope.selected_group_id, + inventory_id: $scope.inventory.id, + pageSize: hostScope.host_page_size + }); + } + else { + Wait('stop'); + } + } + }); + + // Load Inventory + url = GetBasePath('inventory') + $stateParams.inventory_id + '/'; + Rest.setUrl(url); + Rest.get() + .success(function (data) { + $scope.inventory = data; + $scope.$emit('InventoryLoaded'); + }) + .error(function (data, status) { + ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve inventory: ' + $stateParams.inventory_id + + ' GET returned status: ' + status }); + }); + + // start watching for real-time updates + if ($rootScope.removeWatchUpdateStatus) { + $rootScope.removeWatchUpdateStatus(); + } + $rootScope.removeWatchUpdateStatus = $rootScope.$on('JobStatusChange-inventory', function(e, data) { + var stat, group; + if (data.group_id) { + group = Find({ list: $scope.groups, key: 'id', val: data.group_id }); + if (data.status === "failed" || data.status === "successful") { + if (data.group_id === $scope.selected_group_id || group) { + // job completed, fefresh all groups + $log.debug('Update completed. Refreshing the tree.'); + $scope.refreshGroups(); + } + } + else if (group) { + // incremental update, just update + $log.debug('Status of group: ' + data.group_id + ' changed to: ' + data.status); + stat = GetSyncStatusMsg({ + status: data.status, + has_inventory_sources: group.has_inventory_sources, + source: group.source + }); + $log.debug('changing tooltip to: ' + stat.tooltip); + group.status = data.status; + group.status_class = stat['class']; + group.status_tooltip = stat.tooltip; + group.launch_tooltip = stat.launch_tip; + group.launch_class = stat.launch_class; + } + } + }); + + // Load group on selection + function loadGroups(url) { + SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: url }); + PaginateInit({ scope: $scope, list: InventoryGroups , url: url, pageSize: $scope.group_page_size }); + $scope.search(InventoryGroups.iterator, null, true, false, true); + } + + $scope.refreshHosts = function() { + HostsReload({ + scope: hostScope, + group_id: $scope.selected_group_id, + inventory_id: $scope.inventory.id, + pageSize: hostScope.host_page_size + }); + }; + + $scope.refreshGroups = function() { + $scope.refreshHostsOnGroupRefresh = true; + $scope.search(InventoryGroups.iterator, null, true, false, true); + }; + + $scope.restoreSearch = function() { + // Restore search params and related stuff, plus refresh + // groups and hosts lists + SearchInit({ + scope: $scope, + set: PreviousSearchParams.set, + list: PreviousSearchParams.list, + url: PreviousSearchParams.defaultUrl, + iterator: PreviousSearchParams.iterator, + sort_order: PreviousSearchParams.sort_order, + setWidgets: false + }); + $scope.refreshHostsOnGroupRefresh = true; + $scope.search(InventoryGroups.iterator, null, true, false, true); + }; + + $scope.groupSelect = function(id) { + var groups = [], group = Find({ list: $scope.groups, key: 'id', val: id }); + if($state.params.groups){ + groups.push($state.params.groups); + } + groups.push(group.id); + groups = groups.join(); + $state.transitionTo('inventoryManage', {inventory_id: $state.params.inventory_id, groups: groups}, { notify: false }); + loadGroups(group.related.children, group.id); + }; + + $scope.createGroup = function () { + PreviousSearchParams = Store('group_current_search_params'); + GroupsEdit({ + scope: $scope, + inventory_id: $scope.inventory.id, + group_id: $scope.selected_group_id, + mode: 'add' + }); + }; + + $scope.editGroup = function (id) { + PreviousSearchParams = Store('group_current_search_params'); + GroupsEdit({ + scope: $scope, + inventory_id: $scope.inventory.id, + group_id: id, + mode: 'edit' + }); + }; + + // Launch inventory sync + $scope.updateGroup = function (id) { + var group = Find({ list: $scope.groups, key: 'id', val: id }); + if (group) { + if (Empty(group.source)) { + // if no source, do nothing. + } else if (group.status === 'updating') { + Alert('Update in Progress', 'The inventory update process is currently running for group ' + + group.name + ' Click the button to monitor the status.', 'alert-info', null, null, null, null, true); + } else { + Wait('start'); + Rest.setUrl(group.related.inventory_source); + Rest.get() + .success(function (data) { + InventoryUpdate({ + scope: $scope, + url: data.related.update, + group_name: data.summary_fields.group.name, + group_source: data.source, + group_id: group.id, + }); + }) + .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 }); + }); + } + } + }; + + $scope.cancelUpdate = function (id) { + GroupsCancelUpdate({ scope: $scope, id: id }); + }; + + $scope.viewUpdateStatus = function (id) { + ViewUpdateStatus({ + scope: $scope, + group_id: id + }); + }; + + $scope.copyGroup = function(id) { + PreviousSearchParams = Store('group_current_search_params'); + GroupsCopy({ + scope: $scope, + group_id: id + }); + }; + + $scope.deleteGroup = function (id) { + GroupsDelete({ + scope: $scope, + group_id: id, + inventory_id: $scope.inventory.id + }); + }; + + $scope.editInventoryProperties = function () { + // EditInventoryProperties({ scope: $scope, inventory_id: $scope.inventory.id }); + $location.path('/inventories/' + $scope.inventory.id + '/'); + }; + + hostScope.createHost = function () { + HostsEdit({ + host_scope: hostScope, + group_scope: $scope, + mode: 'add', + host_id: null, + selected_group_id: $scope.selected_group_id, + inventory_id: $scope.inventory.id + }); + }; + + hostScope.editHost = function (host_id) { + HostsEdit({ + host_scope: hostScope, + group_scope: $scope, + mode: 'edit', + host_id: host_id, + inventory_id: $scope.inventory.id + }); + }; + + hostScope.deleteHost = function (host_id, host_name) { + HostsDelete({ + parent_scope: $scope, + host_scope: hostScope, + host_id: host_id, + host_name: host_name + }); + }; + + hostScope.copyHost = function(id) { + PreviousSearchParams = Store('group_current_search_params'); + HostsCopy({ + group_scope: $scope, + host_scope: hostScope, + host_id: id + }); + }; + + /*hostScope.restoreSearch = function() { + SearchInit({ + scope: hostScope, + set: PreviousSearchParams.set, + list: PreviousSearchParams.list, + url: PreviousSearchParams.defaultUrl, + iterator: PreviousSearchParams.iterator, + sort_order: PreviousSearchParams.sort_order, + setWidgets: false + }); + hostScope.search('host'); + };*/ + + hostScope.toggleHostEnabled = function (host_id, external_source) { + ToggleHostEnabled({ + parent_scope: $scope, + host_scope: hostScope, + host_id: host_id, + external_source: external_source + }); + }; + + hostScope.showJobSummary = function (job_id) { + ShowJobSummary({ + job_id: job_id + }); + }; + + $scope.showGroupHelp = function (params) { + var opts = { + defn: InventoryGroupsHelp + }; + if (params) { + opts.autoShow = params.autoShow || false; + } + HelpDialog(opts); + } +; + $scope.showHosts = function (group_id, show_failures) { + // Clicked on group + if (group_id !== null) { + Wait('start'); + hostScope.show_failures = show_failures; + $scope.groupSelect(group_id); + hostScope.hosts = []; + $scope.show_failures = show_failures; // turn on failed hosts + // filter in hosts view + } else { + Wait('stop'); + } + }; + + if ($scope.removeGroupDeleteCompleted) { + $scope.removeGroupDeleteCompleted(); + } + $scope.removeGroupDeleteCompleted = $scope.$on('GroupDeleteCompleted', + function() { + $scope.refreshGroups(); + } + ); +} + +export default [ + '$log', '$scope', '$rootScope', '$location', + '$state', '$compile', 'generateList', 'ClearScope', 'Empty', 'Wait', + 'Rest', 'Alert', 'GetBasePath', 'ProcessErrors', + 'InventoryGroups', 'InjectHosts', 'Find', 'HostsReload', + 'SearchInit', 'PaginateInit', 'GetSyncStatusMsg', 'GetHostsStatusMsg', + 'GroupsEdit', 'InventoryUpdate', 'GroupsCancelUpdate', 'ViewUpdateStatus', + 'GroupsDelete', 'Store', 'HostsEdit', 'HostsDelete', + 'EditInventoryProperties', 'ToggleHostEnabled', 'ShowJobSummary', + 'InventoryGroupsHelp', 'HelpDialog', 'GroupsCopy', + 'HostsCopy', '$stateParams', InventoriesManage, +]; diff --git a/awx/ui/client/src/inventory/main.js b/awx/ui/client/src/inventory/main.js new file mode 100644 index 0000000000..0689a2d726 --- /dev/null +++ b/awx/ui/client/src/inventory/main.js @@ -0,0 +1,10 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + + +export default +angular.module('inventory', [ +]) From a76b361f18a9547607ab4773226343cd470f4ac1 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Thu, 17 Mar 2016 16:11:42 -0400 Subject: [PATCH 05/11] Removed artifacts from merge --- .../src/inventory/inventory-add.controller.js | 98 ---- .../inventory/inventory-edit.controller.js | 332 ----------- .../inventory/inventory-list.controller.js | 371 ------------ .../inventory/inventory-manage.controller.js | 532 ------------------ awx/ui/client/src/inventory/main.js | 10 - 5 files changed, 1343 deletions(-) delete mode 100644 awx/ui/client/src/inventory/inventory-add.controller.js delete mode 100644 awx/ui/client/src/inventory/inventory-edit.controller.js delete mode 100644 awx/ui/client/src/inventory/inventory-list.controller.js delete mode 100644 awx/ui/client/src/inventory/inventory-manage.controller.js delete mode 100644 awx/ui/client/src/inventory/main.js diff --git a/awx/ui/client/src/inventory/inventory-add.controller.js b/awx/ui/client/src/inventory/inventory-add.controller.js deleted file mode 100644 index a0903f4fab..0000000000 --- a/awx/ui/client/src/inventory/inventory-add.controller.js +++ /dev/null @@ -1,98 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Inventories - * @description This controller's for the Inventory page - */ - -import '../job-templates/main'; - -function InventoriesAdd($scope, $rootScope, $compile, $location, $log, - $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, - ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, - PaginateInit, LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, - $state) { - - ClearScope(); - - // Inject dynamic view - var defaultUrl = GetBasePath('inventory'), - form = InventoryForm(), - generator = GenerateForm; - - form.well = true; - form.formLabelSize = null; - form.formFieldSize = null; - - generator.inject(form, { mode: 'add', related: false, scope: $scope }); - - generator.reset(); - - $scope.parseType = 'yaml'; - ParseTypeChange({ - scope: $scope, - variable: 'variables', - parse_variable: 'parseType', - field_id: 'inventory_variables' - }); - - LookUpInit({ - scope: $scope, - form: form, - current_item: ($stateParams.organization_id) ? $stateParams.organization_id : null, - list: OrganizationList, - field: 'organization', - input_type: 'radio' - }); - - // Save - $scope.formSave = function () { - generator.clearApiErrors(); - 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('/inventories/' + inventory_id + '/manage'); - }) - .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.transitionTo('inventories'); - }; -} - -export default['$scope', '$rootScope', '$compile', '$location', - '$log', '$stateParams', 'InventoryForm', 'GenerateForm', 'Rest', 'Alert', - 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'generateList', - 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', - 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', '$state', InventoriesAdd] diff --git a/awx/ui/client/src/inventory/inventory-edit.controller.js b/awx/ui/client/src/inventory/inventory-edit.controller.js deleted file mode 100644 index dd45a566ac..0000000000 --- a/awx/ui/client/src/inventory/inventory-edit.controller.js +++ /dev/null @@ -1,332 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Inventories - * @description This controller's for the Inventory page - */ - -import '../job-templates/main'; - -function InventoriesEdit($scope, $rootScope, $compile, $location, - $log, $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, - ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, - PaginateInit, LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, - ParseVariableString, RelatedSearchInit, RelatedPaginateInit, - Prompt, PlaybookRun, CreateDialog, deleteJobTemplate, $state) { - - ClearScope(); - - // Inject dynamic view - var defaultUrl = GetBasePath('inventory'), - form = InventoryForm(), - generator = GenerateForm, - inventory_id = $stateParams.inventory_id, - master = {}, - fld, json_data, data, - relatedSets = {}; - - form.well = true; - form.formLabelSize = null; - form.formFieldSize = null; - $scope.inventory_id = inventory_id; - generator.inject(form, { mode: 'edit', related: true, scope: $scope }); - - generator.reset(); - - - // After the project is loaded, retrieve each related set - if ($scope.inventoryLoadedRemove) { - $scope.inventoryLoadedRemove(); - } - $scope.projectLoadedRemove = $scope.$on('inventoryLoaded', function () { - var set; - for (set in relatedSets) { - $scope.search(relatedSets[set].iterator); - } - }); - - 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]; - } - } - relatedSets = form.relatedSets(data.related); - - // Initialize related search functions. Doing it here to make sure relatedSets object is populated. - RelatedSearchInit({ - scope: $scope, - form: form, - relatedSets: relatedSets - }); - RelatedPaginateInit({ - scope: $scope, - relatedSets: relatedSets - }); - - Wait('stop'); - $scope.parseType = 'yaml'; - ParseTypeChange({ - scope: $scope, - variable: 'variables', - parse_variable: 'parseType', - field_id: 'inventory_variables' - }); - LookUpInit({ - scope: $scope, - form: form, - current_item: $scope.organization, - list: OrganizationList, - field: 'organization', - input_type: 'radio' - }); - $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'); - $location.path('/inventories/'); - }) - .error(function (data, status) { - ProcessErrors($scope, data, status, form, { hdr: 'Error!', - msg: 'Failed to update inventory. PUT returned status: ' + status }); - }); - }; - - $scope.manageInventory = function(){ - $location.path($location.path() + '/manage'); - }; - - $scope.formCancel = function () { - $state.transitionTo('inventories'); - }; - - $scope.addScanJob = function(){ - $location.path($location.path()+'/job_templates/add'); - }; - - $scope.launchScanJob = function(){ - PlaybookRun({ scope: $scope, id: this.scan_job_template.id }); - }; - - $scope.scheduleScanJob = function(){ - $location.path('/job_templates/'+this.scan_job_template.id+'/schedules'); - }; - - $scope.editScanJob = function(){ - $location.path($location.path()+'/job_templates/'+this.scan_job_template.id); - }; - - $scope.copyScanJobTemplate = function(){ - var id = this.scan_job_template.id, - name = this.scan_job_template.name, - element, - buttons = [{ - "label": "Cancel", - "onClick": function() { - $(this).dialog('close'); - }, - "icon": "fa-times", - "class": "btn btn-default", - "id": "copy-close-button" - },{ - "label": "Copy", - "onClick": function() { - copyAction(); - }, - "icon": "fa-copy", - "class": "btn btn-primary", - "id": "job-copy-button" - }], - copyAction = function () { - // retrieve the copy of the job template object from the api, then overwrite the name and throw away the id - Wait('start'); - var url = GetBasePath('job_templates')+id; - Rest.setUrl(url); - Rest.get() - .success(function (data) { - data.name = $scope.new_copy_name; - delete data.id; - $scope.$emit('GoToCopy', data); - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; - - - CreateDialog({ - id: 'copy-job-modal' , - title: "Copy", - scope: $scope, - buttons: buttons, - width: 500, - height: 300, - minWidth: 200, - callback: 'CopyDialogReady' - }); - - $('#job_name').text(name); - $('#copy-job-modal').show(); - - - if ($scope.removeCopyDialogReady) { - $scope.removeCopyDialogReady(); - } - $scope.removeCopyDialogReady = $scope.$on('CopyDialogReady', function() { - //clear any old remaining text - $scope.new_copy_name = "" ; - $scope.copy_form.$setPristine(); - $('#copy-job-modal').dialog('open'); - $('#job-copy-button').attr('ng-disabled', "!copy_form.$valid"); - element = angular.element(document.getElementById('job-copy-button')); - $compile(element)($scope); - - }); - - if ($scope.removeGoToCopy) { - $scope.removeGoToCopy(); - } - $scope.removeGoToCopy = $scope.$on('GoToCopy', function(e, data) { - var url = GetBasePath('job_templates'), - old_survey_url = (data.related.survey_spec) ? data.related.survey_spec : "" ; - Rest.setUrl(url); - Rest.post(data) - .success(function (data) { - if(data.survey_enabled===true){ - $scope.$emit("CopySurvey", data, old_survey_url); - } - else { - $('#copy-job-modal').dialog('close'); - Wait('stop'); - $location.path($location.path() + '/job_templates/' + data.id); - } - - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }); - - if ($scope.removeCopySurvey) { - $scope.removeCopySurvey(); - } - $scope.removeCopySurvey = $scope.$on('CopySurvey', function(e, new_data, old_url) { - // var url = data.related.survey_spec; - Rest.setUrl(old_url); - Rest.get() - .success(function (survey_data) { - - Rest.setUrl(new_data.related.survey_spec); - Rest.post(survey_data) - .success(function () { - $('#copy-job-modal').dialog('close'); - Wait('stop'); - $location.path($location.path() + '/job_templates/' + new_data.id); - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + new_data.related.survey_spec + ' failed. DELETE returned status: ' + status }); - }); - - - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + old_url + ' failed. DELETE returned status: ' + status }); - }); - - }); - - }; - - $scope.deleteScanJob = function () { - var id = this.scan_job_template.id , - action = function () { - $('#prompt-modal').modal('hide'); - Wait('start'); - deleteJobTemplate(id) - .success(function () { - $('#prompt-modal').modal('hide'); - $scope.search(form.related.scan_job_templates.iterator); - }) - .error(function (data) { - Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'DELETE returned status: ' + status }); - }); - }; - - Prompt({ - hdr: 'Delete', - body: '
Are you sure you want to delete the job template below?
' + this.scan_job_template.name + '
', - action: action, - actionText: 'DELETE' - }); - - }; - -} - -export default ['$scope', '$rootScope', '$compile', '$location', - '$log', '$stateParams', 'InventoryForm', 'GenerateForm', 'Rest', 'Alert', - 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'generateList', - 'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', - 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', - 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', - 'PlaybookRun', 'CreateDialog', 'deleteJobTemplate', '$state', - InventoriesEdit, -]; diff --git a/awx/ui/client/src/inventory/inventory-list.controller.js b/awx/ui/client/src/inventory/inventory-list.controller.js deleted file mode 100644 index 98f02df918..0000000000 --- a/awx/ui/client/src/inventory/inventory-list.controller.js +++ /dev/null @@ -1,371 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Inventories - * @description This controller's for the Inventory page - */ - -import '../job-templates/main'; - -function InventoriesList($scope, $rootScope, $location, $log, - $stateParams, $compile, $filter, sanitizeFilter, Rest, Alert, InventoryList, - generateList, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, Wait, - EditInventoryProperties, Find, Empty, $state) { - - var list = InventoryList, - defaultUrl = GetBasePath('inventory'), - view = generateList, - paths = $location.path().replace(/^\//, '').split('/'), - mode = (paths[0] === 'inventories') ? 'edit' : 'select'; - - 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" }); - $compile(elem)($scope); - elem.on('shown.bs.popover', function() { - $('.popover').each(function() { - $compile($(this))($scope); //make nested directives work! - }); - $('.popover-content, .popover-title').click(function() { - elem.popover('hide'); - }); - }); - elem.popover('show'); - } - - view.inject(InventoryList, { mode: mode, scope: $scope }); - $rootScope.flashMessage = null; - - SearchInit({ - scope: $scope, - set: 'inventories', - list: list, - url: defaultUrl - }); - - PaginateInit({ - scope: $scope, - list: list, - url: defaultUrl - }); - - if ($stateParams.name) { - $scope[InventoryList.iterator + 'InputDisable'] = false; - $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.name; - $scope[InventoryList.iterator + 'SearchField'] = 'name'; - $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.name.label; - $scope[InventoryList.iterator + 'SearchSelectValue'] = null; - } - - if ($stateParams.has_active_failures) { - $scope[InventoryList.iterator + 'InputDisable'] = true; - $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_active_failures; - $scope[InventoryList.iterator + 'SearchField'] = 'has_active_failures'; - $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_active_failures.label; - $scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_active_failures === 'true') ? { - value: 1 - } : { - value: 0 - }; - } - - if ($stateParams.has_inventory_sources) { - $scope[InventoryList.iterator + 'InputDisable'] = true; - $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_inventory_sources; - $scope[InventoryList.iterator + 'SearchField'] = 'has_inventory_sources'; - $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_inventory_sources.label; - $scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_inventory_sources === 'true') ? { - value: 1 - } : { - value: 0 - }; - } - - if ($stateParams.inventory_sources_with_failures) { - // pass a value of true, however this field actually contains an integer value - $scope[InventoryList.iterator + 'InputDisable'] = true; - $scope[InventoryList.iterator + 'SearchValue'] = $stateParams.inventory_sources_with_failures; - $scope[InventoryList.iterator + 'SearchField'] = 'inventory_sources_with_failures'; - $scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.inventory_sources_with_failures.label; - $scope[InventoryList.iterator + 'SearchType'] = 'gtzero'; - } - - $scope.search(list.iterator); - - if ($scope.removePostRefresh) { - $scope.removePostRefresh(); - } - $scope.removePostRefresh = $scope.$on('PostRefresh', function () { - //If we got here by deleting an inventory, stop the spinner and cleanup events - Wait('stop'); - try { - $('#prompt-modal').modal('hide'); - } - catch(e) { - // ignore - } - $scope.inventories.forEach(function(inventory, idx) { - $scope.inventories[idx].launch_class = ""; - if (inventory.has_inventory_sources) { - if (inventory.inventory_sources_with_failures > 0) { - $scope.inventories[idx].syncStatus = 'error'; - $scope.inventories[idx].syncTip = inventory.inventory_sources_with_failures + ' groups with sync failures. Click for details'; - } - else { - $scope.inventories[idx].syncStatus = 'successful'; - $scope.inventories[idx].syncTip = 'No inventory sync failures. Click for details.'; - } - } - else { - $scope.inventories[idx].syncStatus = 'na'; - $scope.inventories[idx].syncTip = 'Not configured for inventory sync.'; - $scope.inventories[idx].launch_class = "btn-disabled"; - } - if (inventory.has_active_failures) { - $scope.inventories[idx].hostsStatus = 'error'; - $scope.inventories[idx].hostsTip = inventory.hosts_with_active_failures + ' hosts with failures. Click for details.'; - } - else if (inventory.total_hosts) { - $scope.inventories[idx].hostsStatus = 'successful'; - $scope.inventories[idx].hostsTip = 'No hosts with failures. Click for details.'; - } - else { - $scope.inventories[idx].hostsStatus = 'none'; - $scope.inventories[idx].hostsTip = 'Inventory contains 0 hosts.'; - } - }); - }); - - if ($scope.removeRefreshInventories) { - $scope.removeRefreshInventories(); - } - $scope.removeRefreshInventories = $scope.$on('RefreshInventories', function () { - // Reflect changes after inventory properties edit completes - $scope.search(list.iterator); - }); - - 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(/ /,'
') + "
" + 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(/ /,'
') + "
" + ellipsis(row.summary_fields.group.name) + "
NA" + ellipsis(row.summary_fields.group.name) + "
\n"; - title = "Sync Status"; - attachElem(event, html, title); - }); - - $scope.showGroupSummary = function(event, id) { - 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) { - 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.editInventoryProperties = function (inventory_id) { - EditInventoryProperties({ scope: $scope, inventory_id: inventory_id }); - }; - - $scope.addInventory = function () { - $state.go('inventories.add'); - }; - - $scope.editInventory = function (id) { - $state.go('inventories.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 () { - $scope.search(list.iterator); - }) - .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' - }); - }; - - $scope.lookupOrganization = function (organization_id) { - Rest.setUrl(GetBasePath('organizations') + organization_id + '/'); - Rest.get() - .success(function (data) { - return data.name; - }); - }; - - - // 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', '$log', - '$stateParams', '$compile', '$filter', 'sanitizeFilter', 'Rest', 'Alert', 'InventoryList', - 'generateList', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', - 'ClearScope', 'ProcessErrors', 'GetBasePath', 'Wait', - 'EditInventoryProperties', 'Find', 'Empty', '$state', InventoriesList]; diff --git a/awx/ui/client/src/inventory/inventory-manage.controller.js b/awx/ui/client/src/inventory/inventory-manage.controller.js deleted file mode 100644 index 651547894e..0000000000 --- a/awx/ui/client/src/inventory/inventory-manage.controller.js +++ /dev/null @@ -1,532 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -/** - * @ngdoc function - * @name controllers.function:Inventories - * @description This controller's for the Inventory page - */ - -import '../job-templates/main'; - -function InventoriesManage($log, $scope, $rootScope, $location, - $state, $compile, generateList, ClearScope, Empty, Wait, Rest, Alert, - GetBasePath, ProcessErrors, InventoryGroups, - InjectHosts, Find, HostsReload, SearchInit, PaginateInit, GetSyncStatusMsg, - GetHostsStatusMsg, GroupsEdit, InventoryUpdate, GroupsCancelUpdate, - ViewUpdateStatus, GroupsDelete, Store, HostsEdit, HostsDelete, - EditInventoryProperties, ToggleHostEnabled, ShowJobSummary, - InventoryGroupsHelp, HelpDialog, - GroupsCopy, HostsCopy, $stateParams) { - - var PreviousSearchParams, - url, - hostScope = $scope.$new(); - - ClearScope(); - - // TODO: only display adhoc button if the user has permission to use it. - // TODO: figure out how to get the action-list partial to update so that - // the tooltip can be changed based off things being selected or not. - $scope.adhocButtonTipContents = "Launch adhoc command for the inventory"; - - // watcher for the group list checkbox changes - $scope.$on('multiSelectList.selectionChanged', function(e, selection) { - if (selection.length > 0) { - $scope.groupsSelected = true; - // $scope.adhocButtonTipContents = "Launch adhoc command for the " - // + "selected groups and hosts."; - } else { - $scope.groupsSelected = false; - // $scope.adhocButtonTipContents = "Launch adhoc command for the " - // + "inventory."; - } - $scope.groupsSelectedItems = selection.selectedItems; - }); - - // watcher for the host list checkbox changes - hostScope.$on('multiSelectList.selectionChanged', function(e, selection) { - // you need this so that the event doesn't bubble to the watcher above - // for the host list - e.stopPropagation(); - if (selection.length === 0) { - $scope.hostsSelected = false; - } else if (selection.length === 1) { - $scope.systemTrackingTooltip = "Compare host over time"; - $scope.hostsSelected = true; - $scope.systemTrackingDisabled = false; - } else if (selection.length === 2) { - $scope.systemTrackingTooltip = "Compare hosts against each other"; - $scope.hostsSelected = true; - $scope.systemTrackingDisabled = false; - } else { - $scope.hostsSelected = true; - $scope.systemTrackingDisabled = true; - } - $scope.hostsSelectedItems = selection.selectedItems; - }); - - $scope.systemTracking = function() { - var hostIds = _.map($scope.hostsSelectedItems, function(x){ - return x.id; - }); - $state.transitionTo('systemTracking', - { inventory: $scope.inventory, - inventoryId: $scope.inventory.id, - hosts: $scope.hostsSelectedItems, - hostIds: hostIds - }); - }; - - // populates host patterns based on selected hosts/groups - $scope.populateAdhocForm = function() { - var host_patterns = "all"; - if ($scope.hostsSelected || $scope.groupsSelected) { - var allSelectedItems = []; - if ($scope.groupsSelectedItems) { - allSelectedItems = allSelectedItems.concat($scope.groupsSelectedItems); - } - if ($scope.hostsSelectedItems) { - allSelectedItems = allSelectedItems.concat($scope.hostsSelectedItems); - } - if (allSelectedItems) { - host_patterns = _.pluck(allSelectedItems, "name").join(":"); - } - } - $rootScope.hostPatterns = host_patterns; - $state.go('inventoryManage.adhoc'); - }; - - $scope.refreshHostsOnGroupRefresh = false; - $scope.selected_group_id = null; - - Wait('start'); - - - if ($scope.removeHostReloadComplete) { - $scope.removeHostReloadComplete(); - } - $scope.removeHostReloadComplete = $scope.$on('HostReloadComplete', function() { - if ($scope.initial_height) { - var host_height = $('#hosts-container .well').height(), - group_height = $('#group-list-container .well').height(), - new_height; - - if (host_height > group_height) { - new_height = host_height - (host_height - group_height); - } - else if (host_height < group_height) { - new_height = host_height + (group_height - host_height); - } - if (new_height) { - $('#hosts-container .well').height(new_height); - } - $scope.initial_height = null; - } - }); - - if ($scope.removeRowCountReady) { - $scope.removeRowCountReady(); - } - $scope.removeRowCountReady = $scope.$on('RowCountReady', function(e, rows) { - // Add hosts view - $scope.show_failures = false; - InjectHosts({ - group_scope: $scope, - host_scope: hostScope, - inventory_id: $scope.inventory.id, - tree_id: null, - group_id: null, - pageSize: rows - }); - - SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: $scope.inventory.related.root_groups }); - PaginateInit({ scope: $scope, list: InventoryGroups , url: $scope.inventory.related.root_groups, pageSize: rows }); - $scope.search(InventoryGroups.iterator, null, true); - }); - - if ($scope.removeInventoryLoaded) { - $scope.removeInventoryLoaded(); - } - $scope.removeInventoryLoaded = $scope.$on('InventoryLoaded', function() { - var rows; - - // Add groups view - generateList.inject(InventoryGroups, { - mode: 'edit', - id: 'group-list-container', - searchSize: 'col-lg-6 col-md-6 col-sm-6 col-xs-12', - scope: $scope - }); - - rows = 20; - hostScope.host_page_size = rows; - $scope.group_page_size = rows; - - $scope.show_failures = false; - InjectHosts({ - group_scope: $scope, - host_scope: hostScope, - inventory_id: $scope.inventory.id, - tree_id: null, - group_id: null, - pageSize: rows - }); - - // Load data - SearchInit({ - scope: $scope, - set: 'groups', - list: InventoryGroups, - url: $scope.inventory.related.root_groups - }); - - PaginateInit({ - scope: $scope, - list: InventoryGroups , - url: $scope.inventory.related.root_groups, - pageSize: rows - }); - - $scope.search(InventoryGroups.iterator, null, true); - - $scope.$emit('WatchUpdateStatus'); // init socket io conneciton and start watching for status updates - }); - - if ($scope.removePostRefresh) { - $scope.removePostRefresh(); - } - $scope.removePostRefresh = $scope.$on('PostRefresh', function(e, set) { - if (set === 'groups') { - $scope.groups.forEach( function(group, idx) { - var stat, hosts_status; - stat = GetSyncStatusMsg({ - status: group.summary_fields.inventory_source.status, - has_inventory_sources: group.has_inventory_sources, - source: ( (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null ) - }); // from helpers/Groups.js - $scope.groups[idx].status_class = stat['class']; - $scope.groups[idx].status_tooltip = stat.tooltip; - $scope.groups[idx].launch_tooltip = stat.launch_tip; - $scope.groups[idx].launch_class = stat.launch_class; - hosts_status = GetHostsStatusMsg({ - active_failures: group.hosts_with_active_failures, - total_hosts: group.total_hosts, - inventory_id: $scope.inventory.id, - group_id: group.id - }); // from helpers/Groups.js - $scope.groups[idx].hosts_status_tip = hosts_status.tooltip; - $scope.groups[idx].show_failures = hosts_status.failures; - $scope.groups[idx].hosts_status_class = hosts_status['class']; - - $scope.groups[idx].source = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null; - $scope.groups[idx].status = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.status : null; - - }); - if ($scope.refreshHostsOnGroupRefresh) { - $scope.refreshHostsOnGroupRefresh = false; - HostsReload({ - scope: hostScope, - group_id: $scope.selected_group_id, - inventory_id: $scope.inventory.id, - pageSize: hostScope.host_page_size - }); - } - else { - Wait('stop'); - } - } - }); - - // Load Inventory - url = GetBasePath('inventory') + $stateParams.inventory_id + '/'; - Rest.setUrl(url); - Rest.get() - .success(function (data) { - $scope.inventory = data; - $scope.$emit('InventoryLoaded'); - }) - .error(function (data, status) { - ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve inventory: ' + $stateParams.inventory_id + - ' GET returned status: ' + status }); - }); - - // start watching for real-time updates - if ($rootScope.removeWatchUpdateStatus) { - $rootScope.removeWatchUpdateStatus(); - } - $rootScope.removeWatchUpdateStatus = $rootScope.$on('JobStatusChange-inventory', function(e, data) { - var stat, group; - if (data.group_id) { - group = Find({ list: $scope.groups, key: 'id', val: data.group_id }); - if (data.status === "failed" || data.status === "successful") { - if (data.group_id === $scope.selected_group_id || group) { - // job completed, fefresh all groups - $log.debug('Update completed. Refreshing the tree.'); - $scope.refreshGroups(); - } - } - else if (group) { - // incremental update, just update - $log.debug('Status of group: ' + data.group_id + ' changed to: ' + data.status); - stat = GetSyncStatusMsg({ - status: data.status, - has_inventory_sources: group.has_inventory_sources, - source: group.source - }); - $log.debug('changing tooltip to: ' + stat.tooltip); - group.status = data.status; - group.status_class = stat['class']; - group.status_tooltip = stat.tooltip; - group.launch_tooltip = stat.launch_tip; - group.launch_class = stat.launch_class; - } - } - }); - - // Load group on selection - function loadGroups(url) { - SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: url }); - PaginateInit({ scope: $scope, list: InventoryGroups , url: url, pageSize: $scope.group_page_size }); - $scope.search(InventoryGroups.iterator, null, true, false, true); - } - - $scope.refreshHosts = function() { - HostsReload({ - scope: hostScope, - group_id: $scope.selected_group_id, - inventory_id: $scope.inventory.id, - pageSize: hostScope.host_page_size - }); - }; - - $scope.refreshGroups = function() { - $scope.refreshHostsOnGroupRefresh = true; - $scope.search(InventoryGroups.iterator, null, true, false, true); - }; - - $scope.restoreSearch = function() { - // Restore search params and related stuff, plus refresh - // groups and hosts lists - SearchInit({ - scope: $scope, - set: PreviousSearchParams.set, - list: PreviousSearchParams.list, - url: PreviousSearchParams.defaultUrl, - iterator: PreviousSearchParams.iterator, - sort_order: PreviousSearchParams.sort_order, - setWidgets: false - }); - $scope.refreshHostsOnGroupRefresh = true; - $scope.search(InventoryGroups.iterator, null, true, false, true); - }; - - $scope.groupSelect = function(id) { - var groups = [], group = Find({ list: $scope.groups, key: 'id', val: id }); - if($state.params.groups){ - groups.push($state.params.groups); - } - groups.push(group.id); - groups = groups.join(); - $state.transitionTo('inventoryManage', {inventory_id: $state.params.inventory_id, groups: groups}, { notify: false }); - loadGroups(group.related.children, group.id); - }; - - $scope.createGroup = function () { - PreviousSearchParams = Store('group_current_search_params'); - GroupsEdit({ - scope: $scope, - inventory_id: $scope.inventory.id, - group_id: $scope.selected_group_id, - mode: 'add' - }); - }; - - $scope.editGroup = function (id) { - PreviousSearchParams = Store('group_current_search_params'); - GroupsEdit({ - scope: $scope, - inventory_id: $scope.inventory.id, - group_id: id, - mode: 'edit' - }); - }; - - // Launch inventory sync - $scope.updateGroup = function (id) { - var group = Find({ list: $scope.groups, key: 'id', val: id }); - if (group) { - if (Empty(group.source)) { - // if no source, do nothing. - } else if (group.status === 'updating') { - Alert('Update in Progress', 'The inventory update process is currently running for group ' + - group.name + ' Click the button to monitor the status.', 'alert-info', null, null, null, null, true); - } else { - Wait('start'); - Rest.setUrl(group.related.inventory_source); - Rest.get() - .success(function (data) { - InventoryUpdate({ - scope: $scope, - url: data.related.update, - group_name: data.summary_fields.group.name, - group_source: data.source, - group_id: group.id, - }); - }) - .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 }); - }); - } - } - }; - - $scope.cancelUpdate = function (id) { - GroupsCancelUpdate({ scope: $scope, id: id }); - }; - - $scope.viewUpdateStatus = function (id) { - ViewUpdateStatus({ - scope: $scope, - group_id: id - }); - }; - - $scope.copyGroup = function(id) { - PreviousSearchParams = Store('group_current_search_params'); - GroupsCopy({ - scope: $scope, - group_id: id - }); - }; - - $scope.deleteGroup = function (id) { - GroupsDelete({ - scope: $scope, - group_id: id, - inventory_id: $scope.inventory.id - }); - }; - - $scope.editInventoryProperties = function () { - // EditInventoryProperties({ scope: $scope, inventory_id: $scope.inventory.id }); - $location.path('/inventories/' + $scope.inventory.id + '/'); - }; - - hostScope.createHost = function () { - HostsEdit({ - host_scope: hostScope, - group_scope: $scope, - mode: 'add', - host_id: null, - selected_group_id: $scope.selected_group_id, - inventory_id: $scope.inventory.id - }); - }; - - hostScope.editHost = function (host_id) { - HostsEdit({ - host_scope: hostScope, - group_scope: $scope, - mode: 'edit', - host_id: host_id, - inventory_id: $scope.inventory.id - }); - }; - - hostScope.deleteHost = function (host_id, host_name) { - HostsDelete({ - parent_scope: $scope, - host_scope: hostScope, - host_id: host_id, - host_name: host_name - }); - }; - - hostScope.copyHost = function(id) { - PreviousSearchParams = Store('group_current_search_params'); - HostsCopy({ - group_scope: $scope, - host_scope: hostScope, - host_id: id - }); - }; - - /*hostScope.restoreSearch = function() { - SearchInit({ - scope: hostScope, - set: PreviousSearchParams.set, - list: PreviousSearchParams.list, - url: PreviousSearchParams.defaultUrl, - iterator: PreviousSearchParams.iterator, - sort_order: PreviousSearchParams.sort_order, - setWidgets: false - }); - hostScope.search('host'); - };*/ - - hostScope.toggleHostEnabled = function (host_id, external_source) { - ToggleHostEnabled({ - parent_scope: $scope, - host_scope: hostScope, - host_id: host_id, - external_source: external_source - }); - }; - - hostScope.showJobSummary = function (job_id) { - ShowJobSummary({ - job_id: job_id - }); - }; - - $scope.showGroupHelp = function (params) { - var opts = { - defn: InventoryGroupsHelp - }; - if (params) { - opts.autoShow = params.autoShow || false; - } - HelpDialog(opts); - } -; - $scope.showHosts = function (group_id, show_failures) { - // Clicked on group - if (group_id !== null) { - Wait('start'); - hostScope.show_failures = show_failures; - $scope.groupSelect(group_id); - hostScope.hosts = []; - $scope.show_failures = show_failures; // turn on failed hosts - // filter in hosts view - } else { - Wait('stop'); - } - }; - - if ($scope.removeGroupDeleteCompleted) { - $scope.removeGroupDeleteCompleted(); - } - $scope.removeGroupDeleteCompleted = $scope.$on('GroupDeleteCompleted', - function() { - $scope.refreshGroups(); - } - ); -} - -export default [ - '$log', '$scope', '$rootScope', '$location', - '$state', '$compile', 'generateList', 'ClearScope', 'Empty', 'Wait', - 'Rest', 'Alert', 'GetBasePath', 'ProcessErrors', - 'InventoryGroups', 'InjectHosts', 'Find', 'HostsReload', - 'SearchInit', 'PaginateInit', 'GetSyncStatusMsg', 'GetHostsStatusMsg', - 'GroupsEdit', 'InventoryUpdate', 'GroupsCancelUpdate', 'ViewUpdateStatus', - 'GroupsDelete', 'Store', 'HostsEdit', 'HostsDelete', - 'EditInventoryProperties', 'ToggleHostEnabled', 'ShowJobSummary', - 'InventoryGroupsHelp', 'HelpDialog', 'GroupsCopy', - 'HostsCopy', '$stateParams', InventoriesManage, -]; diff --git a/awx/ui/client/src/inventory/main.js b/awx/ui/client/src/inventory/main.js deleted file mode 100644 index 0689a2d726..0000000000 --- a/awx/ui/client/src/inventory/main.js +++ /dev/null @@ -1,10 +0,0 @@ -/************************************************* - * Copyright (c) 2015 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - - -export default -angular.module('inventory', [ -]) From 66b96ced38d84b9f5a3485ece47523d60dd008d5 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Fri, 18 Mar 2016 10:37:26 -0400 Subject: [PATCH 06/11] Manage hosts directive set up w/ route --- .../manage/inventory-manage.partial.html | 5 +++- awx/ui/client/src/inventories/manage/main.js | 5 ++++ .../manage-groups.controller.html | 0 .../manage-groups.directive.html | 0 .../manage-groups/manage-groups.partial.html | 0 .../manage-hosts/manage-hosts.controller.js | 20 +++++++++++++ .../manage-hosts/manage-hosts.directive.js | 25 ++++++++++++++++ .../manage-hosts/manage-hosts.partial.html | 2 ++ .../manage/manage-hosts/manage-hosts.route.js | 29 +++++++++++++++++++ 9 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 awx/ui/client/src/inventories/manage/manage-groups/manage-groups.controller.html create mode 100644 awx/ui/client/src/inventories/manage/manage-groups/manage-groups.directive.html create mode 100644 awx/ui/client/src/inventories/manage/manage-groups/manage-groups.partial.html create mode 100644 awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.controller.js create mode 100644 awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.directive.js create mode 100644 awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.partial.html create mode 100644 awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.route.js diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.partial.html b/awx/ui/client/src/inventories/manage/inventory-manage.partial.html index ecae801c20..816f2fb040 100644 --- a/awx/ui/client/src/inventories/manage/inventory-manage.partial.html +++ b/awx/ui/client/src/inventories/manage/inventory-manage.partial.html @@ -1,5 +1,8 @@
-
+ +
In the ui view + +
diff --git a/awx/ui/client/src/inventories/manage/main.js b/awx/ui/client/src/inventories/manage/main.js index 7bd839ecc1..14bcb8a5e5 100644 --- a/awx/ui/client/src/inventories/manage/main.js +++ b/awx/ui/client/src/inventories/manage/main.js @@ -7,8 +7,13 @@ import route from './inventory-manage.route'; import controller from './inventory-manage.controller'; +import manageHostsDirective from './manage-hosts/manage-hosts.directive'; +import manageHostsRoute from './manage-hosts/manage-hosts.route'; + export default angular.module('inventoryManage', []) + .directive('manageHosts', manageHostsDirective) .run(['$stateExtender', function($stateExtender) { $stateExtender.addState(route); + $stateExtender.addState(manageHostsRoute); }]); diff --git a/awx/ui/client/src/inventories/manage/manage-groups/manage-groups.controller.html b/awx/ui/client/src/inventories/manage/manage-groups/manage-groups.controller.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/awx/ui/client/src/inventories/manage/manage-groups/manage-groups.directive.html b/awx/ui/client/src/inventories/manage/manage-groups/manage-groups.directive.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/awx/ui/client/src/inventories/manage/manage-groups/manage-groups.partial.html b/awx/ui/client/src/inventories/manage/manage-groups/manage-groups.partial.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.controller.js b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.controller.js new file mode 100644 index 0000000000..01dda998c1 --- /dev/null +++ b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.controller.js @@ -0,0 +1,20 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +function manageHostDirectiveController($q, $rootScope, $scope, $state, + $stateParams, $compile, Rest, ProcessErrors, + CreateDialog, GetBasePath, Wait, GenerateList, GroupList, SearchInit, + PaginateInit, GetRootGroups) { + + var vm = this; + + }; + +export default ['$q', '$rootScope', '$scope', '$state', '$stateParams', + 'ScopePass', '$compile', 'Rest', 'ProcessErrors', 'CreateDialog', + 'GetBasePath', 'Wait', 'generateList', 'GroupList', 'SearchInit', + 'PaginateInit', 'GetRootGroups', manageHostDirectiveController +]; diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.directive.js b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.directive.js new file mode 100644 index 0000000000..531e965ee9 --- /dev/null +++ b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.directive.js @@ -0,0 +1,25 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/* jshint unused: vars */ +import manageHostsController from './manage-hosts.controller'; + +export default ['templateUrl', + function(templateUrl) { + return { + restrict: 'EA', + scope: true, + replace: true, + templateUrl: templateUrl('inventories/manage/manage-hosts/manage-hosts'), + link: function(scope, element, attrs) { + + }, + // controller: manageHostsController, + // controllerAs: 'vm', + // bindToController: true + }; + } +]; diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.partial.html b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.partial.html new file mode 100644 index 0000000000..a8016b0ba6 --- /dev/null +++ b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.partial.html @@ -0,0 +1,2 @@ +
This is the manage hosts directive. +
diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.route.js b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.route.js new file mode 100644 index 0000000000..c8de0182be --- /dev/null +++ b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.route.js @@ -0,0 +1,29 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import { + templateUrl +} from '../../../shared/template-url/template-url.factory'; + +export default { + name: 'inventoryManage.manageHosts', + route: '/managehosts', + template: 'SOMETHING', + + // data: { + // activityStream: true, + // activityStreamTarget: 'inventory', + // activityStreamId: 'inventory_id' + // }, + // ncyBreadcrumb: { + // label: "INVENTORY MANAGE" + // }, + // resolve: { + // features: ['FeaturesService', function(FeaturesService) { + // return FeaturesService.get(); + // }] + // }, +}; From 632f3ca56781931e112ebac430ca6a0549ca6ba3 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Fri, 18 Mar 2016 15:22:41 -0400 Subject: [PATCH 07/11] More route work and directive --- awx/ui/client/src/helpers/Hosts.js | 8 ++++--- .../manage/inventory-manage.partial.html | 5 ++--- awx/ui/client/src/inventories/manage/main.js | 10 ++++----- .../inventories/manage/manage-hosts/main.js | 13 +++++++++++ .../manage-hosts/manage-hosts.controller.js | 12 +++++----- .../manage-hosts/manage-hosts.directive.js | 6 ++--- .../manage/manage-hosts/manage-hosts.route.js | 22 +++++++++++++------ awx/ui/client/src/shared/Utilities.js | 18 ++++++++++++++- 8 files changed, 67 insertions(+), 27 deletions(-) create mode 100644 awx/ui/client/src/inventories/manage/manage-hosts/main.js diff --git a/awx/ui/client/src/helpers/Hosts.js b/awx/ui/client/src/helpers/Hosts.js index f55b1199d2..1e4e22bec7 100644 --- a/awx/ui/client/src/helpers/Hosts.js +++ b/awx/ui/client/src/helpers/Hosts.js @@ -437,12 +437,14 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', listGenerator.name, .factory('HostsEdit', ['$rootScope', '$location', '$log', '$stateParams', 'Rest', 'Alert', 'HostForm', 'GenerateForm', 'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', 'Find', 'SetStatus', 'ApplyEllipsis', - 'ToJSON', 'ParseVariableString', 'CreateDialog', 'TextareaResize', + 'ToJSON', 'ParseVariableString', 'CreateDialog', 'TextareaResize', 'ScopePass', function($rootScope, $location, $log, $stateParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors, GetBasePath, HostsReload, ParseTypeChange, Wait, Find, SetStatus, ApplyEllipsis, ToJSON, - ParseVariableString, CreateDialog, TextareaResize) { + ParseVariableString, CreateDialog, TextareaResize, ScopePass) { return function(params) { - + ScopePass.set(params); + var passing = ScopePass.get(); + console.info(passing); var parent_scope = params.host_scope, group_scope = params.group_scope, host_id = params.host_id, diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.partial.html b/awx/ui/client/src/inventories/manage/inventory-manage.partial.html index 816f2fb040..c04eb31552 100644 --- a/awx/ui/client/src/inventories/manage/inventory-manage.partial.html +++ b/awx/ui/client/src/inventories/manage/inventory-manage.partial.html @@ -1,7 +1,6 @@
- -
In the ui view - +
+
diff --git a/awx/ui/client/src/inventories/manage/main.js b/awx/ui/client/src/inventories/manage/main.js index 14bcb8a5e5..c33658777f 100644 --- a/awx/ui/client/src/inventories/manage/main.js +++ b/awx/ui/client/src/inventories/manage/main.js @@ -11,9 +11,9 @@ import manageHostsDirective from './manage-hosts/manage-hosts.directive'; import manageHostsRoute from './manage-hosts/manage-hosts.route'; export default - angular.module('inventoryManage', []) +angular.module('inventoryManage', []) .directive('manageHosts', manageHostsDirective) - .run(['$stateExtender', function($stateExtender) { - $stateExtender.addState(route); - $stateExtender.addState(manageHostsRoute); - }]); + .run(['$stateExtender', function($stateExtender) { + $stateExtender.addState(route); + $stateExtender.addState(manageHostsRoute); + }]); diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/main.js b/awx/ui/client/src/inventories/manage/manage-hosts/main.js new file mode 100644 index 0000000000..3815d1bc98 --- /dev/null +++ b/awx/ui/client/src/inventories/manage/manage-hosts/main.js @@ -0,0 +1,13 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import route from './manage-hosts.route'; + +export default + angular.module('manageHosts', []) + .run(['$stateExtender', function($stateExtender) { + $stateExtender.addState(route); + }]); diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.controller.js b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.controller.js index 01dda998c1..3f38abfaaf 100644 --- a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.controller.js +++ b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.controller.js @@ -5,16 +5,18 @@ *************************************************/ function manageHostDirectiveController($q, $rootScope, $scope, $state, - $stateParams, $compile, Rest, ProcessErrors, + $stateParams, $compile, ScopePass, Rest, ProcessErrors, CreateDialog, GetBasePath, Wait, GenerateList, GroupList, SearchInit, PaginateInit, GetRootGroups) { - var vm = this; + var vm = this; + console.info(ScopePass); - }; +}; export default ['$q', '$rootScope', '$scope', '$state', '$stateParams', - 'ScopePass', '$compile', 'Rest', 'ProcessErrors', 'CreateDialog', + 'ScopePass', '$compile', 'ScopePass', 'Rest', 'ProcessErrors', 'CreateDialog', 'GetBasePath', 'Wait', 'generateList', 'GroupList', 'SearchInit', - 'PaginateInit', 'GetRootGroups', manageHostDirectiveController + 'PaginateInit', 'GetRootGroups', + manageHostDirectiveController ]; diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.directive.js b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.directive.js index 531e965ee9..734d043019 100644 --- a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.directive.js +++ b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.directive.js @@ -17,9 +17,9 @@ export default ['templateUrl', link: function(scope, element, attrs) { }, - // controller: manageHostsController, - // controllerAs: 'vm', - // bindToController: true + controller: manageHostsController, + controllerAs: 'vm', + bindToController: true }; } ]; diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.route.js b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.route.js index c8de0182be..ec9679fccb 100644 --- a/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.route.js +++ b/awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.route.js @@ -4,23 +4,31 @@ * All Rights Reserved *************************************************/ -import { - templateUrl -} from '../../../shared/template-url/template-url.factory'; +// import { +// templateUrl +// } from '../../../shared/template-url/template-url.factory'; + +import manageHostDirectiveController from './manage-hosts.controller' export default { name: 'inventoryManage.manageHosts', route: '/managehosts', - template: 'SOMETHING', + //template: '
SOMETHING
', + views: { + "manage@inventoryManage" : { + template: '
the template from route
' + } + }, // data: { // activityStream: true, // activityStreamTarget: 'inventory', // activityStreamId: 'inventory_id' // }, - // ncyBreadcrumb: { - // label: "INVENTORY MANAGE" - // }, + ncyBreadcrumb: { + label: "INVENTORY MANAGE" + }, + controller: manageHostDirectiveController, // resolve: { // features: ['FeaturesService', function(FeaturesService) { // return FeaturesService.get(); diff --git a/awx/ui/client/src/shared/Utilities.js b/awx/ui/client/src/shared/Utilities.js index 434526cd7d..3190bb775e 100644 --- a/awx/ui/client/src/shared/Utilities.js +++ b/awx/ui/client/src/shared/Utilities.js @@ -871,4 +871,20 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter']) }; } -]); +]) +.factory('ScopePass', function() { + var savedData = {} + + function set(data) { + savedData = data; + } + + function get() { + return savedData; + } + + return { + set: set, + get: get + } +}); From d6c13043bd2e14eca04cfd2a1166c75ac31e1b05 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Mon, 21 Mar 2016 09:11:02 -0400 Subject: [PATCH 08/11] Inventory modularization, manage inventory groups/hosts Hosts mostly working, groups directive scaffold in place, rerouting. Groups edit mostly working. Source populating in group edit. Pre cleanup. Cleanup and fresh routing fixed. --- awx/ui/client/src/helpers/Hosts.js | 8 +- .../manage/inventory-manage.controller.js | 56 +- .../manage/inventory-manage.partial.html | 7 +- awx/ui/client/src/inventories/manage/main.js | 12 +- .../manage-groups.directive.controller.js | 540 ++++++++++++++++++ .../directive/manage-groups.directive.js | 25 + .../manage-groups.directive.partial.html | 18 + .../inventories/manage/manage-groups/main.js | 16 + .../manage-groups.controller.html | 0 .../manage-groups.directive.html | 0 .../manage-groups/manage-groups.partial.html | 5 + .../manage-groups/manage-groups.route.js | 46 ++ .../manage-hosts.directive.controller.js | 186 ++++++ .../{ => directive}/manage-hosts.directive.js | 14 +- .../manage-hosts.directive.partial.html | 17 + .../inventories/manage/manage-hosts/main.js | 7 +- .../manage-hosts/manage-hosts.controller.js | 22 - .../manage-hosts/manage-hosts.partial.html | 7 +- .../manage/manage-hosts/manage-hosts.route.js | 59 +- .../src/inventories/manage/manage.block.less | 6 + awx/ui/client/src/shared/Utilities.js | 6 +- awx/ui/client/src/shared/form-generator.js | 15 +- 22 files changed, 979 insertions(+), 93 deletions(-) create mode 100644 awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.controller.js create mode 100644 awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.js create mode 100644 awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.partial.html create mode 100644 awx/ui/client/src/inventories/manage/manage-groups/main.js delete mode 100644 awx/ui/client/src/inventories/manage/manage-groups/manage-groups.controller.html delete mode 100644 awx/ui/client/src/inventories/manage/manage-groups/manage-groups.directive.html create mode 100644 awx/ui/client/src/inventories/manage/manage-groups/manage-groups.route.js create mode 100644 awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js rename awx/ui/client/src/inventories/manage/manage-hosts/{ => directive}/manage-hosts.directive.js (57%) create mode 100644 awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.partial.html delete mode 100644 awx/ui/client/src/inventories/manage/manage-hosts/manage-hosts.controller.js create mode 100644 awx/ui/client/src/inventories/manage/manage.block.less diff --git a/awx/ui/client/src/helpers/Hosts.js b/awx/ui/client/src/helpers/Hosts.js index 1e4e22bec7..6a7b864e02 100644 --- a/awx/ui/client/src/helpers/Hosts.js +++ b/awx/ui/client/src/helpers/Hosts.js @@ -437,14 +437,12 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', listGenerator.name, .factory('HostsEdit', ['$rootScope', '$location', '$log', '$stateParams', 'Rest', 'Alert', 'HostForm', 'GenerateForm', 'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', 'Find', 'SetStatus', 'ApplyEllipsis', - 'ToJSON', 'ParseVariableString', 'CreateDialog', 'TextareaResize', 'ScopePass', + 'ToJSON', 'ParseVariableString', 'CreateDialog', 'TextareaResize', 'ParamPass', function($rootScope, $location, $log, $stateParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors, GetBasePath, HostsReload, ParseTypeChange, Wait, Find, SetStatus, ApplyEllipsis, ToJSON, - ParseVariableString, CreateDialog, TextareaResize, ScopePass) { + ParseVariableString, CreateDialog, TextareaResize, ParamPass) { return function(params) { - ScopePass.set(params); - var passing = ScopePass.get(); - console.info(passing); + var parent_scope = params.host_scope, group_scope = params.group_scope, host_id = params.host_id, diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js index 58c50dfbe2..a5c215bb0a 100644 --- a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js +++ b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js @@ -18,7 +18,7 @@ function InventoriesManage($log, $scope, $rootScope, $location, ViewUpdateStatus, GroupsDelete, Store, HostsEdit, HostsDelete, EditInventoryProperties, ToggleHostEnabled, ShowJobSummary, InventoryGroupsHelp, HelpDialog, - GroupsCopy, HostsCopy, $stateParams) { + GroupsCopy, HostsCopy, $stateParams, ParamPass) { var PreviousSearchParams, url, @@ -335,22 +335,38 @@ function InventoriesManage($log, $scope, $rootScope, $location, $scope.createGroup = function () { PreviousSearchParams = Store('group_current_search_params'); - GroupsEdit({ + // GroupsEdit({ + // scope: $scope, + // inventory_id: $scope.inventory.id, + // group_id: $scope.selected_group_id, + // mode: 'add' + // }); + var params = { scope: $scope, inventory_id: $scope.inventory.id, group_id: $scope.selected_group_id, mode: 'add' - }); + } + ParamPass.set(params); + $state.go('inventoryManage.addGroup'); }; $scope.editGroup = function (id) { PreviousSearchParams = Store('group_current_search_params'); - GroupsEdit({ + // GroupsEdit({ + // scope: $scope, + // inventory_id: $scope.inventory.id, + // group_id: id, + // mode: 'edit' + // }); + var params = { scope: $scope, inventory_id: $scope.inventory.id, group_id: id, mode: 'edit' - }); + } + ParamPass.set(params); + $state.go('inventoryManage.editGroup', {group_id: id}); }; // Launch inventory sync @@ -416,24 +432,44 @@ function InventoriesManage($log, $scope, $rootScope, $location, }; hostScope.createHost = function () { - HostsEdit({ + // HostsEdit({ + // host_scope: hostScope, + // group_scope: $scope, + // mode: 'add', + // host_id: null, + // selected_group_id: $scope.selected_group_id, + // inventory_id: $scope.inventory.id + // }); + + var params = { host_scope: hostScope, group_scope: $scope, mode: 'add', host_id: null, selected_group_id: $scope.selected_group_id, inventory_id: $scope.inventory.id - }); + } + ParamPass.set(params); + $state.go('inventoryManage.addHost'); }; hostScope.editHost = function (host_id) { - HostsEdit({ + // HostsEdit({ + // host_scope: hostScope, + // group_scope: $scope, + // mode: 'edit', + // host_id: host_id, + // inventory_id: $scope.inventory.id + // }); + var params = { host_scope: hostScope, group_scope: $scope, mode: 'edit', host_id: host_id, inventory_id: $scope.inventory.id - }); + } + ParamPass.set(params); + $state.go('inventoryManage.editHost', {host_id: host_id}); }; hostScope.deleteHost = function (host_id, host_name) { @@ -526,5 +562,5 @@ export default [ 'GroupsDelete', 'Store', 'HostsEdit', 'HostsDelete', 'EditInventoryProperties', 'ToggleHostEnabled', 'ShowJobSummary', 'InventoryGroupsHelp', 'HelpDialog', 'GroupsCopy', - 'HostsCopy', '$stateParams', InventoriesManage, + 'HostsCopy', '$stateParams', 'ParamPass', InventoriesManage, ]; diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.partial.html b/awx/ui/client/src/inventories/manage/inventory-manage.partial.html index c04eb31552..f465ef47c0 100644 --- a/awx/ui/client/src/inventories/manage/inventory-manage.partial.html +++ b/awx/ui/client/src/inventories/manage/inventory-manage.partial.html @@ -1,7 +1,5 @@
-
- -
+
@@ -12,9 +10,6 @@
- -
- \n"; //end of Form-header - html += "
"; - html += "
\n"; - html += "
\n"; //end of Form-header if (this.form.tabs) { var collection; From 23ae408e567159c879a52fecb2dfd0e5f4585f10 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Wed, 23 Mar 2016 15:40:21 -0400 Subject: [PATCH 09/11] Fixed merge wonkiness, added back in groups query string to route --- awx/ui/client/src/app.js | 71 ++----------------- .../manage/inventory-manage.route.js | 2 +- 2 files changed, 5 insertions(+), 68 deletions(-) diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index aabeec0f4c..ffe729895f 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -55,10 +55,10 @@ import {ProjectsList, ProjectsAdd, ProjectsEdit} from './controllers/Projects'; import OrganizationsList from './organizations/list/organizations-list.controller'; import OrganizationsAdd from './organizations/add/organizations-add.controller'; import OrganizationsEdit from './organizations/edit/organizations-edit.controller'; -import InventoriesAdd from './inventory/inventory-add.controller'; -import InventoriesEdit from './inventory/inventory-edit.controller'; -import InventoriesList from './inventory/inventory-list.controller'; -import InventoriesManage from './inventory/inventory-manage.controller'; +import InventoriesAdd from './inventories/add/inventory-add.controller'; +import InventoriesEdit from './inventories/edit/inventory-edit.controller'; +import InventoriesList from './inventories/list/inventory-list.controller'; +import InventoriesManage from './inventories/manage/inventory-manage.controller'; import {AdminsList} from './controllers/Admins'; import {UsersList, UsersAdd, UsersEdit} from './controllers/Users'; import {TeamsList, TeamsAdd, TeamsEdit} from './controllers/Teams'; @@ -373,69 +373,6 @@ var tower = angular.module('Tower', [ } }). - state('inventories', { - url: '/inventories', - templateUrl: urlPrefix + 'partials/inventories.html', - controller: InventoriesList, - data: { - activityStream: true, - activityStreamTarget: 'inventory' - }, - ncyBreadcrumb: { - label: "INVENTORIES" - }, - resolve: { - features: ['FeaturesService', function(FeaturesService) { - return FeaturesService.get(); - }] - } - }). - - state('inventories.add', { - url: '/add', - templateUrl: urlPrefix + 'partials/inventories.html', - controller: InventoriesAdd, - ncyBreadcrumb: { - parent: "inventories", - label: "CREATE INVENTORY" - }, - resolve: { - features: ['FeaturesService', function(FeaturesService) { - return FeaturesService.get(); - }] - } - }). - - state('inventories.edit', { - url: '/:inventory_id', - templateUrl: urlPrefix + 'partials/inventories.html', - controller: InventoriesEdit, - data: { - activityStreamId: 'inventory_id' - }, - resolve: { - features: ['FeaturesService', function(FeaturesService) { - return FeaturesService.get(); - }] - } - }). - - state('inventoryManage', { - url: '/inventories/:inventory_id/manage?groups', - templateUrl: urlPrefix + 'partials/inventory-manage.html', - controller: InventoriesManage, - data: { - activityStream: true, - activityStreamTarget: 'inventory', - activityStreamId: 'inventory_id' - }, - resolve: { - features: ['FeaturesService', function(FeaturesService) { - return FeaturesService.get(); - }] - } - }). - state('organizationAdmins', { url: '/organizations/:organization_id/admins', templateUrl: urlPrefix + 'partials/organizations.html', diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.route.js b/awx/ui/client/src/inventories/manage/inventory-manage.route.js index 1cfc9176ac..62306cd91b 100644 --- a/awx/ui/client/src/inventories/manage/inventory-manage.route.js +++ b/awx/ui/client/src/inventories/manage/inventory-manage.route.js @@ -9,7 +9,7 @@ import InventoriesManage from './inventory-manage.controller'; export default { name: 'inventoryManage', - route: '/inventories/:inventory_id/manage', + url: '/inventories/:inventory_id/manage?groups', templateUrl: templateUrl('inventories/manage/inventory-manage'), controller: InventoriesManage, data: { From 66bab4fcf2aeffba0e7cde37a110c10a50085c8b Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Mon, 28 Mar 2016 11:04:01 -0400 Subject: [PATCH 10/11] Visual updates. Added in Create Host title. --- .../manage-groups.directive.partial.html | 10 +++--- .../manage-hosts.directive.controller.js | 7 ++-- .../manage-hosts.directive.partial.html | 36 +++++++++++-------- .../src/inventories/manage/manage.block.less | 6 ++++ 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.partial.html b/awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.partial.html index 86368afbe4..eacbf795c9 100644 --- a/awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.partial.html +++ b/awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.partial.html @@ -4,14 +4,16 @@
-
-
-
+
+
+
+
+
-
diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js b/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js index 1fdf0d157a..5fde6e3991 100644 --- a/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js +++ b/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js @@ -41,7 +41,7 @@ function manageHostsDirectiveController($rootScope, $location, $log, $stateParam }); generator.reset(); - var name = scope.name; + scope.parseType = 'yaml'; // Retrieve detail record and prepopulate the form @@ -68,7 +68,6 @@ function manageHostsDirectiveController($rootScope, $location, $log, $stateParam } scope.variable_url = data.related.variable_data; scope.has_inventory_sources = data.has_inventory_sources; - //scope.$emit('hostVariablesLoaded'); }) .error(function(data, status) { ProcessErrors(parent_scope, data, status, form, { @@ -172,10 +171,12 @@ function manageHostsDirectiveController($rootScope, $location, $log, $stateParam $state.go('inventoryManage'); }; + + angular.extend(vm, { cancelPanel: cancelPanel, - name: name, saveHost: saveHost, + mode: mode }); } diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.partial.html b/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.partial.html index 7ebdcbbf8d..31c2249234 100644 --- a/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.partial.html +++ b/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.partial.html @@ -1,17 +1,25 @@
-
- -
-
-
-
-
- - -
+
+
Create Host
+
+ +
+
+
+ +
+ +
+
+
+ +
+
diff --git a/awx/ui/client/src/inventories/manage/manage.block.less b/awx/ui/client/src/inventories/manage/manage.block.less index 46598719be..15b41dfd53 100644 --- a/awx/ui/client/src/inventories/manage/manage.block.less +++ b/awx/ui/client/src/inventories/manage/manage.block.less @@ -3,4 +3,10 @@ border: none; text-align: right; } + + #host-panel-form, #properties-tab { + .Form-header { + margin-top: -20px; + } + } } From ed0770b7073b75f1c9999b9978a20ecfd068a6e1 Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Thu, 31 Mar 2016 10:32:04 -0400 Subject: [PATCH 11/11] Updates based on PR feedback. --- awx/ui/client/src/app.js | 5 +-- .../add/inventory-add.controller.js | 3 -- .../edit/inventory-edit.controller.js | 3 -- .../list/inventory-list.controller.js | 9 +--- .../manage/inventory-manage.controller.js | 41 ------------------- .../manage-groups.directive.controller.js | 12 +++++- .../manage-hosts.directive.controller.js | 11 +++-- .../src/inventories/manage/manage.block.less | 26 +++++++----- 8 files changed, 38 insertions(+), 72 deletions(-) diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index ffe729895f..d6c09b439a 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -55,10 +55,7 @@ import {ProjectsList, ProjectsAdd, ProjectsEdit} from './controllers/Projects'; import OrganizationsList from './organizations/list/organizations-list.controller'; import OrganizationsAdd from './organizations/add/organizations-add.controller'; import OrganizationsEdit from './organizations/edit/organizations-edit.controller'; -import InventoriesAdd from './inventories/add/inventory-add.controller'; -import InventoriesEdit from './inventories/edit/inventory-edit.controller'; -import InventoriesList from './inventories/list/inventory-list.controller'; -import InventoriesManage from './inventories/manage/inventory-manage.controller'; +import {InventoriesAdd, InventoriesEdit, InventoriesList, InventoriesManage} from './inventories/main'; import {AdminsList} from './controllers/Admins'; import {UsersList, UsersAdd, UsersEdit} from './controllers/Users'; import {TeamsList, TeamsAdd, TeamsEdit} from './controllers/Teams'; 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 befcc1d14e..bd3cde3041 100644 --- a/awx/ui/client/src/inventories/add/inventory-add.controller.js +++ b/awx/ui/client/src/inventories/add/inventory-add.controller.js @@ -10,8 +10,6 @@ * @description This controller's for the Inventory page */ -import '../../job-templates/main'; - function InventoriesAdd($scope, $rootScope, $compile, $location, $log, $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, @@ -25,7 +23,6 @@ function InventoriesAdd($scope, $rootScope, $compile, $location, $log, form = InventoryForm(), generator = GenerateForm; - form.well = true; form.formLabelSize = null; form.formFieldSize = null; 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 3876f67c20..f7cb6f2601 100644 --- a/awx/ui/client/src/inventories/edit/inventory-edit.controller.js +++ b/awx/ui/client/src/inventories/edit/inventory-edit.controller.js @@ -10,8 +10,6 @@ * @description This controller's for the Inventory page */ -import '../../job-templates/main'; - function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $stateParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, @@ -30,7 +28,6 @@ function InventoriesEdit($scope, $rootScope, $compile, $location, fld, json_data, data, relatedSets = {}; - form.well = true; form.formLabelSize = null; form.formFieldSize = null; $scope.inventory_id = inventory_id; 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 a55529491c..947b1c0341 100644 --- a/awx/ui/client/src/inventories/list/inventory-list.controller.js +++ b/awx/ui/client/src/inventories/list/inventory-list.controller.js @@ -14,7 +14,7 @@ function InventoriesList($scope, $rootScope, $location, $log, $stateParams, $compile, $filter, sanitizeFilter, Rest, Alert, InventoryList, generateList, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, Wait, - EditInventoryProperties, Find, Empty, $state) { + Find, Empty, $state) { var list = InventoryList, defaultUrl = GetBasePath('inventory'), @@ -301,10 +301,6 @@ function InventoriesList($scope, $rootScope, $location, $log, }; - $scope.editInventoryProperties = function (inventory_id) { - EditInventoryProperties({ scope: $scope, inventory_id: inventory_id }); - }; - $scope.addInventory = function () { $state.go('inventories.add'); }; @@ -365,5 +361,4 @@ function InventoriesList($scope, $rootScope, $location, $log, export default ['$scope', '$rootScope', '$location', '$log', '$stateParams', '$compile', '$filter', 'sanitizeFilter', 'Rest', 'Alert', 'InventoryList', 'generateList', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', - 'ClearScope', 'ProcessErrors', 'GetBasePath', 'Wait', - 'EditInventoryProperties', 'Find', 'Empty', '$state', InventoriesList]; + 'ClearScope', 'ProcessErrors', 'GetBasePath', 'Wait', 'Find', 'Empty', '$state', InventoriesList]; diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js index a5c215bb0a..508a74d4c2 100644 --- a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js +++ b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js @@ -335,12 +335,6 @@ function InventoriesManage($log, $scope, $rootScope, $location, $scope.createGroup = function () { PreviousSearchParams = Store('group_current_search_params'); - // GroupsEdit({ - // scope: $scope, - // inventory_id: $scope.inventory.id, - // group_id: $scope.selected_group_id, - // mode: 'add' - // }); var params = { scope: $scope, inventory_id: $scope.inventory.id, @@ -353,12 +347,6 @@ function InventoriesManage($log, $scope, $rootScope, $location, $scope.editGroup = function (id) { PreviousSearchParams = Store('group_current_search_params'); - // GroupsEdit({ - // scope: $scope, - // inventory_id: $scope.inventory.id, - // group_id: id, - // mode: 'edit' - // }); var params = { scope: $scope, inventory_id: $scope.inventory.id, @@ -432,15 +420,6 @@ function InventoriesManage($log, $scope, $rootScope, $location, }; hostScope.createHost = function () { - // HostsEdit({ - // host_scope: hostScope, - // group_scope: $scope, - // mode: 'add', - // host_id: null, - // selected_group_id: $scope.selected_group_id, - // inventory_id: $scope.inventory.id - // }); - var params = { host_scope: hostScope, group_scope: $scope, @@ -454,13 +433,6 @@ function InventoriesManage($log, $scope, $rootScope, $location, }; hostScope.editHost = function (host_id) { - // HostsEdit({ - // host_scope: hostScope, - // group_scope: $scope, - // mode: 'edit', - // host_id: host_id, - // inventory_id: $scope.inventory.id - // }); var params = { host_scope: hostScope, group_scope: $scope, @@ -490,19 +462,6 @@ function InventoriesManage($log, $scope, $rootScope, $location, }); }; - /*hostScope.restoreSearch = function() { - SearchInit({ - scope: hostScope, - set: PreviousSearchParams.set, - list: PreviousSearchParams.list, - url: PreviousSearchParams.defaultUrl, - iterator: PreviousSearchParams.iterator, - sort_order: PreviousSearchParams.sort_order, - setWidgets: false - }); - hostScope.search('host'); - };*/ - hostScope.toggleHostEnabled = function (host_id, external_source) { ToggleHostEnabled({ parent_scope: $scope, diff --git a/awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.controller.js b/awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.controller.js index 37405a5eab..158d6653ec 100644 --- a/awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.controller.js +++ b/awx/ui/client/src/inventories/manage/manage-groups/directive/manage-groups.directive.controller.js @@ -68,13 +68,15 @@ function manageGroupsDirectiveController($filter, $rootScope, $location, $log, $ elem = document.getElementById('group-manage-panel'); $compile(elem)(modal_scope); + $scope.parseType = 'yaml'; + var form_scope = generator.inject(GroupForm, { mode: mode, id: 'properties-tab', related: false, scope: properties_scope, - cancelButton: false + cancelButton: false, }); var source_form_scope = generator.inject(SourceForm, { @@ -114,6 +116,13 @@ function manageGroupsDirectiveController($filter, $rootScope, $location, $log, $ modal_scope.removeLoadSourceData(); } modal_scope.removeLoadSourceData = modal_scope.$on('LoadSourceData', function() { + ParseTypeChange({ + scope: form_scope, + variable: 'variables', + parse_variable: 'parseType', + field_id: 'group_variables' + }); + if (sources_scope.source_url) { // get source data Rest.setUrl(sources_scope.source_url); @@ -239,6 +248,7 @@ function manageGroupsDirectiveController($filter, $rootScope, $location, $log, $ opts: opts }); } + sources_scope.group_update_url = data.related.update; }) .error(function(data, status) { diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js b/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js index 5fde6e3991..90190143f3 100644 --- a/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js +++ b/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js @@ -40,9 +40,16 @@ function manageHostsDirectiveController($rootScope, $location, $log, $stateParam cancelButton: false }); generator.reset(); + console.info(angular.element(document.getElementById('host_variables'))); + $scope.parseType = 'yaml'; + ParseTypeChange({ + scope: form_scope, + variable: 'variables', + parse_variable: 'parseType', + field_id: 'host_variables' + }); - scope.parseType = 'yaml'; // Retrieve detail record and prepopulate the form if (mode === 'edit') { @@ -171,8 +178,6 @@ function manageHostsDirectiveController($rootScope, $location, $log, $stateParam $state.go('inventoryManage'); }; - - angular.extend(vm, { cancelPanel: cancelPanel, saveHost: saveHost, diff --git a/awx/ui/client/src/inventories/manage/manage.block.less b/awx/ui/client/src/inventories/manage/manage.block.less index 15b41dfd53..772423c2e4 100644 --- a/awx/ui/client/src/inventories/manage/manage.block.less +++ b/awx/ui/client/src/inventories/manage/manage.block.less @@ -1,12 +1,18 @@ -#Inventory-groupManage--panel, #Inventory-hostManage--panel { - .ui-dialog-buttonpane.ui-widget-content { - border: none; - text-align: right; - } +#Inventory-groupManage--panel, +#Inventory-hostManage--panel { + .ui-dialog-buttonpane.ui-widget-content { + border: none; + text-align: right; + } - #host-panel-form, #properties-tab { - .Form-header { - margin-top: -20px; - } - } + #host-panel-form, + #properties-tab { + .Form-header { + margin-top: -20px; + } + } + + .Form-textArea { + width: 100%; + } }