From 93921cef3d2e76b53789140fad7153c025a7c340 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Thu, 16 Oct 2014 00:01:23 -0400 Subject: Add generations view. * guix-web/controller.scm (controller): Add '/generations' route. * guix-web/package.scm (profile-generations*): New procedure. * guix-web/view.scm (generations-json): New procedure. (javascripts): Add new JS files. * js/model/generations.js: New file. * js/controller/generations.js: New file. * js/view/generations.js: New file. * js/view/layout.js (guix.withLayout): Add 'Generations' navbar entry. * js/routes.js: Add '/generations' route. --- guix-web/controller.scm | 2 ++ guix-web/package.scm | 11 ++++++++- guix-web/view.scm | 26 +++++++++++++++++++- js/controller/generations.js | 30 +++++++++++++++++++++++ js/model/generations.js | 28 +++++++++++++++++++++ js/routes.js | 3 ++- js/view/generations.js | 58 ++++++++++++++++++++++++++++++++++++++++++++ js/view/layout.js | 10 +++++--- 8 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 js/controller/generations.js create mode 100644 js/model/generations.js create mode 100644 js/view/generations.js diff --git a/guix-web/controller.scm b/guix-web/controller.scm index 61df575..490c80f 100644 --- a/guix-web/controller.scm +++ b/guix-web/controller.scm @@ -47,6 +47,8 @@ (if (package-install package) (created) (unprocessable-entity)))) + ((GET "generations") + (render-json (generations-json))) ((GET "librejs") (render-html (librejs))) ((GET path ...) diff --git a/guix-web/package.scm b/guix-web/package.scm index ae7c152..def44aa 100644 --- a/guix-web/package.scm +++ b/guix-web/package.scm @@ -26,7 +26,8 @@ #:use-module (guix utils) #:use-module (guix ui) #:use-module (gnu packages) - #:export (package-install)) + #:export (package-install + profile-generations*)) (define %profile (string-append "/usr/var/guix/profiles/per-user/" @@ -53,3 +54,11 @@ (count (length entries))) (switch-symlinks name prof) (switch-symlinks %profile name))))))) + +(define (profile-generations*) + (map (lambda (n) + (cons n (reverse + (manifest-entries + (profile-manifest + (generation-file-name %profile n)))))) + (generation-numbers %profile))) diff --git a/guix-web/view.scm b/guix-web/view.scm index f448375..123a1d5 100644 --- a/guix-web/view.scm +++ b/guix-web/view.scm @@ -24,12 +24,15 @@ #:use-module (web uri) #:use-module (guix licenses) #:use-module (guix packages) + #:use-module (guix profiles) #:use-module (gnu packages) + #:use-module (guix-web package) #:export (all-packages all-packages-json view-package view-package-json - librejs)) + librejs + generations-json)) (define-record-type (javascript source-uri license) @@ -53,6 +56,9 @@ (javascript "/js/model/packages.js" agpl3+) (javascript "/js/view/packages.js" agpl3+) (javascript "/js/controller/packages.js" agpl3+) + (javascript "/js/model/generations.js" agpl3+) + (javascript "/js/view/generations.js" agpl3+) + (javascript "/js/controller/generations.js" agpl3+) (javascript "/js/routes.js" agpl3+))) (define (script-tag javascript) @@ -215,3 +221,21 @@ (th "License") (th "Source Code"))) (tbody ,@(map weblabel javascripts)))))) + +(define (generations-json) + (map (match-lambda + ((n . manifest-entries) + (json + (object + ("number" ,n) + ("manifestEntries" + ,(map (match-lambda + (($ name version output location _) + (json + (object + ("name" ,name) + ("version" ,version) + ("output" ,output) + ("location" ,location))))) + manifest-entries)))))) + (profile-generations*))) diff --git a/js/controller/generations.js b/js/controller/generations.js new file mode 100644 index 0000000..011dfa2 --- /dev/null +++ b/js/controller/generations.js @@ -0,0 +1,30 @@ +// guix-web - Web interface for GNU Guix +// Copyright © 2014 David Thompson +// +// This program is free software: you can redistribute it and/or +// modify it under the terms of the GNU Affero General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public +// License along with this program. If not, see +// . + +(function(generations) { + generations.controller = (function() { + function controller() { + this.generations = m.prop([]); + + generations.Generations() + .then(this.generations) + .then(m.redraw); + } + + return controller; + })(); +})(guix.generations); diff --git a/js/model/generations.js b/js/model/generations.js new file mode 100644 index 0000000..0dc4e6c --- /dev/null +++ b/js/model/generations.js @@ -0,0 +1,28 @@ +// guix-web - Web interface for GNU Guix +// Copyright © 2014 David Thompson +// +// This program is free software: you can redistribute it and/or +// modify it under the terms of the GNU Affero General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public +// License along with this program. If not, see +// . + +guix.generations = {}; + +(function(generations) { + generations.Generations = function() { + return m.request({ + method: "GET", + url: "/generations", + background: true + }); + }; +})(guix.generations); diff --git a/js/routes.js b/js/routes.js index d749d3c..b3fee60 100644 --- a/js/routes.js +++ b/js/routes.js @@ -16,5 +16,6 @@ // . m.route(document.body, "/", { - "/": guix.packages + "/": guix.packages, + "/generations": guix.generations }); diff --git a/js/view/generations.js b/js/view/generations.js new file mode 100644 index 0000000..912a1ab --- /dev/null +++ b/js/view/generations.js @@ -0,0 +1,58 @@ +// guix-web - Web interface for GNU Guix +// Copyright © 2014 David Thompson +// +// This program is free software: you can redistribute it and/or +// modify it under the terms of the GNU Affero General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public +// License along with this program. If not, see +// . + +(function(generations) { + generations.view = function(ctrl) { + return guix.withLayout([ + m("h2", [ + "Generations", + m("span.badge", ctrl.generations().length) + ]), + m("table.table.table-bordered", [ + m("thead", m("tr", [ + m("th", "#"), + m("th", "Name"), + m("th", "Version"), + m("th", "Output"), + m("th", "Location") + ])), + m("tbody", [ + ctrl.generations().map(function(generation) { + var entries = generation.manifestEntries; + + function renderRow(entry, isFirst) { + return m("tr", [ + isFirst ? m("td", { + rowspan: entries.length + }, m("strong", generation.number)) : null, + m("td", entry.name), + m("td", entry.version), + m("td", entry.output), + m("td", entry.location) + ]); + } + + return [renderRow(entries[0], true)] + .concat(entries.slice(1).map(function (entry) { + return renderRow(entry, false); + })); + }) + ]) + ]) + ]); + }; +})(guix.generations); diff --git a/js/view/layout.js b/js/view/layout.js index c733a8f..02ee639 100644 --- a/js/view/layout.js +++ b/js/view/layout.js @@ -53,11 +53,13 @@ guix.withLayout = (function() { m(".navbar-header", m("img.logo", { src: "/images/logo.png" })), m("ul.nav.navbar-nav", [ m("li.active", m("a", { - href: "#", - onclick: function() { - m.route("/"); - } + config: m.route, + href: "/" }, "Packages")), + m("li", m("a", { + config: m.route, + href: "/generations" + }, "Generations")) ]), m("ul.nav.navbar-nav.navbar-right") ])), -- cgit v1.2.3