Files
filestash/public/assets/pages/adminpage/ctrl_backend_component_storage.js
2023-11-27 20:58:54 +11:00

127 lines
5.7 KiB
JavaScript

import { createElement } from "../../lib/skeleton/index.js";
import rxjs, { effect, applyMutations, onClick } from "../../lib/rx.js";
import { createForm } from "../../lib/form.js";
import { qs, qsa } from "../../lib/dom.js";
import { formTmpl } from "../../components/form.js";
import { generateSkeleton } from "../../components/skeleton.js";
import { initStorage, getState, getBackendAvailable, getBackendEnabled, addBackendEnabled, removeBackendEnabled } from "./ctrl_backend_state.js";
import { save as saveConfig } from "./model_config.js";
import "./component_box-item.js";
export default async function(render) {
const $page = createElement(`
<div class="component_storagebackend">
<h2>Storage Backend</h2>
<div class="box-container" data-bind="backend-available">
${generateSkeleton(10)}
</div>
<form data-bind="backend-enabled"></form>
</div>
`);
render($page);
await initStorage();
// feature: setup the buttons
const init$ = getBackendAvailable().pipe(
rxjs.tap(() => qs($page, "[data-bind=\"backend-available\"]").innerHTML = ""),
rxjs.mergeMap((specs) => Promise.all(Object.keys(specs).map((label) => createElement(`
<div is="box-item" data-label="${label}"></div>
`)))),
applyMutations(qs($page, "[data-bind=\"backend-available\"]"), "appendChild"),
rxjs.share(),
);
effect(init$);
// feature: state of buttons
effect(init$.pipe(
rxjs.mergeMap(() => getBackendEnabled()),
rxjs.map((enabled) => {
const enabledSet = new Set();
enabled.forEach(({ type }) => {
enabledSet.add(type);
});
return enabledSet;
}),
rxjs.tap((backends) => qsa($page, "[is=\"box-item\"]").forEach(($button) => {
backends.has($button.getAttribute("data-label"))
? $button.classList.add("active")
: $button.classList.remove("active");
})),
));
// feature: click to select a backend
effect(init$.pipe(
rxjs.mergeMap(($nodes) => $nodes),
rxjs.mergeMap(($node) => onClick($node)),
rxjs.map(($node) => addBackendEnabled($node.getAttribute("data-label"))),
saveConnections(),
));
// feature: setup form
const setupForm$ = getBackendEnabled().pipe(
// initialise the forms
rxjs.mergeMap((enabled) => Promise.all(enabled.map(({ type, label }) => createForm({
[type]: {
"": { type: "text", placeholder: "Label", value: label },
}
}, formTmpl({
renderLeaf: () => createElement("<label></label>"),
renderNode: ({ label, format }) => {
const $fieldset = createElement(`
<fieldset>
<legend class="no-select">
${format(label)}
</legend>
<div data-bind="children"></div>
</fieldset>
`);
const $remove = createElement(`
<div class="icons no-select">
<img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MS45NzYgNTEuOTc2Ij4KICA8cGF0aCBzdHlsZT0iZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eTowLjUzMzMzMjg1O3N0cm9rZS13aWR0aDoxLjQ1NjgxMTE5IiBkPSJtIDQxLjAwNTMxLDQwLjg0NDA2MiBjIC0xLjEzNzc2OCwxLjEzNzc2NSAtMi45ODIwODgsMS4xMzc3NjUgLTQuMTE5ODYxLDAgTCAyNi4wNjg2MjgsMzAuMDI3MjM0IDE0LjczNzU1MSw0MS4zNTgzMSBjIC0xLjEzNzc3MSwxLjEzNzc3MSAtMi45ODIwOTMsMS4xMzc3NzEgLTQuMTE5ODYxLDAgLTEuMTM3NzcyMiwtMS4xMzc3NjggLTEuMTM3NzcyMiwtMi45ODIwODggMCwtNC4xMTk4NjEgTCAyMS45NDg3NjYsMjUuOTA3MzcyIDExLjEzMTkzOCwxNS4wOTA1NTEgYyAtMS4xMzc3NjQ3LC0xLjEzNzc3MSAtMS4xMzc3NjQ3LC0yLjk4MzU1MyAwLC00LjExOTg2MSAxLjEzNzc3NCwtMS4xMzc3NzIxIDIuOTgyMDk4LC0xLjEzNzc3MjEgNC4xMTk4NjUsMCBMIDI2LjA2ODYyOCwyMS43ODc1MTIgMzYuMzY5NzM5LDExLjQ4NjM5OSBjIDEuMTM3NzY4LC0xLjEzNzc2OCAyLjk4MjA5MywtMS4xMzc3NjggNC4xMTk4NjIsMCAxLjEzNzc2NywxLjEzNzc2OSAxLjEzNzc2NywyLjk4MjA5NCAwLDQuMTE5ODYyIEwgMzAuMTg4NDg5LDI1LjkwNzM3MiA0MS4wMDUzMSwzNi43MjQxOTcgYyAxLjEzNzc3MSwxLjEzNzc2NyAxLjEzNzc3MSwyLjk4MjA5MSAwLDQuMTE5ODY1IHoiIC8+Cjwvc3ZnPgo=" alt="close">
</div>
`);
$fieldset.appendChild($remove);
return $fieldset;
},
}))))),
rxjs.map((nodeList) => {
if (nodeList.length === 0) { return [createElement(`
<div class="alert">
You need to select at least 1 storage backend
</div>
`)]; }
return nodeList;
}),
rxjs.tap(() => qs($page, "[data-bind=\"backend-enabled\"]").innerHTML = ""),
applyMutations(qs($page, "[data-bind=\"backend-enabled\"]"), "appendChild"),
rxjs.share(),
);
effect(setupForm$);
// feature: remove an existing backend
effect(setupForm$.pipe(
rxjs.mergeMap(($nodes) => $nodes),
rxjs.mergeMap(($node) => onClick($node.querySelector(".icons"))),
rxjs.map(($node) => qs($node.parentElement, "input").value),
rxjs.map((label) => removeBackendEnabled(label)),
saveConnections(),
));
// feature: form input change handler
effect(setupForm$.pipe(
rxjs.mergeMap((forms) => forms),
rxjs.mergeMap(($el) => rxjs.fromEvent($el, "input")),
saveConnections(),
));
}
const saveConnections = () => rxjs.pipe(
rxjs.mergeMap((connections) => getState().pipe(rxjs.map((config) => {
if (Array.isArray(connections)) config.connections = connections;
return config;
}))),
saveConfig(),
);