class CurvesSettingsPopup extends HTMLElement{ constructor(applySettingsCallback){ super(); this.applySettingsCallback = applySettingsCallback; } initTable(){ let userConfiguration = getUserConfiguration(); //located in SEAWebClientLocalStorage.js let tbody = this.querySelector("#curves-settings-popup-table tbody"); tbody.innerHTML = ""; for(let lineConfiguration of userConfiguration){ this.createRow(tbody, lineConfiguration); } this.createRow(tbody); // we add another row by default at the end } doApplySettingsCallback(){ try{ let localStorageBuffer = []; let formattedUserConfiguration = this.getFormattedUserConfiguration(localStorageBuffer); localStorage.clear(); saveUserConfiguration(localStorageBuffer); //located in SEAWebClientLocalStorage.js this.hide(); this.applySettingsCallback(formattedUserConfiguration); }catch{} } /** * Feeds localStorageBuffer with user rows to save, while formatting each row for later API call * Throws an error if a row is invalid (no variable is given for a non empty line) * @param {[]} localStorageBuffer an array feeded by this method, that contains the JS object representing the data out of a line * @returns the formatted user configuration object to be passed as the payload to the server */ getFormattedUserConfiguration(localStorageBuffer){ let formatedUserConfiguration = {}; let rows = this.querySelectorAll("tbody tr"); for(let row of rows){ let configurationLineObject = this.getRowValues(row); let formmatedLineConfiguration = {...configurationLineObject}; if(!formmatedLineConfiguration.hasOwnProperty("variable")){ let definedFields = Object.keys(formmatedLineConfiguration).length; if(formmatedLineConfiguration.hasOwnProperty("cat")){ if(formmatedLineConfiguration["cat"] === "*"){ if (definedFields >= 2){ alertify.error("Variable not defined for some row(s)."); throw Error; } }else{ alertify.error("Variable not defined for some row(s)."); throw Error; } }else{ if (definedFields > 0){ alertify.error("Variable not defined for some row(s)."); throw Error; } } }else{ let key = formmatedLineConfiguration["variable"]; delete formmatedLineConfiguration["variable"]; if(formmatedLineConfiguration.hasOwnProperty("parameter")){ key += (formmatedLineConfiguration["parameter"] != "value") ? "." + formmatedLineConfiguration["parameter"] : ""; delete formmatedLineConfiguration["parameter"]; } if(Object.keys(formmatedLineConfiguration).length > 0){ formatedUserConfiguration[key] = formmatedLineConfiguration; localStorageBuffer.push(configurationLineObject); } } } return formatedUserConfiguration; } /** * Gets the data out of the given HTML row as a JSON object * @param {*} row An HTML tr element of the table * @returns A JS object containing the data out of the HTML element : there is a key if the value is not an empty string */ getRowValues(row){ let configuration = {}; for(let cell of row.children){ let content = cell.children[0]; //there is only one child per cell if(content.nodeName == "DIV"){ //we skip the first cell which is the bin content = content.children[0]; if(content.nodeName == "INPUT" && content.value !== ""){ configuration[content.name] = content.value; } else if (content.nodeName == "SEA-COLOR-SELECTOR" && content.getValue() !== ""){ configuration["color"] = content.getValue(); } } } return configuration; } getUserConfiguration(){ let userConfiguration = []; for(let i = 0; i < localStorage.length; i++){ userConfiguration.push(JSON.parse(localStorage.getItem(localStorage.key(i)))); } return userConfiguration; } saveUserConfiguration(userConfiguration){ for(let i = 0; i < userConfiguration.length; i++){ localStorage.setItem(i, JSON.stringify(userConfiguration[i])); } } addNewRowIfEmpty(){ let tbody = this.querySelector("#curves-settings-popup-table tbody"); if(tbody.childNodes.length == 0){ this.createRow(tbody); } } addRow(){ let tbody = this.querySelector("#curves-settings-popup-table tbody"); this.createRow(tbody); } show(){ this.style.visibility = "visible"; this.initTable(); window.addEventListener("click", this.backgroundClickCallback); } hide(){ this.style.visibility = "hidden"; window.removeEventListener("click", this.backgroundClickCallback); } backgroundClickCallback = ({target}) => { if(target.id == "curves-settings-popup"){ this.doApplySettingsCallback(); } } connectedCallback(){ this.render(); this.hide(); this.getElementsByTagName("img")[0].onclick = () => {this.doApplySettingsCallback();}; this.getElementsByClassName("add-row-button")[0].onclick = () => {this.addRow();}; this.getElementsByClassName("cancel-button")[0].onclick = () => {this.hide();}; this.getElementsByClassName("apply-button")[0].onclick = () => {this.doApplySettingsCallback();}; } // /** * Adds a row to tbody * The process is disigned in this way because seaColorSelector.setValue is called, and its content has to be * generated before calling this method, that is why we need to append the newly created HTML element * as soon as possible. * If lineConfiguration == null, an empty row is added to the table * @param {*} tbody - The HTML element of the table body * @param {*} lineConfiguration - The object representing one line of configuration on the client side * @returns */ createRow(tbody, lineConfiguration = null){ let row = document.createElement("tr"); tbody.appendChild(row) let binCell = document.createElement("td"); let binImg = document.createElement("img"); binImg.src = "res/bin.png"; binImg.onclick = () => { binImg.parentNode.parentNode.remove(); this.addNewRowIfEmpty(); } binCell.appendChild(binImg); row.append(binCell) this.createTextInput(row, lineConfiguration, "variable") this.createTextInput(row, lineConfiguration, "parameter") this.createTextInput(row, lineConfiguration, "cat") let colorCell = document.createElement("td"); let colorDiv = document.createElement("div"); let seaColorSelector = new ColorSelector(); row.append(colorCell); colorCell.append(colorDiv); colorDiv.appendChild(seaColorSelector); //need to first append it before calling setValue seaColorSelector.setValue(""); if(lineConfiguration != null && lineConfiguration.hasOwnProperty('color')){ seaColorSelector.setValue(lineConfiguration['color']); } this.createTextInput(row, lineConfiguration, "unit") return row; } createTextInput(row, lineConfiguration, type){ let cell = document.createElement("td"); let div = document.createElement("div"); let input = document.createElement("input"); input.type = "text"; input.spellcheck = false input.autocorrect = "off" input.name = type; input.classList.add("text-input"); input.value = ""; if (type == "cat"){ input.value = "*"; } if(lineConfiguration != null && lineConfiguration.hasOwnProperty(type)){ input.value = lineConfiguration[type]; } div.appendChild(input) cell.appendChild(div); row.append(cell) } render(){ this.innerHTML = `
Variable | Parameter | Category | Color | Unit |
---|