unpkg/modules/client/autoIndex/DirectoryListing.js

127 lines
2.7 KiB
JavaScript

require("./DirectoryListing.css");
const React = require("react");
const formatBytes = require("pretty-bytes");
const sortBy = require("sort-by");
function getDirname(name) {
return (
name
.split("/")
.slice(0, -1)
.join("/") || "."
);
}
function getMatchingEntries(entry, entries) {
const dirname = entry.name || ".";
return Object.keys(entries)
.filter(name => entry.name !== name && getDirname(name) === dirname)
.map(name => entries[name]);
}
function getRelativeName(base, name) {
return base.length ? name.substr(base.length + 1) : name;
}
function DirectoryListing({ filename, entry, entries }) {
const rows = [];
if (filename !== "/") {
rows.push(
<tr key="..">
<td>
<a title="Parent directory" href="../">
..
</a>
</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
);
}
const matchingEntries = getMatchingEntries(entry, entries);
matchingEntries
.filter(({ type }) => type === "directory")
.sort(sortBy("name"))
.forEach(({ name }) => {
const relName = getRelativeName(entry.name, name);
const href = relName + "/";
rows.push(
<tr key={name}>
<td>
<a title={relName} href={href}>
{href}
</a>
</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
);
});
matchingEntries
.filter(({ type }) => type === "file")
.sort(sortBy("name"))
.forEach(({ name, size, contentType, lastModified }) => {
const relName = getRelativeName(entry.name, name);
rows.push(
<tr key={name}>
<td>
<a title={relName} href={relName}>
{relName}
</a>
</td>
<td>{contentType}</td>
<td>{formatBytes(size)}</td>
<td>{lastModified}</td>
</tr>
);
});
return (
<div className="directory-listing">
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Size</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
{rows.map((row, index) =>
React.cloneElement(row, {
className: index % 2 ? "odd" : "even"
})
)}
</tbody>
</table>
</div>
);
}
if (process.env.NODE_ENV === "development") {
const PropTypes = require("prop-types");
const entryType = PropTypes.shape({
name: PropTypes.string.isRequired
});
DirectoryListing.propTypes = {
filename: PropTypes.string.isRequired,
entry: entryType.isRequired,
entries: PropTypes.objectOf(entryType).isRequired
};
}
module.exports = DirectoryListing;