Files
tultemplategen/ui.js

256 lines
7.4 KiB
JavaScript

let tul_logo = null;
function get_step(id) {
return steps[Object.keys(steps)[id]];
}
async function faculty_layout(content, result) {
if(!Object.keys(faculties).includes(result.name)) {
document.querySelector("#next-button").disabled = true;
}
let buttons = new ButtonListBuilder(Object.keys(faculties))
.should_be_pressed((key) => result.name == key)
.modify((b, key) => b.class("narrow").text(faculties[key].name))
.on_click((key) => {
result.name = key;
document.querySelector("#next-button").disabled = false;
document.documentElement.setAttribute("data-faculty", key);
})
.finish();
for(const button of buttons) {
content.appendChild(button);
}
}
async function thesis_layout(content, result) {
if(!Object.keys(theses).includes(result.type)) {
document.querySelector("#next-button").disabled = true;
}
let buttons = new ButtonListBuilder(Object.keys(theses))
.should_be_pressed((key) => result.type == key)
.modify((b, key) => b.class("narrow").text(theses[key].name))
.on_click((key) => {
result.type = key;
document.querySelector("#next-button").disabled = false;
})
.finish();
for(const button of buttons) {
content.appendChild(button);
}
}
async function author_info_layout(content, result) {
let author_name = new ElementBuilder("input")
.type("text")
.placeholder("Vaše jméno (vč. titulů), příp. jména všech autorů")
.on_input((e) => result.name = e.target.value)
.finish();
if(!Object.keys(genders).includes(result.gender)) {
document.querySelector("#next-button").disabled = true;
}
let gender_buttons = new ButtonListBuilder(Object.keys(genders))
.should_be_pressed((key) => result.gender == key)
.modify((b, key) => b.class("expand").text(genders[key].name))
.on_click((key) => {
result.gender = key;
document.querySelector("#next-button").disabled = false;
})
.finish();
content.appendChild(author_name);
content.appendChild(new ElementBuilder("div.vertical-spacer").finish());
content.appendChild(new ElementBuilder("div")
.text("Způsob sebeoslovení")
.finish());
content.appendChild(new ElementBuilder("div.horizontal-list")
.append_all(gender_buttons)
.finish());
}
async function collaborators_layout(content, result) {
let supervisor_name = new ElementBuilder("input")
.type("text")
.placeholder("Jméno vedoucího práce (vč. titulů), příp. vedoucích")
.on_input((e) => result.supervisor_name = e.target.value)
.finish();
let consultant_name = new ElementBuilder("input")
.type("text")
.placeholder("Jméno konzultanta práce (vč. titulů), příp. konzultantů")
.on_input((e) => result.consultant_name = e.target.value)
.finish();
let has_supervisor = new ElementBuilder("input#has-supervisor")
.type("checkbox")
.checked(result.has_supervisor)
.on_click(() => update())
.finish();
let has_consultant = new ElementBuilder("input#has-consultant")
.type("checkbox")
.checked(result.has_consultant)
.on_click(() => update())
.finish();
function update() {
supervisor_name.disabled = !has_supervisor.checked;
consultant_name.disabled = !has_consultant.checked;
result.has_supervisor = has_supervisor.checked;
result.has_consultant = has_consultant.checked;
}
update();
content.appendChild(new ElementBuilder("div.horizontal-list")
.append(has_supervisor)
.append(new ElementBuilder("label")
.for("has-supervisor")
.text("Práce má vedoucího"))
.finish());
content.appendChild(supervisor_name);
content.appendChild(new ElementBuilder("div.vertical-spacer").finish());
content.appendChild(new ElementBuilder("div.horizontal-list")
.append(has_consultant)
.append(new ElementBuilder("label")
.for("has-consultant")
.text("Práce má konzultanta"))
.finish());
content.appendChild(consultant_name);
}
async function run() {
startbutton.style.cursor = "auto";
startbutton.disabled = true;
let main_container = document.querySelector(".main-container");
let start_content = main_container.querySelector(".main-content");
start_content.style.opacity = 0;
await delay_ms(300);
start_content.remove();
let container = new ElementBuilder("div.vertical-list")
.style("justifyContent", "space-between")
.finish();
let back_button = new ElementBuilder("button#back-button")
.text("← Zpět")
.finish();
let next_button = new ElementBuilder("button.accent#next-button").finish();
let main_content = new ElementBuilder("div.main-content")
.style("opacity", 0)
.append(container)
.append(new ElementBuilder("div.horizontal-list")
.append(back_button)
.append(new ElementBuilder("div.filler"))
.append(next_button))
.finish();
main_container.appendChild(main_content);
await delay_ms(100);
main_content.style.opacity = 1;
let id = 0;
let animation = 0;
let steps_len = Object.keys(steps).length;
while(id < steps_len) {
back_button.style.display = (id != 0) ? "" : "none";
next_button.innerText = (id < steps_len - 1) ? "Další →" : "Dokončit";
next_button.disabled = false;
container.innerHTML = "";
let step = get_step(id);
let title = new ElementBuilder("h1")
.html(step.title)
.finish();
let content = new ElementBuilder("div.vertical-list")
.style("gap", "12px")
.finish();
let subcontainer = new ElementBuilder("div.vertical-list.slide-animation")
.append(title)
.append(content)
.if(animation < 0, c => c.class("slide-from-left"))
.if(animation > 0, c => c.class("slide-from-right"))
.finish();
await step.layout(content, step.result);
container.appendChild(subcontainer);
animation = 0;
let new_id = await new Promise((r) => {
back_button.onclick = () => {
r(id - 1);
}
next_button.onclick = () => {
r(id + 1);
}
});
if(new_id < steps_len) {
subcontainer.classList.add((new_id > id) ? "slide-to-left" : "slide-to-right");
await delay_ms(250);
subcontainer.remove();
animation = new_id - id;
}
id = new_id;
}
main_content.style.opacity = 0;
let [_, out_blob] = await Promise.all([delay_ms(300), generate_zip()])
main_content.remove();
let color = window.getComputedStyle(document.body).getPropertyValue("--" + steps.faculty.result.name + "-color");
let logo = tul_logo.replaceAll('fill="#5948ad"', 'fill="' + color + '"');
main_content = new ElementBuilder("div.main-content")
.style("opacity", 0)
.append(new ElementBuilder("h1").text("Vaše šablona je připravena!"))
.append(new ElementBuilder("img")
.src(URL.createObjectURL(new Blob([logo], { type: "image/svg+xml" })))
.style("width", "100px")
.style("height", "100px"))
.append(new ElementBuilder("div.paragraphs")
.append(new ElementBuilder("p").html(`
Po stažení archivu můžete šablonu rozbalit a
buď ji otevřít ve svém oblíbeném textovém editoru,
nebo ji nahrát do webového rozhraní Typstu.
`))
.append(new ElementBuilder("p").append(new ElementBuilder("a")
.text("Webové rozhraní Typstu otevřete kliknutím zde.")
.href("https://typst.app/play/")
.target("_blank"))))
.append(new ElementBuilder("a.button.accent")
.href(URL.createObjectURL(out_blob))
.download("tul-thesis-typst.zip")
.text("Klikněte zde pro stažení archivu"))
.finish();
main_container.appendChild(main_content);
await delay_ms(100);
main_content.style.opacity = 1;
}
window.onload = async () => {
let img = await fetch("tul_logo.svg"); // Should already be cached by now (hopefully)
tul_logo = await img.text();
}