Upgrade to Bootstrap 5, and improve UI
parent
38de494408
commit
36cdb9aa8b
|
@ -1,7 +1,7 @@
|
|||
.cmd {
|
||||
word-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
pre {
|
||||
background-color: #eee;
|
||||
min-height: 1.5em;
|
||||
background-color: #eee;
|
||||
min-height: 1.5em;
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont,
|
||||
"Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans",
|
||||
"Droid Sans", "Helvetica Neue", sans-serif;
|
||||
}
|
|
@ -1,4 +1,23 @@
|
|||
.name {
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.badge-alignment {
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
.stretched-invisible-label {
|
||||
display: block;
|
||||
}
|
||||
.stretched-invisible-label > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.stretched-invisible-label::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
/* jshint esversion: 6 */
|
||||
|
||||
$(document).ready(() => {
|
||||
$("[title]").tooltip();
|
||||
});
|
|
@ -8,12 +8,12 @@
|
|||
}
|
||||
|
||||
.input-group-digits input[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
.input-group-digits input[type=number]::-webkit-inner-spin-button,
|
||||
.input-group-digits input[type=number]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.login {
|
||||
|
|
|
@ -1,53 +1,51 @@
|
|||
/* jshint esversion: 6 */
|
||||
|
||||
$(document).ready(() => {
|
||||
let $inputs = $(".input-group-digits");
|
||||
$inputs.each((i, input) => {
|
||||
let cleanup = () => {
|
||||
$(input).find("input").each((i, ele) => {
|
||||
let cleaned = $(ele).val().replace(/[^0-9]/, "");
|
||||
$(ele).val(cleaned);
|
||||
});
|
||||
};
|
||||
let update = (e) => {
|
||||
$digits = $(input).find("input");
|
||||
let $inputs = $(".input-group-digits");
|
||||
$inputs.each((i, input) => {
|
||||
let cleanup = () => {
|
||||
$(input).find("input").each((i, ele) => {
|
||||
let cleaned = $(ele).val().replace(/[^0-9]/, "");
|
||||
$(ele).val(cleaned);
|
||||
});
|
||||
};
|
||||
let update = (e) => {
|
||||
$digits = $(input).find("input");
|
||||
|
||||
// Cleanup
|
||||
cleanup();
|
||||
// Cleanup
|
||||
cleanup();
|
||||
|
||||
// Shift characters
|
||||
let excess = "";
|
||||
$digits.each((i, ele) => {
|
||||
let now = excess + $(ele).val();
|
||||
$(ele).val(now.charAt(0));
|
||||
excess = now.substr(1);
|
||||
});
|
||||
// Shift characters
|
||||
let excess = "";
|
||||
$digits.each((i, ele) => {
|
||||
let now = excess + $(ele).val();
|
||||
$(ele).val(now.charAt(0));
|
||||
excess = now.substr(1);
|
||||
});
|
||||
|
||||
// Move cursor to empty
|
||||
$digits.each((i, ele) => {
|
||||
if (!$(ele).val()) {
|
||||
$(ele).focus();
|
||||
if (e.which == 8) {
|
||||
$(ele).prev().focus().val("");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// Move cursor to empty
|
||||
$digits.each((i, ele) => {
|
||||
if (!$(ele).val()) {
|
||||
$(ele).focus();
|
||||
if (e.which == 8) {
|
||||
$(ele).prev().focus().val("");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Submit if last digit is filled
|
||||
if ($($digits[$digits.length - 1]).val()) {
|
||||
let token = $.map(
|
||||
$digits,
|
||||
d => $(d).val()
|
||||
).join("");
|
||||
let $value = $(input).parent().find("#login-token-value");
|
||||
$value.val(token);
|
||||
$value.closest("form").submit();
|
||||
}
|
||||
};
|
||||
// Submit if last digit is filled
|
||||
if ($($digits[$digits.length - 1]).val()) {
|
||||
let token = $.map(
|
||||
$digits,
|
||||
d => $(d).val()
|
||||
).join("");
|
||||
let $value = $(input).parent().find("#login-token-value");
|
||||
$value.val(token);
|
||||
$value.closest("form").submit();
|
||||
}
|
||||
};
|
||||
|
||||
$digits = $(input).find("input");
|
||||
$digits.on("keyup", update);
|
||||
$digits.on("change", update);
|
||||
});
|
||||
$digits = $(input).find("input");
|
||||
$digits.on("keyup", update);
|
||||
$digits.on("change", update);
|
||||
});
|
||||
|
|
|
@ -1,30 +1,51 @@
|
|||
/* jshint esversion: 6 */
|
||||
|
||||
$(document).ready(() => {
|
||||
let $select = $(".multi-select");
|
||||
function htmlEscape(text) {
|
||||
const p = document.createElement('p');
|
||||
p.innerText = text;
|
||||
return p.innerHTML;
|
||||
}
|
||||
|
||||
let setSelected = (files) => {
|
||||
$(".multi-files-value").val(JSON.stringify(files.map(f => f.name)));
|
||||
$(".multi-files").html(
|
||||
files.map(f => {
|
||||
return `<li class="list-group-item d-flex align-items-start justify-content-between"><span class="name">${f.name}</span> <span class="badge badge-pill badge-secondary">${f.size}</span></li>`;
|
||||
}).join("")
|
||||
);
|
||||
};
|
||||
let $select = $(".multi-select");
|
||||
|
||||
let updateSelected = () => {
|
||||
let $selected = $(".multi-select:checked");
|
||||
let files = [];
|
||||
$selected.each((i, ele) => {
|
||||
files.push({
|
||||
name: $(ele).data("select"),
|
||||
size: $(ele).data("select-size")
|
||||
});
|
||||
});
|
||||
let setSelected = (files) => {
|
||||
$(".multi-files-value").val(JSON.stringify(files.map(f => f.name)));
|
||||
if (files.length == 0) {
|
||||
$(".multi-files").html(`<li class="list-group-item text-muted">No files selected</li>`);
|
||||
return
|
||||
}
|
||||
$(".multi-files").html(
|
||||
files.map(f => {
|
||||
return `
|
||||
<li class="list-group-item d-flex align-items-start justify-content-between">
|
||||
<span class="name">${htmlEscape(f.name)}</span>
|
||||
${f.type == "directory" ? `` : `<span class="badge rounded-pill bg-secondary badge-alignment">${filesize(f.size)}</span>`}
|
||||
</li>
|
||||
`;
|
||||
}).join("")
|
||||
);
|
||||
const hasDirectory = files.reduce((a, f) => a || f.type == "directory", false);
|
||||
const totalSize = files.map(f => f.size).reduce((a, b) => a + b);
|
||||
if (hasDirectory) {
|
||||
$(".multi-files-total").text("Unknown");
|
||||
} else {
|
||||
$(".multi-files-total").text(filesize(totalSize));
|
||||
}
|
||||
};
|
||||
|
||||
setSelected(files);
|
||||
}
|
||||
const updateSelected = () => {
|
||||
let $selected = $(".multi-select:checked");
|
||||
let files = [];
|
||||
$selected.each((i, ele) => {
|
||||
files.push({
|
||||
name: $(ele).data("select"),
|
||||
type: $(ele).data("select-type"),
|
||||
size: $(ele).data("select-size")
|
||||
});
|
||||
});
|
||||
|
||||
$select.on("change", updateSelected);
|
||||
updateSelected();
|
||||
});
|
||||
setSelected(files);
|
||||
}
|
||||
|
||||
$select.on("change", updateSelected);
|
||||
updateSelected();
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#navbar {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.nav-link {
|
||||
white-space: nowrap;
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
/* jshint esversion: 6 */
|
||||
|
||||
$(document).ready(() => {
|
||||
let $shell = $("#shell");
|
||||
if ($shell.length < 1) {
|
||||
return;
|
||||
}
|
||||
let $close = $("#shell-close");
|
||||
const $shell = $("#shell");
|
||||
const $close = $("#shell-close");
|
||||
|
||||
if ($shell.length > 0) {
|
||||
|
||||
const ws = new WebSocket("ws" + (window.location.protocol === "https:" ? "s" : "") + "://" + window.location.host + "/websocket?path=" + encodeURIComponent($shell.data("path")));
|
||||
|
||||
|
@ -54,4 +52,5 @@ $(document).ready(() => {
|
|||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
/* jshint esversion: 6 */
|
||||
|
||||
document.querySelectorAll("[title]").forEach(element => {
|
||||
new bootstrap.Tooltip(element);
|
||||
});
|
|
@ -1,24 +1,22 @@
|
|||
/* jshint esversion: 6 */
|
||||
|
||||
$(document).ready(() => {
|
||||
let $form = $("form[action='@upload']");
|
||||
let $file = $("#upload-file");
|
||||
|
||||
$(".upload-unhide").fadeOut();
|
||||
|
||||
$file.on("change", () => {
|
||||
let file = $file[0].files[0];
|
||||
let fnElement = $file.parent().find(".custom-file-label");
|
||||
fnElement.addClass("file-selected");
|
||||
fnElement.text(file.name);
|
||||
const $form = $("form[action='@upload']");
|
||||
const $file = $("#upload-file");
|
||||
|
||||
$form.find("#upload-file-size").val(filesize(file.size));
|
||||
$form.find("[name=saveas]").val(file.name);
|
||||
$(".upload-unhide").fadeIn();
|
||||
});
|
||||
$(".upload-unhide").fadeOut();
|
||||
|
||||
$form.on("submit", () => {
|
||||
let putresource = $form.find("[name=saveas]").val();
|
||||
// TODO: do XHR to PUT at putresource
|
||||
});
|
||||
$file.on("change", () => {
|
||||
const file = $file[0].files[0];
|
||||
const fnElement = $file.parent().find(".custom-file-label");
|
||||
fnElement.addClass("file-selected");
|
||||
fnElement.text(file.name);
|
||||
|
||||
$form.find("#upload-file-size").val(filesize(file.size));
|
||||
$form.find("[name=saveas]").val(file.name);
|
||||
$(".upload-unhide").fadeIn();
|
||||
});
|
||||
|
||||
$form.on("submit", () => {
|
||||
let putresource = $form.find("[name=saveas]").val();
|
||||
// TODO: do XHR to PUT at putresource
|
||||
});
|
||||
|
|
29
index.js
29
index.js
|
@ -34,6 +34,12 @@ app.engine("handlebars", hbs({
|
|||
layoutsDir: path.join(__dirname, "views", "layouts"),
|
||||
defaultLayout: "main",
|
||||
helpers: {
|
||||
either: (a, b, options) => {
|
||||
if (a || b) {
|
||||
return options.fn();
|
||||
}
|
||||
},
|
||||
filesize: filesize,
|
||||
octicon: (i, options) => {
|
||||
if (!octicons[i]) {
|
||||
return new handlebars.SafeString(octicons.question.toSVG());
|
||||
|
@ -174,7 +180,7 @@ app.put("/*", (req, res) => {
|
|||
res.redirect("back");
|
||||
});
|
||||
save.on("error", (err) => {
|
||||
res.flash("error", err);
|
||||
res.flash("error", err.toString());
|
||||
res.redirect("back");
|
||||
});
|
||||
}
|
||||
|
@ -230,9 +236,13 @@ app.post("/*@upload", (req, res) => {
|
|||
req.flash("error", "File exists, cannot overwrite. ");
|
||||
res.redirect("back");
|
||||
}).catch((err) => {
|
||||
console.log("saving");
|
||||
let save = fs.createWriteStream(relative(res.filename, saveas));
|
||||
const saveName = relative(res.filename, saveas);
|
||||
console.log("saving file to " + saveName);
|
||||
let save = fs.createWriteStream(saveName);
|
||||
save.on("close", () => {
|
||||
if (res.headersSent) {
|
||||
return;
|
||||
}
|
||||
if (buff.length === 0) {
|
||||
req.flash("success", "File saved. Warning: empty file.");
|
||||
}
|
||||
|
@ -243,7 +253,7 @@ app.post("/*@upload", (req, res) => {
|
|||
res.redirect("back");
|
||||
});
|
||||
save.on("error", (err) => {
|
||||
req.flash("error", err);
|
||||
req.flash("error", err.toString());
|
||||
res.redirect("back");
|
||||
});
|
||||
save.write(buff);
|
||||
|
@ -277,7 +287,7 @@ app.post("/*@mkdir", (req, res) => {
|
|||
}).catch((err) => {
|
||||
fs.mkdir(relative(res.filename, folder), (err) => {
|
||||
if (err) {
|
||||
req.flash("error", err);
|
||||
req.flash("error", err.toString());
|
||||
res.redirect("back");
|
||||
return;
|
||||
}
|
||||
|
@ -341,7 +351,7 @@ app.post("/*@delete", (req, res) => {
|
|||
res.redirect("back");
|
||||
});
|
||||
}).catch((err) => {
|
||||
req.flash("error", err);
|
||||
req.flash("error", err.toString());
|
||||
res.redirect("back");
|
||||
});
|
||||
});
|
||||
|
@ -394,7 +404,7 @@ app.get("/*@download", (req, res) => {
|
|||
zip.finalize();
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
req.flash("error", err);
|
||||
req.flash("error", err.toString());
|
||||
res.redirect("back");
|
||||
});
|
||||
});
|
||||
|
@ -515,7 +525,7 @@ app.get("/*", (req, res) => {
|
|||
resolve({
|
||||
name: f,
|
||||
isdirectory: stats.isDirectory(),
|
||||
size: filesize(stats.size)
|
||||
size: stats.size
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -551,6 +561,9 @@ app.get("/*", (req, res) => {
|
|||
}
|
||||
else if (res.stats.isFile()) {
|
||||
res.sendFile(relative(res.filename), {
|
||||
headers: {
|
||||
"Content-Security-Policy": "default-src 'self'; script-src 'none'; sandbox"
|
||||
},
|
||||
dotfiles: "allow"
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"dependencies": {
|
||||
"archiver": "^5.3.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"bootstrap": "^4.6.0",
|
||||
"bootstrap": "^5.0.0",
|
||||
"connect-busboy": "^0.0.2",
|
||||
"connect-flash": "^0.1.1",
|
||||
"express": "^4.17.1",
|
||||
|
@ -32,6 +32,16 @@
|
|||
"file-manager": "index.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@popperjs/core": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz",
|
||||
"integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
|
@ -168,16 +178,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
|
||||
"integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.0.0.tgz",
|
||||
"integrity": "sha512-tmhPET9B9qCl8dCofvHeiIhi49iBt0EehmIsziZib65k1erBW1rHhj2s/2JsuQh5Pq+xz2E9bEbzp9B7xHG+VA==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"jquery": "1.9.1 - 3",
|
||||
"popper.js": "^1.16.1"
|
||||
"@popperjs/core": "^2.9.2"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
|
@ -914,17 +923,6 @@
|
|||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"node_modules/popper.js": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
|
||||
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
|
||||
"deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/printj": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
|
||||
|
@ -1295,6 +1293,12 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@popperjs/core": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz",
|
||||
"integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==",
|
||||
"peer": true
|
||||
},
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
|
@ -1407,9 +1411,9 @@
|
|||
}
|
||||
},
|
||||
"bootstrap": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
|
||||
"integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.0.0.tgz",
|
||||
"integrity": "sha512-tmhPET9B9qCl8dCofvHeiIhi49iBt0EehmIsziZib65k1erBW1rHhj2s/2JsuQh5Pq+xz2E9bEbzp9B7xHG+VA==",
|
||||
"requires": {}
|
||||
},
|
||||
"brace-expansion": {
|
||||
|
@ -1976,12 +1980,6 @@
|
|||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"popper.js": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
|
||||
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
|
||||
"peer": true
|
||||
},
|
||||
"printj": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"dependencies": {
|
||||
"archiver": "^5.3.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"bootstrap": "^4.6.0",
|
||||
"bootstrap": "^5.0.0",
|
||||
"connect-busboy": "^0.0.2",
|
||||
"connect-flash": "^0.1.1",
|
||||
"express": "^4.17.1",
|
||||
|
|
|
@ -2,36 +2,36 @@
|
|||
|
||||
<div style="padding-top: 56px; padding-bottom: 56px;">
|
||||
<main class="container my-4">
|
||||
{{#each errors as |error|}}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{error}}
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each successes as |success|}}
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{success}}
|
||||
</div>
|
||||
{{/each}}
|
||||
<h4>command</h4>
|
||||
<h4 class="cmd"><code>{{cmd}}</code></h4>
|
||||
<h4>stdout</h4>
|
||||
<pre><code>{{stdout}}</code></pre>
|
||||
<h4>stderr</h4>
|
||||
<pre><code>{{stderr}}</code></pre>
|
||||
{{#each errors as |error|}}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{error}}
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each successes as |success|}}
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{success}}
|
||||
</div>
|
||||
{{/each}}
|
||||
<h4>command</h4>
|
||||
<h4 class="cmd"><code>{{cmd}}</code></h4>
|
||||
<h4>stdout</h4>
|
||||
<pre><code>{{stdout}}</code></pre>
|
||||
<h4>stderr</h4>
|
||||
<pre><code>{{stderr}}</code></pre>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<nav class="navbar navbar-light bg-light fixed-bottom p-1 px-2">
|
||||
<div class="btn-group m-1" role="group">
|
||||
<a class="btn btn-primary" href="/{{path}}" data-placement="top" title="Return to folder">
|
||||
{{octicon "chevron-left"}}
|
||||
<span class="d-none d-sm-inline">Back</span>
|
||||
</a>
|
||||
<a class="btn btn-warning" href="@cmd" data-toggle="modal" data-target="#cmd" data-placement="top" title="Run another command">
|
||||
{{octicon "terminal"}}
|
||||
<span class="d-none d-sm-inline">Run command</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group m-1" role="group">
|
||||
<a class="btn btn-primary" href="/{{path}}" data-placement="top" title="Return to folder">
|
||||
{{octicon "chevron-left"}}
|
||||
<span class="d-none d-sm-inline">Back</span>
|
||||
</a>
|
||||
<a class="btn btn-warning" href="@cmd" data-toggle="modal" data-target="#cmd" data-placement="top" title="Run another command">
|
||||
{{octicon "terminal"}}
|
||||
<span class="d-none d-sm-inline">Run command</span>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{{> dialogue-cmd}}
|
||||
|
|
|
@ -1,38 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>File Manager</title>
|
||||
|
||||
<link rel="stylesheet" href="/@assets/octicons/build.css" />
|
||||
|
||||
<script src="/@assets/jquery/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="/@assets/bootstrap/css/bootstrap.min.css" />
|
||||
<script src="/@assets/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="/@assets/xterm/css/xterm.css" />
|
||||
<script src="/@assets/xterm/lib/xterm.js"></script>
|
||||
<script src="/@assets/xterm-addon-attach/lib/xterm-addon-attach.js"></script>
|
||||
<script src="/@assets/xterm-addon-fit/lib/xterm-addon-fit.js"></script>
|
||||
|
||||
<script src="/@assets/filesize/filesize.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/@assets/fonts.css" />
|
||||
|
||||
<link rel="stylesheet" href="/@assets/list.css" />
|
||||
<script src="/@assets/list.js"></script>
|
||||
<script src="/@assets/multi.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/@assets/upload.css" />
|
||||
<script src="/@assets/upload.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/@assets/login.css" />
|
||||
<script src="/@assets/login.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/@assets/cmd.css" />
|
||||
<script src="/@assets/shell.js"></script>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>File Manager</title>
|
||||
<!-- icons -->
|
||||
<link rel="stylesheet" href="/@assets/octicons/build.css" />
|
||||
<!-- bootstrap -->
|
||||
<script src="/@assets/jquery/jquery.min.js" defer></script>
|
||||
<link rel="stylesheet" href="/@assets/bootstrap/css/bootstrap.min.css" />
|
||||
<script src="/@assets/bootstrap/js/bootstrap.bundle.min.js" defer></script>
|
||||
<!-- xterm -->
|
||||
<link rel="stylesheet" href="/@assets/xterm/css/xterm.css" />
|
||||
<script src="/@assets/xterm/lib/xterm.js" defer></script>
|
||||
<script src="/@assets/xterm-addon-attach/lib/xterm-addon-attach.js" defer></script>
|
||||
<script src="/@assets/xterm-addon-fit/lib/xterm-addon-fit.js" defer></script>
|
||||
<!-- file size math -->
|
||||
<script src="/@assets/filesize/filesize.js" defer></script>
|
||||
<!-- navbar, tooltip -->
|
||||
<link rel="stylesheet" href="/@assets/navbar.css" />
|
||||
<script src="/@assets/tooltip.js" defer></script>
|
||||
<!-- list, multi-select -->
|
||||
<link rel="stylesheet" href="/@assets/list.css" />
|
||||
<script src="/@assets/multi.js" defer></script>
|
||||
<!-- upload -->
|
||||
<link rel="stylesheet" href="/@assets/upload.css" />
|
||||
<script src="/@assets/upload.js" defer></script>
|
||||
<!-- login -->
|
||||
<link rel="stylesheet" href="/@assets/login.css" />
|
||||
<script src="/@assets/login.js" defer></script>
|
||||
<!-- cmd -->
|
||||
<link rel="stylesheet" href="/@assets/cmd.css" />
|
||||
<!-- shell -->
|
||||
<script src="/@assets/shell.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
{{{body}}}
|
||||
<body class="bg-light">
|
||||
{{{body}}}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -2,37 +2,39 @@
|
|||
|
||||
<div style="padding-top: 56px; padding-bottom: 56px;">
|
||||
<main class="container my-4">
|
||||
{{#each errors as |error|}}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{error}}
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each successes as |success|}}
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{success}}
|
||||
</div>
|
||||
{{/each}}
|
||||
<ul class="list-group">
|
||||
{{#each files}}
|
||||
<li class="list-group-item">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input multi-select" data-select="{{name}}" data-select-size="{{size}}" id="check{{@index}}">
|
||||
<label class="custom-control-label d-flex align-items-start justify-content-between" for="check{{@index}}">
|
||||
{{#if isdirectory}}
|
||||
<a href="./{{name}}/" class="name">{{name}}/</a>
|
||||
{{else}}
|
||||
<a href="./{{name}}" class="name mr-auto">{{name}}</a>
|
||||
<span class="badge badge-pill badge-secondary">{{size}}</span>
|
||||
{{/if}}
|
||||
</label>
|
||||
</div>
|
||||
</li>
|
||||
{{else}}
|
||||
<li class="list-group-item">
|
||||
No files
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{#each errors as |error|}}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{error}}
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each successes as |success|}}
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{success}}
|
||||
</div>
|
||||
{{/each}}
|
||||
<ul class="list-group">
|
||||
{{#each files}}
|
||||
<li class="list-group-item">
|
||||
<label for="check{{@index}}" class="stretched-invisible-label">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input multi-select" data-select="{{name}}" data-select-size="{{size}}" data-select-type="{{#if isdirectory}}directory{{else}}file{{/if}}" id="check{{@index}}">
|
||||
<span class="form-check-label d-flex align-items-start justify-content-between">
|
||||
{{#if isdirectory}}
|
||||
<a href="./{{name}}/" class="name">{{name}}/</a>
|
||||
{{else}}
|
||||
<a href="./{{name}}" class="name">{{name}}</a>
|
||||
<span class="badge rounded-pill bg-secondary badge-alignment">{{filesize size}}</span>
|
||||
{{/if}}
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
{{else}}
|
||||
<li class="list-group-item">
|
||||
No files
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -2,31 +2,31 @@
|
|||
|
||||
<div style="padding-top: 56px; padding-bottom: 56px;">
|
||||
<main class="container my-4">
|
||||
<div class="login mx-auto">
|
||||
{{#each errors as |error|}}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{error}}
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each successes as |success|}}
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{success}}
|
||||
</div>
|
||||
{{/each}}
|
||||
<form class="py-4" action="/@login" method="post">
|
||||
<h4>One-time token:</h4>
|
||||
<div class="form-group">
|
||||
<div class="input-group input-group-lg input-group-digits">
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
</div>
|
||||
<input name="token" id="login-token-value" type="hidden" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="login mx-auto">
|
||||
{{#each errors as |error|}}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{error}}
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each successes as |success|}}
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{success}}
|
||||
</div>
|
||||
{{/each}}
|
||||
<form class="py-4" action="/@login" method="post">
|
||||
<h4>One-time token:</h4>
|
||||
<div class="form-group">
|
||||
<div class="input-group input-group-lg input-group-digits">
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
<input type="number" class="form-control" placeholder="•" />
|
||||
</div>
|
||||
<input name="token" id="login-token-value" type="hidden" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
<form action="@cmd" method="post">
|
||||
<div id="cmd" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Run command</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="cmd-cmd">Command: </label>
|
||||
<input name="cmd" class="form-control" type="text" id="cmd-cmd" placeholder="g++ sort.c" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="reset" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Run</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="cmd" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-light">
|
||||
<h5 class="modal-title">Run command</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="cmd-cmd">Command: </label>
|
||||
<input name="cmd" class="form-control" type="text" id="cmd-cmd" placeholder="g++ sort.c" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="reset" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Run</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,25 +1,23 @@
|
|||
<form action="@delete" method="post">
|
||||
<div id="delete" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Are you sure?</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>You are deleting the following files: </p>
|
||||
<ul class="list-group multi-files">
|
||||
|
||||
</ul>
|
||||
<input type="hidden" name="files" value="" class="multi-files-value" />
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="reset" class="btn btn-primary" data-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-danger">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="delete" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-light">
|
||||
<h5 class="modal-title">Are you sure?</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>You are deleting the following files: </p>
|
||||
<ul class="list-group multi-files">
|
||||
|
||||
</ul>
|
||||
<input type="hidden" name="files" value="" class="multi-files-value" />
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="reset" class="btn btn-primary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-danger">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
<form action="@download" method="get">
|
||||
<div id="download" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Download file archive?</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Your archive will contain the following files: </p>
|
||||
<ul class="list-group multi-files">
|
||||
|
||||
</ul>
|
||||
<input type="hidden" name="files" value="" class="multi-files-value" />
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="reset" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Download</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="download" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-light">
|
||||
<h5 class="modal-title">Download file archive?</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Your archive will contain the following files: </p>
|
||||
<ul class="list-group multi-files">
|
||||
|
||||
</ul>
|
||||
<p class="mt-3 mb-0">Total size: <span class="multi-files-total">Unknown</span></p>
|
||||
<input type="hidden" name="files" value="" class="multi-files-value" />
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="reset" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Download</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
<form action="@mkdir" method="post">
|
||||
<div id="mkdir" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Create a folder</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="mkdir-folder">Folder name: </label>
|
||||
<input name="folder" class="form-control" type="text" id="mkdir-folder" placeholder="folder" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="reset" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Create</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mkdir" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-light">
|
||||
<h5 class="modal-title">Create a folder</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div>
|
||||
<label class="form-label" for="mkdir-folder">Folder name</label>
|
||||
<input class="form-control" name="folder" type="text" id="mkdir-folder" placeholder="folder" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="reset" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Create</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,34 +1,27 @@
|
|||
<form action="@upload" method="post" enctype="multipart/form-data">
|
||||
<div id="upload" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Upload a file</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<div class="custom-file">
|
||||
<input name="file" type="file" id="upload-file" class="custom-file-input">
|
||||
<label class="custom-file-label" for="upload-file">Choose file</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group upload-unhide">
|
||||
<label for="upload-file-size">Filesize: </label>
|
||||
<input class="form-control" type="text" disabled id="upload-file-size" placeholder="0B" />
|
||||
</div>
|
||||
<div class="form-group upload-unhide">
|
||||
<label for="upload-file-saveas">Save as: </label>
|
||||
<input name="saveas" class="form-control" type="text" id="upload-file-saveas" placeholder="filename" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="reset" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="upload" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-light">
|
||||
<h5 class="modal-title">Upload a file</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input class="form-control" type="file" id="upload-file" name="file">
|
||||
<div class="mt-3 upload-unhide">
|
||||
<label class="form-label" for="upload-file-size">Filesize</label>
|
||||
<input class="form-control" type="text" disabled id="upload-file-size" placeholder="0B" />
|
||||
</div>
|
||||
<div class="mt-3 upload-unhide">
|
||||
<label class="form-label" for="upload-file-saveas">Save as</label>
|
||||
<input class="form-control" type="text" name="saveas" id="upload-file-saveas" placeholder="filename" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="reset" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
<nav class="navbar navbar-dark bg-primary fixed-top navbar-expand-sm">
|
||||
<a class="navbar-brand" href="/">File Manager</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbar">
|
||||
<div class="navbar-nav mr-auto">
|
||||
{{#eachpath path}}
|
||||
<a class="nav-item nav-link{{#if current}} active{{/if}}" href="{{path}}">{{name}}</a>
|
||||
{{/eachpath}}
|
||||
</div>
|
||||
<div class="navbar-nav">
|
||||
{{#if isloginenabled}}
|
||||
{{#if isloggingin}}
|
||||
<a class="nav-item nav-link" href="/@login" title="Sign in">
|
||||
<span class="octicon octicon-sign-in"></span>
|
||||
</a>
|
||||
{{else}}
|
||||
<a class="nav-item nav-link" href="/@logout" title="Sign out">
|
||||
<span class="octicon octicon-sign-out"></span>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/">File Manager</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbar">
|
||||
<div class="navbar-nav mr-auto">
|
||||
{{#eachpath path}}
|
||||
<a class="nav-item nav-link{{#if current}} active{{/if}}" href="{{path}}">{{name}}</a>
|
||||
{{/eachpath}}
|
||||
</div>
|
||||
<div class="navbar-nav">
|
||||
{{#if isloginenabled}}
|
||||
{{#if isloggingin}}
|
||||
<a class="nav-item nav-link" href="/@login" title="Sign in">
|
||||
<span class="octicon octicon-sign-in"></span>
|
||||
</a>
|
||||
{{else}}
|
||||
<a class="nav-item nav-link" href="/@logout" title="Sign out">
|
||||
<span class="octicon octicon-sign-out"></span>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
@ -1,44 +1,52 @@
|
|||
<nav class="navbar navbar-light bg-light fixed-bottom p-1 px-2">
|
||||
<div class="btn-group m-1" role="group">
|
||||
<a class="btn btn-primary" href="@upload" data-toggle="modal" data-target="#upload" data-placement="top" title="Upload">
|
||||
{{octicon "cloud-upload"}}
|
||||
<span class="d-none d-sm-inline">Upload</span>
|
||||
</a>
|
||||
<a class="btn btn-secondary" href="@mkdir" data-toggle="modal" data-target="#mkdir" data-placement="top" title="New folder">
|
||||
{{octicon "file-directory"}}
|
||||
<span class="d-none d-md-inline">New folder</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group m-1" role="group">
|
||||
{{#if cmdable}}
|
||||
<a class="btn btn-info" href="@cmd" data-toggle="modal" data-target="#cmd" data-placement="top" title="Run command">
|
||||
{{octicon "terminal"}}
|
||||
<span class="d-none d-lg-inline">Run command</span>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if shellable}}
|
||||
<a class="btn btn-warning" href="@shell" data-placement="top" title="Open shell">
|
||||
{{octicon "terminal"}}
|
||||
<span class="d-none d-md-inline">Open shell</span>
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="btn-group m-1" role="group">
|
||||
<a class="btn btn-success" href="@download" data-toggle="modal" data-target="#download" data-placement="top" title="Download files as zip">
|
||||
{{octicon "file-zip"}}
|
||||
<span class="d-none d-md-inline">Download</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group m-1" role="group">
|
||||
<a class="btn btn-danger" href="@delete" data-toggle="modal" data-target="#delete" data-placement="top" title="Delete files">
|
||||
{{octicon "trashcan"}}
|
||||
<span class="d-none d-md-inline">Delete</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group m-1 ml-auto" role="group">
|
||||
<a class="btn btn-warning" href="./" data-placement="top" title="Refresh list">
|
||||
{{octicon "sync"}}
|
||||
<span class="d-none d-lg-inline">Refresh</span>
|
||||
</a>
|
||||
</div>
|
||||
<nav class="navbar navbar-light bg-light fixed-bottom">
|
||||
<div class="container-fluid px-2">
|
||||
<div class="d-flex">
|
||||
<div class="btn-group me-1" role="group">
|
||||
<a class="btn btn-primary" href="@upload" data-bs-toggle="modal" data-bs-target="#upload" data-placement="top" title="Upload">
|
||||
{{octicon "cloud-upload"}}
|
||||
<span class="d-none d-sm-inline">Upload</span>
|
||||
</a>
|
||||
<a class="btn btn-secondary" href="@mkdir" data-bs-toggle="modal" data-bs-target="#mkdir" data-placement="top" title="New folder">
|
||||
{{octicon "file-directory"}}
|
||||
<span class="d-none d-md-inline">New folder</span>
|
||||
</a>
|
||||
</div>
|
||||
{{#either cmdable shellable}}
|
||||
<div class="btn-group me-1" role="group">
|
||||
{{#if cmdable}}
|
||||
<a class="btn btn-info" href="@cmd" data-bs-toggle="modal" data-bs-target="#cmd" data-placement="top" title="Run command">
|
||||
{{octicon "terminal"}}
|
||||
<span class="d-none d-lg-inline">Run command</span>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if shellable}}
|
||||
<a class="btn btn-warning" href="@shell" data-placement="top" title="Open shell">
|
||||
{{octicon "terminal"}}
|
||||
<span class="d-none d-md-inline">Open shell</span>
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/either}}
|
||||
<div class="btn-group me-1" role="group">
|
||||
<a class="btn btn-success" href="@download" data-bs-toggle="modal" data-bs-target="#download" data-placement="top" title="Download files as zip">
|
||||
{{octicon "file-zip"}}
|
||||
<span class="d-none d-md-inline">Download</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group me-1" role="group">
|
||||
<a class="btn btn-danger" href="@delete" data-bs-toggle="modal" data-bs-target="#delete" data-placement="top" title="Delete files">
|
||||
{{octicon "trashcan"}}
|
||||
<span class="d-none d-md-inline">Delete</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<div class="btn-group ml-1" role="group">
|
||||
<a class="btn btn-warning" href="./" data-placement="top" title="Refresh list">
|
||||
{{octicon "sync"}}
|
||||
<span class="d-none d-lg-inline">Refresh</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
{{> navbar}}
|
||||
|
||||
<div style="padding-top: 56px; padding-bottom: 56px; height: 100vh">
|
||||
<main id="shell" style="height: 100%; background: #000" data-path="/{{path}}"></main>
|
||||
<main id="shell" style="height: 100%; background: #000" data-path="/{{path}}"></main>
|
||||
</div>
|
||||
|
||||
<nav class="navbar navbar-light bg-light fixed-bottom p-1 px-2">
|
||||
<div class="btn-group m-1" role="group">
|
||||
<a class="btn btn-danger" href="/{{path}}" id="shell-close" data-placement="top" title="Close and return to folder">
|
||||
{{octicon "chevron-left"}}
|
||||
<span class="d-none d-sm-inline">Close shell</span>
|
||||
</a>
|
||||
<a class="btn btn-warning" href="@shell" target="_blank" data-placement="top" title="Open shell in new tab">
|
||||
{{octicon "terminal"}}
|
||||
<span class="d-none d-sm-inline">New shell</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group m-1" role="group">
|
||||
<a class="btn btn-danger" href="/{{path}}" id="shell-close" data-placement="top" title="Close and return to folder">
|
||||
{{octicon "chevron-left"}}
|
||||
<span class="d-none d-sm-inline">Close shell</span>
|
||||
</a>
|
||||
<a class="btn btn-warning" href="@shell" target="_blank" data-placement="top" title="Open shell in new tab">
|
||||
{{octicon "terminal"}}
|
||||
<span class="d-none d-sm-inline">New shell</span>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
Loading…
Reference in New Issue