From a896eb837e6174a94affcb768150c17c85c9e8a2 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Wed, 13 Aug 2014 20:23:54 -0400 Subject: Add column sorting to package table. * css/guix.css: New file. * guix-web/view.scm (main-layout): Include guix.css. * js/guix-packages.js (guix.Sorter.prototype.reverse): New method. (guix.controller.sorter): Make property. (guix.controller.columns): New variable. (guix.controller.prototype.paginate): Use sorter property. (guix.controller.prototype.sortBy): New method. (guix.view): Render column sorting UI. --- js/guix-packages.js | 60 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'js') diff --git a/js/guix-packages.js b/js/guix-packages.js index 1f57f1e..5903754 100644 --- a/js/guix-packages.js +++ b/js/guix-packages.js @@ -46,6 +46,10 @@ guix.Sorter.prototype.sort = function(array) { return this.isDescending ? result.reverse() : result; }; +guix.Sorter.prototype.reverse = function() { + return new guix.Sorter(this.field, !this.isDescending); +}; + guix.controller = function() { var self = this; @@ -54,7 +58,25 @@ guix.controller = function() { this.currentPageIndex = 0; this.pageSize = 20; this.searchTerm = m.prop(""); - this.sorter = new guix.Sorter("name"); + this.columns = [ + { header: "Name", sortField: "name" }, + { header: "Version", sortField: "version" }, + { header: "Synopsis", sortField: "synopsis" }, + { header: "Home Page", sortField: "homepage" }, { + header: "License", + sortField: function(package) { + if(_.isArray(package.license)) { + // Concatenate all license names together for sorting. + return package.license.reduce(function(memo, l) { + return memo.concat(l.name); + }, ""); + } + + return package.license.name; + } + } + ]; + this.sorter = m.prop(new guix.Sorter("name")); // All packages are visible initially this.packages.then(function(packages) { @@ -63,7 +85,7 @@ guix.controller = function() { }; guix.controller.prototype.paginate = function(array, pageSize) { - return guix.chunk(this.sorter.sort(array), pageSize); + return guix.chunk(this.sorter().sort(array), pageSize); }; guix.controller.prototype.currentPage = function() { @@ -97,6 +119,17 @@ guix.controller.prototype.doSearch = function() { }), this.pageSize)); }; +guix.controller.prototype.sortBy = function(field) { + if(this.sorter().field === field) { + // Reverse sort order if the field is the same as before. + this.sorter(this.sorter().reverse()); + } else { + this.sorter(new guix.Sorter(field)); + } + + this.doSearch(); +}; + guix.view = function(ctrl) { function renderName(package) { var name = package.name; @@ -169,6 +202,16 @@ guix.view = function(ctrl) { ])); } + function columnHeaderClass(column) { + var sorter = ctrl.sorter(); + + if(column.sortField === sorter.field) { + return sorter.isDescending ? "sorter sort-descend" : "sorter sort-ascend"; + } + + return "sorter"; + } + return [ m("h2", [ "Packages", @@ -186,12 +229,13 @@ guix.view = function(ctrl) { m("table.table", [ m("thead", [ m("tr", [ - ["Name", - "Version", - "Synopsis", - "Home Page", - "License"].map(function(header) { - return m("th", header); + ctrl.columns.map(function(column) { + return m("th", { + class: columnHeaderClass(column), + onclick: function() { + ctrl.sortBy(column.sortField); + } + }, column.header); }) ]) ]), -- cgit v1.2.3