Skip to content

Commit

Permalink
The packages page boots the app.
Browse files Browse the repository at this point in the history
  • Loading branch information
samueldr committed Apr 9, 2018
1 parent d8f01ff commit ea73d79
Showing 1 changed file with 8 additions and 306 deletions.
314 changes: 8 additions & 306 deletions nixos/packages.tt
Original file line number Diff line number Diff line change
@@ -1,311 +1,13 @@
[% WRAPPER layout.tt title="Search NixOS packages" menu="nixos" %]

<p>
<input name="query" type="text" class="search-query span3"
placeholder="Search by name or description"
id="search" value="" autofocus="autofocus"/>
</p>

<hr />

<p><em id="how-many">Loading…</em></p>

<div id="results-wrapper" class="hide">

[% INCLUDE renderPager %]

<table class="table table-hover" id="search-results">
<thead>
<tr>
<th>Package name</th>
<th>Attribute name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

[% INCLUDE renderPager %]

<div id="packages-explorer">
<div class="app">
<noscript>Sorry, you need to enable JavaScript to run this app.</noscript>
<div class="loading">
Loading...
</div>
</div>
</div>

<div id="details-template" class="search-details hide">
<table>
<tr>
<th>Install command:</th>
<td>
<tt><span class="nix-command">nix-env -iA nixos.<span class="attrname"></span></span></tt> <em class="muted">(NixOS channel)</em>
</td>
</tr>
<tr>
<th>Nix expression:</th>
<td class="nix-expr"><em>Not specified</em></td>
</tr>
<tr>
<th>Platforms:</th>
<td class="platforms"><em>Not specified</em></td>
</tr>
<tr>
<th>Homepage:</th>
<td class="homepage"><em>Not specified</em></td>
</tr>
<tr>
<th>License:</th>
<td class="license"><em>Not specified</em></td>
</tr>
<tr>
<th>Maintainers:</th>
<td class="maintainers"><em>Not specified</em></td>
</tr>
<tr>
<th style="width: 10em">Long description:</th>
<td class="long-description"><em>Not specified</em></td>
</tr>
</table>
</div>

<script>
//<![CDATA[
var nixpkgsCommit = "master";

var packageData = [];

var results = [];

var resultsPerPage = 15;

var curPage = 0;
var lastPage = 0;

function updateTable() {
if (0 > curPage) curPage = 0;
if (curPage > lastPage) curPage = lastPage;

var body = $("#search-results tbody");
$("tr", body).remove();

$(".back").toggleClass("disabled", curPage == 0);
$(".forward").toggleClass("disabled", curPage >= lastPage);

var start = curPage * resultsPerPage;
var end = start + resultsPerPage;
if (end > results.length) end = results.length;
res = results.slice(start, end);

if (results.length == 0) {
$("#results-wrapper").hide();
$("#how-many").text("No matching packages were found.");
return;
}

$("#how-many").text(
"Showing results " + (start + 1) + "-" + end + " of " + results.length + ".");

var odd = true;
res.forEach(function(pkgName) {
var info = packageData[pkgName];
body.append($("<tr/>", { pkgName: pkgName })
.addClass("result")
.addClass(odd ? "odd" : "even")
.click(showPackage)
.append($("<td/>", { text: info["name"] }))
.append($("<td/>", { text: pkgName }))
.append($("<td/>", { text: info["meta"]["description"] }))
);
odd = !odd;
});

$("#results-wrapper").show();
};

function refilter() {
var attrs = Object.keys(packageData);

var words = $("#search").val().toLowerCase().split(/ +/).filter(Boolean);

if (words.length > 0) {
attrs = attrs.filter(function (attr) {
var info = packageData[attr];
var description = info["meta"]["description"] || "";
var longDescription = info["meta"]["longDescription"] || "";

function match(word) {
return (attr.toLowerCase().indexOf(word) != -1
|| info["name"].toLowerCase().indexOf(word) != -1
|| description.toLowerCase().indexOf(word) != -1
|| longDescription.toLowerCase().indexOf(word) != -1);
};

return words.every(match);
});

var encodedWords = words.map(function(value) {
return encodeURIComponent(value);
});
var hash = encodedWords.join('+');
while (document.getElementById(hash)) {
hash = '+' + hash;
}
history.replaceState({}, '', '#' + hash);
} else {
history.replaceState({}, '', '#');
}

results = attrs.sort(function(a, b) {
var ia = packageData[a]["name"].toLowerCase();
var ib = packageData[b]["name"].toLowerCase();
if (ia < ib) return -1;
if (ia > ib) return 1;
return 0;
});

curPage = 0;
lastPage = (results.length - 1) / resultsPerPage >> 0;

updateTable();
};

// Try to figure out a human-readable name for a license object.
// Use the SPDX ID if present; failing that try the long or short names. If all
// else fails fall back on URL.
function licenseName(license) {
return license.spdxId
|| license.fullName
|| license.shortName
|| license.url
|| "Licence name missing!";
}

// Given a license, or array of licenses, generate and return a DOM node
// containing information about it/them.
// A license can be a plain string (in which case it returns the string itself
// as a text node), or a license object, in which case it attempts to construct
// a link to the license's URL (if specified).
function licenseInfo(license) {
if (typeof license == "string") {
return document.createTextNode(license);
}
if (Array.isArray(license)) {
return license
.map(licenseInfo)
.map(function(license) { return $("<li>").append(license) })
.reduce(function(ul, li) {
return ul.append(li);
}, $("<ul>"));
}

if (license.url) {
return $("<a>", {
text: licenseName(license),
href: license.url,
});
} else {
return document.createTextNode(licenseName(license));
}
}

function showPackage() {
var pkgName = $(this).attr("pkgName");
var info = packageData[pkgName];

var expanded = $(this).attr("expanded");
$("tr.details", $(this).parent()).remove();
$("tr", $(this).parent()).removeAttr("expanded");
if (expanded) return;

var details = $("#details-template").clone().removeAttr("id").show();

$(".attrname", details).text(pkgName);

var nixExpr = info["meta"]["position"];
if (typeof nixExpr == "string") {
var n = nixExpr.lastIndexOf(":");
var file = nixExpr.slice(0, n);
var line = nixExpr.slice(n + 1);
var url = "https://github.com/NixOS/nixpkgs/blob/" + nixpkgsCommit + "/" + file + "#L" + line;
$(".nix-expr", details).empty().append($("<a/>", { href: url }).text(file));
}

var platforms = info["meta"]["platforms"];
if (Array.isArray(platforms) && platforms.length > 0) {
var p = $(".platforms", details).empty();
var first = true;
platforms.forEach(function (system) {
if (system != "i686-linux" && system != "x86_64-linux") return;
if (!first) p.append(document.createTextNode(", "));
first = false;
var url = "https://hydra.nixos.org/job/nixos/[%latestNixOSBranch%]/nixpkgs." + pkgName + "." + system;
p.append($("<a/>", { href: url }).append($("<tt/>").text(system)));
});
}

var homepage = info["meta"]["homepage"];
if (typeof homepage == "string")
$(".homepage", details).empty().append($("<a/>", { href: homepage }).text(homepage));

var license = info["meta"]["license"];
if (license) {
$(".license", details).empty().append(licenseInfo(license));
}

var maintainers = info["meta"]["maintainers"];
if (Array.isArray(maintainers) && maintainers.length > 0)
// FIXME: check whether elements are strings.
$(".maintainers", details).empty().text(maintainers.join(", "));

var longDescription = info["meta"]["longDescription"];
if (typeof longDescription == "string")
$(".long-description", details).empty().addClass("pre").text(longDescription);

$(this).after($("<tr/>")
.addClass("details")
.append($("<td/>", { colspan: 3 })
.append(details))
).attr("expanded", 1);
};

$.ajax({
url: ((document.domain == 'nixos.org') ? '[%root%]nixpkgs/packages.json.gz' : '[%root%]nixpkgs/packages.json'),
type: "GET",
dataType: "json",
error: function(a, status, error) { alert("Failed to get package data [" + status + "]: " + error); },
success: function(data) {
nixpkgsCommit = data.commit;
packageData = data.packages;

var lastHash;
var hashChanged = true;

function updateQuery() {
var query = decodeURIComponent(document.location.hash.replace(/^#\+*/, '').replace(/\+/g, ' '));
if (query.length && query.length > 0 ){ $('#search').val(query); } else { $('#search').val('') };
refilter();
lastHash = location.hash || '#';
}

$(window).on('popstate', updateQuery);

updateQuery();

$("#search").on("input", function() {
if (hashChanged) {
history.pushState({}, '', location.hash || '#');
hashChanged = false;
}
refilter();
});
$('#search').on('change', function() {
var hash = location.hash || '#';
if (lastHash != hash) {
hashChanged = true;
lastHash = hash;
}
});
}
});

//]]>
</script>

<script type="text/javascript" src="packages-explorer.js"></script>
[% END %]

0 comments on commit ea73d79

Please sign in to comment.