intermediate: buildui with config ready to save/load

This commit is contained in:
andreas 2023-10-01 11:55:13 +02:00
parent a48d52b30a
commit 728b4a4347
2 changed files with 99 additions and 52 deletions

View File

@ -8,7 +8,8 @@ import {load as yamlLoad} from "https://cdn.skypack.dev/js-yaml@4.1.0";
let downloadUrl=undefined; let downloadUrl=undefined;
let timer=undefined; let timer=undefined;
let structure=undefined; let structure=undefined;
let config={}; let config={}; //values as read and stored
let configStruct={}; //complete struct merged of config and struct
let branch=getParam('branch'); let branch=getParam('branch');
if (! branch) branch='master'; if (! branch) branch='master';
const showError=(text)=>{ const showError=(text)=>{
@ -136,31 +137,57 @@ import {load as yamlLoad} from "https://cdn.skypack.dev/js-yaml@4.1.0";
let parsed=yamlLoad(config); let parsed=yamlLoad(config);
return parsed; return parsed;
} }
const getVal=(cfg,keys)=>{
for (let i in keys){
let k=cfg[keys[i]];
if (k !== undefined) return k;
}
}
const KEY_NAMES=['key','value','label'];
const LABEL_NAMES=['label','value'];
const PATH_ATTR='data-path'; const PATH_ATTR='data-path';
const buildSelector=(parent,config,prefix,current,callback)=>{ const SEPARATOR=':';
let name=prefix+"_"+config.key; /**
let level=name.replace(/[^_]*/g,''); *
* @param {build a selector} parent
* @param {*} config
* @param {*} name
* @param {*} current
* @param {*} callback will be called with: children,key,value,initial
* @returns
*/
const buildSelector=(parent,config,name,current,callback)=>{
let rep=new RegExp("[^"+SEPARATOR+"]*","g");
let level=name.replace(rep,'');
let frame=addEl('div','selector level'+level.length,parent); let frame=addEl('div','selector level'+level.length,parent);
frame.setAttribute(PATH_ATTR,name); frame.setAttribute(PATH_ATTR,name);
let title=addEl('div','title',frame,config.label); let title=addEl('div','title',frame,config.label);
if (! config.values) return; if (config.type === 'select') {
config.values.forEach((v)=>{ if (!config.values) return;
let ef=addEl('div','radioFrame',frame); config.values.forEach((v) => {
addEl('div','label',ef,v.label); let ef = addEl('div', 'radioFrame', frame);
let re=addEl('input','radioCi',ef); addEl('div', 'label', ef, getVal(v, LABEL_NAMES));
re.setAttribute('type','radio'); let re = addEl('input', 'radioCi', ef);
re.setAttribute('name',name); let val = v.value;
re.setAttribute('value',v.value); let key=getVal(v,KEY_NAMES);
re.addEventListener('change',(ev)=>callback(v,ev)); re.setAttribute('type', 'radio');
if (v.description && v.url){ re.setAttribute('name', name);
let lnk=addEl('a','radioDescription',ef,v.description); re.addEventListener('change', (ev) => callback(v.children,key,val,false));
lnk.setAttribute('href',v.url); if (v.description && v.url) {
lnk.setAttribute('target','_'); let lnk = addEl('a', 'radioDescription', ef, v.description);
} lnk.setAttribute('href', v.url);
}); lnk.setAttribute('target', '_');
}
if (key == current) {
window.setTimeout(() => {
callback(v.children,key,val,true);
}, 0);
}
});
}
return frame; return frame;
} }
const removeSelectors=(prefix)=>{ const removeSelectors=(prefix,removeValues)=>{
forEachEl('.selectorFrame',(el)=>{ forEachEl('.selectorFrame',(el)=>{
let path=el.getAttribute(PATH_ATTR); let path=el.getAttribute(PATH_ATTR);
if (! path) return; if (! path) return;
@ -168,40 +195,58 @@ import {load as yamlLoad} from "https://cdn.skypack.dev/js-yaml@4.1.0";
el.remove(); el.remove();
} }
}) })
let removeKeys=[]; if (removeValues){
for (let k in config){ let removeKeys=[];
if (k.indexOf(prefix) == 0) removeKeys.push(k); for (let k in configStruct){
if (k.indexOf(prefix) == 0) removeKeys.push(k);
}
for (let k in config){
if (k.indexOf(prefix) == 0) removeKeys.push(k);
}
removeKeys.forEach((k)=>{
delete config[k];
delete configStruct[k];
});
} }
removeKeys.forEach((k)=>delete config[k]);
} }
const buildSelectors=(prefix,configList)=>{ const buildSelectors=(prefix,configList,initial)=>{
removeSelectors(prefix); removeSelectors(prefix,!initial);
if (!configList) return; if (!configList) return;
let parent=document.getElementById("selectors"); let parent=document.getElementById("selectors");
if (!parent) return; if (!parent) return;
let frame=addEl('div','selectorFrame',parent); let frame=addEl('div','selectorFrame',parent);
frame.setAttribute(PATH_ATTR,prefix); frame.setAttribute(PATH_ATTR,prefix);
configList.forEach((cfg)=>{ configList.forEach((cfg)=>{
let name=prefix?(prefix+"_"+cfg.key):cfg.key; let name=prefix?(prefix+SEPARATOR+cfg.key):cfg.key;
let current=config[name]; let current=config[name];
buildSelector(frame,cfg,prefix,current,(ecfg,ev)=>{ buildSelector(frame,cfg,name,current,(children,key,value,initial)=>{
buildSelectors(name,ecfg.children); buildSelectors(name,children,initial);
config[name]={cfg:cfg, value:ecfg.value}; configStruct[name]={cfg:cfg, key: key, value:value};
buildValues(); buildValues();
}) })
}) })
} }
const ROOT_PATH='root';
const buildValues=()=>{ const buildValues=()=>{
let environment; let environment;
let flags=""; let flags="";
for (let k in config){ config={};
let struct=config[k].cfg; for (let k in configStruct){
if (! struct) continue; let struct=configStruct[k];
if (struct.target === 'environment'){ if (! struct || ! struct.cfg || struct.value === undefined) continue;
environment=config[k].value; config[k]=struct.key;
} if (struct.cfg.target !== undefined) {
if (struct.target === 'define'){ if (struct.cfg.target === 'environment') {
flags+=" -D"+config[k].value; environment = struct.value;
}
if (struct.cfg.target === 'define') {
flags += " -D" + struct.value;
}
const DEFPRFX = "define:";
if (struct.cfg.target.indexOf(DEFPRFX) == 0) {
let def = struct.cfg.target.substring(DEFPRFX.length);
flags += " -D" + def + "=" + struct.value;
}
} }
} }
document.getElementById('environment').value=environment; document.getElementById('environment').value=environment;
@ -219,7 +264,7 @@ import {load as yamlLoad} from "https://cdn.skypack.dev/js-yaml@4.1.0";
setRunning(true); setRunning(true);
} }
structure=await loadConfig("testconfig.yaml"); structure=await loadConfig("testconfig.yaml");
buildSelectors('base',[structure.config.board]); buildSelectors(ROOT_PATH,structure.config.children,true);
buildValues(); buildValues();
} }
})(); })();

View File

@ -30,11 +30,13 @@ types:
key: m5grooveserial key: m5grooveserial
values: values:
- label: "RS485" - label: "RS485"
key: unit485
value: SERIAL_GROOVE_485 value: SERIAL_GROOVE_485
description: "M5 RS485 unit" description: "M5 RS485 unit"
url: "http://docs.m5stack.com/en/unit/rs485" url: "http://docs.m5stack.com/en/unit/rs485"
- label: "Tail485" - label: "Tail485"
value: SERIAL_GROOVE_485 value: SERIAL_GROOVE_485
key: tail485
description: "M5 Tail 485" description: "M5 Tail 485"
url: "http://docs.m5stack.com/en/atom/tail485" url: "http://docs.m5stack.com/en/atom/tail485"
@ -54,16 +56,16 @@ types:
config: config:
board: children:
type: select - type: select
target: environment target: environment
label: 'Board' label: 'Board'
key: board key: board
values: values:
- value: m5stack-atom-generic - value: m5stack-atom-generic
label: m5stack-atom label: m5stack-atom
description: "M5 Stack Atom light" description: "M5 Stack Atom light"
url: "http://docs.m5stack.com/en/core/atom_lite" url: "http://docs.m5stack.com/en/core/atom_lite"
children: children:
- *m5base - *m5base
- *m5groove - *m5groove