From c3caa1d370325bdf1e69d16a0e885382687ed33a Mon Sep 17 00:00:00 2001 From: David Thompson Date: Fri, 15 Aug 2014 08:57:29 -0400 Subject: Add basic, hacky package installation. * guix-web/controller.scm (controller): Add package installation route. * guix-web/package.scm: New file. * guix-web/render.scm (unprocessable-entity, created): New procedures. * js/guix-packages.js (guix.PHASE_NONE, guix.PHASE_PROMPT, guix.PHASE_DERIVATION, guix.PHASE_SUCCESS, guix.PHASE_ERROR): New variables. (guix.controller.phase, guix.controller.selectedPackage): New properties. (guix.controller.prototype.installSelectedPackage): New method. (guix.view): Add modal for package installation UI. --- js/guix-packages.js | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 3 deletions(-) (limited to 'js/guix-packages.js') diff --git a/js/guix-packages.js b/js/guix-packages.js index afbf4fb..10e59d8 100644 --- a/js/guix-packages.js +++ b/js/guix-packages.js @@ -54,6 +54,12 @@ guix.Sorter = (function() { return Sorter; })(); +guix.PHASE_NONE = 0; +guix.PHASE_PROMPT = 1; +guix.PHASE_DERIVATION = 2; +guix.PHASE_SUCCESS = 3; +guix.PHASE_ERROR = 4; + guix.controller = (function() { function controller() { var self = this; @@ -82,6 +88,8 @@ guix.controller = (function() { } ]; this.sorter = m.prop(new guix.Sorter("name")); + this.phase = m.prop(guix.PHASE_NONE); + this.selectedPackage = m.prop(null); // All packages are visible initially this.packages.then(function(packages) { @@ -136,6 +144,23 @@ guix.controller = (function() { this.doSearch(); }; + controller.prototype.installSelectedPackage = function() { + var self = this; + + this.phase(guix.PHASE_DERIVATION); + + m.request({ + method: "POST", + url: "/packages/" + .concat(this.selectedPackage().name) + .concat("/install") + }).then(function() { + self.phase(guix.PHASE_SUCCESS); + }, function() { + self.phase(guix.PHASE_ERROR); + }); + }; + return controller; })(); @@ -144,7 +169,7 @@ guix.view = function(ctrl) { function renderName(package) { var name = package.name; - return m("a", { href: "/package/".concat(name) }, name); + return m("a", { href: "/packages/".concat(name) }, name); } function renderHomepage(package) { @@ -171,6 +196,17 @@ guix.view = function(ctrl) { } } + function renderInstallLink(package) { + return m("a", { + href: "#", + onclick: function() { + ctrl.selectedPackage(package); + ctrl.phase(guix.PHASE_PROMPT); + return false; + } + }, "install"); + } + function renderPagination() { function renderPage(text, opts) { return m("li", { @@ -222,11 +258,93 @@ guix.view = function(ctrl) { return "sorter"; } + function renderModal() { + function renderBody() { + switch(ctrl.phase()) { + case guix.PHASE_PROMPT: + return [ + m("p", "Do you want to install the following packages?"), + m("ul", [ + m("li", [ + ctrl.selectedPackage().name, + " ", + ctrl.selectedPackage().version + ]) + ]) + ]; + case guix.PHASE_DERIVATION: + return [ + m("p", "Installing..."), + m(".progress", [ + m(".progress-bar.progress-bar-striped.active", { + role: "progressbar", + style: { width: "100%" } + }) + ]) + ]; + case guix.PHASE_SUCCESS: + return m(".alert.alert-success", "Installation complete!"); + case guix.PHASE_ERROR: + return m(".alert.alert-danger", "Installation failed!"); + } + + return null; + } + + function renderButtons() { + switch(ctrl.phase()) { + case guix.PHASE_PROMPT: + return [ + m(".btn.btn-default", "Cancel"), + m(".btn.btn-primary", { + onclick: function() { + ctrl.installSelectedPackage(); + m.redraw(); + } + }, "Install"), + ]; + case guix.PHASE_DERIVATION: + return m(".btn.btn-default.disabled", "Please wait..."); + case guix.PHASE_SUCCESS: + case guix.PHASE_SUCCESS: + return m(".btn.btn-primary", { + onclick: function() { + ctrl.phase(guix.PHASE_NONE); + } + }, "Close"); + } + + return null; + } + + if(ctrl.phase() != guix.PHASE_NONE) { + return [ + m(".modal-backdrop.in"), + m("div.modal.modal-open", { + style: { + display: "block" + } + }, m(".modal-dialog", [ + m(".modal-content", [ + m(".modal-header", [ + m("h4.modal-title", "Install Packages") + ]), + m(".modal-body", renderBody()), + m(".modal-footer", renderButtons()) + ]) + ])) + ]; + } + + return null; + } + return [ m("h2", [ "Packages", m("span.badge", ctrl.packageCount()) ]), + renderModal(), m("input.form-control", { type: "text", placeholder: "Search", @@ -246,7 +364,7 @@ guix.view = function(ctrl) { ctrl.sortBy(column.sortField); } }, column.header); - }) + }).concat([m("th", "")]) ]) ]), m("tbody", [ @@ -256,7 +374,8 @@ guix.view = function(ctrl) { m("td", package.version), m("td", package.synopsis), m("td", renderHomepage(package)), - m("td", renderLicense(package)) + m("td", renderLicense(package)), + m("td", renderInstallLink(package)) ]); }) ]) -- cgit v1.2.3