Compare commits

...

5 Commits

4 changed files with 158 additions and 54 deletions

59
data.js
View File

@@ -13,12 +13,34 @@ let steps = {
type: "" type: ""
} }
}, },
thesis_title: {
title: "Jak se bude práce jmenovat?",
layout: thesis_title_layout,
result: {
cs: "",
en: ""
},
finalize: (result) => {
if(result.cs === "") {
result.cs = "SEM DOPLŇTE ČESKÝ NÁZEV PRÁCE";
}
if(result.en === "") {
result.en = "SEM DOPLŇTE ANGLICKÝ NÁZEV PRÁCE";
}
}
},
author_info: { author_info: {
title: "Vaše údaje", title: "Vaše údaje",
layout: author_info_layout, layout: author_info_layout,
result: { result: {
name: "", name: "",
pronouns: "" pronouns: ""
},
finalize: (result) => {
if(result.name === "") {
result.name = "SEM DOPLŇTE VAŠE JMÉNO";
}
} }
}, },
collaborators: { collaborators: {
@@ -29,6 +51,15 @@ let steps = {
supervisor_name: "", supervisor_name: "",
has_consultant: false, has_consultant: false,
consultant_name: "" consultant_name: ""
},
finalize: (result) => {
if(result.supervisor_name === "") {
result.supervisor_name = "SEM DOPLŇTE JMÉNO VEDOUCÍHO PRÁCE";
}
if(result.consultant_name === "") {
result.consultant_name = "SEM DOPLŇTE JMÉNO KONZULTANTA PRÁCE";
}
} }
}, },
} }
@@ -104,7 +135,7 @@ const typst_header = `#import "template/template.typ": *
#show: tultemplate2.with( #show: tultemplate2.with(
faculty: "{faculty.name}", faculty: "{faculty.name}",
document: "{thesis_type.type}", document: "{thesis_type.type}",
title: (cs: "Návod na použití Typst TUL šablony"), title: (cs: "{thesis_title.cs}", en: "{thesis_title.en}"),
author: "{author_info.name}", author: "{author_info.name}",
author_pronouns: "{author_info.pronouns}", author_pronouns: "{author_info.pronouns}",
<collaborators.has_supervisor: supervisor: "{collaborators.supervisor_name}", <collaborators.has_supervisor: supervisor: "{collaborators.supervisor_name}",
@@ -118,16 +149,19 @@ const typst_header = `#import "template/template.typ": *
skibidi skibidi
`; `;
async function generate_zip() { function generate_template() {
let assets_zip = await fetch("template.zip");
let out_zip = await new JSZip().loadAsync(await assets_zip.blob());
let out = typst_header; let out = typst_header;
for(const step_key in steps) { for(const step_key in steps) {
console.log(step_key); console.log(step_key);
for(const key in steps[step_key].result) { let result = steps[step_key].result;
if(steps[step_key].finalize) {
steps[step_key].finalize(result);
}
for(const key in result) {
console.log("- " + key); console.log("- " + key);
const search_condition = "<" + step_key + "." + key + ":"; const search_condition = "<" + step_key + "." + key + ":";
@@ -138,7 +172,7 @@ async function generate_zip() {
if(condition_end_pos >= 0) { if(condition_end_pos >= 0) {
const head = out.slice(0, condition_pos); const head = out.slice(0, condition_pos);
const meat = steps[step_key].result[key] ? out.slice(condition_pos + search_condition.length, condition_pos + condition_end_pos) : ""; const meat = result[key] ? out.slice(condition_pos + search_condition.length, condition_pos + condition_end_pos) : "";
const tail = out.slice(condition_pos + condition_end_pos + 1); const tail = out.slice(condition_pos + condition_end_pos + 1);
out = head + meat + tail; out = head + meat + tail;
@@ -150,7 +184,7 @@ async function generate_zip() {
if(replacement_pos >= 0) { if(replacement_pos >= 0) {
const head = out.slice(0, replacement_pos); const head = out.slice(0, replacement_pos);
const meat = steps[step_key].result[key]; const meat = result[key];
const tail = out.slice(replacement_pos + search_replacement.length); const tail = out.slice(replacement_pos + search_replacement.length);
out = head + meat + tail; out = head + meat + tail;
@@ -160,7 +194,14 @@ async function generate_zip() {
console.log(out); console.log(out);
out_zip.file("thesis.typ", out); return out;
}
async function generate_zip() {
let assets_zip = await fetch("template.zip");
let out_zip = await new JSZip().loadAsync(await assets_zip.blob());
out_zip.file("thesis.typ", generate_template());
return await out_zip.generateAsync({ type: "blob" }); return await out_zip.generateAsync({ type: "blob" });
} }

View File

@@ -184,6 +184,12 @@ button:disabled:hover, .button:disabled:hover {
justify-content: center; justify-content: center;
} }
.hint {
color: gray;
font-style: italic;
font-size: 16px;
}
.slide-animation { .slide-animation {
position: relative; position: relative;

76
ui.js
View File

@@ -43,13 +43,20 @@ async function thesis_layout(content, result) {
} }
} }
async function author_info_layout(content, result) { async function thesis_title_layout(content, result) {
let author_name = new ElementBuilder("input") content.appendChild(new TextInputBuilder(result, "cs")
.type("text") .placeholder("Název práce (v češtině)")
.placeholder("Vaše jméno (vč. titulů), příp. jména všech autorů") .finish());
.on_input((e) => result.name = e.target.value) content.appendChild(new TextInputBuilder(result, "en")
.finish(); .placeholder("Název práce (v angličtině)")
.finish());
content.appendChild(new ElementBuilder("div.vertical-spacer").finish());
content.appendChild(new ElementBuilder("div.hint")
.text("Pokud si zatím nejste jisti, můžete tato pole ponechat prázdná.")
.finish());
}
async function author_info_layout(content, result) {
if(!Object.keys(pronounss).includes(result.pronouns)) { if(!Object.keys(pronounss).includes(result.pronouns)) {
document.querySelector("#next-button").disabled = true; document.querySelector("#next-button").disabled = true;
} }
@@ -63,7 +70,12 @@ async function author_info_layout(content, result) {
}) })
.finish(); .finish();
content.appendChild(author_name); content.appendChild(new TextInputBuilder(result, "name")
.placeholder("Vaše jméno (vč. titulů), příp. jména všech autorů")
.finish());
content.appendChild(new ElementBuilder("div.hint")
.text("Pokud si zatím nejste jisti, můžete ponechat toto pole prázdné.")
.finish());
content.appendChild(new ElementBuilder("div.vertical-spacer").finish()); content.appendChild(new ElementBuilder("div.vertical-spacer").finish());
content.appendChild(new ElementBuilder("div") content.appendChild(new ElementBuilder("div")
.text("Způsob sebeoslovení") .text("Způsob sebeoslovení")
@@ -74,55 +86,29 @@ async function author_info_layout(content, result) {
} }
async function collaborators_layout(content, result) { async function collaborators_layout(content, result) {
let supervisor_name = new ElementBuilder("input") let supervisor_name = new TextInputBuilder(result, "supervisor_name")
.type("text")
.placeholder("Jméno vedoucího práce (vč. titulů), příp. vedoucích") .placeholder("Jméno vedoucího práce (vč. titulů), příp. vedoucích")
.on_input((e) => result.supervisor_name = e.target.value)
.finish(); .finish();
let consultant_name = new ElementBuilder("input") let consultant_name = new TextInputBuilder(result, "consultant_name")
.type("text")
.placeholder("Jméno konzultanta práce (vč. titulů), příp. konzultantů") .placeholder("Jméno konzultanta práce (vč. titulů), příp. konzultantů")
.on_input((e) => result.consultant_name = e.target.value)
.finish(); .finish();
let has_supervisor = new ElementBuilder("input#has-supervisor") content.appendChild(new BinaryInputBuilder(result, "has_supervisor")
.type("checkbox") .label("Práce má vedoucího")
.checked(result.has_supervisor) .on_update(val => supervisor_name.disabled = !val)
.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()); .finish());
content.appendChild(supervisor_name); content.appendChild(supervisor_name);
content.appendChild(new ElementBuilder("div.vertical-spacer").finish()); content.appendChild(new ElementBuilder("div.vertical-spacer").finish());
content.appendChild(new ElementBuilder("div.horizontal-list") content.appendChild(new BinaryInputBuilder(result, "has_consultant")
.append(has_consultant) .label("Práce má konzultanta")
.append(new ElementBuilder("label") .on_update(val => consultant_name.disabled = !val)
.for("has-consultant")
.text("Práce má konzultanta"))
.finish()); .finish());
content.appendChild(consultant_name); content.appendChild(consultant_name);
content.appendChild(new ElementBuilder("div.vertical-spacer").finish());
content.appendChild(new ElementBuilder("div.hint")
.text("Pokud si zatím nejste jisti jmény svých vedoucích, můžete tato pole ponechat prázdná.")
.finish());
} }
async function run() { async function run() {

View File

@@ -91,6 +91,11 @@ class ElementBuilder {
return this; return this;
} }
value(value) {
this.element.value = value;
return this;
}
checked(checked) { checked(checked) {
this.element.checked = checked; this.element.checked = checked;
return this; return this;
@@ -181,6 +186,72 @@ class ButtonListBuilder {
} }
} }
class TextInputBuilder {
constructor(result, key) {
this.result = result;
this.key = key;
this.text = "";
}
placeholder(placeholder) {
this.text = placeholder;
return this;
}
finish() {
return new ElementBuilder("input")
.type("text")
.placeholder(this.text)
.value(this.result[this.key])
.on_input((e) => this.result[this.key] = e.target.value)
.finish();
}
}
class BinaryInputBuilder {
constructor(result, key) {
this.result = result;
this.key = key;
this.text = "";
this.update_handler = null;
}
label(label) {
this.text = label;
return this;
}
on_update(handler) {
this.update_handler = handler;
return this;
}
finish() {
let input = new ElementBuilder("input#" + this.key)
.type("checkbox")
.checked(this.result[this.key])
.if(this.update_handler !== null, b => b.on_click(e => {
console.log(e.target.checked);
this.result[this.key] = e.target.checked;
this.update_handler(e.target.checked);
}))
.finish();
let bundle = new ElementBuilder("div.horizontal-list")
.append(input)
.append(new ElementBuilder("label")
.for(this.key)
.text(this.text))
.finish();
if(this.update_handler !== null) {
this.update_handler(this.result[this.key]);
}
return bundle;
}
}
async function delay_ms(ms) { async function delay_ms(ms) {
await new Promise((r) => setTimeout(r, ms)); await new Promise((r) => setTimeout(r, ms));
} }