Snek/src/js/configEditor.js

112 lines
3.1 KiB
JavaScript

const config=require('config');
const assets=require('assets');
const Popup=require('popup');
let lastCEId=0;
class ConfigEditor extends Popup {
constructor() {
super("Config editor", [], {ok: "OK"});
const metaConfig=assets.get('metaConfig');
this.watchers=[];
for(let key in metaConfig) {
const level=Array.from(key).reduce((a, c) => a+c=='.', 0)+2;
const data=metaConfig[key];
if(!data.type) {
this.addHeading(data.name);
} else {
let span=document.createElement('span');
let id='cfgInput-'+(lastCEId++)+'-'+key.replace(/\./g, '-');
let label=span.appendChild(document.createElement('label'));
label.innerText=data.name;
if(config.getB('debug')) label.title=key;
let input;
if(data.type=='boolean') {
input=document.createElement('input');
input.type='checkbox';
input.checked=config.getB(key);
input.addEventListener('change', () => config.set(key, input.checked));
} else if(data.type=='choice') {
input=document.createElement('select');
data.bounds.choices.forEach(choice => {
let option=document.createElement('option');
option.value=choice;
option.innerText=choice;
input.appendChild(option);
});
input.value=config.getS(key);
input.addEventListener('change', () => config.set(key, input.value));
} else if(data.type=='number') {
input=document.createElement('input');
input.type='number';
if(data.bounds) {
input.setAttribute('min', data.bounds.min);
input.setAttribute('max', data.bounds.max);
input.setAttribute('step', data.bounds.inc);
}
input.value=config.getN(key);
input.addEventListener('change', () => config.set(key, input.value));
} else if(data.type=='string') {
input=document.createElement('input');
input.type='text';
input.value=config.getS(key);
input.addEventListener('change', () => config.set(key, input.value));
}
input.setAttribute('id', id);
span.appendChild(input);
label.setAttribute('for', id);
this.addContent(span);
if(data.excludes) {
const setEnabled=() => {
input.disabled=
data.excludes
.some(key => config.getB(key));
input.title=input.disabled?`Disable '${data.excludes.map(k => metaConfig[k].name).join('\', \'')}' to enable`:'';
};
setEnabled();
data.excludes.forEach(key => {
let c=config.watchB(key, setEnabled);
this.watchers.push([key, c]);
});
} else if(data.parent) {
const setEnabled=() => {
input.disabled=!config.getB(data.parent);
input.title=input.disabled?`Enable '${metaConfig[data.parent].name}' to enable`:'';
};
setEnabled();
let c=config.watchB(data.parent, setEnabled);
this.watchers.push([data.parent, c]);
}
if(data.needsBackend) {
if(window.serverless) {
input.disabled=true;
input.title="Needs backend";
}
}
}
}
this.large=true;
}
discard() {
this.watchers.forEach(([k, c]) => config.unwatch(k, c));
}
};
return module.exports={
show: async () => {
let editor=new ConfigEditor();
await editor.display();
editor.discard();
}
};