systemquery/src/static/js/ui/UITable.mjs

108 lines
2.9 KiB
JavaScript

"use strict";
import Emel from 'emel';
import { NightInk as nightink } from 'nightink';
import AbstractUIItem from './AbstractUIItem.mjs';
import peer_name from './peer_name.mjs';
class UITable extends AbstractUIItem {
constructor(el, def) {
super(el, def);
this.emel = new Emel().emel;
const preamble = `h3{${def.name}}`;
let result;
switch(typeof def.content) {
case "string":
result = this.emel(`${preamble}+table>(thead>tr>th{Peer}+th{Value})+tbody`);
break;
default:
result = this.emel(`${preamble}+table>(thead>tr>th{Peer}+${
Object.keys(def.content).map(header => `th{${header}}`).join("+")
})+tbody`);
}
this.el.replaceChildren(result);
}
clear() {
super.clear();
this.el.querySelector(`tbody`).replaceChildren();
}
append(peer, table) {
super.append(peer, table);
const el_tbody = this.el.querySelector("tbody");
let new_row = document.createElement("tr");
// TODO: Insert a <td /> for the name of the peer here
new_row.appendChild(peer_name(peer));
// Note here that the comma is *important*. This is a destructuring assignment where we ignore the first value.
switch(typeof this.def.content) {
case "string":
let cell_value = document.createElement("td");
cell_value.appendChild(document.createTextNode(nightink(this.def.content, table)));
new_row.appendChild(cell_value);
break;
default:
for(let [ , template ] of Object.entries(this.def.content)) {
let table_cell = document.createElement("td");
let value = null;
switch(typeof template) {
case "function":
value = template(table);
break;
case "string":
value = nightink(template, table);
break;
}
table_cell.appendChild(document.createTextNode(value));
new_row.appendChild(table_cell);
}
break;
}
new_row.dataset.peer_name = peer.name;
new_row.dataset.peer_id = peer.id;
const comparer = new Intl.Collator(navigator.language);
// If the peer id exactly matches, replace this row instead
for(let row of el_tbody.childNodes) {
if(peer.id === row.dataset.peer_id) {
row.before(new_row);
el_tbody.removeChild(row);
return;
}
}
// Otherwise, insert it such that the list is sorted
// FUTURE: Use a fanceh thingy that sorts table data?
for(let row of el_tbody.childNodes) {
const comp_name = comparer.compare(
peer.name.toLowerCase(),
row.dataset.peer_name.toLowerCase()
);
const comp_id = comparer.compare(peer.id, row.dataset.peer_id);
let insert_before = false;
if(comp_name < 0) insert_before = true;
if(!insert_before && comp_name === 0 && comp_id < 0) insert_before = true;
if(insert_before) {
row.before(new_row);
return;
}
}
// In the unlikely event we failed to insert it somewhere, make sure it's inserted
// e.g. if this is the first row, or sorts after all existing rows
el_tbody.appendChild(new_row);
}
}
export default UITable;