azkaban-uncached

Added table sorting... yay?

4/3/2013 9:01:03 PM

Details

diff --git a/src/java/azkaban/webapp/servlet/velocity/executionspage.vm b/src/java/azkaban/webapp/servlet/velocity/executionspage.vm
index f31cb29..dc550a1 100644
--- a/src/java/azkaban/webapp/servlet/velocity/executionspage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/executionspage.vm
@@ -25,7 +25,6 @@
 		<script type="text/javascript" src="${context}/js/jquery.simplemodal-1.4.4.js"></script>
 
 		<script type="text/javascript" src="${context}/js/azkaban.nav.js"></script>
-		<script type="text/javascript" src="${context}/js/azkaban.main.view.js"></script>
 		<script type="text/javascript">
 			var contextURL = "${context}";
 			var currentTime = ${currentTime};
diff --git a/src/java/azkaban/webapp/servlet/velocity/index.vm b/src/java/azkaban/webapp/servlet/velocity/index.vm
index 55a7c18..dc32de9 100644
--- a/src/java/azkaban/webapp/servlet/velocity/index.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/index.vm
@@ -23,6 +23,7 @@
 		<script type="text/javascript" src="${context}/js/underscore-1.4.4-min.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/azkaban.table.sort.js"></script>
 		<script type="text/javascript" src="${context}/js/azkaban.nav.js"></script>
 		<script type="text/javascript" src="${context}/js/azkaban.main.view.js"></script>
 		<script type="text/javascript">
@@ -69,28 +70,24 @@
 					<a id="create-project-btn" class="btn1 " href="#">Create Project</a>
 				</div><!-- end .section-hd -->
 			</div>
-			<table id="all-jobs" class="all-jobs job-table">
+			<table id="all-jobs" class="all-jobs job-table project-table">
 				<thead>
 					<tr>
 						<th class="tb-name">Name</th>
 						<th class="tb-up-date">Modified Date</th>
 						<th class="tb-owner">Modified By</th>
-						<th class="tb-action last">Actions</th>
 					</tr>
 				</thead>
 				<tbody>
 #if($projects)
 #foreach($project in $projects)
 					<tr class="row">
-						<td class="tb-name">
-							<div class="jobfolder expand" id="${project.name}">
-								<span class="state-icon"></span>
-								<a href="${context}/manager?project=${project.name}">$project.name</a>
-							</div>
+						<td class="tb-name expand project-expand" id="${project.name}">
+							<span class="state-icon"></span>
+							<a href="${context}/manager?project=${project.name}">$project.name</a>
 						</td>
 						<td class="tb-up-date">$utils.formatDate($project.lastModifiedTimestamp)</td>
 						<td class="tb-owner">$project.lastModifiedUser</td>
-						<td class="tb-action last"></td>
 					</tr>
 					<tr class="childrow" id="${project.name}-child" style="display: none;">
 						<td class="expandedFlow">
diff --git a/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm b/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm
index 189ea93..f65bdfb 100644
--- a/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm
@@ -30,6 +30,7 @@
 		
 		<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>
 		<script type="text/javascript" src="${context}/js/azkaban.nav.js"></script>
 		<script type="text/javascript" src="${context}/js/azkaban.scheduled.view.js"></script>
 		<script type="text/javascript">
@@ -75,7 +76,7 @@
 							<th class="date">Next Execution Time</th>
 							<th class="date">Repeats Every</th>
 							<th>Has SLA</th>
-							<th colspan="2" class="action">Action</th>
+							<th colspan="2" class="action ignoresort">Action</th>
 						</tr>
 					</thead>
 					<tbody>
diff --git a/src/web/css/azkaban.css b/src/web/css/azkaban.css
index 390d64f..7015de7 100644
--- a/src/web/css/azkaban.css
+++ b/src/web/css/azkaban.css
@@ -271,17 +271,19 @@ tr:hover td {
 
 .all-jobs .tb-name {
   padding-left: 2.7272727%;
-  width: 64.818182%;
+  width: 70%;
   border-bottom-width: 0;
   border-bottom-style: none;
 }
 
 .all-jobs .tb-up-date {
-  width: 160px;
+  width: 140px;
+  min-width: 130px;
 }
 
 .all-jobs .tb-owner {
   width: 10%;
+  min-width: 95px;
 }
 
 .all-jobs .tb-pname {
@@ -2929,6 +2931,29 @@ div.menuContent {
 	margin: 10px 20px;
 }
 
+.sortableTable .sortable:hover .sortIcon {
+	visibility: visible;
+}
+
+.sortableTable .sortable .sortIcon {
+	float: right;
+	width: 16px;
+	height: 16px;
+	background-image: url("../css/images/ui-icons_cccccc_256x240.png");
+	background-position: -128px -16px;
+	visibility: hidden;
+}
+
+.sortableTable .sortable.desc .sortIcon {
+	background-position: -64px -16px;
+	visibility: visible;
+}
+
+.sortableTable .sortable.asc .sortIcon {
+	background-position: 0 -16px;
+	visibility: visible;
+}
+
 /* old styles */
 .azkaban-charts .hitarea {
 	background-image: url("../css/images/ui-icons_cccccc_256x240.png");
diff --git a/src/web/js/azkaban.main.view.js b/src/web/js/azkaban.main.view.js
index 3f540bb..5332cab 100644
--- a/src/web/js/azkaban.main.view.js
+++ b/src/web/js/azkaban.main.view.js
@@ -3,7 +3,7 @@ $.namespace('azkaban');
 var projectTableView;
 azkaban.ProjectTableView= Backbone.View.extend({
   events : {
-    "click .jobfolder": "expandProject"
+    "click .project-expand": "expandProject"
   },
   initialize : function(settings) {
 
@@ -180,8 +180,10 @@ azkaban.CreateProjectView= Backbone.View.extend({
   }
 });
 
+var tableSorterView;
 $(function() {
 	projectHeaderView = new azkaban.ProjectHeaderView({el:$( '#all-jobs-content'), successMsg: successMessage, errorMsg: errorMessage });
 	projectTableView = new azkaban.ProjectTableView({el:$('#all-jobs')});
+	tableSorterView = new azkaban.TableSorter({el:$('#all-jobs')});
 	uploadView = new azkaban.CreateProjectView({el:$('#create-project')});
 });
diff --git a/src/web/js/azkaban.scheduled.view.js b/src/web/js/azkaban.scheduled.view.js
index 2c1ee76..a6f1e83 100644
--- a/src/web/js/azkaban.scheduled.view.js
+++ b/src/web/js/azkaban.scheduled.view.js
@@ -325,13 +325,13 @@ azkaban.ChangeSlaView = Backbone.View.extend({
 });
 
 var slaView;
-
+var tableSorterView;
 $(function() {
 	var selected;
 
 
 	slaView = new azkaban.ChangeSlaView({el:$('#sla-options')});
-	
+	tableSorterView = new azkaban.TableSorter({el:$('#scheduledFlowsTbl')});
 //	var requestURL = contextURL + "/manager";
 
 	// Set up the Flow options view. Create a new one every time :p
diff --git a/src/web/js/azkaban.staging.flow.view.js b/src/web/js/azkaban.staging.flow.view.js
index 4f7a049..3f417bc 100644
--- a/src/web/js/azkaban.staging.flow.view.js
+++ b/src/web/js/azkaban.staging.flow.view.js
@@ -192,7 +192,6 @@ azkaban.FlowTabView= Backbone.View.extend({
   	else {
   		this.handleGraphLinkClick();
   	}
-
   },
   render: function() {
   	console.log("render graph");
diff --git a/src/web/js/azkaban.table.sort.js b/src/web/js/azkaban.table.sort.js
new file mode 100644
index 0000000..029e5bd
--- /dev/null
+++ b/src/web/js/azkaban.table.sort.js
@@ -0,0 +1,134 @@
+$.namespace('azkaban');
+
+azkaban.TableSorter= Backbone.View.extend({
+  events : {
+  	"click .sortable": "handleClickSort"
+  },
+  initialize : function(settings) {
+  	$(this.el).addClass("sortableTable");
+  
+  	var thead = $(this.el).children("thead");
+	var th = $(thead).find("th");
+	
+	$(th).addClass("sortable");
+	$("th.ignoresort").removeClass("sortable");
+	var sortDiv = document.createElement("div");
+
+	$(sortDiv).addClass("sortIcon");
+	
+	$(th).append(sortDiv);
+	
+	var tbody = $(this.el).children("tbody");
+	var rows = $(tbody).children("tr");
+	
+	var row;
+	for (var i = 0; i < rows.length; ++i ) {
+		var nextRow = rows[i];
+		if (row && $(nextRow).hasClass("childrow")) {
+			if (!row.childRows) {
+				row.childRows = new Array();
+			}
+		
+			row.childRows.push(nextRow);
+		}
+		else {
+			row = nextRow;
+		}
+	}
+	
+	if (settings.initialSort) {
+		this.toggleSort(settings.initialSort);
+	}
+  },
+  handleClickSort: function(evt) {
+  	this.toggleSort(evt.currentTarget);
+  },
+  toggleSort: function(th) {
+  	console.log("sorting by index " + $(th).index());
+  	if ($(th).hasClass("asc")) {
+  		$(th).removeClass("asc");
+  		$(th).addClass("desc");
+  		// Sort to descending
+  		
+  		this.sort($(th).index(), true);
+  	}
+  	else if ($(th).hasClass("desc")) {
+  		$(th).removeClass("desc");
+  		$(th).addClass("asc");
+  		
+  		this.sort($(th).index(), false);
+  	}
+  	else {
+  		$(th).parent().children(".sortable").removeClass("asc").removeClass("desc");
+  		$(th).addClass("asc");
+  		
+  		this.sort($(th).index(), false);
+  	}
+  },
+  sort: function(index, desc) {
+	var tbody = $(this.el).children("tbody");
+	var rows = $(tbody).children("tr");
+
+	var tdToSort = new Array();
+	for (var i = 0; i < rows.length; ++i) {
+		var row = rows[i];
+		if (!$(row).hasClass("childrow")) {
+			var td = row.children[index];
+			tdToSort.push(td);
+		}
+	}
+
+	if (desc) {
+		tdToSort.sort(function(a,b) {
+			var texta = $(a).text().trim().toLowerCase();
+			var textb = $(b).text().trim().toLowerCase();
+			
+			if (texta < textb) {
+				return 1;
+			}
+			else if (texta > textb) {
+				return -1;
+			} 
+			else {
+				return 0;
+			}
+		});
+	}
+	else {
+		tdToSort.sort(function(a,b) {
+			var texta = $(a).text().trim().toLowerCase();
+			var textb = $(b).text().trim().toLowerCase();
+			
+			if (texta < textb) {
+				return -1;
+			}
+			else if (texta > textb) {
+				return 1;
+			} 
+			else {
+				return 0;
+			}
+		});
+	}
+
+	var sortedTR = new Array();
+	for (var i = 0; i < tdToSort.length; ++i) {
+		var tr = $(tdToSort[i]).parent();
+		sortedTR.push(tr);
+		
+		var childRows = tr[0].childRows;
+		if (childRows) {
+			for(var j=0; j < childRows.length; ++j) {
+				sortedTR.push(childRows[j]);
+			}
+		}
+	}
+	
+	for (var i = 0; i < sortedTR.length; ++i) {
+		$(tbody).append(sortedTR[i]);
+	}
+  },
+  render: function() {
+  	console.log("render graph");
+  }
+});
\ No newline at end of file