import { createElement, createRender, onDestroy } from "../../lib/skeleton/index.js"; import rxjs, { effect, stateMutation, applyMutation, preventDefault } from "../../lib/rxjs/index.js"; import { qs } from "../../lib/dom/index.js"; import { ApplicationError } from "../../lib/error/index.js"; import { transition, animate } from "../../lib/animate/index.js"; import CSSLoader from "../../helpers/css.js"; import modal from "../../helpers/modal.js"; import ctrlError from "../ctrl_error.js"; import WithShell from "./decorator_sidemenu.js"; import { zoomIn, slideXOut, slideXIn, cssHideMenu } from "./animate.js"; import "../../components/icon.js"; const stepper$ = new rxjs.BehaviorSubject(2); export default function(render) { const $page = createElement(`
`); render($page); effect(stepper$.pipe( rxjs.map((step) => { switch(step) { case 1: return WithShell(componentStep1); case 2: return WithShell(componentStep2); default: throw new ApplicationError("INTERNAL_ERROR", "Assumption failed"); } }), rxjs.tap((ctrl) => ctrl(createRender(qs($page, `[data-bind="multistep-form"]`)))), rxjs.catchError((err) => ctrlError(err)(render)), )); }; function componentStep1(render) { const $page = createElement(`

Admin Password

Create your instance admin password:

`); render(transition($page, { timeEnter: 250, enter: zoomIn(1.2), timeLeave: 0, })); // feature: form handling effect(rxjs.fromEvent(qs($page, "form"), "submit").pipe( preventDefault(), rxjs.mapTo(["name", "loading"]), applyMutation(qs($page, "component-icon"), "setAttribute"), rxjs.map(() => qs($page, "input").value), rxjs.delay(1000), rxjs.tap(() => animate($page, { time: 200, keyframes: slideXOut(-30) })), rxjs.delay(200), rxjs.tap(() => stepper$.next(2)), )); // feature: hide side menu to remove distractions effect(rxjs.of(cssHideMenu).pipe( stateMutation(qs($page, "style"), "textContent"), )); // feature: autofocus effect(rxjs.of([]).pipe( applyMutation(qs($page, "input"), "focus"), )); } function componentStep2(render) { const deps = []; const $page = createElement(`

Summary

${deps.map((t) => t.label).join("")}
`); render($page); // feature: navigate previous step effect(rxjs.fromEvent(qs($page, `[data-bind="previous"]`), "click").pipe( rxjs.tap(() => stepper$.next(1)), )); // feature: reveal animation effect(rxjs.of(cssHideMenu).pipe( stateMutation(qs($page, "style"), "textContent"), rxjs.tap(() => animate(qs($page, "h4"), { time: 200, keyframes: slideXIn(30) })), rxjs.delay(200), rxjs.mapTo([]), applyMutation(qs($page, "style"), "remove"), )); // feature: telemetry popup onDestroy(() => { const $node = createElement(`

Help making this software better by sending crash reports and anonymous usage statistics

`); return new Promise((done) => { modal.alert($node, { onQuit: done, }); }); }); } 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 CSSLoader(import.meta, "ctrl_setup.css");