finish dashboard hosts edit, resolves #1598

remove debug line
This commit is contained in:
Leigh Johnson
2016-04-25 13:47:04 -04:00
parent baf8d9ef6f
commit 85698213cb
10 changed files with 172 additions and 44 deletions

View File

@@ -15,12 +15,25 @@
flex-direction: row; 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{ .Form-header{
display: flex; display: flex;
} }
.Form-title{ .Form-title{
flex: 1 0 auto; flex: 0 1 auto;
text-transform: uppercase; text-transform: uppercase;
color: @list-header-txt; color: @list-header-txt;
font-size: 14px; font-size: 14px;

View File

@@ -5,14 +5,44 @@
*************************************************/ *************************************************/
export default export default
['$scope', '$state', '$stateParams', 'DashboardHostsForm', 'GenerateForm', 'host', ['$scope', '$state', '$stateParams', 'DashboardHostsForm', 'GenerateForm', 'ParseTypeChange', 'DashboardHostService', 'host',
function($scope, $state, $stateParams, DashboardHostsForm, GenerateForm, host){ function($scope, $state, $stateParams, DashboardHostsForm, GenerateForm, ParseTypeChange, DashboardHostService, host){
var generator = GenerateForm, var generator = GenerateForm,
form = DashboardHostsForm; 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(){ var init = function(){
$scope.host = host; $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(); init();

View File

@@ -5,12 +5,13 @@
*************************************************/ *************************************************/
export default export default
['$scope', '$state', '$stateParams', 'Rest', 'GetBasePath', 'DashboardHostsList', ['$scope', '$state', '$stateParams', 'PageRangeSetup', 'GetBasePath', 'DashboardHostsList',
'generateList', 'PaginateInit', 'SetStatus', 'DashboardHostsService', 'hosts', 'generateList', 'PaginateInit', 'SetStatus', 'DashboardHostService', 'hosts',
function($scope, $state, $stateParams, Rest, GetBasePath, DashboardHostsList, GenerateList, PaginateInit, SetStatus, DashboardHostsService, hosts){ function($scope, $state, $stateParams, PageRangeSetup, GetBasePath, DashboardHostsList, GenerateList, PaginateInit, SetStatus, DashboardHostService, hosts){
var generator = GenerateList, var generator = GenerateList,
list = DashboardHostsList, list = DashboardHostsList,
defaultUrl = GetBasePath('hosts'); defaultUrl = GetBasePath('hosts');
$scope.hostPageSize = 10;
$scope.editHost = function(id){ $scope.editHost = function(id){
$state.go('dashboardHosts.edit', {id: id}); $state.go('dashboardHosts.edit', {id: id});
}; };
@@ -21,6 +22,14 @@ export default
$scope.hosts[index].enabled = res.data.enabled; $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(){ var setJobStatus = function(){
_.forEach($scope.hosts, function(value, key){ _.forEach($scope.hosts, function(value, key){
SetStatus({ SetStatus({
@@ -30,19 +39,26 @@ export default
}); });
}; };
var init = function(){ var init = function(){
$scope.list = list; $scope.list = list;
$scope.host_active_search = false; $scope.host_active_search = false;
$scope.host_total_rows = hosts.length; $scope.host_total_rows = hosts.results.length;
$scope.hosts = hosts; $scope.hosts = hosts.results;
setJobStatus(); setJobStatus();
generator.inject(list, {mode: 'edit', scope: $scope}); generator.inject(list, {mode: 'edit', scope: $scope});
PaginateInit({ PaginateInit({
scope: $scope, scope: $scope,
list: list, list: list,
url: defaultUrl url: defaultUrl,
}); pageSize: 10
console.log($scope) });
$scope.hostLoading = false; PageRangeSetup({
scope: $scope,
count: hosts.count,
next: hosts.next,
previous: hosts.previous,
iterator: list.iterator
});
$scope.hostLoading = false;
}; };
init(); init();
}]; }];

View File

@@ -11,36 +11,34 @@ export default function(){
well: true, well: true,
formLabelSize: 'col-lg-3', formLabelSize: 'col-lg-3',
formFieldSize: 'col-lg-9', formFieldSize: 'col-lg-9',
iterator: 'host',
headerFields:{ headerFields:{
enabled: { enabled: {
label: 'Enabled?', //flag: 'host.enabled',
type: 'checkbox', class: 'Form-header-field',
ngClick: 'toggleHostEnabled()',
type: 'toggle',
editRequired: false, editRequired: false,
'default': true, awToolTip: "<p>Indicates if a host is available and should be included in running jobs.</p><p>For hosts that " +
awPopOver: "<p>Indicates if a host is available and should be included in running jobs.</p><p>For hosts that " +
"are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.</p>", "are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.</p>",
dataTitle: 'Host Enabled' dataTitle: 'Host Enabled'
} }
}, },
fields: { fields: {
enabled: {
label: 'Status',
columnClass: 'List-staticColumn--toggle',
type: 'toggle',
ngClick: 'toggleHostEnabled(host)',
searchable: false,
nosort: true
},
name: { name: {
label: 'Host Name', label: 'Host Name',
type: 'text', type: 'text',
editRequired: true, editRequired: true,
awPopOver: "<p>Provide a host name, ip address, or ip address:port. Examples include:</p>" + value: '{{name}}',
awPopOver: "<p>Provide a host name, ip address, or ip address:port. Examples include:</p>" +
"<blockquote>myserver.domain.com<br/>" + "<blockquote>myserver.domain.com<br/>" +
"127.0.0.1<br />" + "127.0.0.1<br />" +
"10.1.0.140:25<br />" + "10.1.0.140:25<br />" +
"server.example.com:25" + "server.example.com:25" +
"</blockquote>", "</blockquote>",
dataTitle: 'Host Name',
dataPlacement: 'right',
dataContainer: 'body'
}, },
description: { description: {
label: 'Description', label: 'Description',
@@ -52,6 +50,10 @@ export default function(){
type: 'textarea', type: 'textarea',
editRequired: false, editRequired: false,
rows: 6, rows: 6,
class: 'modal-input-xlarge Form-textArea',
dataTitle: 'Host Variables',
dataPlacement: 'right',
dataContainer: 'body',
default: '---', default: '---',
awPopOver: "<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" + awPopOver: "<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" + "JSON:<br />\n" +
@@ -61,6 +63,15 @@ export default function(){
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' + '<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>', '<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
} }
},
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()'
}
} }
} };
}; };

View File

@@ -54,7 +54,9 @@ export default function(){
type: 'toggle', type: 'toggle',
ngClick: 'toggleHostEnabled(host)', ngClick: 'toggleHostEnabled(host)',
searchable: false, searchable: false,
nosort: true nosort: true,
awToolTip: "<p>Indicates if a host is available and should be included in running jobs.</p><p>For hosts that are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.</p>",
dataTitle: 'Host Enabled',
}, },
has_active_failures: { has_active_failures: {
label: 'Has failed jobs?', label: 'Has failed jobs?',

View File

@@ -29,11 +29,13 @@ var dashboardHostsList = {
var defaultUrl = GetBasePath('hosts') + '?page_size=10'; var defaultUrl = GetBasePath('hosts') + '?page_size=10';
Rest.setUrl(defaultUrl); Rest.setUrl(defaultUrl);
return Rest.get().then(function(res){ 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_name = value.summary_fields.inventory.name;
value.inventory_id = value.summary_fields.inventory.id; value.inventory_id = value.summary_fields.inventory.id;
return value; return value;
}); });
res.data.results = results;
return res.data
}); });
}] }]
} }

View File

@@ -13,6 +13,18 @@ export default
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!', ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status }); 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 });
});
} }
}; };
}]; }];

View File

@@ -11,7 +11,7 @@ import service from './dashboard-hosts.service';
export default export default
angular.module('dashboardHosts', []) angular.module('dashboardHosts', [])
.service('DashboardHostsService', service) .service('DashboardHostService', service)
.factory('DashboardHostsList', list) .factory('DashboardHostsList', list)
.factory('DashboardHostsForm', form) .factory('DashboardHostsForm', form)
.run(['$stateExtender', function($stateExtender){ .run(['$stateExtender', function($stateExtender){

View File

@@ -1,7 +1,6 @@
export default ['$scope', 'Refresh', 'tagSearchService', export default ['$scope', 'Refresh', 'tagSearchService',
function($scope, Refresh, tagSearchService) { function($scope, Refresh, tagSearchService) {
// JSONify passed field elements that can be searched // JSONify passed field elements that can be searched
console.log($scope.list)
$scope.list = angular.fromJson($scope.list); $scope.list = angular.fromJson($scope.list);
// Access config lines from list spec // Access config lines from list spec
$scope.listConfig = $scope.$parent.list; $scope.listConfig = $scope.$parent.list;

View File

@@ -230,6 +230,11 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
this.scope[fld + '_field'].name = fld; 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); $compile(element)(this.scope);
if (!options.html) { if (!options.html) {
@@ -606,9 +611,26 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
return html; return html;
}, },
buildHeaderField: function(key, field, options, form){
var html = '';
// extend these blocks to include elements similarly buildField()
if (field.type === 'toggle'){
html += "<div class=\"Field-header--" + key;
html += (field['class']) ? " " + field['class'] : "";
html += " " + field.columnClass;
html += "\"><div class='ScheduleToggle' ng-class='{\"is-on\": " + form.iterator + ".";
html += (field.flag) ? field.flag : "enabled";
html += "\}' aw-tool-tip='" + field.awToolTip + "' data-placement='" + field.dataPlacement + "' data-tip-watch='" + field.dataTipWatch + "'><div ng-show='" + form.iterator + "." ;
html += (field.flag) ? field.flag : 'enabled';
html += "' class='ScheduleToggle-switch is-on' ng-click='" + field.ngClick + "'>ON</div><div ng-show='!" + form.iterator + "." ;
html += (field.flag) ? field.flag : "enabled";
html += "' class='ScheduleToggle-switch' ng-click='" + field.ngClick + "'>OFF</div></div></div>";
}
return html;
},
buildField: function (fld, field, options, form) { buildField: function (fld, field, options, form) {
var i, fldWidth, offset, html = '', var i, fldWidth, offset, html = '',
horizontal = (this.form.horizontal) ? true : false; horizontal = (this.form.horizontal) ? true : false;
@@ -725,6 +747,18 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
return html; return html;
} }
if (field.type === 'toggle'){
html += "<td class=\"List-tableCell " + fld + "-column";
html += (field['class']) ? " " + field['class'] : "";
html += " " + field.columnClass;
html += "\"><div class='ScheduleToggle' ng-class='{\"is-on\": " + form.iterator + ".";
html += (field.flag) ? field.flag : "enabled";
html += "\}' aw-tool-tip='" + field.awToolTip + "' data-placement='" + field.dataPlacement + "' data-tip-watch='" + field.dataTipWatch + "'><div ng-show='" + form.iterator + "." ;
html += (field.flag) ? field.flag : 'enabled';
html += "' class='ScheduleToggle-switch is-on' ng-click='" + field.ngClick + "'>ON</div><div ng-show='!" + form.iterator + "." ;
html += (field.flag) ? field.flag : "enabled";
html += "' class='ScheduleToggle-switch' ng-click='" + field.ngClick + "'>OFF</div></div></td>";
}
if (field.type === 'alertblock') { if (field.type === 'alertblock') {
html += "<div class=\"row\">\n"; html += "<div class=\"row\">\n";
@@ -1429,17 +1463,26 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
html+= "<span class=\"Form-title--is_superuser\" "+ html+= "<span class=\"Form-title--is_superuser\" "+
"ng-if=is_superuser>Admin</span>"; "ng-if=is_superuser>Admin</span>";
} }
html += "</div>\n"; html += "</div>\n";
html += "<div class=\"Form-header--fields\">";
if(this.form.headerFields){
var that = this;
_.forEach(this.form.headerFields, function(value, key){
html += that.buildHeaderField(key, value, options, that.form);
});
html += "</div>\n";
}
else{ html += "</div>\n"; }
if(this.form.cancelButton !== undefined && this.form.cancelButton === false) { if(this.form.cancelButton !== undefined && this.form.cancelButton === false) {
html += "<div class=\"Form-exitHolder\">"; html += "<div class=\"Form-exitHolder\">";
html += "</div>"; html += "</div></div>";
} else { } else {
html += "<div class=\"Form-exitHolder\">"; html += "<div class=\"Form-exitHolder\">";
html += "<button class=\"Form-exit\" ng-click=\"formCancel()\">"; html += "<button class=\"Form-exit\" ng-click=\"formCancel()\">";
html += "<i class=\"fa fa-times-circle\"></i>"; html += "<i class=\"fa fa-times-circle\"></i>";
html += "</button></div>\n"; html += "</button></div>\n";
} }
html += "</div>\n"; //end of Form-header html += "</div></div>\n"; //end of Form-header
} }
if (!_.isEmpty(this.form.related)) { if (!_.isEmpty(this.form.related)) {