1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-31 15:21:13 +03:00

Job Events detail page starting to work.

This commit is contained in:
chouseknecht 2013-05-20 00:05:26 -04:00 committed by chouseknecht
parent 0bd576de62
commit 3d3782fcee
17 changed files with 205 additions and 60 deletions

View File

@ -267,5 +267,11 @@
.job-pending, .job-running {
color: #5bb75b;
}
.job-detail-status {
font-size: 15px;
font-weight: bold;
padding-left: 15px;
}
/* End Jobs Page */

View File

@ -46,7 +46,8 @@ angular.module('ansible', [
'JobTemplateHelper',
'ProjectsListDefinition',
'JobsListDefinition',
'JobFormDefinition'
'JobFormDefinition',
'JobEventFormDefinition'
])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.
@ -55,6 +56,9 @@ angular.module('ansible', [
when('/jobs/:id',
{ templateUrl: urlPrefix + 'partials/jobs.html', controller: JobsEdit }).
when('/jobs/:id/job_events',
{ templateUrl: urlPrefix + 'partials/jobs.html', controller: JobEvents }).
when('/job_templates',
{ templateUrl: urlPrefix + 'partials/job_templates.html', controller: JobTemplatesList }).

View File

@ -31,6 +31,11 @@ function JobsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Aler
scope.editJob = function(id) {
$location.path($location.path() + '/' + id);
}
scope.viewEvents = function(id) {
console.log('headed to: ' + $location.path() + '/' + id + '/job_events');
$location.path($location.path() + '/' + id + '/job_events');
}
}
@ -265,4 +270,54 @@ JobsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit',
'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList',
'ProjectList', 'LookUpInit', 'PromptPasswords', 'GetBasePath'
];
];
function JobEvents ($scope, $rootScope, $compile, $location, $log, $routeParams, JobEventForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath)
{
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope.
// Inject dynamic view
var form = JobEventForm;
var generator = GenerateForm;
var scope = GenerateForm.inject(form, {mode: 'edit', related: true});
generator.reset();
var defaultUrl = GetBasePath('jobs') + $routeParams.id + '/job_events';
var base = $location.path().replace(/^\//,'').split('/')[0];
var master = {};
var id = $routeParams.id;
var relatedSets = {};
// Retrieve detail record and prepopulate the form
Rest.setUrl(defaultUrl);
Rest.get({ params: {page_size: 1} })
.success( function(data, status, headers, config) {
LoadBreadCrumbs({ path: '/organizations/' + id, title: data.name });
for (var fld in form.fields) {
if (data[fld]) {
scope[fld] = data[fld];
}
}
for (var fld in form.items) {
if (data[fld]) {
scope[fld] = data[fld];
}
}
scope['event_satus'] = (data.failed) ? 'failed' : 'success';
scope.next = data.next;
scope.previous = data.previous;
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to retrieve job event data: ' + $routeParams.id + '. GET status: ' + status });
});
}
JobEvents.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobEventForm',
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath' ];

View File

@ -0,0 +1,74 @@
/*********************************************
* Copyright (c) 2013 AnsibleWorks, Inc.
*
* JobEvents.js
* Form definition for Job Events model
*
*
*/
angular.module('JobEventFormDefinition', [])
.value(
'JobEventForm', {
editTitle: '{{ name }} Events', //Legend in edit mode
name: 'job_events',
well: true,
formInline: true,
fields: {
job: {
label: 'Job ID',
type: 'text',
readonly: true
},
name: {
label: 'Name',
type: 'text',
sourceModel: 'job',
sourceField: 'name',
readonly: true
},
description: {
label: 'Description',
type: 'text',
sourceModel: 'job',
sourceField: 'description',
readonly: true
}
},
buttons: {
},
items: {
event: {
label: 'Event',
type: 'text',
readonly: true
},
created: {
label: 'Event Timestamp',
type: 'text',
readonly: true
},
event_status: {
label: 'Event Status <span class="job-detail-status job-\{\{ status \}\}"><i class="icon-circle"></i> \{\{ status \}\}</span>',
type: 'text',
readonly: true,
control: false
},
event_data: {
label: 'Event Data',
type: 'textarea',
class: 'span12',
rows: 10
}
},
related: { //related colletions (and maybe items?)
}
}); //Form

View File

@ -138,11 +138,10 @@ angular.module('JobFormDefinition', [])
statusFields: {
status: {
label: 'Status',
label: 'Job Status <span class="job-detail-status job-\{\{ status \}\}"><i class="icon-circle"></i> \{\{ status \}\}</span>',
type: 'text',
readonly: true,
icon: 'icon-circle',
class: 'job-\{\{ job.status \}\}'
control: false
},
result_stdout: {
label: 'Standard Out',

View File

@ -55,7 +55,7 @@ angular.module('CredentialsListDefinition', [])
ngClick: "editCredential(\{\{ credential.id \}\})",
icon: 'icon-edit',
class: 'btn-mini',
awToolTip: 'Edit credential'
awToolTip: 'View/Edit credential'
},
delete: {

View File

@ -42,7 +42,7 @@ angular.module('GroupListDefinition', [])
ngClick: "editGroup(\{\{ group.id \}\})",
icon: 'icon-edit',
class: 'btn-mini',
awToolTip: 'Edit group'
awToolTip: 'View/Edit group'
},
delete: {

View File

@ -42,7 +42,7 @@ angular.module('HostListDefinition', [])
ngClick: "editHost(\{\{ host.id \}\})",
icon: 'icon-edit',
class: 'btn-mini',
awToolTip: 'Edit host'
awToolTip: 'View/Edit host'
},
delete: {

View File

@ -48,7 +48,7 @@ angular.module('InventoriesListDefinition', [])
ngClick: "editInventory(\{\{ inventory.id \}\})",
icon: 'icon-edit',
class: 'btn-mini',
awToolTip: 'Edit'
awToolTip: 'View/Edit inventory'
},
delete: {

View File

@ -42,13 +42,13 @@ angular.module('JobTemplatesListDefinition', [])
edit: {
ngClick: "editJobTemplate(\{\{ job_template.id \}\})",
icon: 'icon-edit',
awToolTip: 'Edit template',
awToolTip: 'View/Edit template',
class: 'btn-mini'
},
submit: {
icon: 'icon-play',
mode: 'all',
class: 'btn-mini',
class: 'btn-mini btn-success',
ngClick: 'submitJob(\{\{ job_template.id \}\})',
awToolTip: 'Create and run a job using this template'
},

View File

@ -46,13 +46,13 @@ angular.module('JobsListDefinition', [])
ngClick: "editJob(\{\{ job.id \}\})",
icon: 'icon-edit',
class: 'btn-mini',
awToolTip: 'Edit/View detail',
awToolTip: 'View/Edit detail',
},
summary: {
title: 'Summary',
icon: 'icon-filter',
ngClick: 'viewSummary()',
class: 'btn-info btn-mini',
ngClick: 'viewSummary(\{{ job.id \}\})',
class: 'btn-success btn-mini',
awToolTip: 'View host summary',
ngDisabled: "job.status == 'new'"
},
@ -60,8 +60,8 @@ angular.module('JobsListDefinition', [])
title: 'Detail',
icon: 'icon-list-ul',
mode: 'all',
ngClick: 'viewEvents()',
class: 'btn-info btn-mini',
ngClick: 'viewEvents(\{{ job.id \}\})',
class: 'btn-success btn-mini',
awToolTip: 'View events',
ngDisabled: "job.status == 'new'"
},

View File

@ -41,14 +41,14 @@ angular.module('OrganizationListDefinition', [])
ngClick: "editOrganization(\{\{ organization.id \}\})",
icon: 'icon-edit',
class: 'btn-mini',
awToolTip: 'Edit'
awToolTip: 'View/Edit organization'
},
delete: {
ngClick: "deleteOrganization(\{\{ organization.id \}\},'\{\{ organization.name \}\}')",
icon: 'icon-remove',
class: 'btn-mini btn-danger',
awToolTip: 'Delete'
awToolTip: 'Delete organization'
}
}
});

View File

@ -42,7 +42,7 @@ angular.module('ProjectsListDefinition', [])
ngClick: "editProject(\{\{ project.id \}\})",
icon: 'icon-edit',
class: 'btn-mini',
awToolTip: 'Edit project'
awToolTip: 'View/edit project'
},
delete: {

View File

@ -48,7 +48,7 @@ angular.module('TeamsListDefinition', [])
ngClick: "editTeam(\{\{ team.id \}\})",
icon: 'icon-edit',
class: 'btn-mini',
awToolTip: 'Edit team'
awToolTip: 'View/Edit team'
},
delete: {

View File

@ -47,7 +47,7 @@ angular.module('UserListDefinition', [])
ngClick: "editUser(\{\{ user.id \}\})",
icon: 'icon-edit',
class: 'btn-mini',
awToolTip: 'Edit user'
awToolTip: 'View/Edit user'
},
delete: {

View File

@ -154,48 +154,54 @@ angular.module('FormGenerator', ['GeneratorHelpers'])
html += "<div class=\"control-group\""
html += (field.ngShow) ? this.attr(field,'ngShow') : "";
html += ">\n";
html += "<label class=\"control-label\" for=\"" + fld + '">' + field.label + '</label>' + "\n";
html += "<label class=\"control-label";
html += (field.labelClass) ? " " + field.labelClass : "";
html += "\" for=\"" + fld + '">';
html += (field.icon) ? this.icon(field.icon) : "";
html += field.label + '</label>' + "\n";
html += "<div class=\"controls\">\n";
html += (field.clear) ? "<div class=\"input-append\">\n" : "";
html += "<input ";
html += this.attr(field,'type');
html += "ng-model=\"" + fld + '" ';
html += 'name="' + fld + '" ';
html += (field.ngChange) ? this.attr(field,'ngChange') : "";
html += (field.id) ? this.attr(field,'id') : "";
html += (field.placeholder) ? this.attr(field,'placeholder') : "";
html += (options.mode == 'edit' && field.editRequired) ? "required " : "";
html += (options.mode == 'add' && field.addRequired) ? "required " : "";
html += (field.readonly) ? "readonly " : "";
html += (field.awPassMatch) ? "awpassmatch=\"" + field.associated + "\" " : "";
html += (field.capitalize) ? "capitalize " : "";
html += (field.ask) ? "ng-disabled=\"" + fld + "_ask\" " : "";
html += (field.associated && this.form.fields[field.associated].ask) ? "ng-disabled=\"" + field.associated + "_ask\" " : "";
html += "/>";
if (field.clear) {
html += " \n<button class=\"btn\" ng-click=\"clear('" + fld + "','" + field.associated + "')\" " +
"aw-tool-tip=\"Clear " + field.label + "\" id=\"" + fld + "-clear-btn\"><i class=\"icon-undo\"></i></button>\n";
html += "</div>\n";
if (field.control === null || field.control === undefined || field.control) {
html += "<input ";
html += this.attr(field,'type');
html += "ng-model=\"" + fld + '" ';
html += 'name="' + fld + '" ';
html += (field.ngChange) ? this.attr(field,'ngChange') : "";
html += (field.id) ? this.attr(field,'id') : "";
html += (field.placeholder) ? this.attr(field,'placeholder') : "";
html += (options.mode == 'edit' && field.editRequired) ? "required " : "";
html += (options.mode == 'add' && field.addRequired) ? "required " : "";
html += (field.readonly) ? "readonly " : "";
html += (field.awPassMatch) ? "awpassmatch=\"" + field.associated + "\" " : "";
html += (field.capitalize) ? "capitalize " : "";
html += (field.ask) ? "ng-disabled=\"" + fld + "_ask\" " : "";
html += (field.associated && this.form.fields[field.associated].ask) ? "ng-disabled=\"" + field.associated + "_ask\" " : "";
html += "/>";
if (field.clear) {
html += " \n<button class=\"btn\" ng-click=\"clear('" + fld + "','" + field.associated + "')\" " +
"aw-tool-tip=\"Clear " + field.label + "\" id=\"" + fld + "-clear-btn\"><i class=\"icon-undo\"></i></button>\n";
html += "</div>\n";
}
if (field.ask) {
html += " \n<label class=\"checkbox inline ask-checkbox\"><input type=\"checkbox\" ng-model=\"" +
fld + "_ask\" ng-change=\"ask('" + fld + "','" + field.associated + "')\" /> Ask at runtime?</label>";
}
html += "<br />\n";
// Add error messages
if ( (options.mode == 'add' && field.addRequired) || (options.mode == 'edit' && field.editRequired) ) {
html += "<span class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld + ".$dirty && " +
this.form.name + '_form.' + fld + ".$error.required\">A value is required!</span>\n";
}
if (field.type == "email") {
html += "<span class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld + ".$dirty && " +
this.form.name + '_form.' + fld + ".$error.email\">A valid email address is required!</span>\n";
}
if (field.awPassMatch) {
html += "<span class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld +
".$error.awpassmatch\">Must match Password value</span>\n";
}
html += "<span class=\"error api-error\" ng-bind=\"" + fld + "_api_error\"></span>\n";
}
if (field.ask) {
html += " \n<label class=\"checkbox inline ask-checkbox\"><input type=\"checkbox\" ng-model=\"" +
fld + "_ask\" ng-change=\"ask('" + fld + "','" + field.associated + "')\" /> Ask at runtime?</label>";
}
html += "<br />\n";
// Add error messages
if ( (options.mode == 'add' && field.addRequired) || (options.mode == 'edit' && field.editRequired) ) {
html += "<span class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld + ".$dirty && " +
this.form.name + '_form.' + fld + ".$error.required\">A value is required!</span>\n";
}
if (field.type == "email") {
html += "<span class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld + ".$dirty && " +
this.form.name + '_form.' + fld + ".$error.email\">A valid email address is required!</span>\n";
}
if (field.awPassMatch) {
html += "<span class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld +
".$error.awpassmatch\">Must match Password value</span>\n";
}
html += "<span class=\"error api-error\" ng-bind=\"" + fld + "_api_error\"></span>\n";
html += "</div>\n";
html += "</div>\n";
}

View File

@ -45,6 +45,7 @@
<script src="{{ STATIC_URL }}js/forms/Credentials.js"></script>
<script src="{{ STATIC_URL }}js/forms/JobTemplates.js"></script>
<script src="{{ STATIC_URL }}js/forms/Jobs.js"></script>
<script src="{{ STATIC_URL }}js/forms/JobEvents.js"></script>
<script src="{{ STATIC_URL }}js/lists/Users.js"></script>
<script src="{{ STATIC_URL }}js/lists/Organizations.js"></script>
<script src="{{ STATIC_URL }}js/lists/Admins.js"></script>