You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// TODO: Add Advanced parameters modale on each cmd
*/functionprintEqLogic(_eqLogic){// Initialize the counter of the next root level command to be addedvarn_cmd=1;// Is the JSON view is activevaris_json_view=$('.eqLogicAction[data-action=jsonView].active').length!=0;// JSON view button is activeif(is_json_view){// Compute the ordering string of each commands// On JSON view, we completely rebuild the command tablevarnew_cmds=newArray();/** * Add a command to the JSON commands tree * @return tree_id of the added cmd */functionaddCmd(c,parent_id=''){if(parent_id!==''){c.tree_parent_id=parent_id;varm_cmd=0;//we need to find existing childrens of this parent//and find higher existing numbernew_cmds.forEach(function(c){if(c.tree_parent_id===parent_id){varid_number=parseInt(c.tree_id.substring(parent_id.length+1));// keep only end part of id and parse itif(id_number>m_cmd)m_cmd=id_number;}});c.tree_id=parent_id+'.'+(m_cmd+1).toString();}else{c.tree_id=(n_cmd++).toString();}new_cmds.push(c);returnc.tree_id;}/** * Check if the given command is in the given array * @return found command or undefined */functioninArray(cmds,cmd){returncmds.find(function(c){returnc==cmd});}/** * Check if the given topic+jsonPath is in the given array * @return found command or undefined */functionexistingCmd(cmds,topic,jsonPath){// try to find cmd that match with topic and jsonPath (or jsonPath with dollar sign in front)varexist_cmds=cmds.filter(function(c){returnc.configuration.topic==topic&&(c.configuration.jsonPath==jsonPath||c.configuration.jsonPath=='$'+jsonPath);});if(exist_cmds.length>0)returnexist_cmds[0];elsereturnundefined;}/** * Add the given topic/jsonPath/payload to the command array. * If the command already exists, add the existing command. Otherwise create a no name command. * @return tree_id of the added payload */functionaddPayload(topic,jsonPath,payload,parent_id){varval=(typeofpayload==='object') ? JSON.stringify(payload) : payload;varc=existingCmd(_eqLogic.cmd,topic,jsonPath);//console.log('addPayload: topic=' + topic + ', jsonPath=' + jsonPath + ', payload=' + val + ', parent_id=' + parent_id + ', exist=' + (c == undefined ? false : true));if(c===undefined){returnaddCmd({configuration: {topic: topic,jsonPath: jsonPath},isHistorized: "0",isVisible: "1",type: 'info',subType: 'string',state: val},parent_id);}else{c.state=val;returnaddCmd(c,parent_id);}}/** * Add to the JSON command tree the given command identified by its topic, jsonPath and JSON payload * plus the commands deriving from the JSON payload */functionrecursiveAddJsonPayload(topic,jsonPath,payload,parent_id=''){//console.log('recursiveAddJsonPayload: topic=' + topic + ', jsonPath=' + jsonPath + ', payload=' + JSON.stringify(payload));varthis_id=addPayload(topic,jsonPath,payload,parent_id);for(iinpayload){varescapedi=i;if(escapedi.match(/[^\w-]/)){// Escape if a special character is foundescapedi='\''+escapedi.replace(/'/g,"\\'")+'\'';}if(typeofpayload[i]==='object'){recursiveAddJsonPayload(topic,jsonPath+'['+escapedi+']',payload[i],this_id);}else{addPayload(topic,jsonPath+'['+escapedi+']',payload[i],this_id);}}}/** * Add commands from their topic */functionrecursiveAddCmdFromTopic(topic,jsonPath){//console.log('recursiveAddCmdFromTopic: ' + topic + jsonPath);varparent_id='';// For commands deriving from a JSON payload (i.e. jsonPath is not undefined or empty),// start the addition from the father commandif(jsonPath){// Call recursively this method with the topic and no jsonPathrecursiveAddCmdFromTopic(topic,'');// We need to get the tree id of the father command to be able to add this command to tree in the next stepvarc=existingCmd(new_cmds,topic,'');if(c!==undefined)parent_id=c.tree_id;}// Add this command to the tree if not previously addedvarc=existingCmd(new_cmds,topic,jsonPath);if(c===undefined){c=existingCmd(_eqLogic.cmd,topic,jsonPath);if(c!==undefined){// Get the payload associated to the commandif(c.state==undefined){console.log('missed c',c.id);jeedom.cmd.execute({async: false,id: c.id,cache: 0,notify: false,success: function(result){c.state=result;}});}try{varparsed_json_value=JSON.parse(c.state);}catch(e){}// Add the command: in case of JSON payload, call recursiveAddJsonPayload to add// also the derived commandsif(typeofparsed_json_value==='object'){recursiveAddJsonPayload(c.configuration.topic,c.configuration.jsonPath,parsed_json_value,parent_id);}else{addCmd(c,parent_id);}}}}// Main loop on the existing command: objective is to add to the JSON command tree all the// existing commands plus the commands that can be created from JSON payloadsfor(varcof_eqLogic.cmd){if(!inArray(new_cmds,c)){if(c.type=='info'){//console.log('loop: add info ' + c.configuration.topic + c.configuration.jsonPath);recursiveAddCmdFromTopic(c.configuration.topic,c.configuration.jsonPath);}else{// Action commands are added directlyaddCmd(c);}}}_eqLogic.cmd=new_cmds;// JSON view: disable the sortable functionalityjmqtt.setCmdsSortable(false);}else{// CLASSIC view button is activefor(varcof_eqLogic.cmd){c.tree_id=(n_cmd++).toString();}// Classical view: enable the sortable functionalityjmqtt.setCmdsSortable(true);}// Show UI elements depending on the typeif((_eqLogic.configuration.type=='eqpt'&&(_eqLogic.configuration.eqLogic==undefined||_eqLogic.configuration.eqLogic<0))||(_eqLogic.configuration.type!='eqpt'&&_eqLogic.configuration.type!='broker')){// Unknow EQ / orphan$('.toDisable').addClass('disabled');$('.typ-brk').hide();$('.typ-std').hide();$('.typ-brk-select').show();$('.eqLogicAction[data-action=configure]').addClass('roundedLeft');// Udpate panel as if on an eqLogic$('.eqLogicAttr[data-l1key=configuration][data-l2key=type]').val('eqpt');jmqtt.updateEqptTabs(_eqLogic);}elseif(_eqLogic.configuration.type=='broker'){// jMQTT Broker$('.toDisable').removeClass('disabled');$('.typ-std').hide();$('.typ-brk').show();$('.eqLogicAction[data-action=configure]').addClass('roundedLeft');// Udpate panel on eqBrokerjmqtt.updateBrokerTabs(_eqLogic);}elseif(_eqLogic.configuration.type=='eqpt'){// jMQTT Eq$('.toDisable').removeClass('disabled');$('.typ-brk').hide();$('.typ-std').show();$('.eqLogicAction[data-action=configure]').removeClass('roundedLeft');// Udpate panel on eqLogicjmqtt.updateEqptTabs(_eqLogic);}}/** * saveEqLogic callback called by plugin.template before saving an eqLogic */functionsaveEqLogic(_eqLogic){if(_eqLogic.configuration.type!='broker'&&_eqLogic.configuration.type!='eqpt'){// not on an jMQTT eqLogic, to fix issue #153return_eqLogic;}// pass the log level when defined for a broker objectif(_eqLogic.configuration.type=='broker'){varlog_level=$('#div_broker_log').getValues('.configKey')[0];if(!$.isEmptyObject(log_level)){_eqLogic.loglevel=log_level;}}// remove non existing commands added for the JSON view and add new commands at the endfor(vari=_eqLogic.cmd.length-1;i>=0;i--){if((_eqLogic.cmd[i].id==""||_eqLogic.cmd[i].id===null)&&_eqLogic.cmd[i].name==""){_eqLogic.cmd.splice(i,1);}}// if this eqLogic is not a brokerif(_eqLogic.configuration.type!='broker'){// get hidden settings for Broker and remove them of eqLogic_eqLogic=jmqtt.substractKeys(_eqLogic,$('#brokertab').getValues('.eqLogicAttr')[0]);}return_eqLogic;}/** * addCmdToTable callback called by plugin.template: render eqLogic commands */functionaddCmdToTable(_cmd){constindent_size=16;constexpander_expanded_class='fas fa-minus';constexpander_collapsed_class='fas fa-plus';// Set _cmd and config if emptyif(!isset(_cmd))var_cmd={configuration: {}};if(!isset(_cmd.configuration))_cmd.configuration={};// Is the JSON view is activevaris_json_view=$('.eqLogicAction[data-action=jsonView].active').length!=0;if(!isset(_cmd.tree_id)){//looking for all tree-id, keep part before the first dot, convert to Intvarroot_tree_ids=$('[tree-id]').map((pos,e)=>parseInt(e.getAttribute("tree-id").split('.')[0]))//if some tree-id has been foundif(root_tree_ids.length>0){_cmd.tree_id=(Math.max.apply(null,root_tree_ids)+1).toString();//use the highest one plus one}else{_cmd.tree_id='1';// else this is the first one}}// TODO: Merge Action & Info cmd generation code and reuse it in templates// Fix disabled variable use (virtualAction never exists)// labels: quality, javascriptif(init(_cmd.type)=='info'){vardisabled=(init(_cmd.configuration.virtualAction)=='1') ? 'disabled' : '';vartr='<tr class="cmd" tree-id="'+_cmd.tree_id+'"';if(is_json_view){if(_cmd.tree_parent_id!==undefined){tr+=' tree-parent-id="'+_cmd.tree_parent_id+'"';}}tr+=' data-cmd_id="'+init(_cmd.id)+'" style="display: none;">';// SPEED Improvement : Create TR hiden then show it at the end after setValues, etc.tr+='<td class="fitwidth">';// Add Indent blockif(is_json_view){vartree_level=(_cmd.tree_id.match(/\./g)||[]).lengthtr+='<span class="tree-indent" style="display:inline-block; width: '+(tree_level*indent_size).toString()+'px;"></span>';tr+='<span class="tree-expander" style="display:inline-block; width: '+(indent_size).toString()+'px;"></span>';// TRICK: For the JSON view include the "order" value in a hidden element// so that the original/natural order is kept when savingtr+='<span style="display:none;" class="cmdAttr" data-l1key="order"></span>';}tr+='<span class="cmdAttr" data-l1key="id"></span>';tr+='</td>';tr+='<td>';tr+='<div class="input-group">';tr+='<input class="cmdAttr form-control input-sm roundedLeft" data-l1key="name" placeholder="{{Nom de la commande}}">';tr+='<span class="input-group-btn">';tr+='<a class="cmdAction btn btn-sm btn-default" data-l1key="chooseIcon" title="{{Choisir une icône}}"><i class="fas fa-icons"></i></a>';tr+='</span>';tr+='<span class="cmdAttr input-group-addon roundedRight" data-l1key="display" data-l2key="icon" style="font-size:19px;padding:0 5px 0 0!important;"></span>';tr+='</div>';tr+='</td>';tr+='<td>';tr+='<input class="cmdAttr form-control type input-sm" data-l1key="type" value="info" disabled style="margin-bottom:5px;width:120px;" />';tr+='<span class="cmdAttr subType" subType="'+init(_cmd.subType)+'"></span>';tr+='</td><td>';tr+='<input class="cmdAttr form-control input-sm" data-l1key="configuration" data-l2key="topic" placeholder="{{Topic}}" style="margin-bottom:5px;" '+disabled+'>';tr+='<input class="cmdAttr form-control input-sm col-lg-11 col-md-10 col-sm-10 col-xs-10" style="float: right;" data-l1key="configuration" data-l2key="jsonPath" placeholder="{{Chemin JSON}}" '+disabled+'>';tr+='</td><td>';tr+='<textarea class="form-control input-sm" data-key="value" style="min-height:62px;" '+disabled+' placeholder="{{Valeur}}" readonly=true></textarea>';tr+='</td><td>';tr+='<input class="tooltips cmdAttr form-control input-sm" data-l1key="configuration" data-l2key="minValue" placeholder="{{Min}}" title="{{Min}}" style="width:60px;display:inline-block;">';tr+='<input class="tooltips cmdAttr form-control input-sm" data-l1key="configuration" data-l2key="maxValue" placeholder="{{Max}}" title="{{Max}}" style="width:60px;display:inline-block;">';tr+='<input class="cmdAttr form-control input-sm" data-l1key="unite" placeholder="Unité" title="{{Unité}}" style="width:60px;display:inline-block;">';tr+='</td><td>';tr+='<span><label class="checkbox-inline"><input type="checkbox" class="cmdAttr checkbox-inline" data-l1key="isHistorized" checked/>{{Historiser}}</label></span><br/> ';tr+='<span><label class="checkbox-inline"><input type="checkbox" class="cmdAttr checkbox-inline" data-l1key="isVisible" checked/>{{Afficher}}</label></span><br/> ';tr+='<span><label class="checkbox-inline"><input type="checkbox" class="cmdAttr checkbox-inline" data-l1key="display" data-l2key="invertBinary"/>{{Inverser}}</label></span><br/> ';tr+='</td><td align="right">';// TODO: Add Advanced parameters modale on each cmd// The modale should include autoPub, Qos, related discovery config, etc// labels: enhancement, javascript// tr += '<a class="btn btn-default btn-xs cmdAction tooltips" data-action="advanced" title="{{Paramètres avancés}}"><i class="fas fa-wrench"></i></a> ';if(is_numeric(_cmd.id)){tr+='<a class="btn btn-default btn-xs cmdAction tooltips" data-action="configure" title="{{Configurer}}"><i class="fas fa-cogs"></i></a> ';tr+='<a class="btn btn-default btn-xs cmdAction tooltips" data-action="test" title="{{Tester}}"><i class="fas fa-rss"></i></a> ';}tr+='<i class="fas fa-minus-circle pull-right cmdAction cursor" data-action="remove"></i>';tr+='</td></tr>';$('#table_cmd tbody').append(tr);// Update mismatch status of this cmd on change and input$('#table_cmd [tree-id="'+_cmd.tree_id+'"] .cmdAttr[data-l1key=configuration][data-l2key=topic]').on('change input',function(e){if(jmqtt.checkTopicMatch(jmqtt_globals.mainTopic,$(this).value()))$(this).removeClass('topicMismatch');else$(this).addClass('topicMismatch');});// Set cmdAttr values of cmd from json _cmd$('#table_cmd [tree-id="'+_cmd.tree_id+'"]').setValues(_cmd,'.cmdAttr');if(isset(_cmd.type))$('#table_cmd [tree-id="'+_cmd.tree_id+'"] .cmdAttr[data-l1key=type]').value(init(_cmd.type));jeedom.cmd.changeType($('#table_cmd [tree-id="'+_cmd.tree_id+'"]'),init(_cmd.subType));// Fill in value of current cmd. Efficient in JSON view only as _cmd.state was set in JSON view only in printEqLogic.if(is_json_view){$('#table_cmd [tree-id="'+_cmd.tree_id+'"] .form-control[data-key=value]').value(_cmd.state);}// Get and display the value in CLASSIC view (for JSON view, see few lines above)if(_cmd.id!=undefined){if(!is_json_view){if(_cmd.state!=undefined){$('#table_cmd [tree-id="'+_cmd.tree_id+'"][data-cmd_id="'+_cmd.id+'"] .form-control[data-key=value]').value(_cmd.state);}else{jeedom.cmd.execute({id: _cmd.id,cache: 0,notify: false,success: function(result){$('#table_cmd [tree-id="'+_cmd.tree_id+'"][data-cmd_id="'+_cmd.id+'"] .form-control[data-key=value]').value(result);}});}}// Set the update value callbackjeedom.cmd.addUpdateFunction(_cmd.id,function(_options){$('#table_cmd [tree-id="'+_cmd.tree_id+'"][data-cmd_id="'+_cmd.id+'"] .form-control[data-key=value]').addClass('modifiedVal').value(_options.display_value);setTimeout(function(){$('#table_cmd [tree-id="'+_cmd.tree_id+'"][data-cmd_id="'+_cmd.id+'"] .form-control[data-key=value]').removeClass('modifiedVal');},1500);});}$('#table_cmd [tree-id="'+_cmd.tree_id+'"]').show();// SPEED Improvement : Create TR hiden then show it at the end after setValues, etc.}if(init(_cmd.type)=='action'){vardisabled='';vartr='<tr class="cmd" tree-id="'+_cmd.tree_id+'" data-cmd_id="'+init(_cmd.id)+'" style="display: none;">';// SPEED Improvement : Create TR hiden then show it at the end after setValues, etc.tr+='<td class="fitwidth">';tr+='<span class="cmdAttr" data-l1key="id"></span>';tr+='</td>';tr+='<td>';tr+='<div class="input-group">';tr+='<input class="cmdAttr form-control input-sm roundedLeft" data-l1key="name" placeholder="{{Nom de la commande}}">';tr+='<span class="input-group-btn">';tr+='<a class="cmdAction btn btn-sm btn-default" data-l1key="chooseIcon" title="{{Choisir une icône}}"><i class="fas fa-icons"></i></a>';tr+='</span>';tr+='<span class="cmdAttr input-group-addon roundedRight" data-l1key="display" data-l2key="icon" style="font-size:19px;padding:0 5px 0 0!important;"></span>';tr+='</div>';tr+='<select class="cmdAttr form-control input-sm" data-l1key="value" style="display:none;margin-top:5px;" title="{{Commande information liée}}">';tr+='<option value="">{{Aucune}}</option>';tr+='</select>';tr+='</td>';tr+='<td>';tr+='<input class="cmdAttr form-control type input-sm" data-l1key="type" value="action" disabled style="margin-bottom:5px;width:120px;" />';tr+='<span class="cmdAttr subType" subType="'+init(_cmd.subType)+'" style=""></span>';tr+='</td>';tr+='<td>';tr+='<textarea class="cmdAttr form-control input-sm" data-l1key="configuration" data-l2key="topic" style="min-height:62px;margin-top:14px;"'+disabled+' placeholder="{{Topic}}"></textarea><br/>';tr+='</td><td>';tr+='<div class="input-group">';tr+='<textarea class="cmdAttr form-control input-sm roundedLeft" data-l1key="configuration" data-l2key="request" '+disabled+' style="min-height:62px;height:62px;" placeholder="Valeur"></textarea>';tr+='<a class="btn btn-sm btn-default listEquipementInfo input-group-addon roundedRight" title="{{Rechercher un équipement}}" data-input="request"><i class="fas fa-list-alt "></i></a>';tr+='</div>';tr+='</td><td>';tr+='<input class="tooltips cmdAttr form-control input-sm" data-l1key="configuration" data-l2key="minValue" placeholder="{{Min}}" title="{{Min}}" style="width:60px;display:inline-block;">';tr+='<input class="tooltips cmdAttr form-control input-sm" data-l1key="configuration" data-l2key="maxValue" placeholder="{{Max}}" title="{{Max}}" style="width:60px;display:inline-block;">';tr+='<input class="tooltips cmdAttr form-control input-sm" data-l1key="configuration" data-l2key="listValue" placeholder="{{Liste : valeur|texte}}" title="{{Liste : valeur|texte (séparées entre elles par des points-virgules)}}">';tr+='</td><td>';tr+='<span><label class="checkbox-inline"><input type="checkbox" class="cmdAttr checkbox-inline" data-l1key="isVisible" checked/>{{Afficher}}</label></span><br/> ';tr+='<span><label class="checkbox-inline"><input type="checkbox" class="cmdAttr checkbox-inline" data-l1key="configuration" data-l2key="retain"/>{{Retain}}</label></span><br/> ';tr+='<span><label class="checkbox-inline"><input type="checkbox" class="cmdAttr checkbox-inline" data-l1key="configuration" data-l2key="autoPub"/>{{Pub. auto}} ';tr+='<sup><i class="fas fa-question-circle tooltips" title="'+"{{Publication automatique en MQTT lors d'un changement <br/>(A utiliser avec au moins une commande info dans Valeur).}}"+'"></i></sup></label></span><br/> ';tr+='<span class="checkbox-inline">{{Qos}}: <input class="tooltips cmdAttr form-control input-sm" data-l1key="configuration" data-l2key="Qos" placeholder="{{Qos}}" title="{{Qos}}" style="width:50px;display:inline-block;"></span> ';tr+='</td>';tr+='<td align="right">';// tr += '<a class="btn btn-default btn-xs cmdAction tooltips" data-action="advanced" title="{{Paramètres avancés}}"><i class="fas fa-wrench"></i></a> ';if(is_numeric(_cmd.id)){tr+='<a class="btn btn-default btn-xs cmdAction tooltips" data-action="configure" title="{{Configurer}}"><i class="fas fa-cogs"></i></a> ';tr+='<a class="btn btn-default btn-xs cmdAction tooltips" data-action="test" title="{{Tester}}"><i class="fas fa-rss"></i></a> ';}tr+='<i class="fas fa-minus-circle pull-right cmdAction cursor" data-action="remove"></i>';tr+='</td></tr>';$('#table_cmd tbody').append(tr);// Update mismatch status of this cmd on change and input$('#table_cmd [tree-id="'+_cmd.tree_id+'"] .cmdAttr[data-l1key=configuration][data-l2key=topic]').on('change input',function(e){lettopic=$(this).value();if(topic==''||topic.includes('#')||topic.includes('?'))$(this).addClass('topicMismatch');else$(this).removeClass('topicMismatch');});// $('#table_cmd [tree-id="' + _cmd.tree_id + '"]').setValues(_cmd, '.cmdAttr');vartr=$('#table_cmd [tree-id="'+_cmd.tree_id+'"]');jeedom.eqLogic.buildSelectCmd({id: jmqtt.getEqId(),filter: {type: 'info'},error: function(error){$.fn.showAlert({message: error.message,level: 'danger'});},success: function(result){tr.find('.cmdAttr[data-l1key=value]').append(result);tr.setValues(_cmd,'.cmdAttr');jeedom.cmd.changeType(tr,init(_cmd.subType));}});$('#table_cmd [tree-id="'+_cmd.tree_id+'"]').show();// SPEED Improvement : Create TR hiden then show it at the end after setValues, etc.}if(is_json_view){// add event on expander click$('#table_cmd [tree-id="'+_cmd.tree_id+'"] .tree-expander').click(function(){var$this=$(this);// "this" but in jQueryvartree_id=this.parentNode.parentNode.getAttribute('tree-id');// find tree-id in TR (2 DOM level up)if($this.hasClass(expander_expanded_class)){// if expanded$this.removeClass(expander_expanded_class).addClass(expander_collapsed_class);$('#table_cmd [tree-parent-id^="'+tree_id+'"]').hide();// hide all childs and sub-childs}elseif($this.hasClass(expander_collapsed_class)){// if collapsed$this.removeClass(expander_collapsed_class).addClass(expander_expanded_class);/** * Display childs if their own parent are expanded */functionrecursiveDisplayChilds(tree_parent_id){// if parent is expandedif($('#table_cmd [tree-id="'+tree_parent_id+'"] .tree-expander').hasClass(expander_expanded_class)){// for each direct child$('#table_cmd [tree-parent-id="'+tree_parent_id+'"]').each(function(){// show$(this).show();// process child of itrecursiveDisplayChilds(this.getAttribute('tree-id'));});}}recursiveDisplayChilds(tree_id);}});//if there is a parent_id, we need to enable his expanderif(_cmd.tree_parent_id!==undefined){$('#table_cmd [tree-id="'+_cmd.tree_parent_id+'"] .tree-expander').addClass(expander_expanded_class);}}}// TODO: Review events that should be sent to front-end// Change visual on dashboard on new events?// Replace/remove `jMQTT::EventState`?// Use `jMQTT::brkEvent`? `jMQTT::eqptEvent`? `jMQTT::cmdEvent`?// labels: enhancement, javascript/*$('body').off('jMQTT::brkEvent').on('jMQTT::brkEvent', function (_event,_options) { var msg = `{{La commande <b>${_options.name}</b> vient d'être ${_options.action}.}}`; console.log(msg, _options);});$('body').off('jMQTT::eqptEvent').on('jMQTT::eqptEvent', function (_event,_options) { var msg = `{{La commande <b>${_options.name}</b> vient d'être ${_options.action}.}}`; console.log(msg, _options);});$('body').off('jMQTT::cmdEvent').on('jMQTT::cmdEvent', function (_event,_options) { var msg = `{{La commande <b>${_options.name}</b> vient d'être ${_options.action}.}}`; console.log(msg, _options);});*/
The text was updated successfully, but these errors were encountered:
The modale should include autoPub, Qos, related discovery config, etc
tr += '<a class="btn btn-default btn-xs cmdAction tooltips" data-action="advanced" title="{{Paramètres avancés}}"><i class="fas fa-wrench"></i></a> ';
var tree_id = this.parentNode.parentNode.getAttribute('tree-id'); // find tree-id in TR (2 DOM level up)
} else if ($this.hasClass(expander_collapsed_class)) { // if collapsed
jMQTT/desktop/js/jMQTT.js
Line 897 in 68f8470
The text was updated successfully, but these errors were encountered: