intermediate: prepare for js api

This commit is contained in:
andreas 2024-10-11 19:23:19 +02:00
parent 09b583ebd6
commit f6e3fa369f
6 changed files with 1976 additions and 1904 deletions

Binary file not shown.

Binary file not shown.

View File

@ -18,6 +18,8 @@ OWN_FILE="extra_script.py"
GEN_DIR='lib/generated'
CFG_FILE='web/config.json'
XDR_FILE='web/xdrconfig.json'
INDEXJS="index.js"
INDEXCSS="index.css"
CFG_INCLUDE='GwConfigDefinitions.h'
CFG_INCLUDE_IMPL='GwConfigDefImpl.h'
XDR_INCLUDE='GwXdrTypeMappings.h'
@ -66,6 +68,7 @@ def isCurrent(infile,outfile):
def compressFile(inFile,outfile):
if isCurrent(inFile,outfile):
return
print("compressing %s"%inFile)
with open(inFile, 'rb') as f_in:
with gzip.open(outfile, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
@ -372,6 +375,16 @@ def getLibs():
rt.append(e)
return rt
def joinFiles(target,pattern,dirlist):
with gzip.open(target,"wb") as oh:
for dir in dirlist:
fn=os.path.join(dir,pattern)
if os.path.exists(fn):
print("adding %s to %s"%(fn,target))
with open(fn,"rb") as rh:
shutil.copyfileobj(rh,oh)
OWNLIBS=getLibs()+["FS","WiFi"]
GLOBAL_INCLUDES=[]
@ -440,6 +453,8 @@ def prebuild(env):
compressFile(mergedConfig,mergedConfig+".gz")
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE),False)
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE_IMPL),True)
joinFiles(os.path.join(outPath(),INDEXJS+".gz"),INDEXJS,["web"]+userTaskDirs)
joinFiles(os.path.join(outPath(),INDEXCSS+".gz"),INDEXCSS,["web"]+userTaskDirs)
embedded=getEmbeddedFiles(env)
filedefs=[]
for ef in embedded:
@ -453,7 +468,6 @@ def prebuild(env):
filedefs.append((pureName,usname,ct))
inFile=os.path.join(basePath(),"web",pureName)
if os.path.exists(inFile):
print("compressing %s"%inFile)
compressFile(inFile,ef)
else:
print("#WARNING: infile %s for %s not found"%(inFile,ef))

View File

@ -351,7 +351,7 @@
"check": "checkMinMax",
"min": -1,
"max": 256,
"description": "the temp instance of PGN 130312 used for water temperature, use -1 for none, 256 for any",
"description": "the temp instance of PGN 130312 used for water temperature (0...255), use -1 for none, 256 for any",
"default": "256",
"category":"converter"
},

View File

@ -341,3 +341,6 @@ body {
.error{
color: red;
}
.changed input.error{
color: red;
}

View File

@ -1,3 +1,4 @@
(function () {
let self = this;
let lastUpdate = (new Date()).getTime();
let reloadConfig = false;
@ -5,6 +6,7 @@ let needAdminPass=true;
let lastSalt = "";
let channelList = {};
let minUser = 200;
let listeners = [];
function addEl(type, clazz, parent, text) {
let el = document.createElement(type);
if (clazz) {
@ -238,6 +240,7 @@ function checkXDR(v,allValues){
}
}
}
let loggedChecks={};
function getAllConfigs(omitPass) {
let values = document.querySelectorAll('.configForm select , .configForm input');
let allValues = {};
@ -253,12 +256,23 @@ function getAllConfigs(omitPass) {
}
let check = v.getAttribute('data-check');
if (check) {
if (typeof (self[check]) === 'function') {
let res = self[check](v.value, allValues, getConfigDefition(name));
let checkFunction;
try{
checkFunction=eval(check);
}catch(e){}
if (typeof (checkFunction) === 'function') {
if (! loggedChecks[check]){
loggedChecks[check]=true;
console.log("check:"+check);
}
let res = checkFunction(v.value, allValues, getConfigDefition(name));
if (res) {
let value = v.value;
if (v.type === 'password') value = "******";
alert("invalid config for " + v.getAttribute('name') + "(" + value + "):\n" + res);
let label = v.getAttribute('data-label');
if (!label) label = v.getAttribute('name');
v.classList.add("error");
alert("invalid config for " + label + "(" + value + "):\n" + res);
return;
}
}
@ -408,6 +422,7 @@ function hideOverlay() {
el.textContent = '';
}
function checkChange(el, row, name) {
el.classList.remove("error");
let loaded = el.getAttribute('data-loaded');
if (loaded !== undefined) {
if (loaded != el.value) {
@ -505,11 +520,13 @@ function createCalSetInput(configItem,frame,clazz){
window.clearInterval(caliv);
}
}, 200);
showOverlay(cs,false,[{label:'Set',click:()=>{
showOverlay(cs, false, [{
label: 'Set', click: () => {
el.value = vel.textContent;
let cev = new Event('change');
el.dispatchEvent(cev);
}}]);
}
}]);
})
el.setAttribute('name', configItem.name)
return el;
@ -554,11 +571,13 @@ function createCalValInput(configItem,frame,clazz){
window.clearInterval(caliv);
}
}, 200);
showOverlay(cs,false,[{label:'Set',click:()=>{
showOverlay(cs, false, [{
label: 'Set', click: () => {
el.value = vinp.value;
let cev = new Event('change');
el.dispatchEvent(cev);
}}]);
}
}]);
})
el.setAttribute('name', configItem.name)
return el;
@ -1140,7 +1159,7 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
configDefinitions = defs;
let currentCategoryPopulated = true;
defs.forEach(function (item) {
if (!item.type) return;
if (!item.type || item.category === undefined) return;
if (item.category.match(/^xdr/)) {
if (!includeXdr) return;
}
@ -1228,6 +1247,7 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
})
}
if (item.check) valueEl.setAttribute('data-check', item.check);
valueEl.setAttribute('data-label', label);
let btContainer = addEl('div', 'buttonContainer', row);
if (!readOnly) {
let bt = addEl('button', 'defaultButton', btContainer, 'X');
@ -1265,6 +1285,12 @@ function loadConfigDefinitions() {
let el = document.getElementById('helpButton');
if (el) el.setAttribute('data-url', capabilities.HELP_URL);
}
try{
Object.freeze(capabilities);
callListeners(api.EVENTS.capabilities,capabilities);
}catch (e){
console.log(e);
}
getJson("config.json")
.then(function (defs) {
getJson("xdrconfig.json")
@ -1861,6 +1887,26 @@ function checkImageFile(file){
reader.readAsArrayBuffer(slice);
});
}
const api= {
registerListener: function (callback) {
listeners.push(callback);
},
addEl: addEl,
forEl: forEl,
closestParent: closestParent,
EVENTS: {
init: 0,
capabilities: 1, //called when capabilities are loaded
}
};
function callListeners(event,data){
listeners.forEach((listener)=>{
if (typeof(listener) === 'function'){
listener(event,data);
}
})
}
window.esp32nmea = api;
window.setInterval(update, 1000);
window.setInterval(function () {
let dp = document.getElementById('dashboardPage');
@ -1873,7 +1919,14 @@ window.addEventListener('load', function () {
let buttons = document.querySelectorAll('button');
for (let i = 0; i < buttons.length; i++) {
let be = buttons[i];
be.onclick = window[be.id]; //assume a function with the button id
let buttonFunction=eval(be.id);
if (typeof(buttonFunction) === 'function'){
be.onclick = buttonFunction; //assume a function with the button id
console.log("button: "+be.id);
}
else{
console.log("no handler for button "+be.id);
}
}
forEl('.showMsgDetails', function (cd) {
cd.addEventListener('change', function (ev) {
@ -1930,4 +1983,6 @@ window.addEventListener('load', function () {
})
})
})
callListeners(api.EVENTS.init);
});
}());