cleanup and document structure handling

This commit is contained in:
andreas 2023-10-07 12:25:04 +02:00
parent 82c98eec15
commit c057271e37
3 changed files with 132 additions and 79 deletions

View File

@ -1,3 +1,40 @@
# structure
# below config we define the structure to be displayed
# basically there are 2 object types:
# children - a list of cfg objects that define the inputs to be shown
# if the parent is selected
# parameters:
# key: unique key - defines the name(part) in the cfg
# if not set a potential "value" is taken
# null (empty) is a valid key
# label: title to be shown, if unset key will be used
# resorce: a resource that is used by the value children
# simple string use as is
# string + ':' - add value to the resource
# type: if empty or 'frame' only the children are considered
# children: only for type empty or 'frame' - list of child objects
# target: how the selected child value should be stored:
# environment - set the environment to the child value
# define - add -D<childValue> to the flags
# define:name - add -D<name>=<childValue> to the flags
# values - a list of value objects for a particular config
# if the object is just a string it is converted to an object
# with value being set to the string
# parameters:
# key: unique key, defines the name(part) and the value store in cfg
# for the parent
# if not set, value is used
# null (empty) is a valid key
# value: the value (mandatory)
# if null the value will be set to undefined and ignored
# label: text to be shown
# if not set value will be used
# description,url
# resource: for parent-target environment:
# an object with allowed resource counts
# for other values: the resource to be counted
#
#
types: types:
- &m5base - &m5base
type: select type: select
@ -71,13 +108,13 @@ types:
key: m5groove key: m5groove
label: 'M5 groove type' label: 'M5 groove type'
values: values:
- label: 'CAN' - key: 'CAN'
children: children:
- *m5groovecan - *m5groovecan
- label: 'I2C' - key: 'I2C'
children: children:
- *m5groovei2c - *m5groovei2c
- label: 'Serial' - key: 'Serial'
children: children:
- *m5grooveserial - *m5grooveserial
- &gpiopin - &gpiopin
@ -95,10 +132,10 @@ types:
key: serial1 key: serial1
children: children:
- <<: *gpiopin - <<: *gpiopin
label: RX key: RX
target: "define:GWSERIAL_RX" target: "define:GWSERIAL_RX"
- <<: *gpiopin - <<: *gpiopin
label: TX key: TX
target: "define:GWSERIAL_TX" target: "define:GWSERIAL_TX"
resources: resources:

View File

@ -113,10 +113,7 @@
margin-right: 0.5em; margin-right: 0.5em;
z-index: unset; z-index: unset;
} }
.configui .selector {
padding-bottom: 0.5em;
border-bottom: 1px solid grey;
}
.configui .selector .title { .configui .selector .title {
font-weight: bold; font-weight: bold;
} }
@ -133,10 +130,15 @@
padding-bottom: 0; padding-bottom: 0;
border-bottom: unset; border-bottom: unset;
} }
.configui .selector.tdropdown { .configui .childFrame {
padding-bottom: unset; border-top: 1px solid grey;
border-bottom: unset; margin-top: 0.3em;
} }
.configui .tframe>.childFrame {
border-top: unset;
margin-top: 0.3em;
}
.configui .selector.tdropdown { .configui .selector.tdropdown {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@ -243,16 +243,44 @@ class PipelineInfo{
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 SEPARATOR=':'; const SEPARATOR=':';
const expandObject=(obj,parent)=>{
if (typeof(obj) !== 'object'){
obj={value:obj}
}
let rt=Object.assign({},obj);
if (rt.value === undefined && rt.key !== undefined) rt.value=rt.key;
if (rt.key === undefined) rt.key=rt.value;
if (rt.value === null) rt.value=undefined;
if (rt.label === undefined){
if (rt.value !== undefined) rt.label=rt.value;
else rt.label=rt.key;
}
if (rt.resource === undefined && typeof(parent) === 'object'){
if (parent.resource !== undefined){
if (parent.resource.match(/:$/)){
if(rt.value !== undefined && rt.value !== null){
rt.resource=parent.resource+rt.value;
}
}
else{
rt.resource=parent.resource;
}
}
}
if (rt.target === undefined && typeof(parent) === 'object' && parent.target !== undefined){
rt.target=parent.target;
}
return rt;
}
const expandList=(lst,parent)=>{
let rt=[];
if (! lst) return rt;
lst.forEach((e)=>rt.push(expandObject(e,parent)));
return rt;
}
/** /**
* *
* @param {build a selector} parent * @param {build a selector} parent
@ -262,27 +290,28 @@ class PipelineInfo{
* @param {*} callback will be called with: children,key,value,initial * @param {*} callback will be called with: children,key,value,initial
* @returns * @returns
*/ */
const buildSelector=(parent,config,name,current,callback)=>{ const buildSelector=(parent,cfgBase,name,current,callback)=>{
let config=expandObject(cfgBase);
let rep=new RegExp("[^"+SEPARATOR+"]*","g"); let rep=new RegExp("[^"+SEPARATOR+"]*","g");
let level=name.replace(rep,''); let level=name.replace(rep,'');
let frame=addEl('div','selector level'+level.length+' t'+config.type,parent); let frame=addEl('div','selector level'+level.length+' t'+config.type,parent);
frame.setAttribute(PATH_ATTR,name); frame.setAttribute(PATH_ATTR,name);
let title=addEl('div','title t'+config.type,frame,config.label); let title=addEl('div','title t'+config.type,frame,config.label);
if (config.type === 'frame'){ let initialConfig=undefined
callback(config.children,true,true,undefined,true); if (config.type === 'frame' || config.type === undefined){
initialConfig=config;
} }
let expandedValues=expandList(config.values,config);
if (config.type === 'select') { if (config.type === 'select') {
if (!config.values) return; for (let idx=0;idx<expandedValues.length;idx++){
config.values.forEach((v) => { let v=expandedValues[idx];
if (v.key === undefined) continue;
let ef = addEl('div', 'radioFrame', frame); let ef = addEl('div', 'radioFrame', frame);
addEl('div', 'label', ef, getVal(v, LABEL_NAMES)); addEl('div', 'label', ef, v.label);
let re = addEl('input', 'radioCi', ef); let re = addEl('input', 'radioCi', ef);
let val = v.value;
let key=getVal(v,KEY_NAMES);
if (val === undefined) val=key;
re.setAttribute('type', 'radio'); re.setAttribute('type', 'radio');
re.setAttribute('name', name); re.setAttribute('name', name);
re.addEventListener('change', (ev) => callback(v.children,key,val,v.resource,false)); re.addEventListener('change', (ev) => callback(v,false));
if (v.description){ if (v.description){
if(v.url) { if(v.url) {
let lnk = addEl('a', 'radioDescription', ef, v.description); let lnk = addEl('a', 'radioDescription', ef, v.description);
@ -293,53 +322,35 @@ class PipelineInfo{
let de=addEl('span','radioDescription',ef,v.description); let de=addEl('span','radioDescription',ef,v.description);
} }
} }
if (key == current) { if (v.key == current) {
re.setAttribute('checked','checked'); re.setAttribute('checked','checked');
callback(v.children,key,val,v.resource,true); initialConfig=v;
} }
}); };
} }
if (config.type === 'dropdown'){ if (config.type === 'dropdown'){
if (!config.values) return;
const valForIdx=(idx)=>{
let v=config.values[idx];
if (typeof(v) !== 'object'){
v={label:v,value:v};
}
if (v.value === null) v.value=undefined;
if (v.key === null) v.key=undefined;
return v;
};
const resourceForVal=(v)=>{
if (v === undefined) return undefined;
let key=getVal(v,KEY_NAMES);
if (key === undefined) return key;
let resource=v.resource;
if (! resource && config.resource && config.resource.match(/:$/)){
resource=config.resource+key;
}
return resource;
};
let sel=addEl('select','t'+config.type,frame); let sel=addEl('select','t'+config.type,frame);
for (let idx=0;idx<config.values.length;idx++){ for (let idx=0;idx<expandedValues.length;idx++){
let v=valForIdx(idx); let v=expandedValues[idx];
if (v.key === undefined) continue;
let opt=addEl('option','',sel,v.label); let opt=addEl('option','',sel,v.label);
let key=getVal(v,KEY_NAMES);
if (key === null) key=undefined;
opt.setAttribute('value',idx); opt.setAttribute('value',idx);
if (key == current){ if (v.key == current){
opt.setAttribute('selected',true); opt.setAttribute('selected',true);
callback(undefined,key,key,resourceForVal(v),true); initialConfig=v;
} }
}; };
sel.addEventListener('change',(ev)=>{ sel.addEventListener('change',(ev)=>{
let resource; let v=expandedValues[ev.target.value];
let v=valForIdx(ev.target.value);
if (! v) return; if (! v) return;
callback(undefined,getVal(v,KEY_NAMES), v.value,resourceForVal(v),false); callback(v,false);
}); });
} }
return frame; let childFrame=addEl('div','childFrame',frame);
if (initialConfig !== undefined){
callback(initialConfig,true,childFrame);
}
return childFrame;
} }
const removeSelectors=(prefix,removeValues)=>{ const removeSelectors=(prefix,removeValues)=>{
forEachEl('.selectorFrame',(el)=>{ forEachEl('.selectorFrame',(el)=>{
@ -363,20 +374,24 @@ class PipelineInfo{
}); });
} }
} }
const buildSelectors=(prefix,configList,initial)=>{ const buildSelectors=(prefix,configList,initial,parent)=>{
removeSelectors(prefix,!initial); removeSelectors(prefix,!initial);
if (!parent) parent=document.getElementById("selectors");;
if (!configList) return; if (!configList) return;
let parent=document.getElementById("selectors");
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)=>{ let expandedList=expandList(configList);
let key=getVal(cfg,KEY_NAMES); expandedList.forEach((cfg)=>{
let name=prefix?(prefix+SEPARATOR+key):key; if (cfg.key === undefined){
console.log("config without key",cfg);
return;
}
let name=prefix?(prefix+SEPARATOR+cfg.key):cfg.key;
let current=config[name]; let current=config[name];
buildSelector(frame,cfg,name,current,(children,key,value,resource,initial)=>{ let childFrame=buildSelector(frame,cfg,name,current,
buildSelectors(name,children,initial); (child,initial,opt_frame)=>{
configStruct[name]={cfg:cfg, key: key, value:value,resource:resource}; buildSelectors(name,child.children,initial,opt_frame||childFrame);
configStruct[name]=child;
buildValues(initial); buildValues(initial);
}) })
}) })
@ -396,10 +411,9 @@ class PipelineInfo{
//round2: really collect values //round2: really collect values
for (let k in configStruct) { for (let k in configStruct) {
let struct = configStruct[k]; let struct = configStruct[k];
if (!struct || !struct.cfg || struct.value === undefined) continue;
if (round > 0) config[k] = struct.key; if (round > 0) config[k] = struct.key;
if (struct.cfg.target !== undefined) { if (struct.target !== undefined) {
if (struct.cfg.target === 'environment') { if (struct.target === 'environment') {
if (round > 0) environment = struct.value; if (round > 0) environment = struct.value;
else allowedResources=struct.resource; else allowedResources=struct.resource;
continue; continue;
@ -413,13 +427,13 @@ class PipelineInfo{
} }
resList.push(struct); resList.push(struct);
} }
if (struct.cfg.target === 'define') { if (struct.target === 'define') {
flags += " -D" + struct.value; flags += " -D" + struct.value;
continue; continue;
} }
const DEFPRFX = "define:"; const DEFPRFX = "define:";
if (struct.cfg.target.indexOf(DEFPRFX) == 0) { if (struct.target.indexOf(DEFPRFX) == 0) {
let def = struct.cfg.target.substring(DEFPRFX.length); let def = struct.target.substring(DEFPRFX.length);
flags += " -D" + def + "=" + struct.value; flags += " -D" + def + "=" + struct.value;
continue; continue;
} }