mirror of
https://github.com/xoseperez/espurna.git
synced 2026-03-10 10:17:05 +01:00
170 lines
4.1 KiB
JavaScript
170 lines
4.1 KiB
JavaScript
import { addFromTemplate, addFromTemplateWithSchema } from './template.mjs';
|
|
import { groupSettingsOnAddElem, variableListeners } from './settings.mjs';
|
|
import { sendAction } from './connection.mjs';
|
|
|
|
/**
|
|
* @typedef {Map<number, string>} FiltersMap
|
|
*/
|
|
|
|
/** @type {FiltersMap} */
|
|
const Filters = new Map();
|
|
|
|
/** @param {function(HTMLTableElement): void} callback */
|
|
function withTable(callback) {
|
|
callback(/** @type {!HTMLTableElement} */
|
|
(document.getElementById("rfm69-messages")));
|
|
}
|
|
|
|
/** @param {function(HTMLTableSectionElement): void} callback */
|
|
function withMessages(callback) {
|
|
withTable((elem) => {
|
|
callback(elem.tBodies[0]);
|
|
});
|
|
}
|
|
|
|
/** @param {[number, number, number, string, string, number, number, number]} message */
|
|
function addMessage(message) {
|
|
withTable((elem) => {
|
|
const timestamp = (new Date())
|
|
.toLocaleTimeString("en-US", {hour12: false});
|
|
|
|
const row = elem.tBodies[0].insertRow();
|
|
for (let value of [timestamp, ...message]) {
|
|
const cell = row.insertCell();
|
|
cell.appendChild(
|
|
document.createTextNode(value.toString()));
|
|
filterRow(Filters, row);
|
|
}
|
|
});
|
|
}
|
|
|
|
/** @param {function(HTMLElement): void} callback */
|
|
function withMapping(callback) {
|
|
callback(/** @type {!HTMLElement} */
|
|
(document.getElementById("rfm69-mapping")));
|
|
}
|
|
|
|
/** @param {HTMLElement} elem */
|
|
function addMappingNode(elem) {
|
|
addFromTemplate(elem, "rfm69-node", {});
|
|
}
|
|
|
|
/** @param {any} value */
|
|
function onMapping(value) {
|
|
withMapping((elem) => {
|
|
addFromTemplateWithSchema(
|
|
elem, "rfm69-node",
|
|
value.mapping, value.schema,
|
|
value.max ?? 0);
|
|
});
|
|
}
|
|
|
|
function clearCounters() {
|
|
sendAction("rfm69Clear");
|
|
return false;
|
|
}
|
|
|
|
function clearMessages() {
|
|
withMessages((elem) => {
|
|
while (elem.rows.length) {
|
|
elem.deleteRow(0);
|
|
}
|
|
});
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param {FiltersMap} filters
|
|
* @param {HTMLTableRowElement} row
|
|
*/
|
|
function filterRow(filters, row) {
|
|
row.style.display = "table-row";
|
|
for (const [cell, filter] of filters) {
|
|
if (row.cells[cell].textContent !== filter) {
|
|
row.style.display = "none";
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {FiltersMap} filters
|
|
* @param {HTMLTableRowElement[]} rows
|
|
*/
|
|
function filterRows(filters, rows) {
|
|
for (let row of rows) {
|
|
filterRow(filters, row);
|
|
}
|
|
}
|
|
|
|
/** @param {Event} event */
|
|
function filterEvent(event) {
|
|
if (!(event.target instanceof HTMLTableCellElement)) {
|
|
return;
|
|
}
|
|
|
|
if (!event.target.textContent) {
|
|
return;
|
|
}
|
|
|
|
const index = event.target.cellIndex;
|
|
if (event.target.classList.contains("filtered")) {
|
|
Filters.delete(index);
|
|
} else {
|
|
Filters.set(index, event.target.textContent);
|
|
}
|
|
|
|
event.target.classList.toggle("filtered");
|
|
withMessages((elem) => {
|
|
filterRows(Filters, Array.from(elem.rows));
|
|
});
|
|
}
|
|
|
|
function clearFilters() {
|
|
withMessages((elem) => {
|
|
for (let filtered of elem.querySelectorAll("filtered")) {
|
|
filtered.classList.remove("filtered");
|
|
}
|
|
|
|
Filters.clear();
|
|
filterRows(Filters, Array.from(elem.rows));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @returns {import('./settings.mjs').KeyValueListeners}
|
|
*/
|
|
function listeners() {
|
|
return {
|
|
"rfm69": (_, value) => {
|
|
if (value.message !== undefined) {
|
|
addMessage(value.message);
|
|
}
|
|
|
|
if (value.mapping !== undefined) {
|
|
onMapping(value);
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
export function init() {
|
|
variableListeners(listeners());
|
|
|
|
document.querySelector(".button-clear-counts")
|
|
?.addEventListener("click", clearCounters);
|
|
document.querySelector(".button-clear-messages")
|
|
?.addEventListener("click", clearMessages);
|
|
|
|
document.querySelector(".button-clear-filters")
|
|
?.addEventListener("click", clearFilters);
|
|
document.querySelector("#rfm69-messages tbody")
|
|
?.addEventListener("click", filterEvent);
|
|
|
|
withMapping((elem) => {
|
|
groupSettingsOnAddElem(elem, () => {
|
|
addMappingNode(elem);
|
|
});
|
|
});
|
|
}
|