From c057271e379b9c27a50a315673cdbf407b0c470f Mon Sep 17 00:00:00 2001 From: andreas Date: Sat, 7 Oct 2023 12:25:04 +0200 Subject: [PATCH] cleanup and document structure handling --- webinstall/build.yaml | 47 +++++++++++-- webinstall/cibuild.css | 16 +++-- webinstall/cibuild.js | 148 ++++++++++++++++++++++------------------- 3 files changed, 132 insertions(+), 79 deletions(-) diff --git a/webinstall/build.yaml b/webinstall/build.yaml index 79591e67..1c49b6c7 100644 --- a/webinstall/build.yaml +++ b/webinstall/build.yaml @@ -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 to the flags +# define:name - add -D= 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: - &m5base type: select @@ -71,13 +108,13 @@ types: key: m5groove label: 'M5 groove type' values: - - label: 'CAN' + - key: 'CAN' children: - *m5groovecan - - label: 'I2C' + - key: 'I2C' children: - *m5groovei2c - - label: 'Serial' + - key: 'Serial' children: - *m5grooveserial - &gpiopin @@ -95,10 +132,10 @@ types: key: serial1 children: - <<: *gpiopin - label: RX + key: RX target: "define:GWSERIAL_RX" - <<: *gpiopin - label: TX + key: TX target: "define:GWSERIAL_TX" resources: diff --git a/webinstall/cibuild.css b/webinstall/cibuild.css index f1903ee6..15b09463 100644 --- a/webinstall/cibuild.css +++ b/webinstall/cibuild.css @@ -113,10 +113,7 @@ margin-right: 0.5em; z-index: unset; } -.configui .selector { - padding-bottom: 0.5em; - border-bottom: 1px solid grey; -} + .configui .selector .title { font-weight: bold; } @@ -133,10 +130,15 @@ padding-bottom: 0; border-bottom: unset; } -.configui .selector.tdropdown { - padding-bottom: unset; - border-bottom: unset; +.configui .childFrame { + border-top: 1px solid grey; + margin-top: 0.3em; +} +.configui .tframe>.childFrame { + border-top: unset; + margin-top: 0.3em; } + .configui .selector.tdropdown { display: flex; flex-direction: row; diff --git a/webinstall/cibuild.js b/webinstall/cibuild.js index c4ea045a..4a1111e8 100644 --- a/webinstall/cibuild.js +++ b/webinstall/cibuild.js @@ -243,16 +243,44 @@ class PipelineInfo{ let parsed=yamlLoad(config); 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 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 @@ -262,27 +290,28 @@ class PipelineInfo{ * @param {*} callback will be called with: children,key,value,initial * @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 level=name.replace(rep,''); let frame=addEl('div','selector level'+level.length+' t'+config.type,parent); frame.setAttribute(PATH_ATTR,name); let title=addEl('div','title t'+config.type,frame,config.label); - if (config.type === 'frame'){ - callback(config.children,true,true,undefined,true); + let initialConfig=undefined + if (config.type === 'frame' || config.type === undefined){ + initialConfig=config; } + let expandedValues=expandList(config.values,config); if (config.type === 'select') { - if (!config.values) return; - config.values.forEach((v) => { + for (let idx=0;idx callback(v.children,key,val,v.resource,false)); + re.addEventListener('change', (ev) => callback(v,false)); if (v.description){ if(v.url) { let lnk = addEl('a', 'radioDescription', ef, v.description); @@ -293,53 +322,35 @@ class PipelineInfo{ let de=addEl('span','radioDescription',ef,v.description); } } - if (key == current) { + if (v.key == current) { re.setAttribute('checked','checked'); - callback(v.children,key,val,v.resource,true); + initialConfig=v; } - }); + }; } 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); - for (let idx=0;idx{ - let resource; - let v=valForIdx(ev.target.value); + let v=expandedValues[ev.target.value]; 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)=>{ forEachEl('.selectorFrame',(el)=>{ @@ -363,21 +374,25 @@ class PipelineInfo{ }); } } - const buildSelectors=(prefix,configList,initial)=>{ + const buildSelectors=(prefix,configList,initial,parent)=>{ removeSelectors(prefix,!initial); + if (!parent) parent=document.getElementById("selectors");; if (!configList) return; - let parent=document.getElementById("selectors"); - if (!parent) return; let frame=addEl('div','selectorFrame',parent); frame.setAttribute(PATH_ATTR,prefix); - configList.forEach((cfg)=>{ - let key=getVal(cfg,KEY_NAMES); - let name=prefix?(prefix+SEPARATOR+key):key; + let expandedList=expandList(configList); + expandedList.forEach((cfg)=>{ + if (cfg.key === undefined){ + console.log("config without key",cfg); + return; + } + let name=prefix?(prefix+SEPARATOR+cfg.key):cfg.key; let current=config[name]; - buildSelector(frame,cfg,name,current,(children,key,value,resource,initial)=>{ - buildSelectors(name,children,initial); - configStruct[name]={cfg:cfg, key: key, value:value,resource:resource}; - buildValues(initial); + let childFrame=buildSelector(frame,cfg,name,current, + (child,initial,opt_frame)=>{ + buildSelectors(name,child.children,initial,opt_frame||childFrame); + configStruct[name]=child; + buildValues(initial); }) }) } @@ -396,10 +411,9 @@ class PipelineInfo{ //round2: really collect values for (let k in configStruct) { let struct = configStruct[k]; - if (!struct || !struct.cfg || struct.value === undefined) continue; if (round > 0) config[k] = struct.key; - if (struct.cfg.target !== undefined) { - if (struct.cfg.target === 'environment') { + if (struct.target !== undefined) { + if (struct.target === 'environment') { if (round > 0) environment = struct.value; else allowedResources=struct.resource; continue; @@ -413,13 +427,13 @@ class PipelineInfo{ } resList.push(struct); } - if (struct.cfg.target === 'define') { + if (struct.target === 'define') { flags += " -D" + struct.value; continue; } const DEFPRFX = "define:"; - if (struct.cfg.target.indexOf(DEFPRFX) == 0) { - let def = struct.cfg.target.substring(DEFPRFX.length); + if (struct.target.indexOf(DEFPRFX) == 0) { + let def = struct.target.substring(DEFPRFX.length); flags += " -D" + def + "=" + struct.value; continue; }