1
0
mirror of https://github.com/octoleo/plantuml-server.git synced 2024-06-02 00:20:48 +00:00
plantuml-server/src/main/webapp/components/modals/diagram-import/diagram-import.js
Florian 478ef3bce7 front-end code refactoring
Since the front-end received much more code (features) than first expected, the files became much too large. For this reason, the JS and CSS code has now been split by component and thus into several small files. However, since there are now many small files, a JS and CSS bundle tool had to come :D.
2023-05-19 13:55:18 +02:00

153 lines
5.6 KiB
JavaScript

/********************
* Diagram Import JS *
*********************/
function initDiagramImport() {
const dialogElement = document.getElementById("diagram-import");
const fileInput = document.getElementById("diagram-import-input");
const okButton = document.getElementById("diagram-import-ok-btn");
const errorMessageElement = document.getElementById("diagram-import-error-message");
function openDialog(isOpenManually = true) {
setVisibility(dialogElement, true, true);
dialogElement.dataset.isOpenManually = isOpenManually.toString();
// reset or clear file input
fileInput.value = "";
onFileInputChange(fileInput);
}
function closeDialog() {
fileInput.value = ""; // reset or clear
onFileInputChange(fileInput);
dialogElement.removeAttribute("data-is-open-manually");
setVisibility(dialogElement, false);
}
function onFileInputChange(fileInput) {
errorMessageElement.innerText = "";
okButton.disabled = fileInput.files?.length < 1;
}
function checkFileLocally(file) {
function getImageFileType({name, type}) {
const supported = ["png", "svg"];
// get type by mime type
let fileType = supported.filter(t => type.toLowerCase().indexOf(t) !== -1)[0];
if (fileType) return fileType;
// fallback: get type by filename extension
if (name.indexOf(".") === -1) return undefined;
const ext = name.substring(name.lastIndexOf(".")+1).toLowerCase();
return supported.filter(t => ext === t)[0];
}
function isDiagramCode({name, type}) {
// get type by mime type
let supported = ["plain", "text", "plantuml", "puml"];
if (supported.filter(t => type.toLowerCase().indexOf(t) !== -1).length > 0) {
return true;
}
// fallback: get type by filename extension
if (name.indexOf(".") === -1) return false;
const ext = name.substring(name.lastIndexOf('.')+1).toLowerCase();
supported = ["txt", "puml", "plantuml"];
return supported.filter(t => ext === t).length > 0;
}
const type = getImageFileType(file);
const isCode = type === undefined ? isDiagramCode(file) : false;
if (!type && !isCode) {
errorMessageElement.innerText = "File not supported. " +
"Only PNG and SVG diagram images as well as PlantUML code text files are supported."
}
return { type, isDiagramCode: isCode, valid: type || isCode };
}
function importDiagram(file, fileCheck) {
function loadDiagram(code) {
setEditorValue(document.editor, code);
}
function requestMetadata(file) {
const fd = new FormData();
fd.append("diagram", file, file.name);
return makeRequest("POST", "metadata", {
data: fd,
responseType: "json",
headers: { "Accept": "application/json" },
});
}
dialogElement.classList.add("wait");
return new Promise((resolve, reject) => {
if (fileCheck.type) {
// upload diagram image, get meta data from server and load diagram from result
requestMetadata(file).then(
metadata => { loadDiagram(metadata.decoded); resolve(); },
({ response }) => { errorMessageElement.innerText = response.message || response; reject(); }
);
} else if (fileCheck.isDiagramCode) {
// read code (text) file
const reader = new FileReader();
reader.onload = event => loadDiagram(event.target.result);
reader.readAsText(file);
resolve();
} else {
// this error should already be handled.
errorMessageElement.innerText = "File not supported. " +
"Only PNG and SVG diagram images as well as PlantUML code text files are supported.";
reject();
}
}).then(() => closeDialog(), () => {}).finally(() => dialogElement.classList.remove("wait"));
}
function onGlobalDragEnter(event) {
event.stopPropagation();
event.preventDefault();
if (!isVisible(dialogElement)) {
openDialog(false);
}
}
function onFileInputDragOver(event) {
event.stopPropagation();
event.preventDefault();
if (event.dataTransfer !== null) {
event.dataTransfer.dropEffect = "copy";
}
}
function onFileInputDrop(event) {
function stop() {
event.stopPropagation();
event.preventDefault();
}
const files = event.dataTransfer.files || event.target.files;
if (!files || files.length < 1) {
return stop();
}
const file = files[0];
const fileCheck = checkFileLocally(file);
if (!fileCheck.valid) {
return stop();
}
if (dialogElement.dataset.isOpenManually === "true") {
return; // let file input handle this event => no `stop()`!
}
// drop and go - close modal without additional ok button click
stop();
importDiagram(file, fileCheck);
}
// global drag&drop events
window.addEventListener("dragenter", onGlobalDragEnter, false);
// diagram import dialog drag&drop events
fileInput.addEventListener("dragenter", event => event.target.classList.add("drop-able"), false);
fileInput.addEventListener("dragover", onFileInputDragOver, false);
fileInput.addEventListener("dragexit", event => event.target.classList.remove("drop-able"), false);
fileInput.addEventListener("drop", onFileInputDrop, false);
fileInput.addEventListener("change", event => onFileInputChange(event.target));
// ok button
okButton.addEventListener("click", () => {
const file = fileInput.files[0]; // should be always a valid file
importDiagram(file, checkFileLocally(file)); // otherwise button should be disabled
});
// register model listeners
registerModalListener("diagram-import", openDialog, closeDialog);
}