diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 1afc218913..19cf74082c 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -15,12 +15,25 @@ flex-direction: row; } +.Form-textArea{ + width: 100% !important; +} + +.Form-header--fields{ + flex: 1 1 auto; +} + +.Form-header-field{ + margin-left: 10px; + flex: 1 1 auto; +} + .Form-header{ display: flex; } .Form-title{ - flex: 1 0 auto; + flex: 0 1 auto; text-transform: uppercase; color: @list-header-txt; font-size: 14px; diff --git a/awx/ui/client/src/dashboard/hosts/dashboard-hosts-edit.controller.js b/awx/ui/client/src/dashboard/hosts/dashboard-hosts-edit.controller.js index 9cd09d55e5..08abb34cdd 100644 --- a/awx/ui/client/src/dashboard/hosts/dashboard-hosts-edit.controller.js +++ b/awx/ui/client/src/dashboard/hosts/dashboard-hosts-edit.controller.js @@ -5,14 +5,44 @@ *************************************************/ export default - ['$scope', '$state', '$stateParams', 'DashboardHostsForm', 'GenerateForm', 'host', - function($scope, $state, $stateParams, DashboardHostsForm, GenerateForm, host){ + ['$scope', '$state', '$stateParams', 'DashboardHostsForm', 'GenerateForm', 'ParseTypeChange', 'DashboardHostService', 'host', + function($scope, $state, $stateParams, DashboardHostsForm, GenerateForm, ParseTypeChange, DashboardHostService, host){ var generator = GenerateForm, form = DashboardHostsForm; - + $scope.parseType = 'yaml'; + $scope.formCancel = function(){ + $state.go('^', null, {reload: true}); + }; + $scope.toggleHostEnabled = function(){ + $scope.host.enabled = !$scope.host.enabled; + }; + $scope.toggleEnabled = function(){ + $scope.host.enabled = !$scope.host.enabled; + }; + $scope.formSave = function(){ + var host = { + id: $scope.host.id, + variables: $scope.extraVars === '---' || $scope.extraVars === '{}' ? null : $scope.extraVars, + name: $scope.name, + description: $scope.description + }; + DashboardHostService.putHost(host).then(function(res){ + $state.go('^', null, {reload: true}); + }); + + }; var init = function(){ $scope.host = host; - GenerateForm.inject(form, {mode: 'edit', related: false, scope: $scope}); + $scope.extraVars = host.variables === '' ? '---' : host.variables; + generator.inject(form, {mode: 'edit', related: false, scope: $scope}); + $scope.extraVars = $scope.host.variables === '' ? '---' : $scope.host.variables; + $scope.name = host.name; + $scope.description = host.description; + ParseTypeChange({ + scope: $scope, + field_id: 'host_variables', + variable: 'extraVars', + }); }; init(); diff --git a/awx/ui/client/src/dashboard/hosts/dashboard-hosts-list.controller.js b/awx/ui/client/src/dashboard/hosts/dashboard-hosts-list.controller.js index 7e891cd1f2..03398be7e9 100644 --- a/awx/ui/client/src/dashboard/hosts/dashboard-hosts-list.controller.js +++ b/awx/ui/client/src/dashboard/hosts/dashboard-hosts-list.controller.js @@ -5,12 +5,13 @@ *************************************************/ export default - ['$scope', '$state', '$stateParams', 'Rest', 'GetBasePath', 'DashboardHostsList', - 'generateList', 'PaginateInit', 'SetStatus', 'DashboardHostsService', 'hosts', - function($scope, $state, $stateParams, Rest, GetBasePath, DashboardHostsList, GenerateList, PaginateInit, SetStatus, DashboardHostsService, hosts){ + ['$scope', '$state', '$stateParams', 'PageRangeSetup', 'GetBasePath', 'DashboardHostsList', + 'generateList', 'PaginateInit', 'SetStatus', 'DashboardHostService', 'hosts', + function($scope, $state, $stateParams, PageRangeSetup, GetBasePath, DashboardHostsList, GenerateList, PaginateInit, SetStatus, DashboardHostService, hosts){ var generator = GenerateList, list = DashboardHostsList, defaultUrl = GetBasePath('hosts'); + $scope.hostPageSize = 10; $scope.editHost = function(id){ $state.go('dashboardHosts.edit', {id: id}); }; @@ -21,6 +22,14 @@ export default $scope.hosts[index].enabled = res.data.enabled; }); }; + $scope.$on('PostRefresh', function(){ + $scope.hosts = _.map($scope.hosts, function(value, key){ + value.inventory_name = value.summary_fields.inventory.name; + value.inventory_id = value.summary_fields.inventory.id; + return value; + }); + setJobStatus(); + }); var setJobStatus = function(){ _.forEach($scope.hosts, function(value, key){ SetStatus({ @@ -30,19 +39,26 @@ export default }); }; var init = function(){ - $scope.list = list; - $scope.host_active_search = false; - $scope.host_total_rows = hosts.length; - $scope.hosts = hosts; - setJobStatus(); - generator.inject(list, {mode: 'edit', scope: $scope}); - PaginateInit({ - scope: $scope, - list: list, - url: defaultUrl - }); - console.log($scope) - $scope.hostLoading = false; + $scope.list = list; + $scope.host_active_search = false; + $scope.host_total_rows = hosts.results.length; + $scope.hosts = hosts.results; + setJobStatus(); + generator.inject(list, {mode: 'edit', scope: $scope}); + PaginateInit({ + scope: $scope, + list: list, + url: defaultUrl, + pageSize: 10 + }); + PageRangeSetup({ + scope: $scope, + count: hosts.count, + next: hosts.next, + previous: hosts.previous, + iterator: list.iterator + }); + $scope.hostLoading = false; }; init(); }]; \ No newline at end of file diff --git a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.form.js b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.form.js index 78a895953d..654e76a13e 100644 --- a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.form.js +++ b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.form.js @@ -11,36 +11,34 @@ export default function(){ well: true, formLabelSize: 'col-lg-3', formFieldSize: 'col-lg-9', + iterator: 'host', headerFields:{ enabled: { - label: 'Enabled?', - type: 'checkbox', + //flag: 'host.enabled', + class: 'Form-header-field', + ngClick: 'toggleHostEnabled()', + type: 'toggle', editRequired: false, - 'default': true, - awPopOver: "

Indicates if a host is available and should be included in running jobs.

For hosts that " + + awToolTip: "

Indicates if a host is available and should be included in running jobs.

For hosts that " + "are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.

", - dataTitle: 'Host Enabled' + dataTitle: 'Host Enabled' } }, fields: { - enabled: { - label: 'Status', - columnClass: 'List-staticColumn--toggle', - type: 'toggle', - ngClick: 'toggleHostEnabled(host)', - searchable: false, - nosort: true - }, name: { label: 'Host Name', type: 'text', editRequired: true, - awPopOver: "

Provide a host name, ip address, or ip address:port. Examples include:

" + + value: '{{name}}', + awPopOver: "

Provide a host name, ip address, or ip address:port. Examples include:

" + "
myserver.domain.com
" + "127.0.0.1
" + "10.1.0.140:25
" + "server.example.com:25" + "
", + dataTitle: 'Host Name', + dataPlacement: 'right', + dataContainer: 'body' }, description: { label: 'Description', @@ -52,6 +50,10 @@ export default function(){ type: 'textarea', editRequired: false, rows: 6, + class: 'modal-input-xlarge Form-textArea', + dataTitle: 'Host Variables', + dataPlacement: 'right', + dataContainer: 'body', default: '---', awPopOver: "

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

" + "JSON:
\n" + @@ -61,6 +63,15 @@ export default function(){ '

View JSON examples at www.json.org

' + '

View YAML examples at docs.ansible.com

', } + }, + buttons: { + save: { + ngClick: 'formSave()', //$scope.function to call on click, optional + ngDisabled: "host_form.$invalid"//true //Disable when $pristine or $invalid, optional and when can_edit = false, for permission reasons + }, + cancel: { + ngClick: 'formCancel()' + } } - } + }; }; \ No newline at end of file diff --git a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js index aac8f8b330..4731155cbb 100644 --- a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js +++ b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js @@ -54,7 +54,9 @@ export default function(){ type: 'toggle', ngClick: 'toggleHostEnabled(host)', searchable: false, - nosort: true + nosort: true, + awToolTip: "

Indicates if a host is available and should be included in running jobs.

For hosts that are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.

", + dataTitle: 'Host Enabled', }, has_active_failures: { label: 'Has failed jobs?', diff --git a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.route.js b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.route.js index ced2ebfc63..84f31ad981 100644 --- a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.route.js +++ b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.route.js @@ -29,11 +29,13 @@ var dashboardHostsList = { var defaultUrl = GetBasePath('hosts') + '?page_size=10'; Rest.setUrl(defaultUrl); return Rest.get().then(function(res){ - return _.map(res.data.results, function(value, key){ + var results = _.map(res.data.results, function(value, key){ value.inventory_name = value.summary_fields.inventory.name; value.inventory_id = value.summary_fields.inventory.id; return value; }); + res.data.results = results; + return res.data }); }] } diff --git a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.service.js b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.service.js index f85050e060..997167b90a 100644 --- a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.service.js +++ b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.service.js @@ -13,6 +13,18 @@ export default ProcessErrors($rootScope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + '. GET returned: ' + status }); }); + }, + putHost: function(host){ + var url = GetBasePath('hosts') + host.id; + Rest.setUrl(url); + return Rest.put(host) + .success(function(data){ + return data; + }) + .error(function(data, status) { + ProcessErrors($rootScope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + '. GET returned: ' + status }); + }); } }; }]; \ No newline at end of file diff --git a/awx/ui/client/src/dashboard/hosts/main.js b/awx/ui/client/src/dashboard/hosts/main.js index 65f0da2373..7a02e597d0 100644 --- a/awx/ui/client/src/dashboard/hosts/main.js +++ b/awx/ui/client/src/dashboard/hosts/main.js @@ -11,7 +11,7 @@ import service from './dashboard-hosts.service'; export default angular.module('dashboardHosts', []) - .service('DashboardHostsService', service) + .service('DashboardHostService', service) .factory('DashboardHostsList', list) .factory('DashboardHostsForm', form) .run(['$stateExtender', function($stateExtender){ diff --git a/awx/ui/client/src/search/tagSearch.controller.js b/awx/ui/client/src/search/tagSearch.controller.js index a07362bfba..d49e294a5b 100644 --- a/awx/ui/client/src/search/tagSearch.controller.js +++ b/awx/ui/client/src/search/tagSearch.controller.js @@ -1,7 +1,6 @@ export default ['$scope', 'Refresh', 'tagSearchService', function($scope, Refresh, tagSearchService) { // JSONify passed field elements that can be searched - console.log($scope.list) $scope.list = angular.fromJson($scope.list); // Access config lines from list spec $scope.listConfig = $scope.$parent.list; diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js index a446b9991e..574d4ac77c 100644 --- a/awx/ui/client/src/shared/form-generator.js +++ b/awx/ui/client/src/shared/form-generator.js @@ -230,6 +230,11 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat this.scope[fld + '_field'].name = fld; } + for (fld in form.headerFields){ + this.scope[fld + '_field'] = form.headerFields[fld]; + this.scope[fld + '_field'].name = fld; + } + $compile(element)(this.scope); if (!options.html) { @@ -606,9 +611,26 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat return html; }, + buildHeaderField: function(key, field, options, form){ + var html = ''; + // extend these blocks to include elements similarly buildField() + if (field.type === 'toggle'){ + html += "
ON
OFF
"; + } + return html; + }, + buildField: function (fld, field, options, form) { - var i, fldWidth, offset, html = '', horizontal = (this.form.horizontal) ? true : false; @@ -725,6 +747,18 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat return html; } + if (field.type === 'toggle'){ + html += "
ON
OFF
"; + } if (field.type === 'alertblock') { html += "
\n"; @@ -1429,17 +1463,26 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html+= "Admin"; } - html += "
\n"; + html += "\n"; + html += "
"; + if(this.form.headerFields){ + var that = this; + _.forEach(this.form.headerFields, function(value, key){ + html += that.buildHeaderField(key, value, options, that.form); + }); + html += "
\n"; + } + else{ html += "\n"; } if(this.form.cancelButton !== undefined && this.form.cancelButton === false) { html += "
"; - html += "
"; + html += ""; } else { html += "
"; html += "
\n"; } - html += "\n"; //end of Form-header + html += "\n"; //end of Form-header } if (!_.isEmpty(this.form.related)) {