TableView, UITable: fill in the plumbing
Int heory, we now have the basics of the UI down now. We just need to hook up the navigation and do some testing :D
This commit is contained in:
parent
1bb6793542
commit
04479d5ce3
3 changed files with 82 additions and 8 deletions
|
@ -32,7 +32,14 @@ class TableView {
|
||||||
el.classList.add("data-item");
|
el.classList.add("data-item");
|
||||||
el_dataitems.appendChild(el);
|
el_dataitems.appendChild(el);
|
||||||
|
|
||||||
let item_manager = new UITable(el, def);
|
let item_manager = null;
|
||||||
|
switch(def.type) {
|
||||||
|
case "table":
|
||||||
|
item_manager = new UITable(el, def);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.warn(`Unknown item definition type '${def.type}', ignoring. This is probably a bug.`);
|
||||||
|
}
|
||||||
this.el_parts.set(def.name, item_manager);
|
this.el_parts.set(def.name, item_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import Emel from 'emel';
|
import Emel from 'emel';
|
||||||
import { NightInk } from 'nightink';
|
import { NightInk as nightink } from 'nightink';
|
||||||
|
|
||||||
import AbstractUIItem from './AbstractUIItem.mjs';
|
import AbstractUIItem from './AbstractUIItem.mjs';
|
||||||
|
import peer_name from './peer_name.mjs';
|
||||||
|
|
||||||
class UITable extends AbstractUIItem {
|
class UITable extends AbstractUIItem {
|
||||||
constructor(el, def) {
|
constructor(el, def) {
|
||||||
|
@ -11,25 +12,68 @@ class UITable extends AbstractUIItem {
|
||||||
|
|
||||||
this.emel = new Emel().emel;
|
this.emel = new Emel().emel;
|
||||||
|
|
||||||
this.el.replaceChildren(this.emel(`table>(thead>tr>${Object.keys(def.content).map(header => `th{${header}}`).join("+")})+tbody`));
|
this.el.replaceChildren(this.emel(`table>(thead>(tr>th{Peer}+${
|
||||||
|
Object.keys(def.content).map(header => `th{${header}}`).join("+")
|
||||||
|
})+tbody`));
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
super.clear();
|
super.clear();
|
||||||
// TODO: Empty the table, but avoiding removing the header, structure etc
|
this.el.querySelector(`tbody`).replaceChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
append(peer, table) {
|
append(peer, table) {
|
||||||
super.append(peer, table);
|
super.append(peer, table);
|
||||||
|
|
||||||
|
const el_tbody = this.el.querySelector("tbody");
|
||||||
|
|
||||||
let new_row = document.createElement("tr");
|
let new_row = document.createElement("tr");
|
||||||
for(let [ _, template ] of Object.entries(this.def.content)) {
|
// 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.
|
||||||
|
for(let [ , template ] of Object.entries(this.def.content)) {
|
||||||
let table_cell = document.createElement("td");
|
let table_cell = document.createElement("td");
|
||||||
table_cell.appendChild(document.createTextNode())
|
table_cell.appendChild(document.createTextNode(nightink(template, table)));
|
||||||
|
new_row.appendChild(table_cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Append the new table item in the right place
|
new_row.dataset.peer_name = peer.name;
|
||||||
// Perhaps we could use .dataset & iterate until we find the right one to insert directly before?
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/static/js/ui/peer_name.mjs
Normal file
23
src/static/js/ui/peer_name.mjs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
export default function peer_name(peer) {
|
||||||
|
const result = document.createElement("span");
|
||||||
|
result.classList.append(`peer-name`);
|
||||||
|
result.dataset.peer_id = peer.id;
|
||||||
|
result.dataset.peer_name = peer.name;
|
||||||
|
|
||||||
|
const peer_name = document.createElement("span");
|
||||||
|
peer_name.appendChild(document.createTextNode(peer.name));
|
||||||
|
|
||||||
|
const peer_id = document.createElement("span");
|
||||||
|
peer_id.appendChild(document.createTextNode(peer.id));
|
||||||
|
|
||||||
|
// TODO: When the id is clicked, copy it to the clipboard - we may need a fancy tooltip library for this
|
||||||
|
|
||||||
|
// text-overflow: ellipsis; may be useful here
|
||||||
|
|
||||||
|
result.replaceChildren(peer_name, peer_id);
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
Reference in a new issue