mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-27 02:35:18 +01:00
chore (migration): migrate frontend code
This commit is contained in:
parent
2e7b49660b
commit
40f4caa213
27 changed files with 144 additions and 115 deletions
|
|
@ -12,10 +12,8 @@ class ComponentBreadcrumb extends HTMLDivElement {
|
|||
: `
|
||||
<a href="/logout" data-link>
|
||||
<img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0ODkuODg4IDQ4OS44ODgiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDQ4OS44ODggNDg5Ljg4ODsiPgogIDxwYXRoIGZpbGw9IiM2ZjZmNmYiIGQ9Ik0yNS4zODMsMjkwLjVjLTcuMi03Ny41LDI1LjktMTQ3LjcsODAuOC0xOTIuM2MyMS40LTE3LjQsNTMuNC0yLjUsNTMuNCwyNWwwLDBjMCwxMC4xLTQuOCwxOS40LTEyLjYsMjUuNyAgICBjLTM4LjksMzEuNy02Mi4zLDgxLjctNTYuNiwxMzYuOWM3LjQsNzEuOSw2NSwxMzAuMSwxMzYuOCwxMzguMWM5My43LDEwLjUsMTczLjMtNjIuOSwxNzMuMy0xNTQuNWMwLTQ4LjYtMjIuNS05Mi4xLTU3LjYtMTIwLjYgICAgYy03LjgtNi4zLTEyLjUtMTUuNi0xMi41LTI1LjZsMCwwYzAtMjcuMiwzMS41LTQyLjYsNTIuNy0yNS42YzUwLjIsNDAuNSw4Mi40LDEwMi40LDgyLjQsMTcxLjhjMCwxMjYuOS0xMDcuOCwyMjkuMi0yMzYuNywyMTkuOSAgICBDMTIyLjE4Myw0ODEuOCwzNS4yODMsMzk2LjksMjUuMzgzLDI5MC41eiBNMjQ0Ljg4MywwYy0xOCwwLTMyLjUsMTQuNi0zMi41LDMyLjV2MTQ5LjdjMCwxOCwxNC42LDMyLjUsMzIuNSwzMi41ICAgIHMzMi41LTE0LjYsMzIuNS0zMi41VjMyLjVDMjc3LjM4MywxNC42LDI2Mi44ODMsMCwyNDQuODgzLDB6IiAvPgo8L3N2Zz4K" alt="power">
|
||||
</a>
|
||||
`;
|
||||
</a>`;
|
||||
const paths = (this.getAttribute("path") || "").split("/");
|
||||
console.log(this.getAttribute("path"), paths);
|
||||
const htmlPathChunks = paths.slice(0, -1).map((chunk, idx) => {
|
||||
const label = idx === 0 ? "Filestash" : chunk;
|
||||
const link = paths.slice(0, idx).join("/") + "/";
|
||||
|
|
@ -54,7 +52,11 @@ class ComponentBreadcrumb extends HTMLDivElement {
|
|||
</div>
|
||||
</div>`;
|
||||
}).join("");
|
||||
this.render({ htmlLogout, htmlPathChunks });
|
||||
}
|
||||
|
||||
async render({ htmlLogout, htmlPathChunks }) {
|
||||
const css = await CSS(import.meta.url, "breadcrumb.css");
|
||||
this.innerHTML = `
|
||||
<div class="component_breadcrumb" role="navigation">
|
||||
<style>${css}</style>
|
||||
|
|
@ -66,11 +68,8 @@ class ComponentBreadcrumb extends HTMLDivElement {
|
|||
<span>${htmlPathChunks}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
const css = await CSS(import.meta, "breadcrumb.css");
|
||||
|
||||
customElements.define("component-breadcrumb", ComponentBreadcrumb, { extends: "div" });
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class Icon extends window.HTMLElement {
|
|||
class="component_icon"
|
||||
draggable="false"
|
||||
src="${img}"
|
||||
alt="${name}" />`;
|
||||
alt="${alt}" />`;
|
||||
}
|
||||
|
||||
_mapOfIcon(name) {
|
||||
|
|
@ -32,4 +32,4 @@ class Icon extends window.HTMLElement {
|
|||
}
|
||||
}
|
||||
|
||||
window.customElements.define("component-icon", Icon);
|
||||
customElements.define("component-icon", Icon);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ const free = () => {
|
|||
|
||||
export default class Modal extends HTMLElement {
|
||||
async trigger($node, opts = {}) {
|
||||
const { onQuit, leftButton, rightButton } = opts;
|
||||
const { onQuit } = opts;
|
||||
const $modal = createElement(`
|
||||
<div class="component_modal" id="modal-box">
|
||||
<style>${await CSS(import.meta.url, "modal.css")}</style>
|
||||
|
|
|
|||
|
|
@ -19,3 +19,6 @@ global.console = {
|
|||
warn: jest.fn(),
|
||||
error: jest.fn()
|
||||
};
|
||||
global.customElements = {
|
||||
define: jest.fn(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ export default function(opts) {
|
|||
else if (typeof opts !== "object") throw new Error("unsupported call");
|
||||
if (!opts.headers) opts.headers = {};
|
||||
opts.headers["X-Requested-With"] = "XmlHttpRequest";
|
||||
const isJson = opts.responseType;
|
||||
return ajax({ ...opts, responseType: "text" }).pipe(
|
||||
rxjs.catchError((err) => rxjs.throwError(processError(err.xhr, err))),
|
||||
rxjs.map((res) => {
|
||||
|
|
@ -52,7 +51,6 @@ function processError(xhr, err) {
|
|||
message || "Oups something went wrong with our servers",
|
||||
err, "INTERNAL_SERVER_ERROR"
|
||||
);
|
||||
break;
|
||||
case 401:
|
||||
return new AjaxError(
|
||||
message || "Authentication error",
|
||||
|
|
@ -60,10 +58,9 @@ function processError(xhr, err) {
|
|||
);
|
||||
case 403:
|
||||
return new AjaxError(
|
||||
message || "You can\'t do that",
|
||||
message || "You can't do that",
|
||||
err, "FORBIDDEN"
|
||||
);
|
||||
break;
|
||||
case 413:
|
||||
return new AjaxError(
|
||||
message || "Payload too large",
|
||||
|
|
@ -77,7 +74,7 @@ function processError(xhr, err) {
|
|||
case 409:
|
||||
if (response.error_summary) { // dropbox way to say doesn't exist
|
||||
return new AjaxError(
|
||||
"Doesn\'t exist",
|
||||
"Doesn't exist",
|
||||
err, "UNKNOWN_PATH"
|
||||
);
|
||||
}
|
||||
|
|
@ -92,7 +89,6 @@ function processError(xhr, err) {
|
|||
"Service unavailable, if the problem persist, contact your administrator",
|
||||
err, "INTERNAL_SERVER_ERROR"
|
||||
);
|
||||
break;
|
||||
default:
|
||||
return new AjaxError(xhr.responseText, err, "INTERNAL_SERVER_ERROR");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { onDestroy, createElement } from "./skeleton/index.js";
|
||||
import rxjs from "./rx.js";
|
||||
import { onDestroy } from "./skeleton/index.js";
|
||||
|
||||
export function transition($node, opts = {}) {
|
||||
const {
|
||||
|
|
@ -18,7 +17,7 @@ export function animate($node, opts = {}) {
|
|||
else if (typeof $node.animate !== "function") return Promise.resolve();
|
||||
|
||||
return new Promise((done) => {
|
||||
const run = $node.animate(keyframes, {
|
||||
$node.animate(keyframes, {
|
||||
duration: time,
|
||||
fill: "forwards"
|
||||
}).onfinish = done;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ export default function t(str = "", replacementString, requestedKey) {
|
|||
// ).replace("{{VALUE}}", replacementString);
|
||||
}
|
||||
|
||||
function reformat(translated, initial) {
|
||||
if (initial[0] && initial[0].toLowerCase() === initial[0]) {
|
||||
return translated || "";
|
||||
}
|
||||
return (translated[0] && translated[0].toUpperCase() + translated.substring(1)) || "";
|
||||
}
|
||||
// function reformat(translated, initial) {
|
||||
// if (initial[0] && initial[0].toLowerCase() === initial[0]) {
|
||||
// return translated || "";
|
||||
// }
|
||||
// return (translated[0] && translated[0].toUpperCase() + translated.substring(1)) || "";
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"description": "Frontend for Filestash",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"check": "tsc",
|
||||
"check": "tsc && eslint .",
|
||||
"test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest"
|
||||
},
|
||||
"author": "Mickael Kerjean",
|
||||
|
|
@ -44,5 +44,33 @@
|
|||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslintConfig": {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true,
|
||||
"jest": true
|
||||
},
|
||||
"ignorePatterns": ["lib/vendor/*.js", "*.test.js"],
|
||||
"extends": "standard",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"quotes": ["error", "double"],
|
||||
"indent": ["error", 4],
|
||||
"semi": ["error", "always"],
|
||||
"space-before-function-paren": ["error", "never"],
|
||||
"camelcase": ["off"],
|
||||
"dot-notation": ["off"],
|
||||
"no-case-declarations": ["off"],
|
||||
"no-fallthrough": ["off"],
|
||||
"prefer-regex-literals": ["off"],
|
||||
"promise/param-names": ["off"],
|
||||
"no-return-assign": ["off"],
|
||||
"brace-style": ["off"],
|
||||
"no-useless-escape": ["off"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,4 +23,4 @@ export default AdminOnly(WithShell(async function(render) {
|
|||
));
|
||||
}));
|
||||
|
||||
const css = await CSS(import.meta, "ctrl_about.css");
|
||||
const css = await CSS(import.meta.url, "ctrl_about.css");
|
||||
|
|
|
|||
|
|
@ -51,4 +51,4 @@ function componentStorageBackend(render) {
|
|||
));
|
||||
}
|
||||
|
||||
const css = await CSS(import.meta, "ctrl_backend.css");
|
||||
const css = await CSS(import.meta.url, "ctrl_backend.css");
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
import { navigate } from "../../lib/skeleton/index.js";
|
||||
import AdminOnly from "./decorator_admin_only.js";
|
||||
|
||||
export default AdminOnly(function() {
|
||||
navigate("/admin/backend");
|
||||
});
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { createElement, createRender } from "../../lib/skeleton/index.js";
|
||||
import rxjs, { effect, stateMutation, applyMutation } from "../../lib/rx.js";
|
||||
import { qs } from "../../lib/dom.js";
|
||||
import { createForm, mutateForm } from "../../lib/form.js";
|
||||
import { createForm } from "../../lib/form.js";
|
||||
import { formTmpl } from "../../components/form.js";
|
||||
|
||||
import transition from "./animate.js";
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import "../../components/icon.js";
|
|||
export default function(render) {
|
||||
const $form = createElement(`
|
||||
<div class="component_container component_page_adminlogin">
|
||||
<style>${css}</style>
|
||||
<style id="adminpage::ctrl_login">.component_page_adminlogin{ visibility: hidden; } </style>
|
||||
<form>
|
||||
<div class="input_group">
|
||||
<input type="password" name="password" placeholder="Password" class="component_input" autocomplete>
|
||||
|
|
@ -41,6 +41,11 @@ export default function(render) {
|
|||
rxjs.delay(300), applyMutation(qs($form, ".input_group"), "classList", "remove")
|
||||
));
|
||||
|
||||
// feature: load CSS
|
||||
effect(rxjs.from(CSS(import.meta.url, "ctrl_login.css")).pipe(
|
||||
stateMutation(qs($form, `style[id="adminpage::ctrl_login"]`), "textContent"),
|
||||
));
|
||||
|
||||
// feature: nice transition
|
||||
render(transition($form, {
|
||||
timeoutEnter: 250,
|
||||
|
|
@ -60,5 +65,3 @@ export default function(render) {
|
|||
applyMutation($form, "style", "setProperty")
|
||||
));
|
||||
}
|
||||
|
||||
const css = await CSS(import.meta, "ctrl_login.css");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { createElement } from "../../lib/skeleton/index.js";
|
|||
import rxjs, { effect, applyMutation } from "../../lib/rx.js";
|
||||
import { qs, qsa } from "../../lib/dom.js";
|
||||
import { createForm, mutateForm } from "../../lib/form.js";
|
||||
import { formTmpl, format } from "../../components/form.js";
|
||||
import { formTmpl } from "../../components/form.js";
|
||||
|
||||
import transition from "./animate.js";
|
||||
import { renderLeaf } from "./helper_form.js";
|
||||
|
|
|
|||
|
|
@ -130,17 +130,17 @@ function componentStep2(render) {
|
|||
});
|
||||
}
|
||||
|
||||
const animateOut = ($el) => {
|
||||
return rxjs.pipe(
|
||||
rxjs.tap(() => animate($el, {
|
||||
time: 300,
|
||||
keyframes: [
|
||||
{ transform: "translateX(0px)", opacity: "1" },
|
||||
{ transform: "translateX(-30px)", opacity: "0" }
|
||||
]
|
||||
})),
|
||||
rxjs.delay(200)
|
||||
);
|
||||
};
|
||||
// const animateOut = ($el) => {
|
||||
// return rxjs.pipe(
|
||||
// rxjs.tap(() => animate($el, {
|
||||
// time: 300,
|
||||
// keyframes: [
|
||||
// { transform: "translateX(0px)", opacity: "1" },
|
||||
// { transform: "translateX(-30px)", opacity: "0" }
|
||||
// ]
|
||||
// })),
|
||||
// rxjs.delay(200)
|
||||
// );
|
||||
// };
|
||||
|
||||
const css = await CSS(import.meta, "ctrl_setup.css");
|
||||
const css = await CSS(import.meta.url, "ctrl_setup.css");
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ export default function AdminOnly(ctrlWrapped) {
|
|||
|
||||
effect(isAdmin$().pipe(
|
||||
rxjs.map((isAdmin) => isAdmin ? ctrlWrapped : ctrlLogin),
|
||||
rxjs.tap((ctrl) => ctrl(render)),
|
||||
rxjs.catchError((err) => ctrlError(err)(render)),
|
||||
rxjs.tap(() => loader$.unsubscribe())
|
||||
rxjs.catchError((err) => rxjs.of(ctrlError(err))),
|
||||
rxjs.tap(() => loader$.unsubscribe()),
|
||||
rxjs.tap((ctrl) => ctrl(render))
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { qs } from "../../lib/dom.js";
|
|||
|
||||
import { CSS } from "../../helpers/loader.js";
|
||||
|
||||
import Release from "./model_release.js";
|
||||
import { get as getRelease } from "./model_release.js";
|
||||
import Config from "./model_config.js";
|
||||
|
||||
import "../../components/icon.js";
|
||||
|
|
@ -45,7 +45,7 @@ export default function(ctrl) {
|
|||
</ul>
|
||||
</div>
|
||||
<div class="page_container scroll-y" data-bind="admin"></div>
|
||||
<style>${css}</style>
|
||||
<style id="adminpage::decorator_sidemenu">.component_menu_sidebar { visibility: hidden; } </style>
|
||||
</div>
|
||||
`);
|
||||
render($page);
|
||||
|
|
@ -53,8 +53,15 @@ export default function(ctrl) {
|
|||
// feature: setup the childrens
|
||||
ctrl(($node) => qs($page, "[data-bind=\"admin\"]").appendChild($node));
|
||||
|
||||
|
||||
// feature: css loading
|
||||
effect(rxjs.from(CSS(import.meta.url, "decorator_sidemenu.css", "index.css")).pipe(
|
||||
rxjs.mergeMap((cssPromise) => cssPromise),
|
||||
stateMutation(qs($page, `style[id="adminpage::decorator_sidemenu"]`), "textContent"),
|
||||
));
|
||||
|
||||
// feature: display the release version
|
||||
effect(Release.get().pipe(
|
||||
effect(getRelease().pipe(
|
||||
rxjs.map(({ version }) => version),
|
||||
stateMutation(qs($page, "[data-bind=\"version\"]"), "textContent")
|
||||
));
|
||||
|
|
@ -79,5 +86,3 @@ export default function(ctrl) {
|
|||
));
|
||||
};
|
||||
}
|
||||
|
||||
const css = await CSS(import.meta, "decorator_sidemenu.css", "index.css");
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import ajax from "../../lib/ajax.js";
|
|||
class AuditManager {
|
||||
get(searchParams = {}) {
|
||||
const p = new URLSearchParams();
|
||||
Object.keys(searchParams).map((key) => {
|
||||
Object.keys(searchParams).forEach((key) => {
|
||||
p.set(key, searchParams[key]);
|
||||
});
|
||||
return ajax({
|
||||
|
|
|
|||
|
|
@ -6,19 +6,15 @@ const release$ = ajax({
|
|||
responseType: "text"
|
||||
}).pipe(rxjs.shareReplay(1));
|
||||
|
||||
class ReleaseImpl {
|
||||
get() {
|
||||
return release$.pipe(
|
||||
rxjs.map(({ response, responseHeaders }) => {
|
||||
const a = document.createElement("html");
|
||||
a.innerHTML = response;
|
||||
return {
|
||||
html: a.querySelector("table").outerHTML,
|
||||
version: responseHeaders["x-powered-by"].trim().replace(/^Filestash\/([v\.0-9]*).*$/, "$1")
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
export function get() {
|
||||
return release$.pipe(
|
||||
rxjs.map(({ response, responseHeaders }) => {
|
||||
const a = document.createElement("html");
|
||||
a.innerHTML = response;
|
||||
return {
|
||||
html: a.querySelector("table").outerHTML,
|
||||
version: responseHeaders["x-powered-by"].trim().replace(/^Filestash\/([v\.0-9]*).*$/, "$1")
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export default new ReleaseImpl();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { createElement } from "../../lib/skeleton/index.js";
|
|||
import rxjs, { effect, applyMutation, preventDefault } from "../../lib/rx.js";
|
||||
import { qs, qsa, safe } from "../../lib/dom.js";
|
||||
import { animate, slideYIn } from "../../lib/animate.js";
|
||||
import { createForm, mutateForm } from "../../lib/form.js";
|
||||
import { createForm } from "../../lib/form.js";
|
||||
import { formTmpl } from "../../components/form.js";
|
||||
|
||||
import { CSS } from "../../helpers/loader.js";
|
||||
|
|
|
|||
6
public/pages/ctrl_adminpage.js
Normal file
6
public/pages/ctrl_adminpage.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { navigate } from "../lib/skeleton/index.js";
|
||||
import AdminOnly from "./adminpage/decorator_admin_only.js";
|
||||
|
||||
export default AdminOnly(function() {
|
||||
navigate("/admin/backend");
|
||||
});
|
||||
|
|
@ -103,22 +103,22 @@ async function setup_device() {
|
|||
});
|
||||
}
|
||||
|
||||
async function setup_sw() {
|
||||
if (!("serviceWorker" in window.navigator)) return;
|
||||
// async function setup_sw() {
|
||||
// if (!("serviceWorker" in window.navigator)) return;
|
||||
|
||||
if (window.navigator.userAgent.indexOf("Mozilla/") !== -1 &&
|
||||
window.navigator.userAgent.indexOf("Firefox/") !== -1 &&
|
||||
window.navigator.userAgent.indexOf("Gecko/") !== -1) {
|
||||
// Firefox was acting weird with service worker so we disabled it
|
||||
// see: https://github.com/mickael-kerjean/filestash/issues/255
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await window.navigator.serviceWorker.register("/sw_cache.js");
|
||||
} catch (err) {
|
||||
report("ServiceWorker registration failed", err);
|
||||
}
|
||||
}
|
||||
// if (window.navigator.userAgent.indexOf("Mozilla/") !== -1 &&
|
||||
// window.navigator.userAgent.indexOf("Firefox/") !== -1 &&
|
||||
// window.navigator.userAgent.indexOf("Gecko/") !== -1) {
|
||||
// // Firefox was acting weird with service worker so we disabled it
|
||||
// // see: https://github.com/mickael-kerjean/filestash/issues/255
|
||||
// return;
|
||||
// }
|
||||
// try {
|
||||
// await window.navigator.serviceWorker.register("/sw_cache.js");
|
||||
// } catch (err) {
|
||||
// report("ServiceWorker registration failed", err);
|
||||
// }
|
||||
// }
|
||||
|
||||
async function setup_blue_death_screen() {
|
||||
window.onerror = function(msg, url, lineNo, colNo, error) {
|
||||
|
|
@ -127,13 +127,13 @@ async function setup_blue_death_screen() {
|
|||
};
|
||||
}
|
||||
|
||||
async function setup_chromecast() {
|
||||
if (!window.CONFIG["enable_chromecast"]) {
|
||||
return Promise.resolve();
|
||||
} else if (!("chrome" in window)) {
|
||||
return Promise.resolve();
|
||||
} else if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return window.Chromecast.init();
|
||||
}
|
||||
// async function setup_chromecast() {
|
||||
// if (!window.CONFIG["enable_chromecast"]) {
|
||||
// return Promise.resolve();
|
||||
// } else if (!("chrome" in window)) {
|
||||
// return Promise.resolve();
|
||||
// } else if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
|
||||
// return Promise.resolve();
|
||||
// }
|
||||
// return window.Chromecast.init();
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import { qs } from "../lib/dom.js";
|
|||
import t from "../lib/locales.js";
|
||||
|
||||
import { AjaxError, ApplicationError } from "../lib/error.js";
|
||||
import { CSS } from "../helpers/loader.js";
|
||||
|
||||
import "../components/icon.js";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { createElement, createRender } from "../lib/skeleton/index.js";
|
||||
import rxjs, { effect, applyMutation } from "../lib/rx.js";
|
||||
import { qs } from "../lib/dom.js";
|
||||
import rxjs, { effect } from "../lib/rx.js";
|
||||
import { CSS } from "../helpers/loader.js";
|
||||
import ctrlError from "./ctrl_error.js";
|
||||
|
||||
|
|
@ -9,7 +8,7 @@ import componentFilesystem from "./filespage/filesystem.js";
|
|||
|
||||
import "../components/breadcrumb.js";
|
||||
|
||||
export default async function(render) {
|
||||
export default function(render) {
|
||||
const currentPath = location.pathname.replace(new RegExp("/files"), "");
|
||||
const $page = createElement(`
|
||||
<div class="component_page_filespage">
|
||||
|
|
@ -21,7 +20,7 @@ export default async function(render) {
|
|||
<div is="component-filesystem"></div>
|
||||
</div>
|
||||
</div>
|
||||
<style>${await CSS(import.meta.url, "ctrl_filespage.css")}</style>
|
||||
<style>${css}</style>
|
||||
</div>
|
||||
`);
|
||||
render($page);
|
||||
|
|
@ -37,3 +36,5 @@ export default async function(render) {
|
|||
// feature2: render the filesystem
|
||||
componentFilesystem(createRender($page.querySelector("[is=\"component-filesystem\"]")));
|
||||
}
|
||||
|
||||
const css = await CSS(import.meta.url, "ctrl_filespage.css");
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { deleteSession } from "../model/session.js";
|
|||
import ctrlError from "./ctrl_error.js";
|
||||
import $loader from "../components/loader.js";
|
||||
|
||||
export default function(render) {
|
||||
export default async function(render) {
|
||||
render($loader);
|
||||
|
||||
effect(deleteSession().pipe(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { createElement } from "../../lib/skeleton/index.js";
|
||||
import rxjs, { applyMutation, effect } from "../../lib/rx.js";
|
||||
import rxjs, { effect } from "../../lib/rx.js";
|
||||
import { qs } from "../../lib/dom.js";
|
||||
|
||||
import { toggle as toggleLoader } from "../../components/loader.js";
|
||||
|
||||
import { createThing, css as cssThing } from "./thing.js";
|
||||
import { getState$, handleError } from "./state.js";
|
||||
import { handleError } from "./state.js";
|
||||
import { ls } from "./model_files.js";
|
||||
|
||||
export default async function(render) {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ export function ls() {
|
|||
);
|
||||
}
|
||||
|
||||
function repeat(element, times) {
|
||||
const result = Array(times);
|
||||
for (let i = 0; i < times; i++) result[i] = element;
|
||||
return result;
|
||||
}
|
||||
// function repeat(element, times) {
|
||||
// const result = Array(times);
|
||||
// for (let i = 0; i < times; i++) result[i] = element;
|
||||
// return result;
|
||||
// }
|
||||
|
|
|
|||
Loading…
Reference in a new issue