// 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() { var packages = guix.packages; var spinner = m(".spinner-container", m(".spinner")); packages.view = function(ctrl) { function renderName(package) { var name = package.name; return m("a", { href: "/packages/".concat(name) }, name); } function renderHomepage(package) { if(package.homepage) { return m("a", { href: package.homepage }, package.homepage); } else { return ""; } } function renderLicense(package) { function licenseLink(license) { return m("a", { href: license.uri }, license.name); } if(_.isArray(package.license)) { return m("ul.list-inline", package.license.map(function(license) { return m("li", licenseLink(license)); })); } else if(package.license) { return licenseLink(package.license); } else { return ""; } } function renderInstallLink(package) { return m("a", { href: "#", onclick: function() { ctrl.selectedPackage(package); ctrl.phase(packages.PHASE_PROMPT); return false; } }, "install"); } function renderPackageTable() { return m("table.table", [ m("thead", [ m("tr", [ ctrl.columns.map(function(column) { return m("th", { class: columnHeaderClass(column), onclick: function() { ctrl.sortBy(column.sortField); } }, column.header); }).concat([m("th", "")]) ]) ]), m("tbody", [ ctrl.pager().currentPage().map(function(package) { return m("tr", [ m("td", renderName(package)), m("td", package.version), m("td", package.synopsis), m("td", renderHomepage(package)), m("td", renderLicense(package)), m("td", renderInstallLink(package)) ]); }) ]) ]); } function renderPagination() { function renderPage(text, opts) { return m("li", { class: opts.class || "", onclick: opts.onclick }, m("a", { href: "#" }, text)); } return m("div", m("ul.pagination", [ // Back page renderPage("«", { class: ctrl.pager().isFirstPage() ? "disabled" : "", onclick: function() { ctrl.pager().previousPage(); return false; } }) ].concat(ctrl.pager().pages.map(function(page, i) { // Jump to page return renderPage(i + 1, { class: ctrl.pager().isCurrentPage(i) ? "active" : "", onclick: function() { ctrl.pager().gotoPage(i); return false; } }); })).concat([ // Forward page renderPage("»", { class: ctrl.pager().isLastPage() ? "disabled" : "", onclick: function() { ctrl.pager().nextPage(); return false; } }) ]))); } function renderSearchBox() { return m("input.form-control", { type: "text", placeholder: "Search", onchange: m.withAttr("value", function(value) { ctrl.searchTerm(value); ctrl.doSearch(); }), value: ctrl.searchTerm() }); } function columnHeaderClass(column) { var sorter = ctrl.sorter(); if(column.sortField === sorter.field) { return sorter.isDescending ? "sorter sort-descend" : "sorter sort-ascend"; } return "sorter"; } function renderModal() { function renderBody() { switch(ctrl.phase()) { case packages.PHASE_PROMPT: return [ m("p", "Do you want to install the following packages?"), m("ul", [ m("li", [ ctrl.selectedPackage().name, " ", ctrl.selectedPackage().version ]) ]) ]; case packages.PHASE_DERIVATION: return [ m("p", [ "Installing ", ctrl.selectedPackage().name, " ", ctrl.selectedPackage().version, "..." ]), m(".progress", [ m(".progress-bar.progress-bar-striped.active", { role: "progressbar", style: { width: "100%" } }) ]) ]; case packages.PHASE_SUCCESS: return m(".alert.alert-success", "Installation complete!"); case packages.PHASE_ERROR: return m(".alert.alert-danger", "Installation failed!"); } return null; } function renderButtons() { switch(ctrl.phase()) { case packages.PHASE_PROMPT: return [ m(".btn.btn-default", "Cancel"), m(".btn.btn-primary", { onclick: function() { ctrl.installSelectedPackage(); m.redraw(); } }, "Install"), ]; case packages.PHASE_DERIVATION: return m(".btn.btn-danger", "Abort"); case packages.PHASE_SUCCESS: case packages.PHASE_ERROR: return m(".btn.btn-primary", { onclick: function() { ctrl.phase(packages.PHASE_NONE); } }, "Close"); } return null; } if(ctrl.phase() != packages.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 guix.withLayout(ctrl.pager().isEmpty() ? spinner : [ m("h2", [ "Packages", m("span.badge", ctrl.packageCount()) ]), renderModal(), renderSearchBox(), renderPackageTable(), renderPagination() ]); }; })();