270 lines
10 KiB
JavaScript
270 lines
10 KiB
JavaScript
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 = `
|
|
<link rel="stylesheet" href="components/curves_settings_popup/curves_settings_popup.css"/>
|
|
<div id="curves-settings-popup">
|
|
<div id="curves-settings-popup-container">
|
|
|
|
<div id="curves-settings-popup-header">
|
|
<span>Curves settings</span>
|
|
<img src="res/close.png"/>
|
|
</div>
|
|
|
|
<div id="curves-settings-popup-content">
|
|
|
|
<div class="scrollable-content">
|
|
<table id="curves-settings-popup-table">
|
|
<thead style="position: sticky;">
|
|
<tr>
|
|
<th class="bin-cell"></th>
|
|
<th class="variable-cell">Variable</th>
|
|
<th class="parameter-cell">Parameter</th>
|
|
<th class="cat-cell">Category</th>
|
|
<th class="color-cell">Color</th>
|
|
<th class="unit-cell">Unit</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
</tbody>
|
|
</table>
|
|
<div class="buttons-wrapper">
|
|
<button class="add-row-button">Add line</button>
|
|
<button class="apply-button">Apply</button>
|
|
<button class="cancel-button">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
|
|
customElements.define("sea-curves-settings-popup", CurvesSettingsPopup); |