function JobViewModel(repo, build, job, status) { var self = this; self.status = status; self.stream = function() { $( "#output" ).html(""); $("#restart").hide(); $("#cancel").show(); var buf = new Drone.Buffer(); buf.start(document.getElementById("output")); $( "#tail" ).show(); $( "#tail" ).click(function() { buf.autoFollow = !buf.autoFollow; if (buf.autoFollow) { $( "#tail i" ).text("pause"); $( "#tail" ).show(); // scroll to the bottom of the page window.scrollTo(0, document.body.scrollHeight); } else { $( "#tail i" ).text("expand_more"); $( "#tail" ).show(); } }) Stream(repo, build, job, function(out){ buf.write(out); }); }; if (status !== "running" && status !== "pending") { Logs(repo, build, job); $("#restart").show(); } if (status === "running") { self.stream(); } $("#restart").click(function() { $("#restart").hide(); $("#output").html(""); $(".status").attr("class", "status pending").text("pending"); $.ajax({ url: "/api/repos/"+repo+"/builds/"+build, type: "POST", success: function( data ) { }, error: function( data ) { console.log(data); } }); }) $("#cancel").click(function() { $("#cancel").hide(); $.ajax({ url: "/api/repos/"+repo+"/builds/"+build+"/"+job, type: "DELETE", success: function( data ) { }, error: function( data ) { console.log(data); } }); }) Subscribe(repo, function(data){ if (!data.jobs) { return; } if (data.number !== build) { return; } var before = self.status; self.status = data.jobs[job-1].status; // update the status for each job in the view for (var i=0;i