filtering mesh message types and nodes
This commit is contained in:
parent
78fe28b3ec
commit
82d1f48685
3 changed files with 95 additions and 12 deletions
38
src/c3nav/mesh/static/mesh/js/searchable-select.js
Normal file
38
src/c3nav/mesh/static/mesh/js/searchable-select.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
(function () {
|
||||
function filterOption(option, value) {
|
||||
if (value === '' || option.text.toLowerCase().includes(value)) {
|
||||
option.style.display = '';
|
||||
return true;
|
||||
} else {
|
||||
option.style.display = 'none';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function performSearch(select, value) {
|
||||
value = value.toLowerCase().trim();
|
||||
for (const child of select.children) {
|
||||
if (child.nodeName === 'OPTGROUP') {
|
||||
let any_visible = false;
|
||||
for (const option of child.children) {
|
||||
if (option.nodeName !== 'OPTION') continue;
|
||||
any_visible |= filterOption(option, value);
|
||||
}
|
||||
if (!any_visible) {
|
||||
child.style.display = 'none';
|
||||
} else {
|
||||
child.style.display = '';
|
||||
}
|
||||
} else if (child.nodeName === 'OPTION') {
|
||||
filterOption(child, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function SearchableSelect(select, search) {
|
||||
search.addEventListener('input', e => performSearch(select, search.value));
|
||||
performSearch(select, search.value);
|
||||
}
|
||||
|
||||
window.SearchableSelect = SearchableSelect;
|
||||
})();
|
|
@ -1,4 +1,5 @@
|
|||
{% extends 'mesh/base.html' %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block heading %}
|
||||
|
@ -14,11 +15,28 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block subcontent %}
|
||||
<style>
|
||||
#id_recipients {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<form method="POST" style="max-width:400px;">
|
||||
{% csrf_token %}
|
||||
{{ form.as_div }}
|
||||
{{ form.conditionals | json_script:"form-conditionals" }}
|
||||
<noscript><input type="hidden" name="noscript" value="1"></noscript>
|
||||
|
||||
<script type="text/javascript" src="{% static 'mesh/js/searchable-select.js' %}"></script>
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
const select = document.getElementById('id_recipients');
|
||||
const searchInput = document.createElement('input');
|
||||
searchInput.type = 'text';
|
||||
select.parentElement.insertBefore(searchInput, select);
|
||||
SearchableSelect(select, searchInput);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var form_conditionals = JSON.parse(document.getElementById('form-conditionals').innerHTML)
|
||||
function update_form() {
|
||||
|
|
|
@ -1,9 +1,19 @@
|
|||
{% extends 'mesh/base.html' %}
|
||||
{% load static %}
|
||||
{% load i18n mesh_node %}
|
||||
|
||||
{% block heading %}{% trans 'Mesh messages' %}{% endblock %}
|
||||
|
||||
{% block subcontent %}
|
||||
<style>
|
||||
.mesh-message-filter .field > select[multiple] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mesh-message-filter .field > input.mesh-message-search {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
</style>
|
||||
<div class="columns">
|
||||
<div>
|
||||
<h4>Send messages</h4>
|
||||
|
@ -25,11 +35,15 @@
|
|||
</div>
|
||||
<form>
|
||||
<h4>Filter</h4>
|
||||
<div class="fields">
|
||||
<div class="fields mesh-message-filter">
|
||||
<div class="field">
|
||||
<input type="text" placeholder="search" class="mesh-message-search" id="mesh-message-type-search"
|
||||
aria-label="search message types"/>
|
||||
{{ form.message_types }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="text" placeholder="search" class="mesh-message-search" id="mesh-message-node-search"
|
||||
aria-label="search nodes"/>
|
||||
{{ form.src_nodes }}
|
||||
</div>
|
||||
<div class="field">
|
||||
|
@ -37,6 +51,15 @@
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript" src="{% static 'mesh/js/searchable-select.js' %}"></script>
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
const typeSearch = document.getElementById('mesh-message-type-search');
|
||||
const nodeSearch = document.getElementById('mesh-message-node-search');
|
||||
SearchableSelect(typeSearch.nextElementSibling, typeSearch);
|
||||
SearchableSelect(nodeSearch.nextElementSibling, nodeSearch);
|
||||
})();
|
||||
</script>
|
||||
|
||||
{% include 'control/fragment_pagination.html' %}
|
||||
|
||||
|
@ -68,25 +91,28 @@
|
|||
<strong>Minor:</strong> {{ msg.parsed.content.minor }}
|
||||
|
||||
{% elif msg.message_type == "CONFIG_HARDWARE" %}
|
||||
<strong>Chip:</strong> {{ msg.parsed.content.chip.pretty_name }} rev{{ msg.parsed.content.revision_major }}.{{ msg.parsed.content.revision_minor }}
|
||||
<strong>Chip:</strong> {{ msg.parsed.content.chip.pretty_name }} rev
|
||||
{{ msg.parsed.content.revision_major }}.{{ msg.parsed.content.revision_minor }}
|
||||
|
||||
{% elif msg.message_type == "CONFIG_BOARD" %}
|
||||
<strong>Board:</strong> {{ msg.parsed.content.board_config.board.pretty_name }}
|
||||
|
||||
{% if msg.parsed.content.led %}
|
||||
<br>
|
||||
<strong>Status LED:</strong> {{ msg.parsed.content.led }}
|
||||
<br>
|
||||
<strong>Status LED:</strong> {{ msg.parsed.content.led }}
|
||||
{% endif %}
|
||||
|
||||
{% if msg.parsed.content.uwb %}
|
||||
<br>
|
||||
<strong>UWB:</strong> {{ msg.parsed.content.led }}
|
||||
<br>
|
||||
<strong>UWB:</strong> {{ msg.parsed.content.led }}
|
||||
{% endif %}
|
||||
|
||||
{% elif msg.message_type == "CONFIG_FIRMWARE" %}
|
||||
<strong>Firmware:</strong> {{ msg.parsed.content.app_desc.project_name }} {{ msg.parsed.content.app_desc.version }} (IDF {{ msg.parsed.content.app_desc.idf_version }})
|
||||
<strong>Firmware:</strong> {{ msg.parsed.content.app_desc.project_name }}
|
||||
{{ msg.parsed.content.app_desc.version }} (IDF {{ msg.parsed.content.app_desc.idf_version }})
|
||||
<br>
|
||||
<strong>Compile Date:</strong> {{ msg.parsed.content.app_desc.compile_date }} {{ msg.parsed.content.app_desc.compile_time }}
|
||||
<strong>Compile Date:</strong> {{ msg.parsed.content.app_desc.compile_date }}
|
||||
{{ msg.parsed.content.app_desc.compile_time }}
|
||||
<br>
|
||||
<strong>SHA256:</strong> <small>{{ msg.parsed.content.app_desc.app_elf_sha256 }}</small>
|
||||
|
||||
|
@ -103,7 +129,8 @@
|
|||
<strong>LED config:</strong> {{ msg.parsed.led_config }}
|
||||
|
||||
{% elif msg.message_type == "CONFIG_POSITION" %}
|
||||
<strong>X=</strong>{{ msg.parsed.content.x_pos }}, <strong>Y=</strong>{{ msg.parsed.content.y_pos }}, <strong>Z=</strong>{{ msg.parsed.content.z_pos }}
|
||||
<strong>X=</strong>{{ msg.parsed.content.x_pos }}, <strong>Y=</strong>
|
||||
{{ msg.parsed.content.y_pos }}, <strong>Z=</strong>{{ msg.parsed.content.z_pos }}
|
||||
|
||||
{% elif msg.message_type == "MESH_ADD_DESTINATIONS" or msg.message_type == "MESH_REMOVE_DESTINATIONS" %}
|
||||
<strong>adresses:</strong><br>
|
||||
|
@ -171,9 +198,9 @@
|
|||
{% else %}
|
||||
{% for key, value in msg.data.items %}
|
||||
{% if key != "src" and key != "dst" and key != "msg_type" %}
|
||||
<div class="mesh-msg-data mesh-msg-type-{{ key }}">
|
||||
<strong>{{ key }}</strong>: {{ value }}
|
||||
</div>
|
||||
<div class="mesh-msg-data mesh-msg-type-{{ key }}">
|
||||
<strong>{{ key }}</strong>: {{ value }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue