allow to set a read only mode for config items, output compiler messages for overwritten configs, add m5 gps unit defs
This commit is contained in:
parent
9572b1e95e
commit
4fa40b98b3
|
@ -145,20 +145,33 @@ def generateCfg(inFile,outFile,addDirs=[]):
|
||||||
secret="false";
|
secret="false";
|
||||||
if item.get('type') == 'password':
|
if item.get('type') == 'password':
|
||||||
secret="true"
|
secret="true"
|
||||||
data+=" #undef __CFGHIDDEN\n"
|
data+=" #undef __CFGMODE\n"
|
||||||
data+=" #ifdef CFGHIDE_%s\n"%(name)
|
data+=" #ifdef CFGMODE_%s\n"%(name)
|
||||||
data+=" #define __CFGHIDDEN true\n"
|
data+=" #define __CFGMODE CFGMODE_%s\n"%(name)
|
||||||
data+=" #else\n"
|
data+=" #else\n"
|
||||||
data+=" #define __CFGHIDDEN false\n"
|
data+=" #define __CFGMODE GwConfigInterface::NORMAL\n"
|
||||||
data+=" #endif\n"
|
data+=" #endif\n"
|
||||||
data+=" #ifdef CFGDEFAULT_%s\n"%(name)
|
data+=" #ifdef CFGDEFAULT_%s\n"%(name)
|
||||||
data+=" new GwConfigInterface(%s,CFGDEFAULT_%s,%s,__CFGHIDDEN)\n"%(name,name,secret)
|
data+=" new GwConfigInterface(%s,CFGDEFAULT_%s,%s,__CFGMODE)\n"%(name,name,secret)
|
||||||
data+=" #else\n"
|
data+=" #else\n"
|
||||||
data+=" new GwConfigInterface(%s,\"%s\",%s,__CFGHIDDEN)\n"%(name,item.get('default'),secret)
|
data+=" new GwConfigInterface(%s,\"%s\",%s,__CFGMODE)\n"%(name,item.get('default'),secret)
|
||||||
data+=" #endif\n"
|
data+=" #endif\n"
|
||||||
|
|
||||||
data+='};\n'
|
data+='};\n'
|
||||||
data+='};\n'
|
data+='};\n'
|
||||||
|
data+="#ifdef CFG_MESSAGES\n"
|
||||||
|
for item in config:
|
||||||
|
name=item.get('name')
|
||||||
|
if name is None:
|
||||||
|
continue
|
||||||
|
data+="#ifdef CFGMODE_%s\n"%(name)
|
||||||
|
data+=" __MSG(\"CFGMODE_%s=\" __XSTR(CFGMODE_%s))\n"%(name,name)
|
||||||
|
data+="#endif\n"
|
||||||
|
data+="#ifdef CFGDEFAULT_%s\n"%(name)
|
||||||
|
data+=" __MSG(\"CFGDEFAULT_%s=\" CFGDEFAULT_%s)\n"%(name,name)
|
||||||
|
data+="#endif\n"
|
||||||
|
data+="#endif"
|
||||||
|
|
||||||
writeFileIfChanged(outFile,data)
|
writeFileIfChanged(outFile,data)
|
||||||
|
|
||||||
|
|
||||||
|
@ -298,6 +311,7 @@ print("#prescript...")
|
||||||
prebuild(env)
|
prebuild(env)
|
||||||
board="PLATFORM_BOARD_%s"%env["BOARD"].replace("-","_").upper()
|
board="PLATFORM_BOARD_%s"%env["BOARD"].replace("-","_").upper()
|
||||||
print("Board=#%s#"%board)
|
print("Board=#%s#"%board)
|
||||||
|
print("BuildFlags=%s"%(" ".join(env["BUILD_FLAGS"])))
|
||||||
env.Append(
|
env.Append(
|
||||||
LINKFLAGS=[ "-u", "custom_app_desc" ],
|
LINKFLAGS=[ "-u", "custom_app_desc" ],
|
||||||
CPPDEFINES=[(board,"1")]
|
CPPDEFINES=[(board,"1")]
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#define CFG_MESSAGES
|
||||||
#include "GWConfig.h"
|
#include "GWConfig.h"
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -159,20 +160,20 @@ void GwConfigHandler::toHex(unsigned long v, char *buffer, size_t bsize)
|
||||||
buffer[2 * i] = 0;
|
buffer[2 * i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<String> GwConfigHandler::getHidden() const{
|
std::vector<String> GwConfigHandler::getSpecial() const{
|
||||||
std::vector<String> rt;
|
std::vector<String> rt;
|
||||||
rt.reserve(numHidden());
|
rt.reserve(numSpecial());
|
||||||
for (int i=0L;i<getNumConfig();i++){
|
for (int i=0L;i<getNumConfig();i++){
|
||||||
if (configs[i]->isHidden()){
|
if (configs[i]->getType() != GwConfigInterface::NORMAL){
|
||||||
rt.push_back(configs[i]->getName());
|
rt.push_back(configs[i]->getName());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
int GwConfigHandler::numHidden() const{
|
int GwConfigHandler::numSpecial() const{
|
||||||
int rt=0;
|
int rt=0;
|
||||||
for (int i=0L;i<getNumConfig();i++){
|
for (int i=0L;i<getNumConfig();i++){
|
||||||
if (configs[i]->isHidden()) rt++;
|
if (configs[i]->getType() != GwConfigInterface::NORMAL) rt++;
|
||||||
}
|
}
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ class GwConfigHandler: public GwConfigDefinitions{
|
||||||
int getInt(const String name,int defaultv=0) const;
|
int getInt(const String name,int defaultv=0) const;
|
||||||
GwConfigInterface * getConfigItem(const String name, bool dummy=false) const;
|
GwConfigInterface * getConfigItem(const String name, bool dummy=false) const;
|
||||||
bool checkPass(String hash);
|
bool checkPass(String hash);
|
||||||
std::vector<String> getHidden() const;
|
std::vector<String> getSpecial() const;
|
||||||
int numHidden() const;
|
int numSpecial() const;
|
||||||
/**
|
/**
|
||||||
* change the value of a config item
|
* change the value of a config item
|
||||||
* will become a noop after stopChanges has been called
|
* will become a noop after stopChanges has been called
|
||||||
|
|
|
@ -5,19 +5,25 @@
|
||||||
|
|
||||||
class GwConfigHandler;
|
class GwConfigHandler;
|
||||||
class GwConfigInterface{
|
class GwConfigInterface{
|
||||||
|
public:
|
||||||
|
typedef enum {
|
||||||
|
NORMAL=0,
|
||||||
|
HIDDEN=1,
|
||||||
|
READONLY=2
|
||||||
|
} ConfigType;
|
||||||
private:
|
private:
|
||||||
String name;
|
String name;
|
||||||
const char * initialValue;
|
const char * initialValue;
|
||||||
String value;
|
String value;
|
||||||
bool secret=false;
|
bool secret=false;
|
||||||
bool hidden=false;
|
ConfigType type=NORMAL;
|
||||||
public:
|
public:
|
||||||
GwConfigInterface(const String &name, const char * initialValue, bool secret=false, bool hidden=false){
|
GwConfigInterface(const String &name, const char * initialValue, bool secret=false,ConfigType type=NORMAL){
|
||||||
this->name=name;
|
this->name=name;
|
||||||
this->initialValue=initialValue;
|
this->initialValue=initialValue;
|
||||||
this->value=initialValue;
|
this->value=initialValue;
|
||||||
this->secret=secret;
|
this->secret=secret;
|
||||||
this->hidden=hidden;
|
this->type=type;
|
||||||
}
|
}
|
||||||
virtual String asString() const{
|
virtual String asString() const{
|
||||||
return value;
|
return value;
|
||||||
|
@ -43,8 +49,8 @@ class GwConfigInterface{
|
||||||
String getDefault() const {
|
String getDefault() const {
|
||||||
return initialValue;
|
return initialValue;
|
||||||
}
|
}
|
||||||
bool isHidden() const {
|
ConfigType getType() const {
|
||||||
return hidden;
|
return type;
|
||||||
}
|
}
|
||||||
friend class GwConfigHandler;
|
friend class GwConfigHandler;
|
||||||
};
|
};
|
||||||
|
@ -67,5 +73,7 @@ class GwNmeaFilter{
|
||||||
String toString();
|
String toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define __XSTR(x) __STR(x)
|
||||||
|
#define __STR(x) #x
|
||||||
|
#define __MSG(x) _Pragma (__STR(message (x)))
|
||||||
#endif
|
#endif
|
|
@ -17,7 +17,7 @@
|
||||||
#define GWSERIAL_TYPE_BI 2
|
#define GWSERIAL_TYPE_BI 2
|
||||||
#define GWSERIAL_TYPE_RX 3
|
#define GWSERIAL_TYPE_RX 3
|
||||||
#define GWSERIAL_TYPE_TX 4
|
#define GWSERIAL_TYPE_TX 4
|
||||||
|
#include <GwConfigItem.h>
|
||||||
#include <HardwareSerial.h>
|
#include <HardwareSerial.h>
|
||||||
#include "GwUserTasks.h"
|
#include "GwUserTasks.h"
|
||||||
|
|
||||||
|
@ -148,8 +148,8 @@
|
||||||
#ifdef M5_GPS_KIT
|
#ifdef M5_GPS_KIT
|
||||||
#define GWSERIAL_RX BOARD_LEFT1
|
#define GWSERIAL_RX BOARD_LEFT1
|
||||||
#define GWSERIAL_TYPE GWSERIAL_TYPE_RX
|
#define GWSERIAL_TYPE GWSERIAL_TYPE_RX
|
||||||
#define CFGGDEFAULT_serialBaud "9600"
|
#define CFGDEFAULT_serialBaud "9600"
|
||||||
#define CFGHIDE_serialBaud
|
#define CFGMODE_serialBaud GwConfigInterface::READONLY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//below we define the final device config based on the above
|
//below we define the final device config based on the above
|
||||||
|
@ -181,6 +181,21 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//http://docs.m5stack.com/en/unit/gps
|
||||||
|
#ifdef M5_GPS_UNIT
|
||||||
|
#ifdef GWSERIAL_TYPE
|
||||||
|
#define GWSERIAL2_RX GROOVE_PIN_2
|
||||||
|
#define GWSERIAL2_TYPE GWSERIAL_TYPE_RX
|
||||||
|
#define CFGDEFAULT_serialBaud "9600"
|
||||||
|
#define CFGMODE_serialBaud GwConfigInterface::READONLY
|
||||||
|
#else
|
||||||
|
#define GWSERIAL_RX GROOVE_PIN_2
|
||||||
|
#define GWSERIAL_TYPE GWSERIAL_TYPE_RX
|
||||||
|
#define CFGDEFAULT_serial2Baud "9600"
|
||||||
|
#define CFGMODE_serial2Baud GwConfigInterface::READONLY
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//can kit for M5 Atom
|
//can kit for M5 Atom
|
||||||
#ifdef M5_CAN_KIT
|
#ifdef M5_CAN_KIT
|
||||||
#define ESP32_CAN_TX_PIN BOARD_LEFT1
|
#define ESP32_CAN_TX_PIN BOARD_LEFT1
|
||||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -430,15 +430,20 @@ class CapabilitiesRequest : public GwRequestMessage{
|
||||||
protected:
|
protected:
|
||||||
virtual void processRequest(){
|
virtual void processRequest(){
|
||||||
int numCapabilities=userCodeHandler.getCapabilities()->size();
|
int numCapabilities=userCodeHandler.getCapabilities()->size();
|
||||||
int numHidden=config.numHidden();
|
int numSpecial=config.numSpecial();
|
||||||
GwJsonDocument json(JSON_OBJECT_SIZE(numCapabilities*3+numHidden*2+8));
|
logger.logDebug(GwLog::LOG,"capabilities user=%d, config=%d",numCapabilities,numSpecial);
|
||||||
|
GwJsonDocument json(JSON_OBJECT_SIZE(numCapabilities*3+numSpecial*2+8));
|
||||||
for (auto it=userCodeHandler.getCapabilities()->begin();
|
for (auto it=userCodeHandler.getCapabilities()->begin();
|
||||||
it != userCodeHandler.getCapabilities()->end();it++){
|
it != userCodeHandler.getCapabilities()->end();it++){
|
||||||
json[it->first]=it->second;
|
json[it->first]=it->second;
|
||||||
}
|
}
|
||||||
std::vector<String> hiddenCfg=config.getHidden();
|
std::vector<String> specialCfg=config.getSpecial();
|
||||||
for (auto it=hiddenCfg.begin();it != hiddenCfg.end();it++){
|
for (auto it=specialCfg.begin();it != specialCfg.end();it++){
|
||||||
json["HIDE"+*it]=true;
|
GwConfigInterface *cfg=config.getConfigItem(*it);
|
||||||
|
if (cfg){
|
||||||
|
logger.logDebug(GwLog::LOG,"config mode %s=%d",it->c_str(),(int)(cfg->getType()));
|
||||||
|
json["CFGMODE"+*it]=(int)cfg->getType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
json["serialmode"]=channels.getMode(SERIAL1_CHANNEL_ID);
|
json["serialmode"]=channels.getMode(SERIAL1_CHANNEL_ID);
|
||||||
json["serial2mode"]=channels.getMode(SERIAL2_CHANNEL_ID);
|
json["serial2mode"]=channels.getMode(SERIAL2_CHANNEL_ID);
|
||||||
|
|
46
web/index.js
46
web/index.js
|
@ -231,6 +231,7 @@ function getAllConfigs(omitPass) {
|
||||||
let name = v.getAttribute('name');
|
let name = v.getAttribute('name');
|
||||||
if (!name) continue;
|
if (!name) continue;
|
||||||
if (name.indexOf("_") >= 0) continue;
|
if (name.indexOf("_") >= 0) continue;
|
||||||
|
if (v.getAttribute('disabled')) continue;
|
||||||
let def = getConfigDefition(name);
|
let def = getConfigDefition(name);
|
||||||
if (def.type === 'password' && ( v.value == '' || omitPass)) {
|
if (def.type === 'password' && ( v.value == '' || omitPass)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -444,6 +445,7 @@ function createInput(configItem, frame,clazz) {
|
||||||
let el;
|
let el;
|
||||||
if (configItem.type === 'boolean' || configItem.type === 'list' || configItem.type == 'boatData') {
|
if (configItem.type === 'boolean' || configItem.type === 'list' || configItem.type == 'boatData') {
|
||||||
el=addEl('select',clazz,frame);
|
el=addEl('select',clazz,frame);
|
||||||
|
if (configItem.readOnly) el.setAttribute('disabled',true);
|
||||||
el.setAttribute('name', configItem.name)
|
el.setAttribute('name', configItem.name)
|
||||||
let slist = [];
|
let slist = [];
|
||||||
if (configItem.list) {
|
if (configItem.list) {
|
||||||
|
@ -476,6 +478,7 @@ function createInput(configItem, frame,clazz) {
|
||||||
return createXdrInput(configItem,frame,clazz);
|
return createXdrInput(configItem,frame,clazz);
|
||||||
}
|
}
|
||||||
el = addEl('input',clazz,frame);
|
el = addEl('input',clazz,frame);
|
||||||
|
if (configItem.readOnly) el.setAttribute('disabled',true);
|
||||||
el.setAttribute('name', configItem.name)
|
el.setAttribute('name', configItem.name)
|
||||||
if (configItem.type === 'password') {
|
if (configItem.type === 'password') {
|
||||||
el.setAttribute('type', 'password');
|
el.setAttribute('type', 'password');
|
||||||
|
@ -591,25 +594,29 @@ function createXdrInput(configItem,frame){
|
||||||
{l:'bidir',v:1},
|
{l:'bidir',v:1},
|
||||||
{l:'to2K',v:2},
|
{l:'to2K',v:2},
|
||||||
{l:'from2K',v:3}
|
{l:'from2K',v:3}
|
||||||
]
|
],
|
||||||
|
readOnly: configItem.readOnly
|
||||||
},d,'xdrdir');
|
},d,'xdrdir');
|
||||||
d=createXdrLine(el,'Category');
|
d=createXdrLine(el,'Category');
|
||||||
let category=createInput({
|
let category=createInput({
|
||||||
type: 'list',
|
type: 'list',
|
||||||
name: configItem.name+"_cat",
|
name: configItem.name+"_cat",
|
||||||
list:getXdrCategories()
|
list:getXdrCategories(),
|
||||||
|
readOnly: configItem.readOnly
|
||||||
},d,'xdrcat');
|
},d,'xdrcat');
|
||||||
d=createXdrLine(el,'Source');
|
d=createXdrLine(el,'Source');
|
||||||
let selector=createInput({
|
let selector=createInput({
|
||||||
type: 'list',
|
type: 'list',
|
||||||
name: configItem.name+"_sel",
|
name: configItem.name+"_sel",
|
||||||
list:[]
|
list:[],
|
||||||
|
readOnly: configItem.readOnly
|
||||||
},d,'xdrsel');
|
},d,'xdrsel');
|
||||||
d=createXdrLine(el,'Field');
|
d=createXdrLine(el,'Field');
|
||||||
let field=createInput({
|
let field=createInput({
|
||||||
type:'list',
|
type:'list',
|
||||||
name: configItem.name+'_field',
|
name: configItem.name+'_field',
|
||||||
list: []
|
list: [],
|
||||||
|
readOnly: configItem.readOnly
|
||||||
},d,'xdrfield');
|
},d,'xdrfield');
|
||||||
d=createXdrLine(el,'Instance');
|
d=createXdrLine(el,'Instance');
|
||||||
let imode=createInput({
|
let imode=createInput({
|
||||||
|
@ -620,22 +627,26 @@ function createXdrInput(configItem,frame){
|
||||||
{l:'single',v:0},
|
{l:'single',v:0},
|
||||||
{l:'ignore',v:1},
|
{l:'ignore',v:1},
|
||||||
{l:'auto',v:2}
|
{l:'auto',v:2}
|
||||||
]
|
],
|
||||||
|
readOnly: configItem.readOnly
|
||||||
},d,'xdrimode');
|
},d,'xdrimode');
|
||||||
let instance=createInput({
|
let instance=createInput({
|
||||||
type:'number',
|
type:'number',
|
||||||
name: configItem.name+"_instance",
|
name: configItem.name+"_instance",
|
||||||
|
readOnly: configItem.readOnly
|
||||||
},d,'xdrinstance');
|
},d,'xdrinstance');
|
||||||
d=createXdrLine(el,'Transducer');
|
d=createXdrLine(el,'Transducer');
|
||||||
let xdrName=createInput({
|
let xdrName=createInput({
|
||||||
type:'text',
|
type:'text',
|
||||||
name: configItem.name+"_xdr"
|
name: configItem.name+"_xdr",
|
||||||
|
readOnly: configItem.readOnly
|
||||||
},d,'xdrname');
|
},d,'xdrname');
|
||||||
d=createXdrLine(el,'Example');
|
d=createXdrLine(el,'Example');
|
||||||
let example=addEl('div','xdrexample',d,'');
|
let example=addEl('div','xdrexample',d,'');
|
||||||
let data = addEl('input','xdrvalue',el);
|
let data = addEl('input','xdrvalue',el);
|
||||||
data.setAttribute('type', 'hidden');
|
data.setAttribute('type', 'hidden');
|
||||||
data.setAttribute('name', configItem.name);
|
data.setAttribute('name', configItem.name);
|
||||||
|
if (configItem.readOnly) data.setAttribute('disabled',true);
|
||||||
let changeFunction = function () {
|
let changeFunction = function () {
|
||||||
let parts=data.value.split(',');
|
let parts=data.value.split(',');
|
||||||
direction.value=parts[1] || 0;
|
direction.value=parts[1] || 0;
|
||||||
|
@ -730,16 +741,19 @@ function createFilterInput(configItem, frame) {
|
||||||
let ais = createInput({
|
let ais = createInput({
|
||||||
type: 'list',
|
type: 'list',
|
||||||
name: configItem.name + "_ais",
|
name: configItem.name + "_ais",
|
||||||
list: ['aison', 'aisoff']
|
list: ['aison', 'aisoff'],
|
||||||
|
readOnly: configItem.readOnly
|
||||||
}, el);
|
}, el);
|
||||||
let mode = createInput({
|
let mode = createInput({
|
||||||
type: 'list',
|
type: 'list',
|
||||||
name: configItem.name + "_mode",
|
name: configItem.name + "_mode",
|
||||||
list: ['whitelist', 'blacklist']
|
list: ['whitelist', 'blacklist'],
|
||||||
|
readOnly: configItem.readOnly
|
||||||
}, el);
|
}, el);
|
||||||
let sentences = createInput({
|
let sentences = createInput({
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: configItem.name + "_sentences",
|
name: configItem.name + "_sentences",
|
||||||
|
readOnly: configItem.readOnly
|
||||||
}, el);
|
}, el);
|
||||||
let data = addEl('input',undefined,el);
|
let data = addEl('input',undefined,el);
|
||||||
data.setAttribute('type', 'hidden');
|
data.setAttribute('type', 'hidden');
|
||||||
|
@ -767,6 +781,7 @@ function createFilterInput(configItem, frame) {
|
||||||
changeFunction();
|
changeFunction();
|
||||||
});
|
});
|
||||||
data.setAttribute('name', configItem.name);
|
data.setAttribute('name', configItem.name);
|
||||||
|
if (configItem.readOnly) data.setAttribute('disabled',true);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
let moreicons=['icon-more','icon-less'];
|
let moreicons=['icon-more','icon-less'];
|
||||||
|
@ -1048,8 +1063,17 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
||||||
});
|
});
|
||||||
if (!found) showItem=false;
|
if (!found) showItem=false;
|
||||||
}
|
}
|
||||||
|
let readOnly=false;
|
||||||
|
let mode=capabilities['CFGMODE'+item.name];
|
||||||
|
if (mode == 1) {
|
||||||
|
//hide
|
||||||
|
showItem=false;
|
||||||
|
}
|
||||||
|
if (mode == 2){
|
||||||
|
readOnly=true;
|
||||||
|
}
|
||||||
if (showItem) {
|
if (showItem) {
|
||||||
|
item.readOnly=readOnly;
|
||||||
currentCategoryPopulated=true;
|
currentCategoryPopulated=true;
|
||||||
let row = addEl('div', 'row', categoryEl);
|
let row = addEl('div', 'row', categoryEl);
|
||||||
let label = item.label || item.name;
|
let label = item.label || item.name;
|
||||||
|
@ -1058,7 +1082,7 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
||||||
let valueEl = createInput(item, valueFrame);
|
let valueEl = createInput(item, valueFrame);
|
||||||
if (!valueEl) return;
|
if (!valueEl) return;
|
||||||
valueEl.setAttribute('data-default', item.default);
|
valueEl.setAttribute('data-default', item.default);
|
||||||
valueEl.addEventListener('change', function (ev) {
|
if (! readOnly) valueEl.addEventListener('change', function (ev) {
|
||||||
let el = ev.target;
|
let el = ev.target;
|
||||||
checkChange(el, row, item.name);
|
checkChange(el, row, item.name);
|
||||||
})
|
})
|
||||||
|
@ -1075,6 +1099,7 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
||||||
}
|
}
|
||||||
if (item.check) valueEl.setAttribute('data-check', item.check);
|
if (item.check) valueEl.setAttribute('data-check', item.check);
|
||||||
let btContainer = addEl('div', 'buttonContainer', row);
|
let btContainer = addEl('div', 'buttonContainer', row);
|
||||||
|
if (!readOnly) {
|
||||||
let bt = addEl('button', 'defaultButton', btContainer, 'X');
|
let bt = addEl('button', 'defaultButton', btContainer, 'X');
|
||||||
bt.setAttribute('data-default', item.default);
|
bt.setAttribute('data-default', item.default);
|
||||||
bt.addEventListener('click', function (ev) {
|
bt.addEventListener('click', function (ev) {
|
||||||
|
@ -1082,6 +1107,7 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
||||||
let changeEvent = new Event('change');
|
let changeEvent = new Event('change');
|
||||||
valueEl.dispatchEvent(changeEvent);
|
valueEl.dispatchEvent(changeEvent);
|
||||||
})
|
})
|
||||||
|
}
|
||||||
bt = addEl('button', 'infoButton', btContainer, '?');
|
bt = addEl('button', 'infoButton', btContainer, '?');
|
||||||
bt.addEventListener('click', function (ev) {
|
bt.addEventListener('click', function (ev) {
|
||||||
if (item.description) {
|
if (item.description) {
|
||||||
|
|
Loading…
Reference in New Issue