458 lines
15 KiB
JavaScript
458 lines
15 KiB
JavaScript
"use strict";
|
|
|
|
class App {
|
|
|
|
lang;
|
|
tls;
|
|
config;
|
|
parserList;
|
|
uploadableFiles;
|
|
wrap;
|
|
actionsArea;
|
|
aside;
|
|
main;
|
|
|
|
generateTextElement(type, value) {
|
|
const elem = document.createElement(type);
|
|
elem.textContent = value;
|
|
return elem;
|
|
}
|
|
|
|
generateLabelInput(id, labelText, explanationText, type, value) {
|
|
|
|
const output = document.createElement("div");
|
|
output.classList.add("label-input");
|
|
|
|
const label = document.createElement("label");
|
|
label.textContent = labelText;
|
|
label.setAttribute("for", id);
|
|
output.appendChild(label);
|
|
|
|
const input = document.createElement("input");
|
|
input.id = id;
|
|
input.type = "text";
|
|
input.value = value;
|
|
output.appendChild(input);
|
|
|
|
const help = document.createElement("span");
|
|
help.classList.add("icon-help");
|
|
help.title = explanationText;
|
|
output.appendChild(help);
|
|
|
|
return {'wrap': output, 'input': input};
|
|
|
|
}
|
|
|
|
async generateSidebar() {
|
|
|
|
this.aside.appendChild(this.generateTextElement("h2", this.tls.settings)); // TODO
|
|
|
|
// Set up fields
|
|
const instanceLinkArea = this.generateLabelInput("instance-link",
|
|
this.tls.instance_link, this.tls.instance_link_explica, "url", this.config.settings.instance);
|
|
this.aside.appendChild(instanceLinkArea.wrap);
|
|
|
|
const usernameArea = this.generateLabelInput("username",
|
|
this.tls.username, this.tls.username_explica, "text", this.config.settings.username);
|
|
this.aside.appendChild(usernameArea.wrap);
|
|
|
|
const mailArea = this.generateLabelInput("mail",
|
|
this.tls.mail, this.tls.mail_explica, "email", this.config.settings.mail);
|
|
this.aside.appendChild(mailArea.wrap);
|
|
|
|
const institutionIdArea = this.generateLabelInput("institutionId",
|
|
this.tls.institution_id, this.tls.institution_id_explica, "number", this.config.settings.institution_id);
|
|
this.aside.appendChild(institutionIdArea.wrap);
|
|
|
|
const tokenArea = this.generateLabelInput("token",
|
|
this.tls.token, this.tls.token_explica, "text", this.config.settings.token);
|
|
this.aside.appendChild(tokenArea.wrap);
|
|
|
|
const parserDiv = document.createElement("div");
|
|
parserDiv.classList.add("label-input");
|
|
|
|
const parserLabel = document.createElement("label");
|
|
parserLabel.setAttribute("for", "parserSelect");
|
|
parserLabel.textContent = this.tls.parser;
|
|
parserDiv.appendChild(parserLabel);
|
|
const parserSelect = document.createElement("select");
|
|
parserSelect.id = "parserSelect";
|
|
|
|
for (const entry of this.parserList) {
|
|
const opt = document.createElement("option");
|
|
opt.value = entry.title;
|
|
opt.textContent = entry.title;
|
|
if (entry.title === this.config.settings.parser) {
|
|
opt.setAttribute("selected", "selected");
|
|
}
|
|
parserSelect.appendChild(opt);
|
|
}
|
|
|
|
parserDiv.appendChild(parserSelect);
|
|
|
|
const parserHelp = document.createElement("span");
|
|
parserHelp.classList.add("icon-help");
|
|
parserHelp.title = this.tls.parser_explica;
|
|
parserDiv.appendChild(parserHelp);
|
|
|
|
this.aside.appendChild(parserDiv);
|
|
|
|
const uploadFolderArea = this.generateLabelInput("upload-folder",
|
|
this.tls.upload_directory, this.tls.upload_directory_explica, "text", this.config.settings.upload_directory);
|
|
this.aside.appendChild(uploadFolderArea.wrap);
|
|
|
|
const visibleDivOuter = document.createElement("div");
|
|
visibleDivOuter.classList.add("label-input");
|
|
const visibleLabel = document.createElement("label");
|
|
visibleLabel.setAttribute("for", "visible");
|
|
visibleLabel.textContent = this.tls.publish_immediately;
|
|
visibleDivOuter.appendChild(visibleLabel);
|
|
|
|
const visibleDiv = document.createElement("div");
|
|
const visibleSwitch = document.createElement("div");
|
|
visibleSwitch.classList.add("switch");
|
|
|
|
const visibleInput = document.createElement("input");
|
|
visibleInput.type = "checkbox";
|
|
if (this.config.settings.visible === true) {
|
|
visibleInput.checked = "checked";
|
|
console.log(visibleInput);
|
|
}
|
|
visibleSwitch.appendChild(visibleInput);
|
|
|
|
const visibleSlider = document.createElement("span");
|
|
visibleSlider.classList.add("slider");
|
|
visibleSlider.addEventListener('click', function() {
|
|
visibleInput.checked = !visibleInput.checked;
|
|
console.log(visibleInput);
|
|
});
|
|
visibleSwitch.appendChild(visibleSlider);
|
|
|
|
visibleDiv.appendChild(visibleSwitch);
|
|
visibleDivOuter.appendChild(visibleDiv);
|
|
|
|
const visibleHelp = document.createElement("span");
|
|
visibleHelp.classList.add("icon-help");
|
|
visibleHelp.title = this.tls.publish_immediately_explica;
|
|
visibleDivOuter.appendChild(visibleHelp);
|
|
|
|
this.aside.appendChild(visibleDivOuter);
|
|
|
|
// Additional settings
|
|
this.aside.appendChild(this.generateTextElement("h3", this.tls.additional_settings));
|
|
|
|
const addSettingsArea = document.createElement("div");
|
|
|
|
const app = this;
|
|
function generateAdditionalSettingsField(key, value) {
|
|
|
|
const line = document.createElement("div");
|
|
line.classList.add("label-input");
|
|
|
|
const newKey = document.createElement("input");
|
|
newKey.placeholder = app.tls.add_settings_key;
|
|
newKey.required = "required";
|
|
newKey.value = key;
|
|
line.appendChild(newKey);
|
|
|
|
const newVal = document.createElement("input");
|
|
newVal.placeholder = app.tls.add_settings_value;
|
|
newVal.required = "required";
|
|
newVal.value = value;
|
|
line.appendChild(newVal);
|
|
|
|
const removeB = document.createElement("button");
|
|
removeB.textContent = " x ";
|
|
removeB.title = app.tls.remove;
|
|
line.appendChild(removeB);
|
|
|
|
removeB.addEventListener('click', function() {
|
|
line.parentElement.removeChild(line);
|
|
});
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
if (this.config.settings.settings != undefined && this.config.settings.settings != null && this.config.settings.settings.length != 0) {
|
|
for (let settingKey in this.config.settings.settings) {
|
|
addSettingsArea.appendChild(generateAdditionalSettingsField(settingKey, this.config.settings.settings[settingKey]));
|
|
}
|
|
}
|
|
|
|
this.aside.appendChild(addSettingsArea);
|
|
|
|
const newSettingLine = document.createElement("form");
|
|
newSettingLine.classList.add("label-input");
|
|
|
|
const newKey = document.createElement("input");
|
|
newKey.placeholder = this.tls.add_settings_key;
|
|
newKey.required = "required";
|
|
newSettingLine.appendChild(newKey);
|
|
|
|
const newVal = document.createElement("input");
|
|
newVal.placeholder = this.tls.add_settings_value;
|
|
newVal.required = "required";
|
|
newSettingLine.appendChild(newVal);
|
|
|
|
const newSubmitB = document.createElement("button");
|
|
newSubmitB.type = "submit";
|
|
newSubmitB.textContent = " > ";
|
|
newSubmitB.title = app.tls.add;
|
|
newSettingLine.appendChild(newSubmitB);
|
|
|
|
newSettingLine.addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
addSettingsArea.appendChild(generateAdditionalSettingsField(newKey.value, newVal.value));
|
|
|
|
newKey.value = "";
|
|
newVal.value = "";
|
|
});
|
|
|
|
this.aside.appendChild(newSettingLine)
|
|
|
|
const updateB = document.createElement("button");
|
|
updateB.textContent = this.tls.save_update;
|
|
updateB.classList.add("updateB");
|
|
this.aside.appendChild(updateB);
|
|
|
|
updateB.addEventListener('click', async function() {
|
|
|
|
let toSave = {
|
|
instance: instanceLinkArea.input.value,
|
|
username: usernameArea.input.value,
|
|
mail: mailArea.input.value,
|
|
token: tokenArea.input.value,
|
|
institution_id: parseInt(institutionIdArea.input.value),
|
|
parser: parserSelect.value,
|
|
upload_directory: uploadFolderArea.input.value,
|
|
visible: visibleInput.checked,
|
|
settings: {}
|
|
};
|
|
|
|
for (const l of addSettingsArea.children) {
|
|
toSave.settings[l.children[0].value] = l.children[1].value;
|
|
}
|
|
|
|
const response = await window.fetch('/update-settings', {
|
|
method: 'POST', cache: 'no-cache',
|
|
credentials: 'same-origin',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
},
|
|
body: "settings=" + encodeURIComponent(JSON.stringify(toSave, null, 2))
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.log("Failed to save");
|
|
window.alert("Failed to store.");
|
|
}
|
|
|
|
const json = await response.json();
|
|
|
|
if (json.success === true) {
|
|
location.reload();
|
|
}
|
|
else {
|
|
alert("Error:\n" + json.error);
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
generateMain() {
|
|
|
|
this.main.appendChild(this.generateTextElement("h2", this.tls.uploadable_files));
|
|
|
|
// Metadata
|
|
const metadataSec = document.createElement("section");
|
|
|
|
metadataSec.appendChild(this.generateTextElement("h3", this.tls.metadata_files));
|
|
const metadataList = document.createElement("div");
|
|
metadataList.classList.add("upload-file-list");
|
|
|
|
for (const filename of this.uploadableFiles.metadata) {
|
|
const fileline = document.createElement("span");
|
|
fileline.classList.add("icon-file");
|
|
fileline.textContent = filename;
|
|
metadataList.appendChild(fileline);
|
|
}
|
|
|
|
metadataSec.appendChild(metadataList);
|
|
|
|
this.main.appendChild(metadataSec);
|
|
|
|
// Media
|
|
const mediaSec = document.createElement("section");
|
|
|
|
mediaSec.appendChild(this.generateTextElement("h3", this.tls.media_files));
|
|
const mediaList = document.createElement("div");
|
|
mediaList.classList.add("upload-file-list");
|
|
|
|
for (const filename of this.uploadableFiles.media_files) {
|
|
const fileline = document.createElement("span");
|
|
fileline.classList.add("icon-file");
|
|
fileline.textContent = filename;
|
|
mediaList.appendChild(fileline);
|
|
}
|
|
|
|
mediaSec.appendChild(mediaList);
|
|
this.main.appendChild(mediaSec);
|
|
|
|
}
|
|
|
|
generateActionsMenu() {
|
|
|
|
if (this.uploadableFiles.metadata.length === 0 && this.uploadableFiles.media_files.length === 0) {
|
|
return false;
|
|
}
|
|
|
|
const uploadTrigger = document.createElement("span");
|
|
uploadTrigger.textContent = this.tls.upload;
|
|
this.actionsArea.appendChild(uploadTrigger);
|
|
|
|
const app = this;
|
|
uploadTrigger.addEventListener('click', function() {
|
|
|
|
const transferOverlay = document.createElement("div");
|
|
transferOverlay.id = "transfer-overlay";
|
|
transferOverlay.classList.add("transfer-overlay");
|
|
const hl = document.createElement("div");
|
|
hl.classList.add("transfer-overlay-hl");
|
|
hl.appendChild(app.generateTextElement("h3", app.tls.upload));
|
|
|
|
const closeB = document.createElement("span");
|
|
closeB.classList.add("overlay-close");
|
|
hl.appendChild(closeB);
|
|
|
|
closeB.addEventListener('click', function() { location.reload(); });
|
|
// closeB.addEventListener('click', function() { transferOverlay.parentElement.removeChild(transferOverlay); });
|
|
|
|
transferOverlay.appendChild(hl);
|
|
|
|
const transferMsgs = document.createElement("div");
|
|
transferMsgs.classList.add("transfer-msgs");
|
|
transferOverlay.appendChild(transferMsgs);
|
|
|
|
app.wrap.appendChild(transferOverlay);
|
|
|
|
const iframe = document.createElement("iframe");
|
|
iframe.src = "/trigger-upload";
|
|
transferOverlay.appendChild(iframe);
|
|
|
|
}, {once: true});
|
|
|
|
|
|
}
|
|
|
|
// Provides a sidebar entry for describing the parser
|
|
generateParserDesc() {
|
|
|
|
for (const parser of this.parserList) {
|
|
if (parser.title == this.config.settings.parser) {
|
|
|
|
const aside = document.createElement("div");
|
|
aside.classList.add("sec-aside");
|
|
|
|
aside.appendChild(this.generateTextElement("h3", this.tls.parser));
|
|
const div = document.createElement("div");
|
|
div.classList.add("parser-desc");
|
|
|
|
const desc = document.createElement("p");
|
|
desc.textContent = parser.comment;
|
|
div.appendChild(desc);
|
|
|
|
aside.appendChild(div);
|
|
|
|
this.wrap.appendChild(aside);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
render() {
|
|
|
|
if (this.config.setup_required === true) {
|
|
wrap.classList.add("one-column");
|
|
this.generateSidebar();
|
|
}
|
|
else {
|
|
this.generateSidebar();
|
|
this.generateMain();
|
|
this.generateActionsMenu();
|
|
|
|
this.generateParserDesc();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setupFromApis() {
|
|
|
|
|
|
const app = this;
|
|
let done = 0;
|
|
|
|
function wrapFinish() {
|
|
if (done === 4) {
|
|
app.render();
|
|
}
|
|
}
|
|
|
|
window.fetch('/get-settings', {method: 'GET', cache: 'no-cache', credentials: 'same-origin'})
|
|
.then(function(response) { return response.json(); })
|
|
.then(function(elements) {
|
|
app.config = elements;
|
|
done++;
|
|
wrapFinish();
|
|
});
|
|
window.fetch('/list-parsers', {method: 'GET', cache: 'no-cache', credentials: 'same-origin'})
|
|
.then(function(response) { return response.json(); })
|
|
.then(function(elements) {
|
|
app.parserList = elements;
|
|
done++;
|
|
wrapFinish();
|
|
});
|
|
window.fetch('/list-uploadable', {method: 'GET', cache: 'no-cache', credentials: 'same-origin'})
|
|
.then(function(response) { return response.json(); })
|
|
.then(function(elements) {
|
|
app.uploadableFiles = elements;
|
|
done++;
|
|
wrapFinish();
|
|
});
|
|
window.fetch('/get-translations?lang=' + encodeURIComponent(this.lang), {method: 'GET', cache: 'no-cache', credentials: 'same-origin'})
|
|
.then(function(response) { return response.json(); })
|
|
.then(function(elements) {
|
|
app.tls = elements.webdav_uploader;
|
|
done++;
|
|
wrapFinish();
|
|
});
|
|
}
|
|
|
|
constructor() {
|
|
|
|
this.wrap = document.getElementById("wrap");
|
|
this.lang = navigator.language.substring(0, 2)
|
|
if (["de", "en"].includes(this.lang) === false) {
|
|
this.lang = "en";
|
|
}
|
|
|
|
this.aside = document.createElement("aside");
|
|
this.main = document.createElement("main");
|
|
this.actionsArea = document.getElementById("actions");
|
|
|
|
this.wrap.appendChild(this.aside);
|
|
this.wrap.appendChild(this.main);
|
|
|
|
this.setupFromApis();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new App();
|