mirror of
https://github.com/ansible/awx.git
synced 2026-01-12 18:40:01 -03:30
AC-201 Added callback URL and lots of tool-tip help around the callback fields.
This commit is contained in:
parent
43fb2d7ae4
commit
7d6507ec0d
@ -62,6 +62,12 @@
|
||||
|
||||
/* End btn heights */
|
||||
|
||||
/* Use code-breakable in pop-over text to indent and wrap code segments */
|
||||
.code-breakable {
|
||||
word-wrap: break-word;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.login-alert {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
|
||||
98
awx/ui/static/js/awx-min.js
vendored
98
awx/ui/static/js/awx-min.js
vendored
@ -4,7 +4,7 @@
|
||||
*
|
||||
* awx-min.js
|
||||
*
|
||||
* master-1512764, Fri Jul 12 11:01:49 2013 -0400
|
||||
* master-987e4d1, Fri Jul 12 13:46:38 2013 -0400
|
||||
*
|
||||
*/
|
||||
var urlPrefix="/static/";
|
||||
@ -68,9 +68,9 @@ q.deleteJob=function(a,b){p.setUrl(B+a+"/");p.get().success(function(b,c,f,n){va
|
||||
k+" failed. POST returned status: "+b})}):p.destroy().success(function(a,b,d,c){$("#prompt-modal").modal("hide");q.search(e.iterator)}).error(function(a,b,d,c){$("#prompt-modal").modal("hide");u(q,a,b,null,{hdr:"Error!",msg:"Call to "+k+" failed. DELETE returned status: "+b})})}})}).error(function(a,b,d,c){u(q,a,b,null,{hdr:"Error!",msg:"Failed to get job details. GET returned status: "+b})})};q.submitJob=function(a,b){r({scope:q,id:a,template:b})}}JobsListCtrl.$inject="$scope $rootScope $location $log $routeParams Rest Alert JobList GenerateList LoadBreadCrumbs Prompt SearchInit PaginateInit ReturnToCaller ClearScope ProcessErrors GetBasePath LookUpInit SubmitJob FormatDate".split(" ");
|
||||
function JobsEdit(l,m,h,g,c,p,f,e,k,a,d,b,y,v,A,u,C,t,r,n,B,q,w,z){function E(a){if(null!==a&&""!==a&&void 0!==a){var b=q("projects")+a+"/playbooks/";k.setUrl(b);k.get().success(function(a,b,d,c){s.playbook_options=[];for(b=0;b<a.length;b++)s.playbook_options.push(a[b])}).error(function(a,c,f,e){d(s,a,c,D,{hdr:"Error!",msg:"Failed to get playbook list for "+b+". GET returned status: "+c})})}}u("htmlTemplate");var F=q("jobs"),D=f,s=e.inject(D,{mode:"edit",related:!0});e.reset();var K=g.path().replace(/^\//,
|
||||
"").split("/")[0],G={},J=p.id,H={};s.statusSearchSpin=!1;s.selectPlaybookUnregister&&s.selectPlaybookUnregister();s.selectPlaybookUnregister=s.$watch("project_name",function(a,b){a!==b&&(""!==b&&null!==b&&void 0!==b)&&(s.playbook=null,E(s.project))});s.jobLoadedRemove&&s.jobLoadedRemove();s.jobLoadedRemove=s.$on("jobLoaded",function(){s[D.name+"ReadOnly"]="new"==s.status?!1:!0;for(var a in H)s.search(H[a].iterator);E(s.project);$("#forks-slider").slider("option","value",s.forks);$("#forks-slider").slider("disable");
|
||||
k.setUrl(s.template_url);k.get().success(function(a,b,d,c){b=a.host_config_key?"true":"false";s.host_config_key=a.host_config_key;w({scope:s,master:G,check_field:"allow_callbacks",default_val:b});$('input[type="checkbox"]').attr("disabled","disabled");$("#host_config_key-gen-btn").attr("disabled","disabled")}).error(function(a,b,c,f){d(s,a,b,D,{hdr:"Error!",msg:"Failed to retrieve job: "+p.id+". GET status: "+b})})});s.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}];s.verbosity_options=
|
||||
[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}];s.playbook_options=null;s.playbook=null;k.setUrl(F+":id/");k.get({params:{id:J}}).success(function(a,d,c,f){b({path:"/job_templates/"+J,title:a.name});for(var e in D.fields){if(null!==a[e]&&void 0!==a[e]){if("select"==D.fields[e].type)if(s[e+"_options"]&&0<s[e+"_options"].length)for(d=0;d<s[e+"_options"].length;d++)a[e]==s[e+"_options"][d].value&&(s[e]=s[e+"_options"][d]);else s[e]=a[e];else s[e]=a[e];G[e]=s[e]}"lookup"==
|
||||
D.fields[e].type&&a.summary_fields[D.fields[e].sourceModel]&&(s[D.fields[e].sourceModel+"_"+D.fields[e].sourceField]=a.summary_fields[D.fields[e].sourceModel][D.fields[e].sourceField],G[D.fields[e].sourceModel+"_"+D.fields[e].sourceField]=s[D.fields[e].sourceModel+"_"+D.fields[e].sourceField])}for(e in D.statusFields)null!==a[e]&&void 0!==a[e]&&("created"==e?s.created=z(new Date(a.created)):s[e]=a[e]);$('form[name="jobs_form"] input[type="text"], form[name="jobs_form"] jobs_form textarea').attr("readonly",
|
||||
k.setUrl(s.template_url);k.get().success(function(a,b,d,c){b=a.host_config_key?"true":"false";s.host_config_key=a.host_config_key;w({scope:s,master:G,check_field:"allow_callbacks",default_val:b});s.callback_url=a.related.callback;$('input[type="checkbox"]').attr("disabled","disabled");$("#host_config_key-gen-btn").attr("disabled","disabled")}).error(function(a,b,c,f){d(s,a,b,D,{hdr:"Error!",msg:"Failed to retrieve job: "+p.id+". GET status: "+b})})});s.job_type_options=[{value:"run",label:"Run"},
|
||||
{value:"check",label:"Check"}];s.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}];s.playbook_options=null;s.playbook=null;k.setUrl(F+":id/");k.get({params:{id:J}}).success(function(a,d,c,f){b({path:"/job_templates/"+J,title:a.name});for(var e in D.fields){if(null!==a[e]&&void 0!==a[e]){if("select"==D.fields[e].type)if(s[e+"_options"]&&0<s[e+"_options"].length)for(d=0;d<s[e+"_options"].length;d++)a[e]==s[e+"_options"][d].value&&(s[e]=s[e+"_options"][d]);
|
||||
else s[e]=a[e];else s[e]=a[e];G[e]=s[e]}"lookup"==D.fields[e].type&&a.summary_fields[D.fields[e].sourceModel]&&(s[D.fields[e].sourceModel+"_"+D.fields[e].sourceField]=a.summary_fields[D.fields[e].sourceModel][D.fields[e].sourceField],G[D.fields[e].sourceModel+"_"+D.fields[e].sourceField]=s[D.fields[e].sourceModel+"_"+D.fields[e].sourceField])}for(e in D.statusFields)null!==a[e]&&void 0!==a[e]&&("created"==e?s.created=z(new Date(a.created)):s[e]=a[e]);$('form[name="jobs_form"] input[type="text"], form[name="jobs_form"] jobs_form textarea').attr("readonly",
|
||||
"readonly");$('form[name="jobs_form"] select').prop("disabled","disabled");$('form[name="jobs_form"] .lookup-btn').prop("disabled","disabled");$('form[name="jobs_form"] .buttons, form[name="jobs_form"] hr').hide();s.url=a.url;e=a.related;for(var k in D.related)e[k]&&(H[k]={url:e[k],iterator:D.related[k].iterator});n({scope:s,form:D,current_item:a.inventory,list:C,field:"inventory"});n({scope:s,form:D,current_item:a.credential,list:t,field:"credential"});n({scope:s,form:D,current_item:a.project,list:r,
|
||||
field:"project"});y({scope:s,form:D,relatedSets:H});v({scope:s,relatedSets:H});s.template_url=a.related.job_template;s.$emit("jobLoaded")}).error(function(a,b,c,f){d(s,a,b,D,{hdr:"Error!",msg:"Failed to retrieve job: "+p.id+". GET status: "+b})});s.formSave=function(){k.setUrl(F+p.id+"/");var a={},b;for(b in D.fields)a[b]="select"==D.fields[b].type&&"playbook"!=b?s[b].value:s[b];k.put(a).success(function(a,b,d,c){"job_templates"==g.path().replace(/^\//,"").split("/")[0]?A():A(1)}).error(function(a,
|
||||
b,c,f){d(s,a,b,D,{hdr:"Error!",msg:"Failed to update job "+p.id+". PUT returned status: "+b})})};s.formReset=function(){e.reset();for(var a in G)s[a]=G[a];$("#forks-slider").slider("option","value",s.forks)};s.add=function(a){m.flashMessage=null;g.path("/"+K+"/"+p.id+"/"+a)};s.edit=function(a,b,d){m.flashMessage=null;g.path("/"+K+"/"+p.id+"/"+a+"/"+b)};s["delete"]=function(a,b,c,f){m.flashMessage=null;Prompt({hdr:"Delete",body:"Are you sure you want to remove "+c+" from "+s.name+" "+f+"?",action:function(){var c=
|
||||
@ -88,11 +88,11 @@ function JobTemplatesEdit(l,m,h,g,c,p,f,e,k,a,d,b,y,v,A,u,C,t,r,n,B,q,w,z){funct
|
||||
"yaml";z(s);s.job_type_options=[{value:"run",label:"Run"},{value:"check",label:"Check"}];s.verbosity_options=[{value:"0",label:"Default"},{value:"1",label:"Verbose"},{value:"3",label:"Debug"}];s.playbook_options=null;s.playbook=null;e.reset();var K=g.path().replace(/^\//,"").split("/")[0],G={},J=p.id,H={};s.selectPlaybookUnregister&&s.selectPlaybookUnregister();s.selectPlaybookUnregister=s.$watch("project_name",function(a,b){a!==b&&(""!==b&&null!==b&&void 0!==b)&&(s.playbook=null,E(s.project))});
|
||||
s.jobTemplateLoadedRemove&&s.jobTemplateLoadedRemove();s.jobTemplateLoadedRemove=s.$on("jobTemplateLoaded",function(){for(var a in H)s.search(H[a].iterator);E(s.project);$("#forks-slider").slider("value",s.forks);w({scope:s,master:G,check_field:"allow_callbacks",default_val:s.host_config_key?"true":"false"})});k.setUrl(F+":id/");k.get({params:{id:J}}).success(function(a,d,c,f){b({path:"/job_templates/"+J,title:a.name});for(var e in D.fields){if("variables"!=e&&null!==a[e]&&void 0!==a[e]){if("select"==
|
||||
D.fields[e].type)if(s[e+"_options"]&&0<s[e+"_options"].length)for(d=0;d<s[e+"_options"].length;d++)a[e]==s[e+"_options"][d].value&&(s[e]=s[e+"_options"][d]);else s[e]=a[e];else s[e]=a[e];G[e]=s[e]}"variables"==e&&($.isEmptyObject(a.extra_vars)||"{}"==a.extra_vars||"null"==a.extra_vars?s.variables="---":(d=JSON.parse(a.extra_vars),s.variables=jsyaml.safeDump(d)),G.variables=s.variables);"lookup"==D.fields[e].type&&a.summary_fields[D.fields[e].sourceModel]&&(s[D.fields[e].sourceModel+"_"+D.fields[e].sourceField]=
|
||||
a.summary_fields[D.fields[e].sourceModel][D.fields[e].sourceField],G[D.fields[e].sourceModel+"_"+D.fields[e].sourceField]=s[D.fields[e].sourceModel+"_"+D.fields[e].sourceField])}s.url=a.url;e=a.related;for(var k in D.related)e[k]&&(H[k]={url:e[k],iterator:D.related[k].iterator});n({scope:s,form:D,current_item:a.inventory,list:C,field:"inventory"});n({scope:s,form:D,current_item:a.credential,list:t,field:"credential"});n({scope:s,form:D,current_item:a.project,list:r,field:"project"});y({scope:s,form:D,
|
||||
relatedSets:H});v({scope:s,relatedSets:H});s.$emit("jobTemplateLoaded")}).error(function(a,b,c,e){d(s,a,b,D,{hdr:"Error!",msg:"Failed to retrieve job template: "+p.id+". GET status: "+b})});s.formSave=function(){var b={};try{var c="json"==s.parseType?JSON.parse(s.variables):jsyaml.load(s.variables);if("object"!==typeof c)throw"failed to return an object!";for(var e in D.fields)"select"==D.fields[e].type&&"playbook"!=e?b[e]=s[e].value:"variables"!=e&&(b[e]=s[e]);b.extra_vars=JSON.stringify(c,void 0,
|
||||
"\t");k.setUrl(F+J+"/");k.put(b).success(function(a,b,d,c){"job_templates"==g.path().replace(/^\//,"").split("/")[0]?A():A(1)}).error(function(a,b,c,e){d(s,a,b,D,{hdr:"Error!",msg:"Failed to update job template. PUT returned status: "+b})})}catch(f){a("Error","Error parsing extra variables. Parser returned: "+f)}};s.formReset=function(){e.reset();for(var a in G)s[a]=G[a];s.parseType="yaml";$("#forks-slider").slider("option","value",s.forks)};s.add=function(a){m.flashMessage=null;g.path("/"+K+"/"+
|
||||
p.id+"/"+a)};s.edit=function(a,b,d){m.flashMessage=null;g.path("/"+a+"/"+b)};s["delete"]=function(a,b,c,e){m.flashMessage=null;Prompt({hdr:"Delete",body:"Are you sure you want to remove "+c+" from "+s.name+" "+e+"?",action:function(){var c=F+J+"/"+a+"/";k.setUrl(c);k.post({id:b,disassociate:1}).success(function(b,d,c,e){$("#prompt-modal").modal("hide");s.search(D.related[a].iterator)}).error(function(a,b,e,f){$("#prompt-modal").modal("hide");d(s,a,b,null,{hdr:"Error!",msg:"Call to "+c+" failed. POST returned status: "+
|
||||
b})})}})}}JobTemplatesEdit.$inject="$scope $rootScope $compile $location $log $routeParams JobTemplateForm GenerateForm Rest Alert ProcessErrors LoadBreadCrumbs RelatedSearchInit RelatedPaginateInit ReturnToCaller ClearScope InventoryList CredentialList ProjectList LookUpInit PromptPasswords GetBasePath md5Setup ParseTypeChange".split(" ");function OrganizationsList(l,m,h,g,c,p,f,e,k,a,d,b,y,v,A){y("htmlTemplate");l="organizations"==h.path().replace(/^\//,"").split("/")[0]?"edit":"select";var u=k.inject(a,{mode:l}),C=A("organizations");m.flashMessage=null;f();u.PostRefreshRemove&&u.PostRefreshRemove();u.PostRefreshRemove=u.$on("PostRefresh",function(){$("tr.success").each(function(a){a=$(this).attr("ng-class");u[a]=""})});d({scope:u,set:a.name,list:a,url:C});b({scope:u,list:a,url:C});u.search(a.iterator);u.addOrganization=function(){h.path(h.path()+
|
||||
a.summary_fields[D.fields[e].sourceModel][D.fields[e].sourceField],G[D.fields[e].sourceModel+"_"+D.fields[e].sourceField]=s[D.fields[e].sourceModel+"_"+D.fields[e].sourceField])}s.url=a.url;e=a.related;for(var k in D.related)e[k]&&(H[k]={url:e[k],iterator:D.related[k].iterator});s.callback_url=a.related.callback;G.callback_url=s.callback_url;n({scope:s,form:D,current_item:a.inventory,list:C,field:"inventory"});n({scope:s,form:D,current_item:a.credential,list:t,field:"credential"});n({scope:s,form:D,
|
||||
current_item:a.project,list:r,field:"project"});y({scope:s,form:D,relatedSets:H});v({scope:s,relatedSets:H});s.$emit("jobTemplateLoaded")}).error(function(a,b,c,e){d(s,a,b,D,{hdr:"Error!",msg:"Failed to retrieve job template: "+p.id+". GET status: "+b})});s.formSave=function(){var b={};try{var c="json"==s.parseType?JSON.parse(s.variables):jsyaml.load(s.variables);if("object"!==typeof c)throw"failed to return an object!";for(var e in D.fields)"select"==D.fields[e].type&&"playbook"!=e?b[e]=s[e].value:
|
||||
"variables"!=e&&"callback_url"!=e&&(b[e]=s[e]);b.extra_vars=JSON.stringify(c,void 0,"\t");k.setUrl(F+J+"/");k.put(b).success(function(a,b,d,c){"job_templates"==g.path().replace(/^\//,"").split("/")[0]?A():A(1)}).error(function(a,b,c,e){d(s,a,b,D,{hdr:"Error!",msg:"Failed to update job template. PUT returned status: "+b})})}catch(f){a("Error","Error parsing extra variables. Parser returned: "+f)}};s.formReset=function(){e.reset();for(var a in G)s[a]=G[a];s.parseType="yaml";$("#forks-slider").slider("option",
|
||||
"value",s.forks)};s.add=function(a){m.flashMessage=null;g.path("/"+K+"/"+p.id+"/"+a)};s.edit=function(a,b,d){m.flashMessage=null;g.path("/"+a+"/"+b)};s["delete"]=function(a,b,c,e){m.flashMessage=null;Prompt({hdr:"Delete",body:"Are you sure you want to remove "+c+" from "+s.name+" "+e+"?",action:function(){var c=F+J+"/"+a+"/";k.setUrl(c);k.post({id:b,disassociate:1}).success(function(b,d,c,e){$("#prompt-modal").modal("hide");s.search(D.related[a].iterator)}).error(function(a,b,e,f){$("#prompt-modal").modal("hide");
|
||||
d(s,a,b,null,{hdr:"Error!",msg:"Call to "+c+" failed. POST returned status: "+b})})}})}}JobTemplatesEdit.$inject="$scope $rootScope $compile $location $log $routeParams JobTemplateForm GenerateForm Rest Alert ProcessErrors LoadBreadCrumbs RelatedSearchInit RelatedPaginateInit ReturnToCaller ClearScope InventoryList CredentialList ProjectList LookUpInit PromptPasswords GetBasePath md5Setup ParseTypeChange".split(" ");function OrganizationsList(l,m,h,g,c,p,f,e,k,a,d,b,y,v,A){y("htmlTemplate");l="organizations"==h.path().replace(/^\//,"").split("/")[0]?"edit":"select";var u=k.inject(a,{mode:l}),C=A("organizations");m.flashMessage=null;f();u.PostRefreshRemove&&u.PostRefreshRemove();u.PostRefreshRemove=u.$on("PostRefresh",function(){$("tr.success").each(function(a){a=$(this).attr("ng-class");u[a]=""})});d({scope:u,set:a.name,list:a,url:C});b({scope:u,list:a,url:C});u.search(a.iterator);u.addOrganization=function(){h.path(h.path()+
|
||||
"/add")};u.editOrganization=function(a){h.path(h.path()+"/"+a)};u.deleteOrganization=function(b,d){e({hdr:"Delete",body:"Are you sure you want to delete "+d+"?",action:function(){var d=C+b+"/";c.setUrl(d);c.destroy().success(function(b,d,c,e){$("#prompt-modal").modal("hide");u.search(a.iterator)}).error(function(a,b,c,e){$("#prompt-modal").modal("hide");v(u,a,b,null,{hdr:"Error!",msg:"Call to "+d+" failed. DELETE returned status: "+b})})}})};u.toggle_organization=function(b){"success"==u[a.iterator+
|
||||
"_"+b+"_class"]?(u[a.iterator+"_"+b+"_class"]="",document.getElementById("check_"+b).checked=!1,-1<u.selected.indexOf(b)&&u.selected.splice(u.selected.indexOf(b),1)):(u[a.iterator+"_"+b+"_class"]="success",document.getElementById("check_"+b).checked=!0,-1==u.selected.indexOf(b)&&u.selected.push(b))}}OrganizationsList.$inject="$scope $rootScope $location $log Rest Alert LoadBreadCrumbs Prompt GenerateList OrganizationList SearchInit PaginateInit ClearScope ProcessErrors GetBasePath".split(" ");
|
||||
function OrganizationsAdd(l,m,h,g,c,p,f,e,k,a,d,b,y,v,A){y("htmlTemplate");var u=e.inject(f,{mode:"add",related:!1}),C=v("organizations");e.reset();b();u.formSave=function(){k.setUrl(C);k.post({name:l.name,description:l.description}).success(function(a,b,d,c){m.flashMessage="New organization successfully created!";g.path("/organizations/"+a.id)}).error(function(a,b,c,e){d(u,a,b,f,{hdr:"Error!",msg:"Failed to add new organization. Post returned status: "+b})})};u.formReset=function(){m.flashMessage=
|
||||
@ -156,16 +156,21 @@ dataTitle:"Job Type",dataPlacement:"right",column:1},inventory:{label:"Inventory
|
||||
credential:{label:"Credential",type:"lookup",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,column:2},forks:{label:"Forks",id:"forks-number",type:"number",integer:!0,min:0,max:100,slider:!0,"class":"input-mini","default":"0",addRequired:!1,editRequired:!1,column:2,awPopOver:"<p>The number of parallel or simultaneous processes to use while executing the playbook. Provide a value between 0 and 100. A value of zero will use the ansible default setting of 5 parallel processes.</p>",
|
||||
dataTitle:"Forks",dataPlacement:"left"},limit:{label:"Limit",type:"text",addRequired:!1,editRequired:!1,column:2,awPopOver:'<p>Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. Multiple patterns can be separated by ; : or ,</p><p>For more information and examples see the <a href="http://ansible.cc/docs/patterns.html#selecting-targets" target="_blank">Selecting Targets section</a> under Inventory and Patterns in the Ansible documentation.</p>',
|
||||
dataTitle:"Limit",dataPlacement:"left"},verbosity:{label:"Verbosity",type:"select",ngOptions:"v.label for v in verbosity_options","default":0,addRequired:!0,editRequired:!0,column:2,awPopOver:"<p>Control the level of output ansible will produce as the playbook executes.</p>",dataTitle:"Verbosity",dataPlacement:"left"},extra_vars:{label:"Extra Variables",type:"textarea",rows:6,"class":"span12",addRequired:!1,editRequired:!1,awPopOver:'<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key=value pairs or JSON. <p><a href="http://www.ansibleworks.com/docs/playbooks2.html#passing-variables-on-the-command-line" target="_blank">Click here to view documentation and examples.</a></p>',
|
||||
column:2},allow_callbacks:{label:"Allow Callbacks",type:"checkbox",addRequired:!1,editRequird:!1,trueValue:"true",falseValue:"false",ngChange:"toggleCallback('host_config_key')","class":"span12",column:2},host_config_key:{label:"Host Config Key",type:"text",ngShow:"allow_callbacks",genMD5:!0,column:2}},buttons:{save:{label:"Save",icon:"icon-ok","class":"btn-success",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",label:"Reset",icon:"icon-remove",ngDisabled:!0}},statusFields:{status:{label:'Job Status <span class="job-detail-status job-{{ status }}"><i class="icon-circle"></i> {{ status }}</span>',
|
||||
type:"text",readonly:!0,control:!1},created:{label:"Date",type:"text",readonly:!0},result_stdout:{label:"Standard Out",type:"textarea",readonly:!0,rows:20,"class":"span12"},result_traceback:{label:"Traceback",type:"textarea",readonly:!0,rows:10,"class":"span12",ngShow:"result_traceback != ''"}},statusActions:{refresh:{label:"Refresh",icon:"icon-refresh",ngClick:"refresh()","class":"btn-small btn-success",awToolTip:"Refresh job status & output",mode:"all"},summary:{label:"Hosts",icon:"icon-th-large",
|
||||
ngClick:"jobSummary()","class":"btn btn-small",awToolTip:"View host summary",mode:"all"},events:{label:"Events",icon:"icon-list-ul",ngClick:"jobEvents()","class":"btn btn-small",awToolTip:"Edit job events",mode:"all"}},related:{}});angular.module("JobTemplateFormDefinition",[]).value("JobTemplateForm",{addTitle:"Create Job Templates",editTitle:"{{ name }}",name:"job_templates",twoColumns:!0,well:!0,fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,column:1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1,column:1},job_type:{label:"Job Type",type:"select",ngOptions:"type.label for type in job_type_options","default":0,addRequired:!0,editRequired:!0,column:1,awPopOver:"<p>When this template is submitted as a job, setting the type to <em>run</em> will execute the playbook, running tasks on the selected hosts.</p> <p>Setting the type to <em>check</em> will not execute the playbook. Instead, ansible will check playbook syntax, test environment setup and report problems.</p>",
|
||||
column:2},allow_callbacks:{label:"Allow Callbacks",type:"checkbox",addRequired:!1,editRequird:!1,trueValue:"true",falseValue:"false",ngChange:"toggleCallback('host_config_key')","class":"span12",column:2,awPopOver:'<p>Create a callback URL a host can use to contact the AWX server and request a configuration update using the job template. The URL will look like the following:</p>\n<p class="code-breakable">http://your.server.com:999/api/v1/job_templates/1/callback/</p><p>The request from the host must be a POST. Here is an example using curl:</p>\n<p class="code-breakable">curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n<p>Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.</p><p>Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.</p>',
|
||||
detailPlacement:"left",dataContainer:"#jobs",dataTitle:"Callback URL"},callback_url:{label:"Callback URL",type:"text",addRequired:!1,editRequired:!1,readonly:!0,column:2,required:!1,"class":"span12",awPopOver:'<p>Using this URL a host can contact the AWX server and request a configuration update using the job template. The request from the host must be a POST. Here is an example using curl:</p>\n<p class="code-breakable">curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n<p>Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.</p><p>Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.</p>',
|
||||
detailPlacement:"left",dataContainer:"#jobs",dataTitle:"Callback URL"},host_config_key:{label:"Host Config Key",type:"text",ngShow:"allow_callbacks",genMD5:!0,column:2,awPopOver:'<p>When contacting the AWX server using the callback URL, the calling host must authenticate by including this key in the POST data of the request. Here\'s an example using curl:</p>\n<p class="code-breakable">curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n',
|
||||
detailPlacement:"left",dataContainer:"#jobs"}},buttons:{save:{label:"Save",icon:"icon-ok","class":"btn-success",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",label:"Reset",icon:"icon-remove",ngDisabled:!0}},statusFields:{status:{label:'Job Status <span class="job-detail-status job-{{ status }}"><i class="icon-circle"></i> {{ status }}</span>',type:"text",readonly:!0,control:!1},created:{label:"Date",type:"text",readonly:!0},result_stdout:{label:"Standard Out",type:"textarea",readonly:!0,
|
||||
rows:20,"class":"span12"},result_traceback:{label:"Traceback",type:"textarea",readonly:!0,rows:10,"class":"span12",ngShow:"result_traceback != ''"}},statusActions:{refresh:{label:"Refresh",icon:"icon-refresh",ngClick:"refresh()","class":"btn-small btn-success",awToolTip:"Refresh job status & output",mode:"all"},summary:{label:"Hosts",icon:"icon-th-large",ngClick:"jobSummary()","class":"btn btn-small",awToolTip:"View host summary",mode:"all"},events:{label:"Events",icon:"icon-list-ul",ngClick:"jobEvents()",
|
||||
"class":"btn btn-small",awToolTip:"Edit job events",mode:"all"}},related:{}});angular.module("JobTemplateFormDefinition",[]).value("JobTemplateForm",{addTitle:"Create Job Templates",editTitle:"{{ name }}",name:"job_templates",twoColumns:!0,well:!0,fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,column:1},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1,column:1},job_type:{label:"Job Type",type:"select",ngOptions:"type.label for type in job_type_options","default":0,addRequired:!0,editRequired:!0,column:1,awPopOver:"<p>When this template is submitted as a job, setting the type to <em>run</em> will execute the playbook, running tasks on the selected hosts.</p> <p>Setting the type to <em>check</em> will not execute the playbook. Instead, ansible will check playbook syntax, test environment setup and report problems.</p>",
|
||||
dataTitle:"Job Type",dataPlacement:"right"},inventory:{label:"Inventory",type:"lookup",sourceModel:"inventory",sourceField:"name",addRequired:!0,editRequired:!0,ngClick:"lookUpInventory()",column:1},project:{label:"Project",type:"lookup",sourceModel:"project",sourceField:"name",addRequired:!0,editRequired:!0,ngClick:"lookUpProject()",column:1},playbook:{label:"Playbook",type:"select",ngOptions:"book for book in playbook_options",id:"playbook-select",addRequired:!0,editRequired:!0,column:1},credential:{label:"Credential",
|
||||
type:"lookup",sourceModel:"credential",sourceField:"name",ngClick:"lookUpCredential()",addRequired:!1,editRequired:!1,column:1},forks:{label:"Forks",id:"forks-number",type:"number",integer:!0,min:0,max:100,slider:!0,"class":"input-mini","default":"0",addRequired:!1,editRequired:!1,column:2,awPopOver:"<p>The number of parallel or simultaneous processes to use while executing the playbook. Provide a value between 0 and 100. A value of zero will use the ansible default setting of 5 parallel processes.</p>",
|
||||
dataTitle:"Forks",dataPlacement:"left"},limit:{label:"Limit",type:"text",addRequired:!1,editRequired:!1,column:2,awPopOver:'<p>Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. Multiple patterns can be separated by ; : or ,</p><p>For more information and examples see the <a href="http://ansible.cc/docs/patterns.html#selecting-targets" target="_blank">Selecting Targets section</a> under Inventory and Patterns in the Ansible documentation.</p>',
|
||||
dataTitle:"Limit",dataPlacement:"left"},verbosity:{label:"Verbosity",type:"select",ngOptions:"v.label for v in verbosity_options","default":0,addRequired:!0,editRequired:!0,column:2,awPopOver:"<p>Control the level of output ansible will produce as the playbook executes.</p>",dataTitle:"Verbosity",dataPlacement:"left"},variables:{label:"Extra Variables",type:"textarea",rows:6,"class":"span12",addRequired:!1,editRequired:!1,"default":"---",column:2,awPopOver:'<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key/value pairs using either YAML or JSON.</p>JSON:<br />\n<blockquote>{<br />"somevar": "somevalue",<br />"password": "magic"<br /> }</blockquote>\nYAML:<br />\n<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n',
|
||||
dataTitle:"Extra Variables",dataPlacement:"left"},allow_callbacks:{label:"Allow Callbacks",type:"checkbox",addRequired:!1,editRequird:!1,trueValue:"true",falseValue:"false",ngChange:"toggleCallback('host_config_key')","class":"span12",column:2},host_config_key:{label:"Host Config Key",type:"text",ngShow:"allow_callbacks",genMD5:!0,column:2}},buttons:{save:{label:"Save",icon:"icon-ok","class":"btn-success",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",label:"Reset",icon:"icon-remove",
|
||||
ngDisabled:!0}},related:{jobs:{type:"collection",title:"Jobs",iterator:"job",index:!1,open:!1,actions:{},fields:{id:{label:"Job ID",key:!0,desc:!0,searchType:"int"},name:{label:"Name",link:!0},description:{label:"Description"},status:{label:"Status",icon:"icon-circle","class":"job-{{ job.status }}",searchType:"select",searchOptions:[{name:"new",value:"new"},{name:"pending",value:"pending"},{name:"running",value:"running"},{name:"successful",value:"successful"},{name:"error",value:"error"},{name:"failed",
|
||||
value:"failed"},{name:"canceled",value:"canceled"}]}},fieldActions:{edit:{label:"View",ngClick:"edit('jobs', {{ job.id }}, '{{ job.name }}')",icon:"icon-zoom-in"}}}}});angular.module("OrganizationFormDefinition",[]).value("OrganizationForm",{addTitle:"Create Organization",editTitle:"{{ name }}",name:"organization",well:!0,fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!0},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1}},buttons:{save:{label:"Save",icon:"icon-ok","class":"btn-success",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",label:"Reset",icon:"icon-remove",ngDisabled:!0}},related:{users:{type:"collection",
|
||||
dataTitle:"Extra Variables",dataPlacement:"left"},allow_callbacks:{label:"Allow Callbacks",type:"checkbox",addRequired:!1,editRequird:!1,trueValue:"true",falseValue:"false",ngChange:"toggleCallback('host_config_key')","class":"span12",column:2,awPopOver:'<p>Create a callback URL a host can use to contact the AWX server and request a configuration update using the job template. The URL will look like the following:</p>\n<p class="code-breakable">http://your.server.com:999/api/v1/job_templates/1/callback/</p><p>The request from the host must be a POST. Here is an example using curl:</p>\n<p class="code-breakable">curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n<p>Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.</p><p>Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.</p>',
|
||||
detailPlacement:"left",dataContainer:"#job_templates",dataTitle:"Callback URL"},callback_url:{label:"Callback URL",type:"text",addRequired:!1,editRequired:!1,readonly:!0,column:2,required:!1,"class":"span12",awPopOver:'<p>Using this URL a host can contact the AWX server and request a configuration update using the job template. The request from the host must be a POST. Here is an example using curl:</p>\n<p class="code-breakable">curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n<p>Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address in one of your defined inventories, the request will be denied.</p><p>Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.</p>',
|
||||
detailPlacement:"left",dataContainer:"#job_templates",dataTitle:"Callback URL"},host_config_key:{label:"Host Config Key",type:"text",ngShow:"allow_callbacks",genMD5:!0,column:2,awPopOver:'<p>When contacting the AWX server using the callback URL, the calling host must authenticate by including this key in the POST data of the request. Here\'s an example using curl:</p>\n<p class="code-breakable">curl --data "host_config_key=5a8ec154832b780b9bdef1061764ae5a" http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n',
|
||||
detailPlacement:"left",dataContainer:"#job_templates"}},buttons:{save:{label:"Save",icon:"icon-ok","class":"btn-success",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",label:"Reset",icon:"icon-remove",ngDisabled:!0}},related:{jobs:{type:"collection",title:"Jobs",iterator:"job",index:!1,open:!1,actions:{},fields:{id:{label:"Job ID",key:!0,desc:!0,searchType:"int"},name:{label:"Name",link:!0},description:{label:"Description"},status:{label:"Status",icon:"icon-circle","class":"job-{{ job.status }}",
|
||||
searchType:"select",searchOptions:[{name:"new",value:"new"},{name:"pending",value:"pending"},{name:"running",value:"running"},{name:"successful",value:"successful"},{name:"error",value:"error"},{name:"failed",value:"failed"},{name:"canceled",value:"canceled"}]}},fieldActions:{edit:{label:"View",ngClick:"edit('jobs', {{ job.id }}, '{{ job.name }}')",icon:"icon-zoom-in"}}}}});angular.module("OrganizationFormDefinition",[]).value("OrganizationForm",{addTitle:"Create Organization",editTitle:"{{ name }}",name:"organization",well:!0,fields:{name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!0},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1}},buttons:{save:{label:"Save",icon:"icon-ok","class":"btn-success",ngClick:"formSave()",ngDisabled:!0},reset:{ngClick:"formReset()",label:"Reset",icon:"icon-remove",ngDisabled:!0}},related:{users:{type:"collection",
|
||||
title:"Users",iterator:"user",open:!1,actions:{add:{ngClick:"add('users')",label:"Add",icon:"icon-plus",awToolTip:"Add a new user"}},fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('users', {{ user.id }}, '{{ user.username }}')",icon:"icon-edit","class":"btn-success",awToolTip:"Edit user"},"delete":{label:"Delete",ngClick:"delete('users', {{ user.id }}, '{{ user.username }}', 'users')",icon:"icon-remove",
|
||||
"class":"btn-danger",awToolTip:"Remove user"}}},admins:{type:"collection",title:"Administrators",iterator:"admin",open:!1,base:"/users",actions:{add:{ngClick:"add('admins')",icon:"icon-plus",label:"Add",awToolTip:"Add new administrator"}},fields:{username:{key:!0,label:"Username"},first_name:{label:"First Name"},last_name:{label:"Last Name"}},fieldActions:{edit:{label:"Edit",ngClick:"edit('users', {{ admin.id }}, '{{ admin.username }}')",icon:"icon-edit","class":"btn-success",awToolTip:"Edit administrator"},
|
||||
"delete":{label:"Delete",ngClick:"delete('admins', {{ admin.id }}, '{{ admin.username }}', 'administrators')",icon:"icon-remove","class":"btn-danger",awToolTip:"Remove administrator"}}}}});angular.module("PermissionFormDefinition",[]).value("PermissionsForm",{addTitle:"Add Permission",editTitle:"{{ name }}",name:"permission",well:!0,fields:{category:{label:"Permission Type",type:"radio",options:[{label:"Inventory",value:"Inventory"},{label:"Deployment",value:"Deploy"}],ngChange:"selectCategory()"},name:{label:"Name",type:"text",addRequired:!0,editRequired:!0,capitalize:!0},description:{label:"Description",type:"text",addRequired:!1,editRequired:!1},user:{label:"User",type:"hidden"},
|
||||
@ -318,37 +323,38 @@ b+=a.ngShow?this.attr(a,"ngShow"):"";b+=">\n";b+='<label class="control-label" f
|
||||
'ng-slider="'+c+'" ':"";b+='ng-model="'+c+'" ';b+='name="'+c+'" ';b+=a.min||0==a.min?this.attr(a,"min"):"";b+=a.max?this.attr(a,"max"):"";b+=a.ngChange?this.attr(a,"ngChange"):"";b+=a.slider?'id="'+c+'-number"':a.id?this.attr(a,"id"):"";b+="edit"==d.mode&&a.editRequired?"required ":"";b+="add"==d.mode&&a.addRequired?"required ":"";b+=a.readonly?"readonly ":"";b+=a.integer?"integer ":"";b+="/>\n";b+="<br />\n";if("add"==d.mode&&a.addRequired||"edit"==d.mode&&a.editRequired)b+='<span class="error" ng-show="'+
|
||||
this.form.name+"_form."+c+".$dirty && "+this.form.name+"_form."+c+'.$error.required">A value is required!</span>\n';a.integer&&(b+='<span class="error" ng-show="'+this.form.name+"_form."+c+'.$error.integer">Must be an integer value</span>\n');if(a.min||a.max)b+='<span class="error" ng-show="'+this.form.name+"_form."+c+".$error.min || "+this.form.name+"_form."+c+'.$error.max">Must be in range '+a.min+" to "+a.max+"</span>\n";b+='<span class="error api-error" ng-bind="'+c+'_api_error"></span>\n';b+=
|
||||
"</div>\n";b+="</div>\n"}if("checkbox"==a.type&&(!a.readonly||a.readonly&&"edit"==d.mode))b+='<div class="control-group" ',b+=a.ngShow?this.attr(a,"ngShow"):"",b+=">\n",b+='<div class="controls">\n',b+='<label class="checkbox">',b+="<input ",b+=this.attr(a,"type"),b+='ng-model="'+c+'" ',b+='name="'+c+'" ',b+=a.ngChange?this.attr(a,"ngChange"):"",b+=a.id?this.attr(a,"id"):"",b+=this.attr(a,"trueValue"),b+=this.attr(a,"falseValue"),b+=a.checked?"checked ":"",b+=a.readonly?"readonly ":"",b+=" /> "+a.label+
|
||||
"\n",b+="</label>\n",b+='<span class="error api-error" ng-bind="'+c+'_api_error"></span>\n',b+="</div>\n",b+="</div>\n";if("radio"==a.type&&(!a.readonly||a.readonly&&"edit"==d.mode)){b+='<div class="control-group" ';b+=a.ngShow?this.attr(a,"ngShow"):"";b+=">\n";b+='<label class="control-label" for="'+c+'">';a.awPopOver&&(b+='<a href="" '+this.attr(a,"awPopOver"),b+=a.dataTitle?this.attr(a,"dataTitle"):"",b+=a.dataPlacement?this.attr(a,"dataPlacement"):"",b+='><i class="icon-info-sign"></i></a> ');
|
||||
for(var b=b+(a.label+"</label>\n"),b=b+'<div class="controls">\n',e=0;e<a.options.length;e++)b+='<label class="radio inline" ',b+=a.options[e].ngShow?this.attr(a.options[e],"ngShow"):"",b+=">",b+='<input type="radio" ',b+='name="'+c+'" ',b+='value="'+a.options[e].value+'" ',b+='ng-model="'+c+'" ',b+=a.ngChange?this.attr(a,"ngChange"):"",b+=a.readonly?"readonly ":"",b+="edit"==d.mode&&a.editRequired?"required ":"",b+="add"==d.mode&&a.addRequired?"required ":"",b+=" /> "+a.options[e].label+"\n",b+=
|
||||
"</label>\n";if("add"==d.mode&&a.addRequired||"edit"==d.mode&&a.editRequired)b+='<p><span class="error" ng-show="'+this.form.name+"_form."+c+".$dirty && "+this.form.name+"_form."+c+'.$error.required">A value is required!</span></p>\n';b+='<p><span class="error api-error" ng-bind="'+c+'_api_error"></span></p>\n';b+="</div>\n";b+="</div>\n"}if("hidden"==a.type&&("edit"==d.mode&&a.includeOnEdit||"add"==d.mode&&a.includeOnAdd))b+='<input type="hidden" ng-model="'+c+'" name="'+c+'" />';if("lookup"==a.type&&
|
||||
(void 0==a.excludeMode||a.excludeMode!=d.mode)){b+='<div class="control-group"';b+=a.ngShow?this.attr(a,"ngShow"):"";b+=">\n";b+='<label class="control-label" for="'+c+'">';a.awPopOver&&(b+='<a href="" '+this.attr(a,"awPopOver"),b+=a.dataTitle?this.attr(a,"dataTitle"):"",b+=a.dataPlacement?this.attr(a,"dataPlacement"):"",b+='><i class="icon-info-sign"></i></a> ');b+=a.label+"</label>\n";b+='<div class="controls">\n';b+='<div class="input-prepend">\n';b+='<button class="lookup-btn btn" '+this.attr(a,
|
||||
"ngClick")+'><i class="icon-search"></i></button>\n';b+='<input class="input-medium" type="text" ';b+='ng-model="'+a.sourceModel+"_"+a.sourceField+'" ';b+='name="'+a.sourceModel+"_"+a.sourceField+'" ';b+=a.ngChange?this.attr(a,"ngChange"):"";b+=a.id?this.attr(a,"id"):"";b+=a.placeholder?this.attr(a,"placeholder"):"";b+="edit"==d.mode&&a.editRequired?"required ":"";b+=a.awRequiredWhen?'data-awrequired-init="'+a.awRequiredWhen.init+'" aw-required-when="'+a.awRequiredWhen.variable+'" ':"";b+=" awlookup />\n";
|
||||
b+="</div><br />\n";if("add"==d.mode&&a.addRequired||"edit"==d.mode&&a.editRequired||a.awRequiredWhen)b+='<span class="error" ng-show="'+this.form.name+"_form."+a.sourceModel+"_"+a.sourceField+".$dirty && "+this.form.name+"_form."+a.sourceModel+"_"+a.sourceField+'.$error.required">A value is required!</span>\n';b+='<span class="error" ng-show="'+this.form.name+"_form."+a.sourceModel+"_"+a.sourceField+".$dirty && "+this.form.name+"_form."+a.sourceModel+"_"+a.sourceField+'.$error.awlookup">Value not found</span>\n';
|
||||
b+='<span class="error api-error" ng-bind="'+a.sourceModel+"_"+a.sourceField+'_api_error"></span>\n';b+="</div>\n";b+="</div>\n"}if("custom"==a.type&&(!a.readonly||a.readonly&&"edit"==d.mode))b+='<div class="control-group"',b+=a.ngShow?this.attr(a,"ngShow"):"",b+=">\n",b+='<label class="control-label',b+=a.labelClass?" "+a.labelClass:"",b+='" for="'+c+'">',a.awPopOver&&(b+='<a href="" '+this.attr(a,"awPopOver"),b+=a.dataTitle?this.attr(a,"dataTitle"):"",b+=a.dataPlacement?this.attr(a,"dataPlacement"):
|
||||
"",b+='><i class="icon-info-sign"></i></a> '),b+=a.icon?this.icon(a.icon):"",b+=a.label+"</label>\n",b+='<div class="controls">\n',b+=a.control,b+="</div>\n",b+="</div>\n";return b},build:function(c){var a="";this.modal||(a+='<div class="nav-path">\n<ul class="breadcrumb">\n',a+='<li ng-repeat="crumb in breadcrumbs"><a href="{{ \'#\' + crumb.path }}">{{ crumb.title | capitalize }}</a> <span class="divider">/</span></li>\n',a+='<li class="active">',a="edit"==c.mode?a+this.form.editTitle:a+this.form.addTitle,
|
||||
a+="</li>\n</ul>\n</div>\n");if(!this.modal&&this.form.statusFields){a+='<div class="well">\n';if(this.form.statusActions){var a=a+'<div class="status-actions">\n',d;for(action in this.form.statusActions)d=this.form.statusActions[action],a+="<button "+this.attr(d,"ngClick")+'class="btn btn-small',a+=d["class"]?" "+d["class"]:"",a+='" ',a+=d.awToolTip?this.attr(d,"awToolTip"):"",a+=d.awToolTip?'data-placement="top" ':"",a+=" >"+this.icon(d.icon),a+=d.label?d.label:"",a+="</button> ";a+="</div>\n";
|
||||
a+='<div class="status-spin"><i class="icon-spinner icon-spin" ng-show="statusSearchSpin == true"></i></div>\n'}var a=a+'<div class="status-fields">\n',b;for(b in this.form.statusFields)d=this.form.statusFields[b],a+=this.buildField(b,d,c);a+="</div>\x3c!-- status fields --\x3e\n";a+="</div>\x3c!-- well --\x3e\n"}if(this.form.fieldsAsHeader){a+='<div class="well">\n';a+='<form class="form-inline" name="'+this.form.name+'_form" id="'+this.form.name+'" novalidate >\n';for(b in this.form.fields)d=this.form.fields[b],
|
||||
a+=this.headerField(b,d,c);a+="</form>\n";a+="</div>\n"}else{this.form.collapse&&this.form.collapseMode==c.mode&&(a+='<div id="'+this.form.name+'-collapse-0" ',a+=this.form.collapseOpen?'data-open="true" ':"",a+='class="jqui-accordion">\n',a+="<h3>"+this.form.collapseTitle+"<h3>\n",a+="<div>\n");this.has("well")&&(a+='<div class="well">\n');a+='<form class="form-horizontal';a+=this.form["class"]?" "+this.form["class"]:"";a+='" name="'+this.form.name+'_form" id="'+this.form.name+'" autocomplete="false" novalidate>\n';
|
||||
a+='<div ng-show="flashMessage != null && flashMessage != undefined" class="alert alert-info">{{ flashMessage }}</div>\n';if(this.form.twoColumns){a+='<div class="row-fluid">\n';a+='<div class="span6">\n';for(b in this.form.fields)d=this.form.fields[b],1==d.column&&(a+=this.buildField(b,d,c));a+="</div>\x3c!-- column 1 --\x3e\n";a+='<div class="span6">\n';for(b in this.form.fields)d=this.form.fields[b],2==d.column&&(a+=this.buildField(b,d,c));a+="</div>\x3c!-- column 2 --\x3e\n";a+="</div>\x3c!-- inner row --\x3e\n"}else for(b in this.form.fields)d=
|
||||
this.form.fields[b],a+=this.buildField(b,d,c);if(!this.modal){this.has("buttons")&&(a+=this.form.twoColumns?"<hr />":"",a+='<div class="control-group">\n',a+='<div class="controls buttons">\n');for(var e in this.form.buttons)d=this.form.buttons[e],a+="<button ",a+='class="btn btn-small',a+=d["class"]?" "+d["class"]:"",a+='" ',d.ngClick&&(a+=this.attr(d,"ngClick")),d.ngDisabled&&(a="reset"!==e?a+('ng-disabled="'+this.form.name+"_form.$pristine || "+this.form.name+"_form.$invalid"):a+('ng-disabled="'+
|
||||
this.form.name+"_form.$pristine"),a+=this.form.allowReadonly?" || "+this.form.name+"ReadOnly == true":"",a+='" '),a+=">",d.icon&&(a+=this.icon(d.icon)),a+=d.label+"</button>\n";this.has("buttons")&&(a+="</div>\n",a+="</div>\n");a+="</form>\n"}this.has("well")&&(a+="</div>\n");this.form.collapse&&this.form.collapseMode==c.mode&&(a+="</div>\n",a+="</div>\n")}if(!this.modal&&this.form.items)for(itm in this.form.items){a+='<div class="well form-items">\n';a+=g({iterator:this.form.items[itm].iterator,
|
||||
template:this.form.items[itm],mini:!1,label:"Filter Events"});a+='<div class="item-count pull-right">Viewing {{ '+this.form.items[itm].iterator+"Page + 1 }} of {{ "+this.form.items[itm].iterator+"Count }}</div>\n";a+="<hr />\n";a+='<ul class="pager">\n';a+='<li ng-class="'+this.form.items[itm].iterator+'PrevUrlDisable"><a href="" ng-click="prevSet(\''+this.form.items[itm].set+"','"+this.form.items[itm].iterator+"')\">← Prev</a></li>\n";a+='<li ng-class="'+this.form.items[itm].iterator+'NextUrlDisable"><a href="" ng-click="nextSet(\''+
|
||||
this.form.items[itm].set+"','"+this.form.items[itm].iterator+"')\">→ Next</a></li>\n";a+="</ul>\n";a+='<form class="form-horizontal" name="'+this.form.name+'_items_form" id="'+this.form.name+'_items_form" novalidate>\n';for(b in this.form.items[itm].fields)d=this.form.items[itm].fields[b],a+=this.buildField(b,d,c);a+="</form>\n";a+='<ul class="pager">\n';a+='<li ng-class="'+this.form.items[itm].iterator+'PrevUrlDisable"><a href="" ng-click="prevSet(\''+this.form.items[itm].set+"','"+this.form.items[itm].iterator+
|
||||
"')\">← Prev</a></li>\n";a+='<li ng-class="'+this.form.items[itm].iterator+'NextUrlDisable"><a href="" ng-click="nextSet(\''+this.form.items[itm].set+"','"+this.form.items[itm].iterator+"')\">→ Next</a></li>\n";a+="</ul>\n";a+="</div>\x3c!-- well --\x3e\n"}"inventory"==this.form.name&&"edit"==c.mode?a+=this.buildTree(c):!this.modal&&(c.related&&this.form.related)&&(a+=this.buildCollections(c));return a},buildTree:function(f){var a=1,d=this.form;html='<div id="'+this.form.name+'-collapse-2" data-open="true" class="jqui-accordion">\n';
|
||||
html+="<h3>Inventory Content<h3>\n";html+="<div>\n";for(var b in d.related){if("tree"==d.related[b].type)html+='<div class="span5">',html+='<div class="inventory-buttons">',html+='<button ng-click="addGroup()" ng-hide="groupAddHide" id="inv-group-add" class="btn btn-mini btn-success" aw-tool-tip="Add existing groups or create a new group" data-placement="bottom"><i class="icon-plus"></i> Add Groups</button>',html+='<button ng-click="editGroup()" ng-hide="groupEditHide" id="inv-group-edit" class="btn btn-mini btn-success" aw-tool-tip="Edit the selected group" data-placement="bottom" <i class="icon-edit"></i> Edit Group</button>',
|
||||
html+='<button ng-click="deleteGroup()" ng-hide="groupDeleteHide" id="inv-group-delete" aw-tool-tip="Delete the selected group" data-placement="bottom" class="btn btn-mini btn-danger"><i class="icon-remove"></i> Delete Group</button>',html+="</div>\n",html+='<div id="tree-view"></div>\n',html+='<div class=" inventory-filter">',html+='<span ng-show="has_active_failures == true"><label class="checkbox inline">',html+='<input ng-model="inventoryFailureFilter" ng-change="filterInventory()" type="checkbox">Show only groups with failures</label></span></div>\n',
|
||||
html+="</div>\n";else{html+='<div id="group-view" class="span7">\n';html+='<div id="hosts-well" class="well">\n';html+='<h4 id="hosts-title">'+d.related[b].title+"</h4>\n";html+=g({iterator:d.related[b].iterator,template:d.related[b],mini:!0});html+='<div class="list-actions">\n';for(var h in d.related[b].actions)html+='<button class="btn btn-mini ',html+=d.related[b].actions[h]["class"]?d.related[b].actions[h]["class"]:"btn-success",html+='" ',html+=d.related[b].actions[h].id?this.attr(d.related[b].actions[h],
|
||||
"id"):"",html+=this.attr(d.related[b].actions[h],"ngClick"),html+=d.related[b].actions[h].awToolTip?this.attr(d.related[b].actions[h],"awToolTip"):"",html+=d.related[b].actions[h].awToolTip?'data-placement="top" ':"",html+=d.related[b].actions[h].ngHide?this.attr(d.related[b].actions[h],"ngHide"):"",html+='><i class="'+d.related[b].actions[h].icon+'"></i>',html+=d.related[b].actions[h].label?" "+d.related[b].actions[h].label:"",html+="</button>\n";html+="</div>\n";html+='<div class="list">\n';html+=
|
||||
'<table class="'+d.related[b].iterator+' table table-condensed table-hover">\n';html+="<thead>\n";html+="<tr>\n";html+="<th>#</th>\n";for(var l in d.related[b].fields)html+='<th class="list-header" id="'+d.related[b].iterator+"-"+l+'-header" ng-click="sort(\''+d.related[b].iterator+"', '"+l+"')\">"+d.related[b].fields[l].label,html+=' <i class="',html=d.related[b].fields[l].key?d.related[b].fields[l].desc?html+"icon-sort-down":html+"icon-sort-up":html+"icon-sort",html+='"></i></a></th>\n';html+="<th></th>\n";
|
||||
html+="</tr>\n";html+="</thead>";html+="<tbody>\n";html+='<tr ng-repeat="'+d.related[b].iterator+" in "+b+'" >\n';html+="<td>{{ $index + ("+d.related[b].iterator+"Page * "+d.related[b].iterator+"PageSize) + 1 }}.</td>\n";var m=1,p=d.related[b].base?d.related[b].base:b,p=p.replace(/^\//,"");for(l in d.related[b].fields)m++,html+=e({list:d.related[b],fld:l,options:f,base:p});html+='<td class="actions">';for(h in d.related[b].fieldActions)html+='<button class="btn btn-mini',html+=d.related[b].fieldActions[h]["class"]?
|
||||
" "+d.related[b].fieldActions[h]["class"]:"",html+='" ',html+=d.related[b].fieldActions[h].awToolTip?this.attr(d.related[b].fieldActions[h],"awToolTip"):"",html+=this.attr(d.related[b].fieldActions[h],"ngClick")+">"+this.icon(d.related[b].fieldActions[h].icon),html+=d.related[b].fieldActions[h].label?" "+d.related[b].fieldActions[h].label:"",html+="</button> ";html+="</td>";html+="</tr>\n";html+='<tr class="info" ng-show="'+d.related[b].iterator+"Loading == false && ("+b+" == null || "+b+'.length == 0)">\n';
|
||||
html+='<td colspan="'+m+'"><div class="alert alert-info">No records matched your search.</div></td>\n';html+="</tr>\n";html+='<tr class="info" ng-show="'+d.related[b].iterator+'Loading == true">\n';html+='<td colspan="'+m+'"><div class="alert alert-info">Loading...</div></td>\n';html+="</tr>\n";html+="</tbody>\n";html+="</table>\n";html+="</div>\n";html+="</div>\n";html+=c({set:b,iterator:d.related[b].iterator,mini:!0})}a++}html+="</div>\n";return html+="</div>\n"},buildCollections:function(f){var a=
|
||||
1,d=this.form;html='<div id="'+this.form.name+"-collapse-"+a+'" class="jqui-accordion">\n';for(var b in d.related)if("collection"==d.related[b].type){html+="<h3>"+d.related[b].title+"<h3>\n";html+="<div>\n";d.related[b].instructions&&(html+='<div class="alert alert-info alert-block">\n',html+='<button type="button" class="close" data-dismiss="alert">×</button>\n',html+="<strong>Hint: </strong>"+d.related[b].instructions+"\n",html+="</div>\n");html+='<div class="well">\n';html+=g({iterator:d.related[b].iterator,
|
||||
template:d.related[b],mini:!0});html+='<div class="list-actions">\n';for(var h in d.related[b].actions){var l=d.related[b].actions[h];html+='<button class="btn btn-small ';html+=d.related[b].actions[h]["class"]?d.related[b].actions[h]["class"]:"btn-success";html+='" ';html+=this.attr(l,"ngClick");html+=l.awToolTip?this.attr(l,"awToolTip"):"";html+=l.awToolTip?'data-placement="right" ':"";html+='><i class="'+l.icon+'"></i>';html+=l.label?" "+l.label:"";html+="</button>\n"}html+="</div>\n";html+='<div class="list">\n';
|
||||
html+='<table class="'+d.related[b].iterator+' table table-condensed table-hover">\n';html+="<thead>\n";html+="<tr>\n";html+=void 0==d.related[b].index||!1!==d.related[b].index?"<th>#</th>\n":"";for(var m in d.related[b].fields)html+='<th class="list-header" id="'+d.related[b].iterator+"-"+m+'-header" ng-click="sort(\''+d.related[b].iterator+"', '"+m+"')\">"+d.related[b].fields[m].label,html+=' <i class="',html=d.related[b].fields[m].key?d.related[b].fields[m].desc?html+"icon-sort-down":html+"icon-sort-up":
|
||||
html+"icon-sort",html+='"></i></a></th>\n';html+="<th></th>\n";html+="</tr>\n";html+="</thead>";html+="<tbody>\n";html+='<tr ng-repeat="'+d.related[b].iterator+" in "+b+'" >\n';if(void 0==d.related[b].index||!1!==d.related[b].index)html+="<td>{{ $index + ("+d.related[b].iterator+"Page * "+d.related[b].iterator+"PageSize) + 1 }}.</td>\n";var p=1,l=d.related[b].base?d.related[b].base:b,l=l.replace(/^\//,"");for(m in d.related[b].fields)p++,html+=e({list:d.related[b],fld:m,options:f,base:l});html+='<td class="actions">';
|
||||
for(h in d.related[b].fieldActions)l=d.related[b].fieldActions[h],html+='<button class="btn btn-small',html+=l["class"]?" "+l["class"]:"",html+='" '+this.attr(l,"ngClick"),html+=l.awToolTip?this.attr(l,"awToolTip"):"",html+=l.awToolTip?'data-placement="top" ':"",html+=">"+this.icon(l.icon),html+=l.label?" "+l.label:"",html+="</button> ";html+="</td>";html+="</tr>\n";html+='<tr class="info" ng-show="'+d.related[b].iterator+"Loading == false && ("+b+" == null || "+b+'.length == 0)">\n';html+='<td colspan="'+
|
||||
p+'"><div class="alert alert-info">No records matched your search.</div></td>\n';html+="</tr>\n";html+='<tr class="info" ng-show="'+d.related[b].iterator+'Loading == true">\n';html+='<td colspan="'+p+'"><div class="alert alert-info">Loading...</div></td>\n';html+="</tr>\n";html+="</tbody>\n";html+="</table>\n";html+="</div>\n";html+="</div>\n";html+=c({set:b,iterator:d.related[b].iterator,mini:!0});html+="</div>\n";a++}html+="</div>\n";return html+="</div>\n"}}}]);angular.module("GeneratorHelpers",["GeneratorHelpers"]).factory("Attr",function(){return function(l,m){var h;h="string"===typeof l[m]?l[m].replace(/\'/g,"""):l[m];switch(m){case "ngClick":h='ng-click="'+h+'" ';break;case "ngOptions":h='ng-options="'+h+'" ';break;case "ngClass":h='ng-class="'+h+'" ';break;case "ngChange":h='ng-change="'+h+'" ';break;case "ngDisabled":h='ng-disabled="'+h+'" ';break;case "ngShow":h='ng-show="'+h+'" ';break;case "ngHide":h='ng-hide="'+h+'" ';break;case "ngBind":h=
|
||||
"\n",a.awPopOver&&(b+='<a href="" '+this.attr(a,"awPopOver"),b+=a.dataTitle?this.attr(a,"dataTitle"):"",b+=a.dataPlacement?this.attr(a,"dataPlacement"):"",b+=a.dataContainer?this.attr(a,"dataContainer"):"",b+='><i class="icon-info-sign"></i></a> '),b+="</label>\n",b+='<span class="error api-error" ng-bind="'+c+'_api_error"></span>\n',b+="</div>\n",b+="</div>\n";if("radio"==a.type&&(!a.readonly||a.readonly&&"edit"==d.mode)){b+='<div class="control-group" ';b+=a.ngShow?this.attr(a,"ngShow"):"";b+=">\n";
|
||||
b+='<label class="control-label" for="'+c+'">';a.awPopOver&&(b+='<a href="" '+this.attr(a,"awPopOver"),b+=a.dataTitle?this.attr(a,"dataTitle"):"",b+=a.dataPlacement?this.attr(a,"dataPlacement"):"",b+='><i class="icon-info-sign"></i></a> ');for(var b=b+(a.label+"</label>\n"),b=b+'<div class="controls">\n',e=0;e<a.options.length;e++)b+='<label class="radio inline" ',b+=a.options[e].ngShow?this.attr(a.options[e],"ngShow"):"",b+=">",b+='<input type="radio" ',b+='name="'+c+'" ',b+='value="'+a.options[e].value+
|
||||
'" ',b+='ng-model="'+c+'" ',b+=a.ngChange?this.attr(a,"ngChange"):"",b+=a.readonly?"readonly ":"",b+="edit"==d.mode&&a.editRequired?"required ":"",b+="add"==d.mode&&a.addRequired?"required ":"",b+=" /> "+a.options[e].label+"\n",b+="</label>\n";if("add"==d.mode&&a.addRequired||"edit"==d.mode&&a.editRequired)b+='<p><span class="error" ng-show="'+this.form.name+"_form."+c+".$dirty && "+this.form.name+"_form."+c+'.$error.required">A value is required!</span></p>\n';b+='<p><span class="error api-error" ng-bind="'+
|
||||
c+'_api_error"></span></p>\n';b+="</div>\n";b+="</div>\n"}if("hidden"==a.type&&("edit"==d.mode&&a.includeOnEdit||"add"==d.mode&&a.includeOnAdd))b+='<input type="hidden" ng-model="'+c+'" name="'+c+'" />';if("lookup"==a.type&&(void 0==a.excludeMode||a.excludeMode!=d.mode)){b+='<div class="control-group"';b+=a.ngShow?this.attr(a,"ngShow"):"";b+=">\n";b+='<label class="control-label" for="'+c+'">';a.awPopOver&&(b+='<a href="" '+this.attr(a,"awPopOver"),b+=a.dataTitle?this.attr(a,"dataTitle"):"",b+=a.dataPlacement?
|
||||
this.attr(a,"dataPlacement"):"",b+='><i class="icon-info-sign"></i></a> ');b+=a.label+"</label>\n";b+='<div class="controls">\n';b+='<div class="input-prepend">\n';b+='<button class="lookup-btn btn" '+this.attr(a,"ngClick")+'><i class="icon-search"></i></button>\n';b+='<input class="input-medium" type="text" ';b+='ng-model="'+a.sourceModel+"_"+a.sourceField+'" ';b+='name="'+a.sourceModel+"_"+a.sourceField+'" ';b+=a.ngChange?this.attr(a,"ngChange"):"";b+=a.id?this.attr(a,"id"):"";b+=a.placeholder?
|
||||
this.attr(a,"placeholder"):"";b+="edit"==d.mode&&a.editRequired?"required ":"";b+=a.awRequiredWhen?'data-awrequired-init="'+a.awRequiredWhen.init+'" aw-required-when="'+a.awRequiredWhen.variable+'" ':"";b+=" awlookup />\n";b+="</div><br />\n";if("add"==d.mode&&a.addRequired||"edit"==d.mode&&a.editRequired||a.awRequiredWhen)b+='<span class="error" ng-show="'+this.form.name+"_form."+a.sourceModel+"_"+a.sourceField+".$dirty && "+this.form.name+"_form."+a.sourceModel+"_"+a.sourceField+'.$error.required">A value is required!</span>\n';
|
||||
b+='<span class="error" ng-show="'+this.form.name+"_form."+a.sourceModel+"_"+a.sourceField+".$dirty && "+this.form.name+"_form."+a.sourceModel+"_"+a.sourceField+'.$error.awlookup">Value not found</span>\n';b+='<span class="error api-error" ng-bind="'+a.sourceModel+"_"+a.sourceField+'_api_error"></span>\n';b+="</div>\n";b+="</div>\n"}if("custom"==a.type&&(!a.readonly||a.readonly&&"edit"==d.mode))b+='<div class="control-group"',b+=a.ngShow?this.attr(a,"ngShow"):"",b+=">\n",b+='<label class="control-label',
|
||||
b+=a.labelClass?" "+a.labelClass:"",b+='" for="'+c+'">',a.awPopOver&&(b+='<a href="" '+this.attr(a,"awPopOver"),b+=a.dataTitle?this.attr(a,"dataTitle"):"",b+=a.dataPlacement?this.attr(a,"dataPlacement"):"",b+='><i class="icon-info-sign"></i></a> '),b+=a.icon?this.icon(a.icon):"",b+=a.label+"</label>\n",b+='<div class="controls">\n',b+=a.control,b+="</div>\n",b+="</div>\n";return b},build:function(c){var a="";this.modal||(a+='<div class="nav-path">\n<ul class="breadcrumb">\n',a+='<li ng-repeat="crumb in breadcrumbs"><a href="{{ \'#\' + crumb.path }}">{{ crumb.title | capitalize }}</a> <span class="divider">/</span></li>\n',
|
||||
a+='<li class="active">',a="edit"==c.mode?a+this.form.editTitle:a+this.form.addTitle,a+="</li>\n</ul>\n</div>\n");if(!this.modal&&this.form.statusFields){a+='<div class="well">\n';if(this.form.statusActions){var a=a+'<div class="status-actions">\n',d;for(action in this.form.statusActions)d=this.form.statusActions[action],a+="<button "+this.attr(d,"ngClick")+'class="btn btn-small',a+=d["class"]?" "+d["class"]:"",a+='" ',a+=d.awToolTip?this.attr(d,"awToolTip"):"",a+=d.awToolTip?'data-placement="top" ':
|
||||
"",a+=" >"+this.icon(d.icon),a+=d.label?d.label:"",a+="</button> ";a+="</div>\n";a+='<div class="status-spin"><i class="icon-spinner icon-spin" ng-show="statusSearchSpin == true"></i></div>\n'}var a=a+'<div class="status-fields">\n',b;for(b in this.form.statusFields)d=this.form.statusFields[b],a+=this.buildField(b,d,c);a+="</div>\x3c!-- status fields --\x3e\n";a+="</div>\x3c!-- well --\x3e\n"}if(this.form.fieldsAsHeader){a+='<div class="well">\n';a+='<form class="form-inline" name="'+this.form.name+
|
||||
'_form" id="'+this.form.name+'" novalidate >\n';for(b in this.form.fields)d=this.form.fields[b],a+=this.headerField(b,d,c);a+="</form>\n";a+="</div>\n"}else{this.form.collapse&&this.form.collapseMode==c.mode&&(a+='<div id="'+this.form.name+'-collapse-0" ',a+=this.form.collapseOpen?'data-open="true" ':"",a+='class="jqui-accordion">\n',a+="<h3>"+this.form.collapseTitle+"<h3>\n",a+="<div>\n");this.has("well")&&(a+='<div class="well">\n');a+='<form class="form-horizontal';a+=this.form["class"]?" "+this.form["class"]:
|
||||
"";a+='" name="'+this.form.name+'_form" id="'+this.form.name+'" autocomplete="false" novalidate>\n';a+='<div ng-show="flashMessage != null && flashMessage != undefined" class="alert alert-info">{{ flashMessage }}</div>\n';if(this.form.twoColumns){a+='<div class="row-fluid">\n';a+='<div class="span6">\n';for(b in this.form.fields)d=this.form.fields[b],1==d.column&&(a+=this.buildField(b,d,c));a+="</div>\x3c!-- column 1 --\x3e\n";a+='<div class="span6">\n';for(b in this.form.fields)d=this.form.fields[b],
|
||||
2==d.column&&(a+=this.buildField(b,d,c));a+="</div>\x3c!-- column 2 --\x3e\n";a+="</div>\x3c!-- inner row --\x3e\n"}else for(b in this.form.fields)d=this.form.fields[b],a+=this.buildField(b,d,c);if(!this.modal){this.has("buttons")&&(a+=this.form.twoColumns?"<hr />":"",a+='<div class="control-group">\n',a+='<div class="controls buttons">\n');for(var e in this.form.buttons)d=this.form.buttons[e],a+="<button ",a+='class="btn btn-small',a+=d["class"]?" "+d["class"]:"",a+='" ',d.ngClick&&(a+=this.attr(d,
|
||||
"ngClick")),d.ngDisabled&&(a="reset"!==e?a+('ng-disabled="'+this.form.name+"_form.$pristine || "+this.form.name+"_form.$invalid"):a+('ng-disabled="'+this.form.name+"_form.$pristine"),a+=this.form.allowReadonly?" || "+this.form.name+"ReadOnly == true":"",a+='" '),a+=">",d.icon&&(a+=this.icon(d.icon)),a+=d.label+"</button>\n";this.has("buttons")&&(a+="</div>\n",a+="</div>\n");a+="</form>\n"}this.has("well")&&(a+="</div>\n");this.form.collapse&&this.form.collapseMode==c.mode&&(a+="</div>\n",a+="</div>\n")}if(!this.modal&&
|
||||
this.form.items)for(itm in this.form.items){a+='<div class="well form-items">\n';a+=g({iterator:this.form.items[itm].iterator,template:this.form.items[itm],mini:!1,label:"Filter Events"});a+='<div class="item-count pull-right">Viewing {{ '+this.form.items[itm].iterator+"Page + 1 }} of {{ "+this.form.items[itm].iterator+"Count }}</div>\n";a+="<hr />\n";a+='<ul class="pager">\n';a+='<li ng-class="'+this.form.items[itm].iterator+'PrevUrlDisable"><a href="" ng-click="prevSet(\''+this.form.items[itm].set+
|
||||
"','"+this.form.items[itm].iterator+"')\">← Prev</a></li>\n";a+='<li ng-class="'+this.form.items[itm].iterator+'NextUrlDisable"><a href="" ng-click="nextSet(\''+this.form.items[itm].set+"','"+this.form.items[itm].iterator+"')\">→ Next</a></li>\n";a+="</ul>\n";a+='<form class="form-horizontal" name="'+this.form.name+'_items_form" id="'+this.form.name+'_items_form" novalidate>\n';for(b in this.form.items[itm].fields)d=this.form.items[itm].fields[b],a+=this.buildField(b,d,c);a+="</form>\n";
|
||||
a+='<ul class="pager">\n';a+='<li ng-class="'+this.form.items[itm].iterator+'PrevUrlDisable"><a href="" ng-click="prevSet(\''+this.form.items[itm].set+"','"+this.form.items[itm].iterator+"')\">← Prev</a></li>\n";a+='<li ng-class="'+this.form.items[itm].iterator+'NextUrlDisable"><a href="" ng-click="nextSet(\''+this.form.items[itm].set+"','"+this.form.items[itm].iterator+"')\">→ Next</a></li>\n";a+="</ul>\n";a+="</div>\x3c!-- well --\x3e\n"}"inventory"==this.form.name&&"edit"==c.mode?a+=
|
||||
this.buildTree(c):!this.modal&&(c.related&&this.form.related)&&(a+=this.buildCollections(c));return a},buildTree:function(f){var a=1,d=this.form;html='<div id="'+this.form.name+'-collapse-2" data-open="true" class="jqui-accordion">\n';html+="<h3>Inventory Content<h3>\n";html+="<div>\n";for(var b in d.related){if("tree"==d.related[b].type)html+='<div class="span5">',html+='<div class="inventory-buttons">',html+='<button ng-click="addGroup()" ng-hide="groupAddHide" id="inv-group-add" class="btn btn-mini btn-success" aw-tool-tip="Add existing groups or create a new group" data-placement="bottom"><i class="icon-plus"></i> Add Groups</button>',
|
||||
html+='<button ng-click="editGroup()" ng-hide="groupEditHide" id="inv-group-edit" class="btn btn-mini btn-success" aw-tool-tip="Edit the selected group" data-placement="bottom" <i class="icon-edit"></i> Edit Group</button>',html+='<button ng-click="deleteGroup()" ng-hide="groupDeleteHide" id="inv-group-delete" aw-tool-tip="Delete the selected group" data-placement="bottom" class="btn btn-mini btn-danger"><i class="icon-remove"></i> Delete Group</button>',html+="</div>\n",html+='<div id="tree-view"></div>\n',
|
||||
html+='<div class=" inventory-filter">',html+='<span ng-show="has_active_failures == true"><label class="checkbox inline">',html+='<input ng-model="inventoryFailureFilter" ng-change="filterInventory()" type="checkbox">Show only groups with failures</label></span></div>\n',html+="</div>\n";else{html+='<div id="group-view" class="span7">\n';html+='<div id="hosts-well" class="well">\n';html+='<h4 id="hosts-title">'+d.related[b].title+"</h4>\n";html+=g({iterator:d.related[b].iterator,template:d.related[b],
|
||||
mini:!0});html+='<div class="list-actions">\n';for(var h in d.related[b].actions)html+='<button class="btn btn-mini ',html+=d.related[b].actions[h]["class"]?d.related[b].actions[h]["class"]:"btn-success",html+='" ',html+=d.related[b].actions[h].id?this.attr(d.related[b].actions[h],"id"):"",html+=this.attr(d.related[b].actions[h],"ngClick"),html+=d.related[b].actions[h].awToolTip?this.attr(d.related[b].actions[h],"awToolTip"):"",html+=d.related[b].actions[h].awToolTip?'data-placement="top" ':"",html+=
|
||||
d.related[b].actions[h].ngHide?this.attr(d.related[b].actions[h],"ngHide"):"",html+='><i class="'+d.related[b].actions[h].icon+'"></i>',html+=d.related[b].actions[h].label?" "+d.related[b].actions[h].label:"",html+="</button>\n";html+="</div>\n";html+='<div class="list">\n';html+='<table class="'+d.related[b].iterator+' table table-condensed table-hover">\n';html+="<thead>\n";html+="<tr>\n";html+="<th>#</th>\n";for(var l in d.related[b].fields)html+='<th class="list-header" id="'+d.related[b].iterator+
|
||||
"-"+l+'-header" ng-click="sort(\''+d.related[b].iterator+"', '"+l+"')\">"+d.related[b].fields[l].label,html+=' <i class="',html=d.related[b].fields[l].key?d.related[b].fields[l].desc?html+"icon-sort-down":html+"icon-sort-up":html+"icon-sort",html+='"></i></a></th>\n';html+="<th></th>\n";html+="</tr>\n";html+="</thead>";html+="<tbody>\n";html+='<tr ng-repeat="'+d.related[b].iterator+" in "+b+'" >\n';html+="<td>{{ $index + ("+d.related[b].iterator+"Page * "+d.related[b].iterator+"PageSize) + 1 }}.</td>\n";
|
||||
var m=1,p=d.related[b].base?d.related[b].base:b,p=p.replace(/^\//,"");for(l in d.related[b].fields)m++,html+=e({list:d.related[b],fld:l,options:f,base:p});html+='<td class="actions">';for(h in d.related[b].fieldActions)html+='<button class="btn btn-mini',html+=d.related[b].fieldActions[h]["class"]?" "+d.related[b].fieldActions[h]["class"]:"",html+='" ',html+=d.related[b].fieldActions[h].awToolTip?this.attr(d.related[b].fieldActions[h],"awToolTip"):"",html+=this.attr(d.related[b].fieldActions[h],"ngClick")+
|
||||
">"+this.icon(d.related[b].fieldActions[h].icon),html+=d.related[b].fieldActions[h].label?" "+d.related[b].fieldActions[h].label:"",html+="</button> ";html+="</td>";html+="</tr>\n";html+='<tr class="info" ng-show="'+d.related[b].iterator+"Loading == false && ("+b+" == null || "+b+'.length == 0)">\n';html+='<td colspan="'+m+'"><div class="alert alert-info">No records matched your search.</div></td>\n';html+="</tr>\n";html+='<tr class="info" ng-show="'+d.related[b].iterator+'Loading == true">\n';html+=
|
||||
'<td colspan="'+m+'"><div class="alert alert-info">Loading...</div></td>\n';html+="</tr>\n";html+="</tbody>\n";html+="</table>\n";html+="</div>\n";html+="</div>\n";html+=c({set:b,iterator:d.related[b].iterator,mini:!0})}a++}html+="</div>\n";return html+="</div>\n"},buildCollections:function(f){var a=1,d=this.form;html='<div id="'+this.form.name+"-collapse-"+a+'" class="jqui-accordion">\n';for(var b in d.related)if("collection"==d.related[b].type){html+="<h3>"+d.related[b].title+"<h3>\n";html+="<div>\n";
|
||||
d.related[b].instructions&&(html+='<div class="alert alert-info alert-block">\n',html+='<button type="button" class="close" data-dismiss="alert">×</button>\n',html+="<strong>Hint: </strong>"+d.related[b].instructions+"\n",html+="</div>\n");html+='<div class="well">\n';html+=g({iterator:d.related[b].iterator,template:d.related[b],mini:!0});html+='<div class="list-actions">\n';for(var h in d.related[b].actions){var l=d.related[b].actions[h];html+='<button class="btn btn-small ';html+=d.related[b].actions[h]["class"]?
|
||||
d.related[b].actions[h]["class"]:"btn-success";html+='" ';html+=this.attr(l,"ngClick");html+=l.awToolTip?this.attr(l,"awToolTip"):"";html+=l.awToolTip?'data-placement="right" ':"";html+='><i class="'+l.icon+'"></i>';html+=l.label?" "+l.label:"";html+="</button>\n"}html+="</div>\n";html+='<div class="list">\n';html+='<table class="'+d.related[b].iterator+' table table-condensed table-hover">\n';html+="<thead>\n";html+="<tr>\n";html+=void 0==d.related[b].index||!1!==d.related[b].index?"<th>#</th>\n":
|
||||
"";for(var m in d.related[b].fields)html+='<th class="list-header" id="'+d.related[b].iterator+"-"+m+'-header" ng-click="sort(\''+d.related[b].iterator+"', '"+m+"')\">"+d.related[b].fields[m].label,html+=' <i class="',html=d.related[b].fields[m].key?d.related[b].fields[m].desc?html+"icon-sort-down":html+"icon-sort-up":html+"icon-sort",html+='"></i></a></th>\n';html+="<th></th>\n";html+="</tr>\n";html+="</thead>";html+="<tbody>\n";html+='<tr ng-repeat="'+d.related[b].iterator+" in "+b+'" >\n';if(void 0==
|
||||
d.related[b].index||!1!==d.related[b].index)html+="<td>{{ $index + ("+d.related[b].iterator+"Page * "+d.related[b].iterator+"PageSize) + 1 }}.</td>\n";var p=1,l=d.related[b].base?d.related[b].base:b,l=l.replace(/^\//,"");for(m in d.related[b].fields)p++,html+=e({list:d.related[b],fld:m,options:f,base:l});html+='<td class="actions">';for(h in d.related[b].fieldActions)l=d.related[b].fieldActions[h],html+='<button class="btn btn-small',html+=l["class"]?" "+l["class"]:"",html+='" '+this.attr(l,"ngClick"),
|
||||
html+=l.awToolTip?this.attr(l,"awToolTip"):"",html+=l.awToolTip?'data-placement="top" ':"",html+=">"+this.icon(l.icon),html+=l.label?" "+l.label:"",html+="</button> ";html+="</td>";html+="</tr>\n";html+='<tr class="info" ng-show="'+d.related[b].iterator+"Loading == false && ("+b+" == null || "+b+'.length == 0)">\n';html+='<td colspan="'+p+'"><div class="alert alert-info">No records matched your search.</div></td>\n';html+="</tr>\n";html+='<tr class="info" ng-show="'+d.related[b].iterator+'Loading == true">\n';
|
||||
html+='<td colspan="'+p+'"><div class="alert alert-info">Loading...</div></td>\n';html+="</tr>\n";html+="</tbody>\n";html+="</table>\n";html+="</div>\n";html+="</div>\n";html+=c({set:b,iterator:d.related[b].iterator,mini:!0});html+="</div>\n";a++}html+="</div>\n";return html+="</div>\n"}}}]);angular.module("GeneratorHelpers",["GeneratorHelpers"]).factory("Attr",function(){return function(l,m){var h;h="string"===typeof l[m]?l[m].replace(/\'/g,"""):l[m];switch(m){case "ngClick":h='ng-click="'+h+'" ';break;case "ngOptions":h='ng-options="'+h+'" ';break;case "ngClass":h='ng-class="'+h+'" ';break;case "ngChange":h='ng-change="'+h+'" ';break;case "ngDisabled":h='ng-disabled="'+h+'" ';break;case "ngShow":h='ng-show="'+h+'" ';break;case "ngHide":h='ng-hide="'+h+'" ';break;case "ngBind":h=
|
||||
'ng-bind="'+h+'" ';break;case "trueValue":h='ng-true-value="'+h+'" ';break;case "falseValue":h='ng-false-value="'+h+'" ';break;case "awToolTip":h='aw-tool-tip="'+h+'" ';break;case "awPopOver":h="aw-pop-over='"+h+"' ";break;case "dataTitle":h='data-title="'+h+'" ';break;case "dataPlacement":h='data-placement="'+h+'" ';break;case "dataContainer":h='data-container="'+h+'" ';break;case "icon":h='<i class="'+h+(l.iconSize?" icon-"+l.iconSize:"");h+='"></i>';break;case "autocomplete":h='autocomplete="'+
|
||||
(h?"true":"false");h+='" ';break;default:h=m+'="'+h+'" '}return h}}).factory("Icon",function(){return function(l){return'<i class="'+l+'"></i> '}}).factory("Column",["Attr","Icon",function(l,m){return function(h){var g=h.list,c=h.fld,p=h.options;h=h.base;var f=g.fields[c],e;e="<td "+('<td class="'+c+"-column");e+=f["class"]?" "+f["class"]:"";e+=f.columnClass?" "+f.columnClass:"";e+='" ';e+=f.ngClass?l(f,"ngClass"):"";e+=">\n";e+=f.ngShow?"<span "+l(f,"ngShow")+">":"";g.hasChildren&&f.hasChildren&&
|
||||
(e+='<span class="level-{{ '+g.iterator+'.event_level }}"><a href="" ng-click="{{ '+g.iterator+'.ngclick }}"> <i class="{{ '+g.iterator+'.ngicon }}" ng-show="\'{{ '+g.iterator+".related.children }}' !== ''\" ></i></a> ");if((f.key||f.link||f.linkTo||f.ngClick)&&"lookup"!=p.mode&&"select"!=p.mode)if(f.linkTo)e+='<a href="#'+f.linkTo+'">';else if(f.ngClick)e+='<a href=""'+l(f,"ngClick")+'">';else if(void 0==f.link||f.link)e+='<a href="#/'+h+"/{{"+g.iterator+'.id }}">';f.ngShowIcon?e+='<i ng-show="'+
|
||||
|
||||
@ -384,7 +384,7 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
|
||||
check_field: 'allow_callbacks',
|
||||
default_val: dft
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
// Retrieve detail record and prepopulate the form
|
||||
@ -437,6 +437,9 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
|
||||
}
|
||||
}
|
||||
|
||||
scope['callback_url'] = data.related['callback'];
|
||||
master['callback_url'] = scope['callback_url'];
|
||||
|
||||
LookUpInit({
|
||||
scope: scope,
|
||||
form: form,
|
||||
@ -493,7 +496,7 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
|
||||
data[fld] = scope[fld].value;
|
||||
}
|
||||
else {
|
||||
if (fld != 'variables') {
|
||||
if (fld != 'variables' && fld != 'callback_url') {
|
||||
data[fld] = scope[fld];
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,6 +226,7 @@ function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams,
|
||||
check_field: 'allow_callbacks',
|
||||
default_val: dft
|
||||
});
|
||||
scope['callback_url'] = data.related['callback'];
|
||||
$('input[type="checkbox"]').attr('disabled','disabled');
|
||||
$('#host_config_key-gen-btn').attr('disabled','disabled');
|
||||
})
|
||||
|
||||
@ -154,14 +154,52 @@ angular.module('JobTemplateFormDefinition', [])
|
||||
falseValue: 'false',
|
||||
ngChange: "toggleCallback('host_config_key')",
|
||||
"class": "span12",
|
||||
column: 2
|
||||
column: 2,
|
||||
awPopOver: "<p>Create a callback URL a host can use to contact the AWX server and request a configuration update " +
|
||||
"using the job template. The URL will look like the following:</p>\n" +
|
||||
"<p class=\"code-breakable\">http://your.server.com:999/api/v1/job_templates/1/callback/</p>" +
|
||||
"<p>The request from the host must be a POST. Here is an example using curl:</p>\n" +
|
||||
"<p class=\"code-breakable\">curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
|
||||
"http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n" +
|
||||
"<p>Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address " +
|
||||
"in one of your defined inventories, the request will be denied.</p>" +
|
||||
"<p>Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.</p>",
|
||||
detailPlacement: 'left',
|
||||
dataContainer: '#job_templates',
|
||||
dataTitle: 'Callback URL'
|
||||
},
|
||||
callback_url: {
|
||||
label: 'Callback URL',
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
readonly: true,
|
||||
column: 2,
|
||||
required: false,
|
||||
'class': 'span12',
|
||||
awPopOver: "<p>Using this URL a host can contact the AWX server and request a configuration update using the job " +
|
||||
"template. The request from the host must be a POST. Here is an example using curl:</p>\n" +
|
||||
"<p class=\"code-breakable\">curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
|
||||
"http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n" +
|
||||
"<p>Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address " +
|
||||
"in one of your defined inventories, the request will be denied.</p>" +
|
||||
"<p>Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.</p>",
|
||||
detailPlacement: 'left',
|
||||
dataContainer: '#job_templates',
|
||||
dataTitle: 'Callback URL'
|
||||
},
|
||||
host_config_key: {
|
||||
label: 'Host Config Key',
|
||||
type: 'text',
|
||||
ngShow: "allow_callbacks",
|
||||
genMD5: true,
|
||||
column: 2
|
||||
column: 2,
|
||||
awPopOver: "<p>When contacting the AWX server using the callback URL, the calling host must authenticate by including " +
|
||||
"this key in the POST data of the request. Here's an example using curl:</p>\n" +
|
||||
"<p class=\"code-breakable\">curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
|
||||
"http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n",
|
||||
detailPlacement: 'left',
|
||||
dataContainer: '#job_templates'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -148,14 +148,52 @@ angular.module('JobFormDefinition', [])
|
||||
falseValue: 'false',
|
||||
ngChange: "toggleCallback('host_config_key')",
|
||||
"class": "span12",
|
||||
column: 2
|
||||
column: 2,
|
||||
awPopOver: "<p>Create a callback URL a host can use to contact the AWX server and request a configuration update " +
|
||||
"using the job template. The URL will look like the following:</p>\n" +
|
||||
"<p class=\"code-breakable\">http://your.server.com:999/api/v1/job_templates/1/callback/</p>" +
|
||||
"<p>The request from the host must be a POST. Here is an example using curl:</p>\n" +
|
||||
"<p class=\"code-breakable\">curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
|
||||
"http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n" +
|
||||
"<p>Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address " +
|
||||
"in one of your defined inventories, the request will be denied.</p>" +
|
||||
"<p>Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.</p>",
|
||||
detailPlacement: 'left',
|
||||
dataContainer: '#jobs',
|
||||
dataTitle: 'Callback URL'
|
||||
},
|
||||
callback_url: {d
|
||||
label: 'Callback URL',
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
readonly: true,
|
||||
column: 2,
|
||||
required: false,
|
||||
'class': 'span12',
|
||||
awPopOver: "<p>Using this URL a host can contact the AWX server and request a configuration update using the job " +
|
||||
"template. The request from the host must be a POST. Here is an example using curl:</p>\n" +
|
||||
"<p class=\"code-breakable\">curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
|
||||
"http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n" +
|
||||
"<p>Note the requesting host must be defined in your inventory. If ansible fails to locate the host either by name or IP address " +
|
||||
"in one of your defined inventories, the request will be denied.</p>" +
|
||||
"<p>Successful requests will result in an entry on the Jobs tab, where the results and history can be viewed.</p>",
|
||||
detailPlacement: 'left',
|
||||
dataContainer: '#jobs',
|
||||
dataTitle: 'Callback URL'
|
||||
},
|
||||
host_config_key: {
|
||||
label: 'Host Config Key',
|
||||
type: 'text',
|
||||
ngShow: "allow_callbacks",
|
||||
genMD5: true,
|
||||
column: 2
|
||||
column: 2,
|
||||
awPopOver: "<p>When contacting the AWX server using the callback URL, the calling host must authenticate by including " +
|
||||
"this key in the POST data of the request. Here's an example using curl:</p>\n" +
|
||||
"<p class=\"code-breakable\">curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
|
||||
"http://your.server.com:999/api/v1/job_templates/1/callback/</p>\n",
|
||||
detailPlacement: 'left',
|
||||
dataContainer: '#jobs'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -425,6 +425,13 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
|
||||
html += (field.checked) ? "checked " : "";
|
||||
html += (field.readonly) ? "readonly " : "";
|
||||
html += " /> " + field.label + "\n";
|
||||
if (field.awPopOver) {
|
||||
html += "<a href=\"\" " + this.attr(field,'awPopOver');
|
||||
html += (field.dataTitle) ? this.attr(field, 'dataTitle') : "";
|
||||
html += (field.dataPlacement) ? this.attr(field, 'dataPlacement') : "";
|
||||
html += (field.dataContainer) ? this.attr(field, 'dataContainer') : "";
|
||||
html += "><i class=\"icon-info-sign\"></i></a> ";
|
||||
}
|
||||
html += "</label>\n";
|
||||
html += "<span class=\"error api-error\" ng-bind=\"" + fld + "_api_error\"></span>\n";
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user