parent
77aeebd90a
commit
a141b23608
@ -1,4 +1,17 @@
|
||||
@import 'editMenu.css';
|
||||
@import 'dialogue.css';
|
||||
:root {
|
||||
--color-bg-normal: #FFF;
|
||||
--color-bg-raised: #EEE;
|
||||
--color-bg-raised2: #FAFAFA;
|
||||
--color-fg-normal: #000;
|
||||
--color-fg-less: #212121;
|
||||
--color-borders: #D6D6D6;
|
||||
--color-borders-dark: #646464;
|
||||
|
||||
--color-accent-normal: #FFCCBC;
|
||||
--color-accent-hover: #CB9B8C;
|
||||
}
|
||||
|
||||
/* ==============
|
||||
| Load fonts
|
||||
@ -18,16 +31,17 @@
|
||||
|
||||
* { box-sizing: border-box; z-index: 1; }
|
||||
|
||||
body { margin: 2em; background: #FFF;
|
||||
body { margin: 2em; background: var(--color-bg-normal);
|
||||
font-family: sourceSansPro, Arial, Helvetica, Times; font-size: 1.2em; line-height: 1.5em; }
|
||||
|
||||
a { text-decoration: none; color: inherit; }
|
||||
|
||||
h1 { display: block; max-width: 600px; margin: 0 auto 1.5em auto; }
|
||||
h1 > * { display: inline-block; vertical-align: middle; color: #212121; }
|
||||
h1 > * { display: inline-block; vertical-align: middle; color: var(--color-fg-less); }
|
||||
h1 img { height: 2em; margin-right: .2em; border-radius: .1em; opacity: .7; transition: opacity .4s; }
|
||||
h1 img:hover { opacity: 1; }
|
||||
|
||||
main,
|
||||
body > div,
|
||||
body > form { display: block; max-width: 90vw; margin: 0 auto 3em auto; padding-bottom: 3em; }
|
||||
|
||||
@ -40,8 +54,8 @@ label { display: block; font-weight: bold; margin-bottom: .5em; }
|
||||
select,
|
||||
button,
|
||||
textarea,
|
||||
input { display: block; width: 100%; padding: .5em .5em; border: 2.5px solid #EEE;
|
||||
background: inherit; color: #424242; font-family: roboto; font-size: 1em;
|
||||
input { display: block; width: 100%; padding: .5em .5em; border: 2.5px solid var(--color-bg-raised);
|
||||
background: inherit; color: var(--color-fg-less); font-family: roboto; font-size: 1em;
|
||||
border-radius: .2em; transition: border .2s; }
|
||||
|
||||
.buttonLike { display: inline-block; text-align: center; }
|
||||
@ -49,7 +63,7 @@ input[type="submit"],
|
||||
button { padding: .5em .8em; }
|
||||
.buttonLike,
|
||||
input[type="submit"],
|
||||
button { background: #FFCCBC; color: #424242; border: none; font-weight: bold; text-transform: uppercase; transition: background .2s, color .2s; }
|
||||
button { background: var(--color-accent-normal); color: var(--color-fg-less); border: none; font-weight: bold; text-transform: uppercase; transition: background .2s, color .2s; }
|
||||
textarea { line-height: 1.2em; }
|
||||
|
||||
select:hover,
|
||||
@ -61,7 +75,7 @@ input[type="submit"]:focus,
|
||||
button:focus,
|
||||
.buttonLike:hover,
|
||||
input[type="submit"]:hover,
|
||||
button:hover { background: #CB9B8C; color: #000; }
|
||||
button:hover { background: var(--color-accent-hover); color: #000; }
|
||||
|
||||
aside .buttonLike + .buttonLike,
|
||||
aside button + button { margin-top: .5em; }
|
||||
@ -69,7 +83,7 @@ aside > h4:first-child { margin-top: 0; }
|
||||
|
||||
select:focus,
|
||||
textarea:focus,
|
||||
input:focus { border-color: #CB9B8C; box-shadow: none; }
|
||||
input:focus { border-color: var(--color-accent-hover); box-shadow: none; }
|
||||
|
||||
textarea:invalid,
|
||||
input:invalid { box-shadow: none; }
|
||||
@ -80,29 +94,29 @@ textarea { min-height: 30vh; }
|
||||
|
||||
table { width: 100%; max-height: 60vh; margin: 2em 0; border-collapse: collapse; overflow: auto; }
|
||||
|
||||
th { padding: .3em .5em; text-align: left; border-bottom: 2px solid #424242; }
|
||||
tbody > tr:nth-child(2n + 1) { background: #F2F2F2; }
|
||||
td { padding: .3em .5em; border-bottom: 1px solid #D6D6D6; }
|
||||
th { padding: .3em .5em; text-align: left; border-bottom: 2px solid var(--color-fg-less); }
|
||||
tbody > tr:nth-child(2n + 1) { background: var(--color-bg-raised2); }
|
||||
td { padding: .3em .5em; border-bottom: 1px solid var(--color-borders); }
|
||||
|
||||
body > div.uploader { background: #F2F2F2; border: 2px solid #EEE; padding: 1em 1em; }
|
||||
body > div.uploader { background: var(--color-bg-raised2); border: 2px solid var(--color-bg-raised); padding: 1em 1em; }
|
||||
|
||||
ul.fieldList { display: block; margin: .5em 0; padding: 0 0; list-style: none; }
|
||||
ul.fieldList > li { display: inline-block; padding: .3em; margin: .1em; border: 1px solid #D6D6D6; background: #FAFAFA; cursor: pointer; transition: background .4s, border .4s, box-shadow .4s;; }
|
||||
ul.fieldList > li:hover { background: #FFF; border-color: #212121; }
|
||||
ul.fieldList > li { display: inline-block; padding: .3em; margin: .1em; border: 1px solid var(--color-borders); background: var(--color-bg-raised2); cursor: pointer; transition: background .4s, border .4s, box-shadow .4s;; }
|
||||
ul.fieldList > li:hover { background: var(--color-bg-normal); border-color: var(--color-fg-less); }
|
||||
ul.fieldList > li.requiredField:before { display: inline-block; content: " \002612 "; margin-right: .5em; }
|
||||
ul.fieldList > li.humanTLToggled { border-color: #CB9B8C; background: #CB9B8C; box-shadow: 0 8px 6px -6px black; }
|
||||
ul.fieldList > li.humanTLToggled { border-color: var(--color-accent-hover); background: var(--color-accent-hover); box-shadow: 0 8px 6px -6px black; }
|
||||
|
||||
.options > a.buttonLike { display: inline-block; width: auto;
|
||||
margin: .15em 0; padding: .4em .5em;
|
||||
text-transform: inherit; cursor: pointer;
|
||||
background: initial; border: 2px solid #D6D6D6;
|
||||
background: initial; border: 2px solid var(--color-borders);
|
||||
opacity: 1;
|
||||
transition: background .4s, opacity .4s; }
|
||||
.options > a.buttonLike:hover { background: #D6D6D6; }
|
||||
.options > a.buttonLike:hover { background: var(--color-borders); }
|
||||
|
||||
.actionList { margin: 1em 0 1em 1em; padding: .5em 0; }
|
||||
.actionList > li a { display: inline-block; padding: .3em; border-radius: .3em; transition: background .4s; }
|
||||
.actionList > li a:hover { background: #CB9B8C; }
|
||||
.actionList > li a:hover { background: var(--color-accent-hover); }
|
||||
|
||||
/* =============
|
||||
| Dark mode
|
||||
|
40
public/assets/css/dialogue.css
Normal file
40
public/assets/css/dialogue.css
Normal file
@ -0,0 +1,40 @@
|
||||
/* ========
|
||||
| Reference overlay
|
||||
|= ======== */
|
||||
|
||||
#dialogueArea { display: block; position: fixed; left: 0; top: 0;
|
||||
width: 100%; height: 100%;
|
||||
max-width: initial; max-height: initial;
|
||||
background: rgba(0,0,0,.7); backdrop-filter: blur(3px);
|
||||
z-index: 10000; }
|
||||
#dialogue { display: block; position: absolute; left: 50%; top: 50%;
|
||||
transform: translate(-50%, -50%); min-width: 60vw; min-height: 2em;
|
||||
max-width: 90vw; max-height: 90vh; overflow-y: auto;
|
||||
padding: 1.5em 1em;
|
||||
background: var(--color-bg-normal); border-radius: .3em;
|
||||
box-shadow: 2px 2px 4px var(--color-fg-less), -2px -2px 4px var(--color-fg-less); }
|
||||
#dialogue h3 { margin-top: 0; padding-top: 0; text-transform: initial; color: var(--color-fg-less); }
|
||||
|
||||
#confirmButtons { text-align: right; }
|
||||
#dialogue .buttonLike { margin: .5em 0 .2em .5em; background: transparent; transition: background .4s, color .4s; }
|
||||
#dialogue .buttonLike:hover { background: var(--color-borders-dark); color: var(--color-bg-normal); }
|
||||
|
||||
#dialogue input[type="text"],
|
||||
#dialogue textarea { padding: .5em; border-radius: .1em; border: 2px solid var(--color-borders); transition: border .4s; }
|
||||
#dialogue input[type="text"]:hover,
|
||||
#dialogue textarea:hover { border-color: var(--color-fg-normal); }
|
||||
#dialogue button { padding: .6em .8em; font-size: .8em; background: var(--color-bg-normal); border: 1px solid var(--color-borders);
|
||||
transition: .4s; }
|
||||
#dialogue button:focus,
|
||||
#dialogue button:hover { background: var(--color-fg-less); color: var(--color-bg-normal); border-color: var(--color-fg-less); }
|
||||
#dialogue form > * { display: block; width: 100%; }
|
||||
#dialogue form label { font-weight: bold; color: var(--color-fg-less); }
|
||||
#dialogueClose { float: right; display: inline-block; padding: 0 .6em .2em .6em; background: var(--color-bg-raised);
|
||||
border-radius: 100%; cursor: pointer; transition: .4s; }
|
||||
#dialogueClose:hover { background: var(--color-fg-less); color: var(--color-bg-normal); }
|
||||
|
||||
#dialogue ul { margin-left: 1em; padding-left: 0; transition: .4s; }
|
||||
#dialogue ul.minimized { height: 20px; background-color: var(--color-accent-normal);
|
||||
background-size: 20px 20px;
|
||||
background-image: repeating-linear-gradient(to right, var(--color-fg-normal), var(--color-fg-normal) 1px, var(--color-accent-normal) 1px, var(--color-accent-normal)); }
|
||||
#dialogue ul.minimized > * { display: none; }
|
@ -3,11 +3,11 @@
|
||||
|= ======== */
|
||||
|
||||
.newToolTip { position: fixed; display: none !important; min-width: 300px !important; max-width: 600px;
|
||||
background: #212121 !important; color: #FFF; text-align: left; font-size: .95rem;
|
||||
border-radius: .2em; box-shadow: 1px 1px 4px #646464; z-index: 3000; white-space: initial !important; }
|
||||
background: var(--color-fg-less) !important; color: var(--color-bg-normal); text-align: left; font-size: .95rem;
|
||||
border-radius: .2em; box-shadow: 1px 1px 4px var(--color-borders-dark); z-index: 3000; white-space: initial !important; }
|
||||
#newToolTipMain:before { content: attr(data-title); display: block; padding: .5em 1em; max-width: 598px;
|
||||
background: #212121; color: #BDBDBD; font-weight: bold;
|
||||
box-shadow: 0px 4px 2px -2px #646464; }
|
||||
background: var(--color-fg-less); color: var(--color-bg-raised2); font-weight: bold;
|
||||
box-shadow: 0px 4px 2px -2px var(--color-borders-dark); }
|
||||
#newToolTipMain > * { padding: .5rem 1rem !important; }
|
||||
#newToolTipMain > table td { padding: .5rem 1em; vertical-align: top; }
|
||||
@media screen and (min-width:75em) {
|
||||
@ -21,10 +21,6 @@ dl#newToolTipMain dd { margin: -1em 0 0 0; padding: 0 0 0 0; }
|
||||
|
||||
.newToolTipMain p + .toolTipHierarchy { padding-bottom: 0 !important; }
|
||||
#newToolTipMain > h5 { padding: 0 1rem !important; margin: -.5rem 0 !important; }
|
||||
.toolTipHierarchy { margin: 0; padding: 0; border-top: 1px solid #424242; list-style: none; }
|
||||
.toolTipHierarchy ul { margin: 0; padding: .2em 0 .2em 0; list-style: none; }
|
||||
.toolTipHierarchy ul ul { padding: .1em 0 .1em 1.2em; }
|
||||
.toolTipHierarchy ul > li:before { content: " \002514 "; display: inline-block; padding-right: .4em; }
|
||||
|
||||
.copyToDialogue { cursor: pointer; }
|
||||
|
||||
|
@ -26,22 +26,38 @@ class CsvxmlValidator {
|
||||
|
||||
const lines = csvRaw.trim().replace("\r\n", "\n").split("\n");
|
||||
|
||||
const SEPARATOR = ';';
|
||||
let separator;
|
||||
let delimiter;
|
||||
if (csvRaw.substr(0, 1) === '"') {
|
||||
separator = '";"';
|
||||
delimiter = '"'
|
||||
}
|
||||
else {
|
||||
separator = ';';
|
||||
delimiter = '';
|
||||
}
|
||||
|
||||
// Gets first line
|
||||
let headers = lines.shift().split(SEPARATOR);
|
||||
let headersFields = lines.shift();
|
||||
let headers;
|
||||
if (delimiter === "") headers = headersFields.split(separator);
|
||||
else headers = headersFields.substr(1, headersFields.length - 2).split(separator);
|
||||
let expectedFieldCount = headers.length;
|
||||
|
||||
let toValidate = [];
|
||||
let lineCounter = 1;
|
||||
for (let line of lines) {
|
||||
|
||||
if (delimiter !== '') {
|
||||
line = line.substr(1, line.length - 2);
|
||||
}
|
||||
|
||||
// Remove fully empty lines (both without content and those with fields set up,
|
||||
// but without content there.
|
||||
if (line.length <= headers.length) continue;
|
||||
|
||||
let lineContents = {};
|
||||
let fields = line.split(SEPARATOR);
|
||||
let fields = line.split(separator);
|
||||
|
||||
if (fields.length !== headers.length) {
|
||||
this.errors.parsing.push("Number of columns in line " + lineCounter + " does not match number of headers");
|
||||
@ -55,11 +71,13 @@ class CsvxmlValidator {
|
||||
lineContents[headers[i]] = fields[i];
|
||||
}
|
||||
|
||||
// Skip totally empty lines
|
||||
if (Object.values(lineContents).join("").length === 0) continue;
|
||||
|
||||
toValidate.push(lineContents);
|
||||
lineCounter++;
|
||||
}
|
||||
|
||||
console.log(toValidate);
|
||||
this.toValidate = toValidate;
|
||||
|
||||
if (toValidate.length === 0) {
|
||||
@ -120,7 +138,7 @@ class CsvxmlValidator {
|
||||
const headers = Object.keys(this.toValidate[0]);
|
||||
|
||||
for (let header of headers) {
|
||||
if (this.fieldList[header].dependsOn === undefined || this.fieldList[header].dependsOn === null) continue;
|
||||
if (this.fieldList[header] === undefined || this.fieldList[header].dependsOn === undefined || this.fieldList[header].dependsOn === null) continue;
|
||||
|
||||
let dependencies = this.fieldList[header].dependsOn;
|
||||
for (let dep of dependencies) {
|
||||
@ -138,12 +156,17 @@ class CsvxmlValidator {
|
||||
for (let line of this.toValidate) {
|
||||
for (let fieldName in line) {
|
||||
|
||||
if (this.fieldList[fieldName] === undefined) {
|
||||
console.log("Undefined but requested field " + fieldName);
|
||||
continue;
|
||||
}
|
||||
|
||||
let allowedValues = this.fieldList[fieldName].allowedValues;
|
||||
|
||||
// No error if the field doesn't have a controlled list
|
||||
if (allowedValues === undefined || allowedValues === null) continue;
|
||||
// No error if the line's content is in the list
|
||||
if (Object.values(allowedValues).length === 0 || Object.values(allowedValues).includes(line.fieldName)) {
|
||||
if (Object.values(allowedValues).length === 0 || Object.values(allowedValues).includes(line[fieldName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -161,7 +184,7 @@ class CsvxmlValidator {
|
||||
isValid() {
|
||||
|
||||
for (let errorClass in this.errors) {
|
||||
if (errorClass.length !== 0) return false;
|
||||
if (this.errors[errorClass].length !== 0) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -270,9 +293,7 @@ class CsvxmlTooltip {
|
||||
|
||||
newMain.setAttribute("data-title", tooltipTitle);
|
||||
|
||||
const tooltipDesc = document.createElement("p");
|
||||
tooltipDesc.textContent = tooltipContent;
|
||||
newMain.appendChild(tooltipDesc);
|
||||
newMain.appendChild(tooltipContent);
|
||||
|
||||
document.body.appendChild(newMain);
|
||||
newMain.classList.add("visible");
|
||||
@ -297,15 +318,75 @@ class CsvxmlTooltip {
|
||||
|
||||
}
|
||||
|
||||
class CsvxmlDialogue {
|
||||
|
||||
static closeDialogue(e) {
|
||||
|
||||
if (e !== undefined) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
let dialogueArea = document.getElementById("dialogueArea");
|
||||
if (dialogueArea !== null && dialogueArea !== false) {
|
||||
while (dialogueArea.firstChild) {
|
||||
dialogueArea.removeChild(dialogueArea.firstChild);
|
||||
}
|
||||
dialogueArea.parentElement.removeChild(dialogueArea);
|
||||
|
||||
document.removeEventListener('keydown', CsvxmlDialogue.closeDialogueByEscape, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static closeDialogueByEscape(e) {
|
||||
|
||||
if (e.keyCode === 27) { // 27 = Esc
|
||||
|
||||
CsvxmlDialogue.closeDialogue(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for drawing a dialogue and attaching it to the body elem.
|
||||
*
|
||||
* @param {DOMElement} contents Contents.
|
||||
*/
|
||||
static drawDialogue(contents) {
|
||||
let dialogueArea = document.createElement("div");
|
||||
dialogueArea.id = "dialogueArea";
|
||||
|
||||
let dialogue = document.createElement("div");
|
||||
dialogue.id = "dialogue";
|
||||
|
||||
dialogue.appendChild(contents);
|
||||
dialogueArea.appendChild(dialogue);
|
||||
|
||||
document.body.appendChild(dialogueArea);
|
||||
|
||||
document.addEventListener('keydown', CsvxmlDialogue.closeDialogueByEscape);
|
||||
|
||||
return dialogue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CsvxmlPage {
|
||||
|
||||
fieldList;
|
||||
tls;
|
||||
domUploaderWrapper;
|
||||
domMainWrapper;
|
||||
selectedFields;
|
||||
|
||||
csvBySelectionButton;
|
||||
unsetSelectionButton;
|
||||
|
||||
constructor(fieldList) {
|
||||
this.fieldList = Object.freeze(fieldList);
|
||||
this.tls = Object.freeze(JSON.parse(document.body.getAttribute("data-tls")));
|
||||
|
||||
let domUploaderWrapper = document.createElement("div");
|
||||
domUploaderWrapper.id = "uploader";
|
||||
@ -394,6 +475,70 @@ class CsvxmlPage {
|
||||
|
||||
}
|
||||
|
||||
listValidationErrors(validator) {
|
||||
|
||||
const dialogueContent = document.createElement("div");
|
||||
|
||||
const headline = document.createElement("h3");
|
||||
headline.textContent = this.tls.validation_errors;
|
||||
|
||||
const cancelB = document.createElement("a");
|
||||
cancelB.classList.add("icons");
|
||||
cancelB.classList.add("iconsClose");
|
||||
cancelB.classList.add("dialogueCloseX");
|
||||
cancelB.id = "dialogueClose";
|
||||
cancelB.textContent = "X";
|
||||
cancelB.title = "Close";
|
||||
cancelB.href = "#" + location.href;
|
||||
cancelB.addEventListener('click', CsvxmlDialogue.closeDialogue);
|
||||
headline.appendChild(cancelB);
|
||||
|
||||
dialogueContent.appendChild(headline);
|
||||
|
||||
const domErrorsSection = document.createElement("div");
|
||||
|
||||
for (let errorType in validator.errors) {
|
||||
|
||||
if (validator.errors[errorType].length === 0) continue;
|
||||
|
||||
const ulHl = document.createElement("h4");
|
||||
ulHl.textContent = this.tls['errors_' + errorType] + " (" + validator.errors[errorType].length + ")";
|
||||
ulHl.style.cursor = "pointer";
|
||||
domErrorsSection.appendChild(ulHl);
|
||||
|
||||
const ul = document.createElement("ul");
|
||||
|
||||
for (let error of validator.errors[errorType]) {
|
||||
const li = document.createElement("li");
|
||||
li.textContent = error;
|
||||
ul.appendChild(li);
|
||||
}
|
||||
|
||||
ulHl.addEventListener('click', function() {
|
||||
ul.classList.toggle("minimized");
|
||||
});
|
||||
|
||||
domErrorsSection.appendChild(ul);
|
||||
|
||||
}
|
||||
|
||||
dialogueContent.appendChild(domErrorsSection);
|
||||
|
||||
const domDlSection = document.createElement("div");
|
||||
const domDlA = document.createElement("span");
|
||||
domDlA.textContent = this.tls.download;
|
||||
domDlA.classList.add("buttonLike");
|
||||
let app = this;
|
||||
domDlA.addEventListener('click', function() {
|
||||
app.zipUploadToXml(validator);
|
||||
});
|
||||
domDlSection.appendChild(domDlA);
|
||||
dialogueContent.appendChild(domDlSection);
|
||||
|
||||
dialogue = CsvxmlDialogue.drawDialogue(dialogueContent);
|
||||
|
||||
}
|
||||
|
||||
uploadFileForValidation(file) {
|
||||
|
||||
const reader = new FileReader();
|
||||
@ -408,15 +553,13 @@ class CsvxmlPage {
|
||||
// Validate the file
|
||||
let validator = new CsvxmlValidator(app.fieldList, reader.result);
|
||||
if (validator.isValid() === true) {
|
||||
alert("Document is valid");
|
||||
alert("Document is valid. Press ok to download.");
|
||||
app.zipUploadToXml(validator);
|
||||
}
|
||||
else {
|
||||
console.log(validator.errors);
|
||||
alert("Document is not valid. Errors are " + validator.errors);
|
||||
app.listValidationErrors(validator);
|
||||
}
|
||||
|
||||
app.zipUploadToXml(validator);
|
||||
|
||||
};
|
||||
reader.onerror = function() {
|
||||
alert(reader.error);
|
||||
@ -432,7 +575,7 @@ class CsvxmlPage {
|
||||
const form = document.createElement("form");
|
||||
|
||||
const label = document.createElement("label");
|
||||
label.textContent = "Please select a CSV file to create XML files"; // TODO
|
||||
label.textContent = app.tls.select_csv_file_for_upload;
|
||||
label.setAttribute("for", "fileToUpload");
|
||||
form.appendChild(label);
|
||||
|
||||
@ -446,10 +589,12 @@ class CsvxmlPage {
|
||||
});
|
||||
form.appendChild(input);
|
||||
|
||||
/*
|
||||
const button = document.createElement("button");
|
||||
button.textContent = "Upload"; // TODO
|
||||
button.type = "submit";
|
||||
form.appendChild(button);
|
||||
*/
|
||||
|
||||
app.domUploaderWrapper.appendChild(form);
|
||||
|
||||
@ -459,6 +604,58 @@ class CsvxmlPage {
|
||||
|
||||
}
|
||||
|
||||
// Takes a callback function
|
||||
doForFieldList(callback) {
|
||||
let fieldLists = document.getElementsByClassName("fieldList");
|
||||
for (let i = 0, max = fieldLists.length; i < max; i++) {
|
||||
|
||||
let fields = fieldLists[i].getElementsByTagName("li");
|
||||
for (let j = 0, maxj = fields.length; j < maxj; j++) {
|
||||
|
||||
callback(fields[j]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
toggleListFieldSelectionState(field) {
|
||||
|
||||
let app = this;
|
||||
|
||||
let newValue = field.getAttribute("data-alt");
|
||||
field.setAttribute("data-alt", field.textContent);
|
||||
field.textContent = newValue;
|
||||
field.classList.toggle("humanTLToggled");
|
||||
|
||||
if (field.classList.contains("humanTLToggled") === false) return;
|
||||
|
||||
let dependencies = field.getAttribute("data-dependencies");
|
||||
if (dependencies !== undefined && dependencies !== null) {
|
||||
let linkedFields = dependencies.split(";");
|
||||
for (let i = 0, max = linkedFields.length; i < max; i++) {
|
||||
let linkedField = document.getElementById(linkedFields[i]);
|
||||
if (linkedField.classList.contains("humanTLToggled") === true) continue;
|
||||
app.toggleListFieldSelectionState(linkedField);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
checkCSVBySelectionAccessibility() {
|
||||
|
||||
let selected = document.getElementsByClassName("humanTLToggled");
|
||||
if (selected.length === 0) {
|
||||
this.csvBySelectionButton.classList.add("invisible");
|
||||
this.unsetSelectionButton.classList.add("invisible");
|
||||
}
|
||||
else {
|
||||
this.csvBySelectionButton.classList.remove("invisible");
|
||||
this.unsetSelectionButton.classList.remove("invisible");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getOptionsSection() {
|
||||
|
||||
function genButton(id, text, link = "") {
|
||||
@ -477,93 +674,28 @@ class CsvxmlPage {
|
||||
|
||||
const app = this;
|
||||
|
||||
const dlAllButton = genButton("dlAll", "Download all");
|
||||
const dlAllButton = genButton("dlAll", this.tls.download_csv_all);
|
||||
dlAllButton.cursor = "pointer";
|
||||
dlAllButton.addEventListener('click', function() {
|
||||
app.generateCsv();
|
||||
});
|
||||
options.appendChild(dlAllButton); // TODO
|
||||
options.appendChild(dlAllButton);
|
||||
|
||||
const csvBySelectionButton = genButton("csvBySelection", "Csv by selection");
|
||||
csvBySelectionButton.classList.add("invisible");
|
||||
// TODO: Add toggle via event listener
|
||||
options.appendChild(csvBySelectionButton);
|
||||
this.csvBySelectionButton = genButton("csvBySelection", this.tls.download_csv_by_selection);
|
||||
this.csvBySelectionButton.classList.add("invisible");
|
||||
options.appendChild(this.csvBySelectionButton);
|
||||
|
||||
const optionSelectRequired = genButton("selectRequired", "Select required");
|
||||
const optionSelectRequired = genButton("selectRequired", this.tls.select_required_fields);
|
||||
options.appendChild(optionSelectRequired);
|
||||
|
||||
const optionSelectAll = genButton("selectAll", "Select all");
|
||||
const optionSelectAll = genButton("selectAll", this.tls.select_all_fields);
|
||||
options.appendChild(optionSelectAll);
|
||||
|
||||
const unsetSelectionButton = genButton("unsetSelection", "Unset selection");
|
||||
unsetSelectionButton.classList.add("invisible");
|
||||
// TODO: Add toggle via event listener
|
||||
options.appendChild(unsetSelectionButton);
|
||||
this.unsetSelectionButton = genButton("unsetSelection", this.tls.unset_selection);
|
||||
this.unsetSelectionButton.classList.add("invisible");
|
||||
options.appendChild(this.unsetSelectionButton);
|
||||
|
||||
function checkCSVBySelectionAccessibility() {
|
||||
|
||||
let selected = document.getElementsByClassName("humanTLToggled");
|
||||
if (selected.length === 0) {
|
||||
csvBySelectionButton.classList.add("invisible");
|
||||
unsetSelectionButton.classList.add("invisible");
|
||||
}
|
||||
else {
|
||||
csvBySelectionButton.classList.remove("invisible");
|
||||
unsetSelectionButton.classList.remove("invisible");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Takes a callback function
|
||||
function doForFieldList(callback) {
|
||||
let fieldLists = document.getElementsByClassName("fieldList");
|
||||
for (let i = 0, max = fieldLists.length; i < max; i++) {
|
||||
|
||||
let fields = fieldLists[i].getElementsByTagName("li");
|
||||
for (let j = 0, maxj = fields.length; j < maxj; j++) {
|
||||
|
||||
callback(fields[j]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function toggleListFieldSelectionState(field) {
|
||||
|
||||
let newValue = field.getAttribute("data-alt");
|
||||
field.setAttribute("data-alt", field.textContent);
|
||||
field.textContent = newValue;
|
||||
field.classList.toggle("humanTLToggled");
|
||||
|
||||
if (field.classList.contains("humanTLToggled") === false) return;
|
||||
|
||||
let dependencies = field.getAttribute("data-dependencies");
|
||||
if (dependencies !== undefined && dependencies !== null) {
|
||||
let linkedFields = dependencies.split(";");
|
||||
for (let i = 0, max = linkedFields.length; i < max; i++) {
|
||||
let linkedField = document.getElementById(linkedFields[i]);
|
||||
if (linkedField.classList.contains("humanTLToggled") === true) continue;
|
||||
toggleListFieldSelectionState(linkedField);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
doForFieldList(function(field) {
|
||||
|
||||
// Each field should switch its visible content and human-readable
|
||||
// translation on a click.
|
||||
field.addEventListener('click', function(e) {
|
||||
|
||||
toggleListFieldSelectionState(field);
|
||||
checkCSVBySelectionAccessibility();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
csvBySelectionButton.addEventListener('click', function(e) {
|
||||
this.csvBySelectionButton.addEventListener('click', function(e) {
|
||||
|
||||
let selected = document.getElementsByClassName("humanTLToggled");
|
||||
let selectedFields = [];
|
||||
@ -576,12 +708,12 @@ class CsvxmlPage {
|
||||
|
||||
optionSelectRequired.addEventListener('click', function(e) {
|
||||
|
||||
doForFieldList(function(field) {
|
||||
app.doForFieldList(function(field) {
|
||||
if (field.classList.contains("requiredField") === false) return;
|
||||
if (field.classList.contains("humanTLToggled") === true) return;
|
||||
|
||||
toggleListFieldSelectionState(field);
|
||||
checkCSVBySelectionAccessibility();
|
||||
app.toggleListFieldSelectionState(field);
|
||||
app.checkCSVBySelectionAccessibility();
|
||||
|
||||
});
|
||||
|
||||
@ -589,23 +721,23 @@ class CsvxmlPage {
|
||||
|
||||
optionSelectAll.addEventListener('click', function(e) {
|
||||
|
||||
doForFieldList(function(field) {
|
||||
app.doForFieldList(function(field) {
|
||||
if (field.classList.contains("humanTLToggled") === true) return;
|
||||
|
||||
toggleListFieldSelectionState(field);
|
||||
checkCSVBySelectionAccessibility();
|
||||
app.toggleListFieldSelectionState(field);
|
||||
app.checkCSVBySelectionAccessibility();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
unsetSelectionButton.addEventListener('click', function(e) {
|
||||
this.unsetSelectionButton.addEventListener('click', function(e) {
|
||||
|
||||
doForFieldList(function(field) {
|
||||
app.doForFieldList(function(field) {
|
||||
if (field.classList.contains("humanTLToggled") === false) return;
|
||||
|
||||
toggleListFieldSelectionState(field);
|
||||
checkCSVBySelectionAccessibility();
|
||||
app.toggleListFieldSelectionState(field);
|
||||
app.checkCSVBySelectionAccessibility();
|
||||
|
||||
});
|
||||
|
||||
@ -618,7 +750,7 @@ class CsvxmlPage {
|
||||
renderMain() {
|
||||
|
||||
const domH2 = document.createElement("h2");
|
||||
domH2.textContent = "Currently approved tags (column names) for md:import";
|
||||
domH2.textContent = this.tls.currently_approved_tags;
|
||||
this.domMainWrapper.appendChild(domH2);
|
||||
|
||||
this.domMainWrapper.appendChild(this.getOptionsSection());
|
||||
@ -634,8 +766,6 @@ class CsvxmlPage {
|
||||
const domUl = document.createElement("ul");
|
||||
domUl.classList.add("fieldList");
|
||||
|
||||
console.log(sectionName);
|
||||
|
||||
const sectionFields = this.fieldList[sectionName];
|
||||
for (let fieldName in sectionFields) {
|
||||
const field = sectionFields[fieldName];
|
||||
@ -648,7 +778,32 @@ class CsvxmlPage {
|
||||
if (field.required === true) domLi.classList.add("requiredField");
|
||||
domUl.appendChild(domLi);
|
||||
|
||||
CsvxmlTooltip.bindTooltipToElement(domLi, field.name_human_readable, field.explica);
|
||||
const tooltipContent = document.createElement("div");
|
||||
const explicaP = document.createElement("p");
|
||||
explicaP.textContent = field.explica;
|
||||
tooltipContent.appendChild(explicaP);
|
||||
|
||||
if (field.remarks !== undefined && field.remarks !== '') {
|
||||
|
||||
const remarkHl = document.createElement("h4");
|
||||
remarkHl.textContent = this.tls.remarks;
|
||||
tooltipContent.appendChild(remarkHl)
|
||||
const remarkCont = document.createElement("p");
|
||||
remarkCont = field.remarks;
|
||||
tooltipContent.appendChild(remarkCont);
|
||||
|
||||
}
|
||||
|
||||
if (field.allowedValues !== undefined && Object.values(field.allowedValues).length !== 0) {
|
||||
const allowedHl = document.createElement("h4");
|
||||
allowedHl.textContent = this.tls.allowed_values;
|
||||
tooltipContent.appendChild(allowedHl);
|
||||
const allowedList = document.createElement("p");
|
||||
allowedList.textContent = Object.values(field.allowedValues).join(', ');
|
||||
tooltipContent.appendChild(allowedList);
|
||||
}
|
||||
|
||||
CsvxmlTooltip.bindTooltipToElement(domLi, field.name_human_readable, tooltipContent);
|
||||
|
||||
}
|
||||
|
||||
@ -660,6 +815,20 @@ class CsvxmlPage {
|
||||
|
||||
document.body.appendChild(this.domMainWrapper);
|
||||
|
||||
let app = this;
|
||||
this.doForFieldList(function(field) {
|
||||
|
||||
// Each field should switch its visible content and human-readable
|
||||
// translation on a click.
|
||||
field.addEventListener('click', function(e) {
|
||||
|
||||
app.toggleListFieldSelectionState(field);
|
||||
app.checkCSVBySelectionAccessibility();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,30 @@
|
||||
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||
*/
|
||||
declare(strict_types = 1);
|
||||
require_once __DIR__ . "/../functions/functions.php";
|
||||
|
||||
$allowed_langs = ['ar', 'de', 'en', 'hu', 'id', 'it', 'pl', 'pt'];
|
||||
$lang = MD_STD::get_user_lang($allowed_langs, "en");
|
||||
$tlLoader = new MDTlLoader("csxml_start_v2", $lang);
|
||||
|
||||
$outFormat = MD_STD_IN::get_http_input_text("output", "html", ['html', 'json']);
|
||||
|
||||
if ($outFormat === 'json') {
|
||||
|
||||
$fieldsGetter = new CsvxmlAvailableFields($lang);
|
||||
$availableFields = $fieldsGetter->getFields();
|
||||
|
||||
header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0'); // HTTP/1.1
|
||||
header('Pragma: no-cache'); // HTTP/1.0
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET");
|
||||
header("Access-Control-Allow-Headers: X-PINGOTHER, Content-Type, Accept-Encoding, cache-control");
|
||||
header("Access-Control-Max-Age: 86400");
|
||||
header('content-type: application/json');
|
||||
echo json_encode($availableFields);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
echo '
|
||||
<!DOCTYPE HTML>
|
||||
@ -18,7 +42,7 @@ echo '
|
||||
<meta name="description" content="Validate import CSV files for museum-digital" />
|
||||
<script src="assets/js/jszip/dist/jszip.min.js" type="text/javascript" async defer></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="assets/css/csvxml.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="assets/css/csvxml.css" />
|
||||
<meta name="theme-color" content="#aa4400" />
|
||||
<link rel="shortcut icon" sizes="128x128" href="assets/img/mdlogo-csvxml.svg" />
|
||||
<meta name="robots" content="noindex" />
|
||||
@ -29,14 +53,34 @@ echo '
|
||||
|
||||
|
||||
</head>
|
||||
<body class="loading">
|
||||
<body class="loading" data-tls="' . htmlspecialchars(MD_STD::json_encode([
|
||||
'remarks' => $tlLoader->tl('basis', 'basis', 'remarks'),
|
||||
'download' => $tlLoader->tl('export', 'export', 'download'),
|
||||
'upload' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'upload'),
|
||||
'select_csv_file_for_upload' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'select_csv_file_for_upload'),
|
||||
'currently_approved_tags' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'currently_approved_tags'),
|
||||
'download_csv_all' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'download_csv_all'),
|
||||
'download_csv_by_selection' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'download_csv_by_selection'),
|
||||
'select_required_fields' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'select_required_fields'),
|
||||
'select_all_fields' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'select_all_fields'),
|
||||
'unset_selection' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'unset_selection'),
|
||||
'file_format' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'file_format'),
|
||||
'validation_errors' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'validation_errors'),
|
||||
'errors_parsing' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'errors_parsing'),
|
||||
'errors_mandatoryTags' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'errors_mandatoryTags'),
|
||||
'errors_duplicateInvNos' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'errors_duplicateInvNos'),
|
||||
'errors_dependentColumns' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'errors_dependentColumns'),
|
||||
'errors_controlledLists' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'errors_controlledLists'),
|
||||
'errors_mainImageResource' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'errors_mainImageResource'),
|
||||
'allowed_values' => $tlLoader->tl("csvxml-overview", "csvxml_overview", 'allowed_values'),
|
||||
])) . '">
|
||||
|
||||
<h1>
|
||||
<img src="assets/img/mdlogo-csvxml.svg" alt="" />
|
||||
<span>museum-digital:csvxml</span>
|
||||
</h1>
|
||||
|
||||
<script src="assets/js/csvxmlV2.js" type="text/javascript" defer></script>
|
||||
<script src="assets/js/csvxmlV2.js" type="text/javascript" async></script>
|
||||
|
||||
</body>
|
||||
</html>';
|
||||
|
Loading…
Reference in New Issue
Block a user