azkaban-uncached

Details

diff --git a/src/java/azkaban/webapp/servlet/velocity/projectpage.vm b/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
index f5b0d4e..8837399 100644
--- a/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
@@ -62,21 +62,21 @@
 			<div class="alert alert-success">$success_message</div>
 	#end
 
-## Alert message
+	## Alert message
 
 			<div class="alert alert-dismissable" id="messaging">
 				<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
 				<p id="messaging-message"></p>
 			</div>
 
-## Page header.
+	## Page header.
 
 			<div class="page-header">
 				<h1><a href="${context}/manager?project=${project.name}">Project <small>$project.name</small></a></h1>
 				<p>$project.description</p>
 			</div>
 
-## Page content.
+	## Page content.
 
 			<div class="row">
 				<div class="col-lg-8">
diff --git a/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm b/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm
index 0987dd6..e839b26 100644
--- a/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm
@@ -17,17 +17,13 @@
 <!DOCTYPE html> 
 <html>
 	<head>
-#parse( "azkaban/webapp/servlet/velocity/style.vm" )
+
+#parse ("azkaban/webapp/servlet/velocity/style2.vm")
+#parse ("azkaban/webapp/servlet/velocity/javascript.vm")
+
 		<link rel="stylesheet" type="text/css" href="${context}/css/jquery-ui-1.10.1.custom.css" />
-		<link rel="stylesheet" type="text/css" href="${context}/css/jquery-ui.css" />
 		
-		<script type="text/javascript" src="${context}/js/jquery/jquery-1.9.1.js"></script>    
 		<script type="text/javascript" src="${context}/js/jqueryui/jquery-ui-1.10.1.custom.js"></script>
-		<script type="text/javascript" src="${context}/js/underscore-1.4.4-min.js"></script>
-		<script type="text/javascript" src="${context}/js/namespace.js"></script>
-		<script type="text/javascript" src="${context}/js/backbone-0.9.10-min.js"></script>
-		<script type="text/javascript" src="${context}/js/jquery.simplemodal-1.4.4.js"></script>
-		
 		<script type="text/javascript" src="${context}/js/jqueryui/jquery-ui-timepicker-addon.js"></script> 
 		<script type="text/javascript" src="${context}/js/jqueryui/jquery-ui-sliderAccess.js"></script>
 		<script type="text/javascript" src="${context}/js/azkaban.table.sort.js"></script>
@@ -42,123 +38,139 @@
 		</script>
 	</head>
 	<body>
-#set($current_page="schedule")
-#parse( "azkaban/webapp/servlet/velocity/nav.vm" )
-		<div class="messaging"><p id="messageClose">X</p><p id="message"></p></div>  
 
-		<div class="content">
-		
-#if($errorMsg)
-		<div class="box-error-message">$errorMsg</div>
-#else
-#if($error_message != "null")
-		<div class="box-error-message">$error_message</div>
-#elseif($success_message != "null")
-		<div class="box-success-message">$success_message</div>
-#end
-#end		
-		
-			<div id="all-scheduledFlows-content">
-				<div class="section-hd">
-					<h2>Scheduled Flows</h2>
+#set ($current_page="schedule")
+#parse ("azkaban/webapp/servlet/velocity/nav2.vm")
+
+		<div class="container">
+
+## Page error or success message.
+
+#if ($errorMsg)
+			<div class="panel panel-danger">
+				<div class="panel-heading">Error</div>
+				<div class="panel-body">
+					$errorMsg
 				</div>
 			</div>
-			
-			<div class="scheduledFlows">
-				<table id="scheduledFlowsTbl">
-					<thead>
-						<tr>
-							<!--th class="execid">Execution Id</th-->
-							<th>ID</th>
-							<th>Flow</th>
-							<th>Project</th>
-							<th>Submitted By</th>
-							<th class="date">First Scheduled to Run</th>
-							<th class="date">Next Execution Time</th>
-							<th class="date">Repeats Every</th>
-							<th>Has SLA</th>
-							<th colspan="2" class="action ignoresort">Action</th>
-						</tr>
-					</thead>
-					<tbody>
-#if(!$schedules.isEmpty())
-	#foreach($sched in $schedules)
-						<tr class="row" >
-
-							<td>${sched.scheduleId}</td>
-							<td class="tb-name">
-								<a href="${context}/manager?project=${sched.projectName}&flow=${sched.flowName}">${sched.flowName}</a>
-							</td>
-							<td>
-								<a href="${context}/manager?project=${sched.projectName}">${sched.projectName}</a>
-							</td>
-							<td>${sched.submitUser}</td>
-							<td>$utils.formatDateTime(${sched.firstSchedTime})</td>
-							<td>$utils.formatDateTime(${sched.nextExecTime})</td>
-							<td>$utils.formatPeriod(${sched.period})</td>
-							<td>#if(${sched.slaOptions}) true #else false #end</td>
-							<td><button id="removeSchedBtn" onclick="removeSched(${sched.scheduleId})" >Remove Schedule</button></td>
-							<td><button id="addSlaBtn" onclick="slaView.initFromSched(${sched.scheduleId}, '${sched.flowName}')" >Set SLA</button></td>
-						</tr>
-	#end
 #else
-						<tr><td class="last">No Scheduled Flow Found</td></tr>
-#end
-					</tbody>
-				</table>
+	#if ($error_message != "null")
+			<div class="alert alert-danger">$error_message</div>
+	#elseif ($success_message != "null")
+			<div class="alert alert-success">$success_message</div>
+	#end
+
+## Alert message
+
+			<div class="alert alert-dismissable" id="messaging">
+				<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
+				<p id="messaging-message"></p>
 			</div>
 
-		<!-- modal content -->
+	## Page header.
 
-		<div id="slaModalBackground" class="modalBackground2">
-			<div id="sla-options" class="modal modalContainer2">
-				<a href='#' title='Close' class='modal-close'>x</a>
-					<h3>SLA Options</h3>
-					<div>
-						<ul class="optionsPicker">
-							<li id="slaOptions">General SLA Options</li>
-						</ul>
-					</div>
-					<div class="optionsPane">
-						<div id="generalPanel" class="generalPanel panel">
-							<div id="slaActions">
-								<h4>SLA Alert Emails</h4>
-								<dl>
-									<dt >SLA Alert Emails</dt>
-									<dd>
-										<textarea id="slaEmails"></textarea>
-									</dd>
-								</dl>
-							</div>
-							<br></br>
-							<div id="slaRules">
-								<h4>Flow SLA Rules</h4>
-								<div class="tableDiv">
-									<table id="flowRulesTbl">
-										<thead>
-											<tr>
-												<th>Flow/Job</th>
-												<th>Sla Rule</th>
-												<th>Duration</th>
-												<th>Email Action</th>
-												<th>Kill Action</th>
-											</tr>
-										</thead>
-										<tbody>
-											<tr id="addRow"><td id="addRow-col" colspan="5"><span class="addIcon"></span><a href="#">Add Row</a></td></tr>
-										</tbody>
-									</table>
+			<div class="page-header">
+				<h1>Scheduled Flows</h1>
+			</div>
+
+	## Page content.
+
+			<div class="row">
+				<div class="col-lg-12">
+					<table id="scheduledFlowsTbl" class="table table-striped">
+						<thead>
+							<tr>
+								<!--th class="execid">Execution Id</th-->
+								<th>ID</th>
+								<th>Flow</th>
+								<th>Project</th>
+								<th>Submitted By</th>
+								<th class="date">First Scheduled to Run</th>
+								<th class="date">Next Execution Time</th>
+								<th class="date">Repeats Every</th>
+								<th>Has SLA</th>
+								<th colspan="2" class="action ignoresort">Action</th>
+							</tr>
+						</thead>
+						<tbody>
+	#if(!$schedules.isEmpty())
+		#foreach($sched in $schedules)
+							<tr>
+								<td>${sched.scheduleId}</td>
+								<td class="tb-name">
+									<a href="${context}/manager?project=${sched.projectName}&flow=${sched.flowName}">${sched.flowName}</a>
+								</td>
+								<td>
+									<a href="${context}/manager?project=${sched.projectName}">${sched.projectName}</a>
+								</td>
+								<td>${sched.submitUser}</td>
+								<td>$utils.formatDateTime(${sched.firstSchedTime})</td>
+								<td>$utils.formatDateTime(${sched.nextExecTime})</td>
+								<td>$utils.formatPeriod(${sched.period})</td>
+								<td>#if(${sched.slaOptions}) true #else false #end</td>
+								<td><button type="button" id="removeSchedBtn" class="btn btn-sm btn-danger" onclick="removeSched(${sched.scheduleId})" >Remove Schedule</button></td>
+								<td><button type="button" id="addSlaBtn" class="btn btn-sm btn-primary" onclick="slaView.initFromSched(${sched.scheduleId}, '${sched.flowName}')" >Set SLA</button></td>
+							</tr>
+
+		#end
+	#else
+							<tr>
+								<td class="last">No scheduled flow found.</td>
+							</tr>
+	#end
+						</tbody>
+					</table>
+				</div>
+			</div><!-- /row -->
+
+## Set SLA modal.
+
+			<div class="modal modal-wide fade" id="sla-options">
+				<div class="modal-dialog">
+					<div class="modal-content">
+						<div class="modal-header">
+							<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+							<h4 class="modal-title">SLA Options</h4>
+						</div>
+						<div class="modal-body">
+							<h4>SLA Alert Emails</h4>
+							<fieldset>
+								<div class="form-group">
+									<label>SLA Alert Emails</label>
+									<textarea id="slaEmails" class="form-control"></textarea>
 								</div>
-							
-							</div>
+							</fieldset>
+							<h4>Flow SLA Rules</h4>
+							<table class="table table-striped" id="flowRulesTbl">
+								<thead>
+									<tr>
+										<th>Flow/Job</th>
+										<th>Sla Rule</th>
+										<th>Duration</th>
+										<th>Email Action</th>
+										<th>Kill Action</th>
+									</tr>
+								</thead>
+								<tbody>
+									<tr id="addRow">
+										<td id="addRow-col" colspan="5">
+											<span class="addIcon"></span>
+											<button type="button" class="btn btn-xs btn-success">Add Row</button>
+										</td>
+									</tr>
+								</tbody>
+							</table>
+						</div>
+						<div class="modal-footer">
+							<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
+							<!--<button type="button" class="btn btn-danger" id="remove-sla-btn">Remove SLA</button>-->
+							<button type="button" class="btn btn-primary" id="set-sla-btn">Set/Change SLA</button>
 						</div>
 					</div>
-					<div class="actions">
-						<!--a class="yes btn1" id="remove-sla-btn" href="#">Remove SLA</a-->
-						<a class="yes btn1" id="set-sla-btn" href="#">Set/Change SLA</a>
-						<a class="no simplemodal-close btn3" id="sla-cancel-btn" href="#">Cancel</a>
-					</div>
+				</div>
 			</div>
+#end
+
 		</div>
 	</body>
 </html>
diff --git a/src/web/js/azkaban.permission.view.js b/src/web/js/azkaban.permission.view.js
index 5cfc495..e142c89 100644
--- a/src/web/js/azkaban.permission.view.js
+++ b/src/web/js/azkaban.permission.view.js
@@ -19,34 +19,40 @@ $.namespace('azkaban');
 var permissionTableView;
 var groupPermissionTableView;
 
-azkaban.PermissionTableView= Backbone.View.extend({
-  events : {
-	"click button": "handleChangePermission"
-  },
-  initialize : function(settings) {
-  	this.group = settings.group;
-  	this.proxy = settings.proxy;
-  },
-  render: function() {
-  },
-  handleChangePermission: function(evt) {
-  	  var currentTarget = evt.currentTarget;
-  	  changePermissionView.display(currentTarget.id, false, this.group, this.proxy);
-  }
+azkaban.PermissionTableView = Backbone.View.extend({
+	events : {
+		"click button": "handleChangePermission"
+	},
+	
+	initialize : function(settings) {
+		this.group = settings.group;
+		this.proxy = settings.proxy;
+	},
+	
+	render: function() {
+	},
+	
+	handleChangePermission: function(evt) {
+		var currentTarget = evt.currentTarget;
+		changePermissionView.display(currentTarget.id, false, this.group, this.proxy);
+	}
 });
 
 var proxyTableView;
 azkaban.ProxyTableView= Backbone.View.extend({
-  events : {
-	"click button": "handleRemoveProxy"
-  },
-  initialize : function(settings) {
-  },
-  render: function() {
-  },
-  handleRemoveProxy: function(evt) {
-	removeProxyView.display($(evt.currentTarget).attr("name"));
-  }
+	events : {
+		"click button": "handleRemoveProxy"
+	},
+	
+	initialize : function(settings) {
+	},
+	
+	render: function() {
+	},
+	
+	handleRemoveProxy: function(evt) {
+		removeProxyView.display($(evt.currentTarget).attr("name"));
+	}
 });
 
 var removeProxyView;
@@ -54,46 +60,48 @@ azkaban.RemoveProxyView = Backbone.View.extend({
 	events: {
 		"click #remove-proxy-btn": "handleRemoveProxy"
 	},
+	
 	initialize : function(settings) {
 		$('#removeProxyErrorMsg').hide();
 	},
+	
 	display: function(proxyName) {
 		this.el.proxyName = proxyName;
 		$("#proxyRemoveMsg").text("Removing proxy user '" + proxyName + "'");
-	  	 $(this.el).modal({
-	          closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
-	          position: ["20%",],
-	          containerId: 'confirm-container',
-	          containerCss: {
-	            'height': '220px',
-	            'width': '565px'
-	          },
-	          onShow: function (dialog) {
-	            var modal = this;
-	            $("#removeProxyErrorMsg").hide();
-	          }
-        });
+		$(this.el).modal({
+			closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
+			position: ["20%",],
+			containerId: 'confirm-container',
+			containerCss: {
+				'height': '220px',
+				'width': '565px'
+			},
+			onShow: function (dialog) {
+				var modal = this;
+				$("#removeProxyErrorMsg").hide();
+			}
+		});
 	},
 	handleRemoveProxy: function() {
-	  	var requestURL = contextURL + "/manager";
+		var requestURL = contextURL + "/manager";
 		var proxyName = this.el.proxyName;
+		var requestData = {
+			"project": projectName, 
+			"name": proxyName, 
+			"ajax": "removeProxyUser"
+		};
+		var successHandler = function(data) {
+			console.log("Output");
+			if (data.error) {
+				$("#removeProxyErrorMsg").text(data.error);
+				$("#removeProxyErrorMsg").show();
+				return;
+			}
+			var replaceURL = requestURL + "?project=" + projectName +"&permissions";
+			window.location.replace(replaceURL);
+		};
 
-	  	$.get(
-	  	      requestURL,
-	  	      {"project": projectName, "name": proxyName, "ajax":"removeProxyUser"},
-	  	      function(data) {
-	  	      	  console.log("Output");
-	  	      	  if (data.error) {
-	  	      	  	$("#removeProxyErrorMsg").text(data.error);
-	  	      	  	$("#removeProxyErrorMsg").show();
-	  	      	  	return;
-	  	      	  }
-	  	      	  
-	  	      	  var replaceURL = requestURL + "?project=" + projectName +"&permissions";
-	  	          window.location.replace(replaceURL);
-	  	      },
-	  	      "json"
-	  	    );
+		$.get(requestURL, requestData, successHandler, "json");
 	}
 });
 
@@ -102,233 +110,265 @@ azkaban.AddProxyView = Backbone.View.extend({
 	events: {
 		"click #add-proxy-btn": "handleAddProxy"
 	},
+	
 	initialize : function(settings) {
 		$('#proxyErrorMsg').hide();
 	},
+	
 	display: function() {
-	  	 $(this.el).modal({
-	          closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
-	          position: ["20%",],
-	          containerId: 'confirm-container',
-	          containerCss: {
-	            'height': '220px',
-	            'width': '565px'
-	          },
-	          onShow: function (dialog) {
-	            var modal = this;
-	            $("#errorMsg").hide();
-	          }
-        });
+		$(this.el).modal({
+			closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
+			position: ["20%",],
+			containerId: 'confirm-container',
+			containerCss: {
+				'height': '220px',
+				'width': '565px'
+			},
+			onShow: function (dialog) {
+				var modal = this;
+				$("#errorMsg").hide();
+			}
+		});
 	},
+	
 	handleAddProxy: function() {
-	  	var requestURL = contextURL + "/manager";
-	  	var name = $('#proxy-user-box').val();
-		
-	  	$.get(
-	  	      requestURL,
-	  	      {"project": projectName, "name": name, "ajax":"addProxyUser"},
-	  	      function(data) {
-	  	      	  console.log("Output");
-	  	      	  if (data.error) {
-	  	      	  	$("#proxyErrorMsg").text(data.error);
-	  	      	  	$("#proxyErrorMsg").show();
-	  	      	  	return;
-	  	      	  }
-	  	      	  
-	  	      	  var replaceURL = requestURL + "?project=" + projectName +"&permissions";
-	  	          window.location.replace(replaceURL);
-	  	      },
-	  	      "json"
-	  	    );
+		var requestURL = contextURL + "/manager";
+		var name = $('#proxy-user-box').val();
+		var requestData = {
+			"project": projectName, 
+			"name": name, 
+			"ajax":"addProxyUser"
+		};
+	
+		var successHandler = function(data) {
+			console.log("Output");
+			if (data.error) {
+				$("#proxyErrorMsg").text(data.error);
+				$("#proxyErrorMsg").show();
+				return;
+			}
+			
+			var replaceURL = requestURL + "?project=" + projectName +"&permissions";
+			window.location.replace(replaceURL);
+		};
+		$.get(requestURL, requestData, successHandler, "json");
 	}
 });
 
 var changePermissionView;
 azkaban.ChangePermissionView= Backbone.View.extend({
-  events : {
-  	"click input[type=checkbox]": "handleCheckboxClick",
-  	"click #change-btn": "handleChangePermissions"
-  },
-  initialize : function(settings) {
-  	$('#errorMsg').hide();
-  },
-  display: function(userid, newPerm, group, proxy) {
-  	// 6 is the length of the prefix "group-"
-  	this.userid = group ? userid.substring(6, userid.length) : userid;
-  	if(group == true) {
-  		this.userid = userid.substring(6, userid.length)
-  	} else if (proxy == true) {
-  		this.userid = userid.substring(6, userid.length)
-  	} else {
-  		this.userid = userid
-  	}
-  	
-  	this.permission = {};
-	$('#user-box').val(this.userid);
-	this.newPerm = newPerm;
-	this.group = group;
+	events: {
+		"click input[type=checkbox]": "handleCheckboxClick",
+		"click #change-btn": "handleChangePermissions"
+	},
 	
-	var prefix = userid;
-	var adminInput = $("#" + prefix + "-admin-checkbox");
-	var readInput = $("#" + prefix + "-read-checkbox");
-	var writeInput = $("#" + prefix + "-write-checkbox");
-	var executeInput = $("#" + prefix + "-execute-checkbox");
-	var scheduleInput = $("#" + prefix + "-schedule-checkbox");
+	initialize: function(settings) {
+		$('#errorMsg').hide();
+	},
 	
-	if (newPerm) {
-		if (group) {
-			$('#change-title').text("Add New Group Permissions");
-		}
-		else if(proxy){
-			$('#change-title').text("Add New Proxy User Permissions");
+	display: function(userid, newPerm, group, proxy) {
+		// 6 is the length of the prefix "group-"
+		this.userid = group ? userid.substring(6, userid.length) : userid;
+		if(group == true) {
+			this.userid = userid.substring(6, userid.length)
+		} else if (proxy == true) {
+			this.userid = userid.substring(6, userid.length)
+		} else {
+			this.userid = userid
 		}
-		else{
-			$('#change-title').text("Add New User Permissions");
-		}
-		$('#user-box').attr("disabled", null);
 		
-		// default
-		this.permission.admin = false;
-		this.permission.read = true;
-		this.permission.write = false;
-		this.permission.execute = false;
-		this.permission.schedule = false;
-	}
-	else {
-		if (group) {
-			$('#change-title').text("Change Group Permissions");
+		this.permission = {};
+		$('#user-box').val(this.userid);
+		this.newPerm = newPerm;
+		this.group = group;
+		
+		var prefix = userid;
+		var adminInput = $("#" + prefix + "-admin-checkbox");
+		var readInput = $("#" + prefix + "-read-checkbox");
+		var writeInput = $("#" + prefix + "-write-checkbox");
+		var executeInput = $("#" + prefix + "-execute-checkbox");
+		var scheduleInput = $("#" + prefix + "-schedule-checkbox");
+		
+		if (newPerm) {
+			if (group) {
+				$('#change-title').text("Add New Group Permissions");
+			}
+			else if(proxy){
+				$('#change-title').text("Add New Proxy User Permissions");
+			}
+			else{
+				$('#change-title').text("Add New User Permissions");
+			}
+			$('#user-box').attr("disabled", null);
+			
+			// default
+			this.permission.admin = false;
+			this.permission.read = true;
+			this.permission.write = false;
+			this.permission.execute = false;
+			this.permission.schedule = false;
 		}
 		else {
-			$('#change-title').text("Change User Permissions");
+			if (group) {
+				$('#change-title').text("Change Group Permissions");
+			}
+			else {
+				$('#change-title').text("Change User Permissions");
+			}
+			
+			$('#user-box').attr("disabled", "disabled");
+			
+			this.permission.admin = $(adminInput).is(":checked");
+			this.permission.read = $(readInput).is(":checked");
+			this.permission.write = $(writeInput).is(":checked");
+			this.permission.execute = $(executeInput).is(":checked");
+			this.permission.schedule = $(scheduleInput).is(":checked");
 		}
 		
-		$('#user-box').attr("disabled", "disabled");
+		this.changeCheckbox();
 		
-		this.permission.admin = $(adminInput).is(":checked");
-		this.permission.read = $(readInput).is(":checked");
-		this.permission.write = $(writeInput).is(":checked");
-		this.permission.execute = $(executeInput).is(":checked");
-		this.permission.schedule = $(scheduleInput).is(":checked");
-	}
+		changePermissionView.render();
+		$('#change-permission').modal({
+			closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
+			position: ["20%",],
+			containerId: 'confirm-container',
+			containerCss: {
+				'height': '220px',
+				'width': '565px'
+			},
+			onShow: function (dialog) {
+				var modal = this;
+				$("#errorMsg").hide();
+			}
+		});
+	},
 	
-	this.changeCheckbox();
+	render: function() {
+	},
 	
-	changePermissionView.render();
-  	 $('#change-permission').modal({
-          closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
-          position: ["20%",],
-          containerId: 'confirm-container',
-          containerCss: {
-            'height': '220px',
-            'width': '565px'
-          },
-          onShow: function (dialog) {
-            var modal = this;
-            $("#errorMsg").hide();
-          }
-        });
-  },
-  render: function() {
-  },
-  handleCheckboxClick : function(evt) {
-  	console.log("click");
-  	var targetName = evt.currentTarget.name;
-  	if(targetName == "proxy") {
-  		this.doProxy = evt.currentTarget.checked;
-  	}
-  	else {
-  		this.permission[targetName] = evt.currentTarget.checked;
-  	}
-  	this.changeCheckbox(evt);
-  },
-  changeCheckbox : function(evt) {
-    var perm = this.permission;
+	handleCheckboxClick: function(evt) {
+		console.log("click");
+		var targetName = evt.currentTarget.name;
+		if(targetName == "proxy") {
+			this.doProxy = evt.currentTarget.checked;
+		}
+		else {
+			this.permission[targetName] = evt.currentTarget.checked;
+		}
+		this.changeCheckbox(evt);
+	},
+	
+	changeCheckbox: function(evt) {
+		var perm = this.permission;
 
-  	if (perm.admin) {
-  		$("#admin-change").attr("checked", true);
-  		$("#read-change").attr("checked", true);
-  		$("#read-change").attr("disabled", "disabled");
-  		
-  		$("#write-change").attr("checked", true);
-  		$("#write-change").attr("disabled", "disabled");
+		if (perm.admin) {
+			$("#admin-change").attr("checked", true);
+			$("#read-change").attr("checked", true);
+			$("#read-change").attr("disabled", "disabled");
+			
+			$("#write-change").attr("checked", true);
+			$("#write-change").attr("disabled", "disabled");
 
-  		$("#execute-change").attr("checked", true);
-  		$("#execute-change").attr("disabled", "disabled"); 
-  		
-  		$("#schedule-change").attr("checked", true);
-  		$("#schedule-change").attr("disabled", "disabled");
-  	}
-  	else {
-  		$("#admin-change").attr("checked", false);
-  		
-  		$("#read-change").attr("checked", perm.read);
-  		$("#read-change").attr("disabled", null);
-  		  		
-  		$("#write-change").attr("checked", perm.write);
-  		$("#write-change").attr("disabled", null);
-  		
-  		$("#execute-change").attr("checked", perm.execute);
-  		$("#execute-change").attr("disabled", null);
-  		
-  		$("#schedule-change").attr("checked", perm.schedule);
+			$("#execute-change").attr("checked", true);
+			$("#execute-change").attr("disabled", "disabled"); 
+			
+			$("#schedule-change").attr("checked", true);
+			$("#schedule-change").attr("disabled", "disabled");
+		}
+		else {
+			$("#admin-change").attr("checked", false);
+			
+			$("#read-change").attr("checked", perm.read);
+			$("#read-change").attr("disabled", null);
+						
+			$("#write-change").attr("checked", perm.write);
+			$("#write-change").attr("disabled", null);
+			
+			$("#execute-change").attr("checked", perm.execute);
+			$("#execute-change").attr("disabled", null);
+			
+			$("#schedule-change").attr("checked", perm.schedule);
 		$("#schedule-change").attr("disabled", null);
-  	}
-  	
-  	$("#change-btn").removeClass("btn-disabled");
-  	$("#change-btn").attr("disabled", null);
-  	
-  	if (perm.admin || perm.read || perm.write || perm.execute || perm.schedule) {
-  		$("#change-btn").text("Commit");
-  	}
-  	else {
-  		if(	this.newPerm) {
-  			$("#change-btn").disabled = true;
-  			$("#change-btn").addClass("btn-disabled");
-  		}
-  		else {
-  			$("#change-btn").text("Remove");
-  		}
-  	}
-  },
-  handleChangePermissions : function(evt) {
-  	var requestURL = contextURL + "/manager";
-  	var name = $('#user-box').val();
-	var command = this.newPerm ? "addPermission" : "changePermission";
-	var group = this.group;
-	
-	var permission = {};
-	permission.admin = $("#admin-change").is(":checked");
-	permission.read = $("#read-change").is(":checked");
-	permission.write = $("#write-change").is(":checked");
-	permission.execute = $("#execute-change").is(":checked");
-	permission.schedule = $("#schedule-change").is(":checked");
+		}
+		
+		$("#change-btn").removeClass("btn-disabled");
+		$("#change-btn").attr("disabled", null);
+		
+		if (perm.admin || perm.read || perm.write || perm.execute || perm.schedule) {
+			$("#change-btn").text("Commit");
+		}
+		else {
+			if(	this.newPerm) {
+				$("#change-btn").disabled = true;
+				$("#change-btn").addClass("btn-disabled");
+			}
+			else {
+				$("#change-btn").text("Remove");
+			}
+		}
+	},
 	
-  	$.get(
-	      requestURL,
-	      {"project": projectName, "name": name, "ajax":command, "permissions": this.permission, "group": group},
-	      function(data) {
-	      	  console.log("Output");
-	      	  if (data.error) {
-	      	  	$("#errorMsg").text(data.error);
-	      	  	$("#errorMsg").show();
-	      	  	return;
-	      	  }
-	      	  
-	      	  var replaceURL = requestURL + "?project=" + projectName +"&permissions";
-	          window.location.replace(replaceURL);
-	      },
-	      "json"
-	    );
-  }
+	handleChangePermissions : function(evt) {
+		var requestURL = contextURL + "/manager";
+		var name = $('#user-box').val();
+		var command = this.newPerm ? "addPermission" : "changePermission";
+		var group = this.group;
+		
+		var permission = {};
+		permission.admin = $("#admin-change").is(":checked");
+		permission.read = $("#read-change").is(":checked");
+		permission.write = $("#write-change").is(":checked");
+		permission.execute = $("#execute-change").is(":checked");
+		permission.schedule = $("#schedule-change").is(":checked");
+
+		var requestData = {
+			"project": projectName, 
+			"name": name, 
+			"ajax": command, 
+			"permissions": this.permission, 
+			"group": group
+		};
+		var successHandler = function(data) {
+			console.log("Output");
+			if (data.error) {
+				$("#errorMsg").text(data.error);
+				$("#errorMsg").show();
+				return;
+			}
+			
+			var replaceURL = requestURL + "?project=" + projectName +"&permissions";
+			window.location.replace(replaceURL);
+		};
+
+		$.get(requestURL, requestData, successHandler, "json");
+	}
 });
 
 $(function() {
-	permissionTableView = new azkaban.PermissionTableView({el:$('#permissions-table'), group: false, proxy: false});
-	groupPermissionTableView = new azkaban.PermissionTableView({el:$('#group-permissions-table'), group: true, proxy: false});
-	proxyTableView = new azkaban.ProxyTableView({el:$('#proxy-user-table'), group: false, proxy: true});
-	changePermissionView = new azkaban.ChangePermissionView({el:$('#change-permission')});
-	addProxyView = new azkaban.AddProxyView({el:$('#add-proxy')});
-	removeProxyView = new azkaban.RemoveProxyView({el:$('#remove-proxy')});
+	permissionTableView = new azkaban.PermissionTableView({
+		el: $('#permissions-table'), 
+		group: false, 
+		proxy: false
+	});
+	groupPermissionTableView = new azkaban.PermissionTableView({
+		el: $('#group-permissions-table'), 
+		group: true, 
+		proxy: false
+	});
+	proxyTableView = new azkaban.ProxyTableView({
+		el: $('#proxy-user-table'), 
+		group: false, 
+		proxy: true
+	});
+	changePermissionView = new azkaban.ChangePermissionView({
+		el: $('#change-permission')
+	});
+	addProxyView = new azkaban.AddProxyView({
+		el: $('#add-proxy')
+	});
+	removeProxyView = new azkaban.RemoveProxyView({
+		el: $('#remove-proxy')
+	});
 	$('#addUser').bind('click', function() {
 		changePermissionView.display("", true, false, false);
 	});
@@ -340,5 +380,4 @@ $(function() {
 	$('#addProxyUser').bind('click', function() {
 		addProxyView.display();
 	});
-	
 });
diff --git a/src/web/js/azkaban.project.view.js b/src/web/js/azkaban.project.view.js
index a9ba1ed..11354ed 100644
--- a/src/web/js/azkaban.project.view.js
+++ b/src/web/js/azkaban.project.view.js
@@ -91,6 +91,7 @@ azkaban.FlowTableView = Backbone.View.extend({
 	},
 
 	initialize: function(settings) {
+		$('#messaging').hide();
 	},
 
 	expandFlowProject: function(evt) {
@@ -130,7 +131,8 @@ azkaban.FlowTableView = Backbone.View.extend({
 			$.get(requestURL, requestData, successHandler, "json");
 		}
 	},
-	createJobListTable : function(data, innerTable) {
+	
+	createJobListTable: function(data, innerTable) {
 		var nodes = data.nodes;
 		var flowId = data.flowId;
 		var project = data.project;
@@ -192,6 +194,7 @@ azkaban.FlowTableView = Backbone.View.extend({
 			$(innerTable).append(tr);
 		}
 	},
+	
 	unhighlight: function(evt) {
 		var currentTarget = evt.currentTarget;
 		$(".dependent").removeClass("dependent");
diff --git a/src/web/js/azkaban.scheduled.view.js b/src/web/js/azkaban.scheduled.view.js
index b713783..bdf13db 100644
--- a/src/web/js/azkaban.scheduled.view.js
+++ b/src/web/js/azkaban.scheduled.view.js
@@ -19,212 +19,203 @@ $.namespace('azkaban');
 function removeSched(scheduleId) {
 	var scheduleURL = contextURL + "/schedule"
 	var redirectURL = contextURL + "/schedule"
-	$.post(
-			scheduleURL,
-			{"action":"removeSched", "scheduleId":scheduleId},
-			function(data) {
-				if (data.error) {
-//                 alert(data.error)
-					$('#errorMsg').text(data.error);
-				}
-				else {
-// 		 alert("Schedule "+schedId+" removed!")
-					window.location = redirectURL;
-				}
-			},
-			"json"
-	)
+	var requestData = {
+		"action": "removeSched", 
+		"scheduleId":scheduleId
+	};
+	var successHandler = function(data) {
+		if (data.error) {
+			$('#errorMsg').text(data.error);
+		}
+		else {
+			window.location = redirectURL;
+		}
+	};
+	$.post(scheduleURL, requestData, successHandler, "json");
 }
 
 function removeSla(scheduleId) {
 	var scheduleURL = contextURL + "/schedule"
 	var redirectURL = contextURL + "/schedule"
-	$.post(
-			scheduleURL,
-			{"action":"removeSla", "scheduleId":scheduleId},
-			function(data) {
-				if (data.error) {
-//                 alert(data.error)
-					$('#errorMsg').text(data.error)
-				}
-				else {
-// 		 alert("Schedule "+schedId+" removed!")
-					window.location = redirectURL
-				}
-			},
-			"json"
-	)
+	var requestData = {
+		"action": "removeSla", 
+		"scheduleId": scheduleId
+	};
+	var successHandler = function(data) {
+		if (data.error) {
+			$('#errorMsg').text(data.error)
+		}
+		else {
+			window.location = redirectURL
+		}
+	};
+	$.post(scheduleURL, requestData, successHandler, "json");
 }
 
+var slaView;
 azkaban.ChangeSlaView = Backbone.View.extend({
-	events : {
-		"click" : "closeEditingTarget",
+	events: {
+		"click": "closeEditingTarget",
 		"click #set-sla-btn": "handleSetSla",	
 		"click #remove-sla-btn": "handleRemoveSla",
-		"click #sla-cancel-btn": "handleSlaCancel",
-		"click .modal-close": "handleSlaCancel",
 		"click #addRow": "handleAddRow"
 	},
+	
 	initialize: function(setting) {
-
+		$('#messaging').hide();
+		$('#sla-options').on('hidden.bs.modal', function() {
+			slaView.handleSlaCancel();
+		});
 	},
-	handleSlaCancel: function(evt) {
+	
+	handleSlaCancel: function() {
 		console.log("Clicked cancel button");
 		var scheduleURL = contextURL + "/schedule";
-
-		$('#slaModalBackground').hide();
-		$('#sla-options').hide();
-		
 		var tFlowRules = document.getElementById("flowRulesTbl").tBodies[0];
 		var rows = tFlowRules.rows;
 		var rowLength = rows.length
-		for(var i = 0; i < rowLength-1; i++) {
+		for (var i = 0; i < rowLength-1; i++) {
 			tFlowRules.deleteRow(0);
 		}
-		
 	},
+	
 	initFromSched: function(scheduleId, flowName) {
 		this.scheduleId = scheduleId;
-		
 		var scheduleURL = contextURL + "/schedule"
 		this.scheduleURL = scheduleURL;
+		
 		var indexToName = {};
 		var nameToIndex = {};
 		var indexToText = {};
 		this.indexToName = indexToName;
 		this.nameToIndex = nameToIndex;
 		this.indexToText = indexToText;
+		
 		var ruleBoxOptions = ["SUCCESS", "FINISH"];
 		this.ruleBoxOptions = ruleBoxOptions;
 		
-		var fetchScheduleData = {"scheduleId": this.scheduleId, "ajax":"slaInfo"};
-		
-		$.get(
-				this.scheduleURL,
-				fetchScheduleData,
-				function(data) {
-					if (data.error) {
-						alert(data.error);
-					}
-					else {
-						if (data.slaEmails) {
-							$('#slaEmails').val(data.slaEmails.join());
+		var fetchScheduleData = {
+			"scheduleId": this.scheduleId, 
+			"ajax": "slaInfo"
+		};
+	
+		var successHandler = function(data) {
+			if (data.error) {
+				alert(data.error);
+				return;
+			}
+			if (data.slaEmails) {
+				$('#slaEmails').val(data.slaEmails.join());
+			}
+			
+			var allJobNames = data.allJobNames;
+			
+			indexToName[0] = "";
+			nameToIndex[flowName] = 0;
+			indexToText[0] = "flow " + flowName;
+			for (var i = 1; i <= allJobNames.length; i++) {
+				indexToName[i] = allJobNames[i-1];
+				nameToIndex[allJobNames[i-1]] = i;
+				indexToText[i] = "job " + allJobNames[i-1];
+			}
+			
+			// populate with existing settings
+			if (data.settings) {
+				var tFlowRules = document.getElementById("flowRulesTbl").tBodies[0];
+				for (var setting in data.settings) {
+					var rFlowRule = tFlowRules.insertRow(0);
+					
+					var cId = rFlowRule.insertCell(-1);
+					var idSelect = document.createElement("select");
+					idSelect.setAttribute("class", "form-control");
+					for (var i in indexToName) {
+						idSelect.options[i] = new Option(indexToText[i], indexToName[i]);
+						if (data.settings[setting].id == indexToName[i]) {
+							idSelect.options[i].selected = true;
 						}
-						
-						var allJobNames = data.allJobNames;
-						
-						indexToName[0] = "";
-						nameToIndex[flowName] = 0;
-						indexToText[0] = "flow " + flowName;
-						for(var i = 1; i <= allJobNames.length; i++) {
-							indexToName[i] = allJobNames[i-1];
-							nameToIndex[allJobNames[i-1]] = i;
-							indexToText[i] = "job " + allJobNames[i-1];
+					}								
+					cId.appendChild(idSelect);
+					
+					var cRule = rFlowRule.insertCell(-1);
+					var ruleSelect = document.createElement("select");
+					ruleSelect.setAttribute("class", "form-control");
+					for (var i in ruleBoxOptions) {
+						ruleSelect.options[i] = new Option(ruleBoxOptions[i], ruleBoxOptions[i]);
+						if (data.settings[setting].rule == ruleBoxOptions[i]) {
+							ruleSelect.options[i].selected = true;
 						}
-						
-						// populate with existing settings
-						if(data.settings) {
-							
-							var tFlowRules = document.getElementById("flowRulesTbl").tBodies[0];
-							
-							for(var setting in data.settings) {
-								var rFlowRule = tFlowRules.insertRow(0);
-								
-								var cId = rFlowRule.insertCell(-1);
-								var idSelect = document.createElement("select");
-								for(var i in indexToName) {
-									idSelect.options[i] = new Option(indexToText[i], indexToName[i]);
-									if(data.settings[setting].id == indexToName[i]) {
-										idSelect.options[i].selected = true;
-									}
-								}								
-								cId.appendChild(idSelect);
-								
-								var cRule = rFlowRule.insertCell(-1);
-								var ruleSelect = document.createElement("select");
-								for(var i in ruleBoxOptions) {
-									ruleSelect.options[i] = new Option(ruleBoxOptions[i], ruleBoxOptions[i]);
-									if(data.settings[setting].rule == ruleBoxOptions[i]) {
-										ruleSelect.options[i].selected = true;
-									}
-								}
-								cRule.appendChild(ruleSelect);
-								
-								var cDuration = rFlowRule.insertCell(-1);
-								var duration = document.createElement("input");
-								duration.type = "text";
-								duration.setAttribute("class", "durationpick");
-								var rawMinutes = data.settings[setting].duration;
-								var intMinutes = rawMinutes.substring(0, rawMinutes.length-1);
-								var minutes = parseInt(intMinutes);
-								var hours = Math.floor(minutes / 60);
-								minutes = minutes % 60;
-								duration.value = hours + ":" + minutes;
-								cDuration.appendChild(duration);
+					}
+					cRule.appendChild(ruleSelect);
+					
+					var cDuration = rFlowRule.insertCell(-1);
+					var duration = document.createElement("input");
+					duration.type = "text";
+					duration.setAttribute("class", "form-control durationpick");
+					var rawMinutes = data.settings[setting].duration;
+					var intMinutes = rawMinutes.substring(0, rawMinutes.length-1);
+					var minutes = parseInt(intMinutes);
+					var hours = Math.floor(minutes / 60);
+					minutes = minutes % 60;
+					duration.value = hours + ":" + minutes;
+					cDuration.appendChild(duration);
 
-								var cEmail = rFlowRule.insertCell(-1);
-								var emailCheck = document.createElement("input");
-								emailCheck.type = "checkbox";
-								for(var act in data.settings[setting].actions) {
-									if(data.settings[setting].actions[act] == "EMAIL") {
-										emailCheck.checked = true;
-									}
-								}
-								cEmail.appendChild(emailCheck);
-								
-								var cKill = rFlowRule.insertCell(-1);
-								var killCheck = document.createElement("input");
-								killCheck.type = "checkbox";
-								for(var act in data.settings[setting].actions) {
-									if(data.settings[setting].actions[act] == "KILL") {
-										killCheck.checked = true;
-									}
-								}
-								cKill.appendChild(killCheck);
-								
-								$('.durationpick').timepicker({hourMax: 99});
-							}
+					var cEmail = rFlowRule.insertCell(-1);
+					var emailCheck = document.createElement("input");
+					emailCheck.type = "checkbox";
+					for (var act in data.settings[setting].actions) {
+						if (data.settings[setting].actions[act] == "EMAIL") {
+							emailCheck.checked = true;
+						}
+					}
+					cEmail.appendChild(emailCheck);
+					
+					var cKill = rFlowRule.insertCell(-1);
+					var killCheck = document.createElement("input");
+					killCheck.type = "checkbox";
+					for (var act in data.settings[setting].actions) {
+						if (data.settings[setting].actions[act] == "KILL") {
+							killCheck.checked = true;
 						}
-						$('.durationpick').timepicker({hourMax: 99});
 					}
-				},
-				"json"
-			);
+					cKill.appendChild(killCheck);
+					$('.durationpick').timepicker({hourMax: 99});
+				}
+			}
+			$('.durationpick').timepicker({hourMax: 99});
+		};
+
+		$.get(this.scheduleURL, fetchScheduleData, successHandler, "json");
 		
-		$('#slaModalBackground').show();
-		$('#sla-options').show();
+		$('#sla-options').modal();
 		
-//		this.schedFlowOptions = sched.flowOptions
+		//this.schedFlowOptions = sched.flowOptions
 		console.log("Loaded schedule info. Ready to set SLA.");
-
 	},
+	
 	handleRemoveSla: function(evt) {
 		console.log("Clicked remove sla button");
 		var scheduleURL = this.scheduleURL;
 		var redirectURL = this.scheduleURL;
-		$.post(
-				scheduleURL,
-				{"action":"removeSla", "scheduleId":this.scheduleId},
-				function(data) {
-				if (data.error) {
-						$('#errorMsg').text(data.error)
-					}
-					else {
-						window.location = redirectURL
-					}
-				"json"
-				}
-			);
-
+		var requestData = {
+			"action": "removeSla", 
+			"scheduleId": this.scheduleId
+		};
+		var successHandler = function(data) {
+			if (data.error) {
+				$('#errorMsg').text(data.error)
+			}
+			else {
+				window.location = redirectURL
+			}
+		};
+		$.post(scheduleURL, requestData, successHanlder, "json");
 	},
+	
 	handleSetSla: function(evt) {
-
 		var slaEmails = $('#slaEmails').val();
 		var settings = {};
-		
-		
 		var tFlowRules = document.getElementById("flowRulesTbl").tBodies[0];
-		for(var row = 0; row < tFlowRules.rows.length-1; row++) {
+		for (var row = 0; row < tFlowRules.rows.length-1; row++) {
 			var rFlowRule = tFlowRules.rows[row];
 			var id = rFlowRule.cells[0].firstChild.value;
 			var rule = rFlowRule.cells[1].firstChild.value;
@@ -242,24 +233,19 @@ azkaban.ChangeSlaView = Backbone.View.extend({
 		};
 
 		var scheduleURL = this.scheduleURL;
-		
-		$.post(
-			scheduleURL,
-			slaData,
-			function(data) {
-				if (data.error) {
-					alert(data.error);
-				}
-				else {
-					tFlowRules.length = 0;
-					window.location = scheduleURL;
-				}
-			},
-			"json"
-		);
+		var successHandler = function(data) {
+			if (data.error) {
+				alert(data.error);
+			}
+			else {
+				tFlowRules.length = 0;
+				window.location = scheduleURL;
+			}
+		};
+		$.post(scheduleURL, slaData, successHandler, "json");
 	},
+	
 	handleAddRow: function(evt) {
-		
 		var indexToName = this.indexToName;
 		var nameToIndex = this.nameToIndex;
 		var indexToText = this.indexToText;
@@ -270,15 +256,16 @@ azkaban.ChangeSlaView = Backbone.View.extend({
 		
 		var cId = rFlowRule.insertCell(-1);
 		var idSelect = document.createElement("select");
-		for(var i in indexToName) {
+		idSelect.setAttribute("class", "form-control");
+		for (var i in indexToName) {
 			idSelect.options[i] = new Option(indexToText[i], indexToName[i]);
 		}
-		
 		cId.appendChild(idSelect);
 		
 		var cRule = rFlowRule.insertCell(-1);
 		var ruleSelect = document.createElement("select");
-		for(var i in ruleBoxOptions) {
+		ruleSelect.setAttribute("class", "form-control");
+		for (var i in ruleBoxOptions) {
 			ruleSelect.options[i] = new Option(ruleBoxOptions[i], ruleBoxOptions[i]);
 		}
 		cRule.appendChild(ruleSelect);
@@ -286,7 +273,7 @@ azkaban.ChangeSlaView = Backbone.View.extend({
 		var cDuration = rFlowRule.insertCell(-1);
 		var duration = document.createElement("input");
 		duration.type = "text";
-		duration.setAttribute("class", "durationpick");
+		duration.setAttribute("class", "durationpick form-control");
 		cDuration.appendChild(duration);
 
 		var cEmail = rFlowRule.insertCell(-1);
@@ -300,12 +287,11 @@ azkaban.ChangeSlaView = Backbone.View.extend({
 		cKill.appendChild(killCheck);
 		
 		$('.durationpick').timepicker({hourMax: 99});
-
 		return rFlowRule;
 	},
-	handleEditColumn : function(evt) {
-		var curTarget = evt.currentTarget;
 	
+	handleEditColumn: function(evt) {
+		var curTarget = evt.currentTarget;
 		if (this.editingTarget != curTarget) {
 			this.closeEditingTarget();
 			
@@ -322,32 +308,26 @@ azkaban.ChangeSlaView = Backbone.View.extend({
 			this.editingTarget = curTarget;
 		}
 	},
-	handleRemoveColumn : function(evt) {
+	
+	handleRemoveColumn: function(evt) {
 		var curTarget = evt.currentTarget;
 		// Should be the table
 		var row = curTarget.parentElement.parentElement;
 		$(row).remove();
 	},
+	
 	closeEditingTarget: function(evt) {
-
 	}
 });
 
-var slaView;
 var tableSorterView;
 $(function() {
-	var selected;
-
-
 	slaView = new azkaban.ChangeSlaView({el:$('#sla-options')});
 	tableSorterView = new azkaban.TableSorter({el:$('#scheduledFlowsTbl')});
-//	var requestURL = contextURL + "/manager";
+	//var requestURL = contextURL + "/manager";
 
 	// Set up the Flow options view. Create a new one every time :p
-//	 $('#addSlaBtn').click( function() {
-//		 slaView.show();
-//	 });
-
-	 
-	
+	//$('#addSlaBtn').click( function() {
+	//	slaView.show();
+	//});
 });