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' %}
|
{% extends 'mesh/base.html' %}
|
||||||
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block heading %}
|
{% block heading %}
|
||||||
|
@ -14,11 +15,28 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block subcontent %}
|
{% block subcontent %}
|
||||||
|
<style>
|
||||||
|
#id_recipients {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<form method="POST" style="max-width:400px;">
|
<form method="POST" style="max-width:400px;">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form.as_div }}
|
{{ form.as_div }}
|
||||||
{{ form.conditionals | json_script:"form-conditionals" }}
|
{{ form.conditionals | json_script:"form-conditionals" }}
|
||||||
<noscript><input type="hidden" name="noscript" value="1"></noscript>
|
<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>
|
<script>
|
||||||
var form_conditionals = JSON.parse(document.getElementById('form-conditionals').innerHTML)
|
var form_conditionals = JSON.parse(document.getElementById('form-conditionals').innerHTML)
|
||||||
function update_form() {
|
function update_form() {
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
{% extends 'mesh/base.html' %}
|
{% extends 'mesh/base.html' %}
|
||||||
|
{% load static %}
|
||||||
{% load i18n mesh_node %}
|
{% load i18n mesh_node %}
|
||||||
|
|
||||||
{% block heading %}{% trans 'Mesh messages' %}{% endblock %}
|
{% block heading %}{% trans 'Mesh messages' %}{% endblock %}
|
||||||
|
|
||||||
{% block subcontent %}
|
{% 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 class="columns">
|
||||||
<div>
|
<div>
|
||||||
<h4>Send messages</h4>
|
<h4>Send messages</h4>
|
||||||
|
@ -25,11 +35,15 @@
|
||||||
</div>
|
</div>
|
||||||
<form>
|
<form>
|
||||||
<h4>Filter</h4>
|
<h4>Filter</h4>
|
||||||
<div class="fields">
|
<div class="fields mesh-message-filter">
|
||||||
<div class="field">
|
<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 }}
|
{{ form.message_types }}
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<input type="text" placeholder="search" class="mesh-message-search" id="mesh-message-node-search"
|
||||||
|
aria-label="search nodes"/>
|
||||||
{{ form.src_nodes }}
|
{{ form.src_nodes }}
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
@ -37,6 +51,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</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' %}
|
{% include 'control/fragment_pagination.html' %}
|
||||||
|
|
||||||
|
@ -68,25 +91,28 @@
|
||||||
<strong>Minor:</strong> {{ msg.parsed.content.minor }}
|
<strong>Minor:</strong> {{ msg.parsed.content.minor }}
|
||||||
|
|
||||||
{% elif msg.message_type == "CONFIG_HARDWARE" %}
|
{% 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" %}
|
{% elif msg.message_type == "CONFIG_BOARD" %}
|
||||||
<strong>Board:</strong> {{ msg.parsed.content.board_config.board.pretty_name }}
|
<strong>Board:</strong> {{ msg.parsed.content.board_config.board.pretty_name }}
|
||||||
|
|
||||||
{% if msg.parsed.content.led %}
|
{% if msg.parsed.content.led %}
|
||||||
<br>
|
<br>
|
||||||
<strong>Status LED:</strong> {{ msg.parsed.content.led }}
|
<strong>Status LED:</strong> {{ msg.parsed.content.led }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if msg.parsed.content.uwb %}
|
{% if msg.parsed.content.uwb %}
|
||||||
<br>
|
<br>
|
||||||
<strong>UWB:</strong> {{ msg.parsed.content.led }}
|
<strong>UWB:</strong> {{ msg.parsed.content.led }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% elif msg.message_type == "CONFIG_FIRMWARE" %}
|
{% 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>
|
<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>
|
<br>
|
||||||
<strong>SHA256:</strong> <small>{{ msg.parsed.content.app_desc.app_elf_sha256 }}</small>
|
<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 }}
|
<strong>LED config:</strong> {{ msg.parsed.led_config }}
|
||||||
|
|
||||||
{% elif msg.message_type == "CONFIG_POSITION" %}
|
{% 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" %}
|
{% elif msg.message_type == "MESH_ADD_DESTINATIONS" or msg.message_type == "MESH_REMOVE_DESTINATIONS" %}
|
||||||
<strong>adresses:</strong><br>
|
<strong>adresses:</strong><br>
|
||||||
|
@ -171,9 +198,9 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
{% for key, value in msg.data.items %}
|
{% for key, value in msg.data.items %}
|
||||||
{% if key != "src" and key != "dst" and key != "msg_type" %}
|
{% if key != "src" and key != "dst" and key != "msg_type" %}
|
||||||
<div class="mesh-msg-data mesh-msg-type-{{ key }}">
|
<div class="mesh-msg-data mesh-msg-type-{{ key }}">
|
||||||
<strong>{{ key }}</strong>: {{ value }}
|
<strong>{{ key }}</strong>: {{ value }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue