export class TreeNode { constructor(parent, data) {// {{{ this.data = data this.parent = parent this.childrenFetched = false this.children = null this.sortChildren() }// }}} render() {// {{{ const nodeHTML = `
${this.name()}
` this.name() const tmpl = document.createElement('template') tmpl.innerHTML = nodeHTML this.children = tmpl.content.querySelector('.children') // data.NumChildren is set regardless of having fetched the children or not. if (this.hasChildren()) { const img = tmpl.content.querySelector('.expand-status img') img.setAttribute('src', `/images/${_VERSION}/node_modules/@mdi/svg/svg/plus-box-outline.svg`) img.addEventListener('click', event => this.toggleExpand(event)) } else tmpl.content.querySelector('.expand-status').classList.add('leaf') if (this.data.TypeIcon) { const img = tmpl.content.querySelector('.icon img') img.setAttribute('src', `/images/${_VERSION}/node_modules/@mdi/svg/svg/${this.data.TypeIcon}.svg`) } this.parent.appendChild(tmpl.content) for (const c of this.data.Children || []) { (new TreeNode(this.children, c)).render() } }// }}} name() {// {{{ if (this.data.TypeName === 'root_node') return 'Start' return this.data.Name }// }}} hasChildren() {// {{{ return this.data.NumChildren > 0 }// }}} sortChildren() {// {{{ this.data.Children.sort((a, b) => { console.log(a.Name, b.Name) if (a.TypeName < b.TypeName) return -1 if (a.TypeName > b.TypeName) return 1 if (a.Name < b.Name) return -1 if (a.Name > b.Name) return 1 return 0 }) }// }}} toggleExpand(event) {// {{{ const node = event.target.closest('.node') node?.classList.toggle('expanded') const img = node?.classList.contains('expanded') ? 'minus-box-outline' : 'plus-box-outline' event.target.setAttribute('src', `/images/${_VERSION}/node_modules/@mdi/svg/svg/${img}.svg`) if (!this.childrenFetched && this.data.NumChildren > 0 && this.data.Children.length == 0) { this.fetchChildren() .then(data => { this.childrenFetched = true this.data.Children = data.Children this.sortChildren() for (const nodeData of this.data.Children) { const node = new TreeNode(this.children, nodeData) node.render() } }) .catch(err => { alert(err) console.error(err) }) } }// }}} async fetchChildren() {// {{{ return new Promise((resolve, reject) => { fetch(`/nodes/tree/${this.data.ID}?depth=2`) .then(data => data.json()) .then(json => resolve(json)) .catch(err => reject(err)) }) }// }}} } // vim: foldmethod=marker