diff options
-rw-r--r-- | css/guix.css | 11 | ||||
-rw-r--r-- | guix-web/view.scm | 4 | ||||
-rw-r--r-- | js/guix-packages.js | 60 |
3 files changed, 66 insertions, 9 deletions
diff --git a/css/guix.css b/css/guix.css new file mode 100644 index 0000000..038a9d0 --- /dev/null +++ b/css/guix.css @@ -0,0 +1,11 @@ +.sort-descend:after { + content: '▼' +} + +.sort-ascend:after { + content: '▲' +} + +.sorter { + cursor: pointer; +} diff --git a/guix-web/view.scm b/guix-web/view.scm index 17d10a8..1a7f2a1 100644 --- a/guix-web/view.scm +++ b/guix-web/view.scm @@ -45,7 +45,9 @@ (head (title ,(string-append "GNU Guix - " subtitle)) (link (@ (rel "stylesheet") - (href "/css/bootstrap.css")))) + (href "/css/bootstrap.css"))) + (link (@ (rel "stylesheet") + (href "/css/guix.css")))) (body (div (@ (class "container")) (image (@ (src "/images/logo.png"))) 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); }) ]) ]), |