Initial rendering of the node tree
This commit is contained in:
commit
c5bec0afa6
7477 changed files with 8513 additions and 0 deletions
100
static/js/app.mjs
Normal file
100
static/js/app.mjs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
export class TreeNode {
|
||||
constructor(parent, data) {// {{{
|
||||
this.data = data
|
||||
this.parent = parent
|
||||
this.childrenFetched = false
|
||||
this.children = null
|
||||
|
||||
this.sortChildren()
|
||||
}// }}}
|
||||
|
||||
render() {// {{{
|
||||
const nodeHTML = `
|
||||
<div class="node">
|
||||
<div class="expand-status"><img /></div>
|
||||
<div class="icon"><img /></div>
|
||||
<div class="name">${this.name()}</div>
|
||||
<div class="children"></div>
|
||||
</div>
|
||||
`
|
||||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue