summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2014-08-13 20:23:54 -0400
committerDavid Thompson <dthompson2@worcester.edu>2014-08-13 20:23:54 -0400
commita896eb837e6174a94affcb768150c17c85c9e8a2 (patch)
tree148948da6fd691e4b9f230fe55582242997b5e7f
parent39165a798408bc76e692e7c8a546e93fd550231d (diff)
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.
-rw-r--r--css/guix.css11
-rw-r--r--guix-web/view.scm4
-rw-r--r--js/guix-packages.js60
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);
})
])
]),