Fix quick arrow navigation not collapsing nodes correctly

This commit is contained in:
Magnus Åhall 2026-06-08 20:27:43 +02:00
parent b3e5d79403
commit 4976a6ebe0
5 changed files with 60 additions and 69 deletions

View file

@ -1,7 +1,6 @@
import { ROOT_NODE } from 'node_store'
import { CustomHTMLElement } from './lib/custom_html_element.mjs'
import { Color, Solver } from './lib/css_colorize.mjs'
import { Node } from './page_node.mjs'
// TreeExpandedHandler is responsible for collapsing or expanding
// the node tree, wide view or narrow "mobile" view.
@ -145,24 +144,21 @@ export class N2Sidebar extends CustomHTMLElement {
treenode.render(true)
})
this.populateFirstLevel()
/* XXX - set color */
let color = new Color(0x80, 0x00, 0x33)
let solver = new Solver(color)
let result = solver.solve()
// console.log(result.filter)
console.log(result.filter)
}// }}}
async render() {// {{{
if (this.rendered)
alert('Tree should only be rendered once.')
this.expandedNodes[ROOT_NODE] = true
const startnode = await nodeStore.get(ROOT_NODE)
const starttreenode = new N2TreeNode(this, startnode, null)
this.treeNodeComponents[startnode.UUID] = starttreenode
this.elTreenodes.appendChild(starttreenode.render())
this.elTreenodes.appendChild(await starttreenode.render())
this.rendered = true
return this
@ -174,27 +170,6 @@ export class N2Sidebar extends CustomHTMLElement {
this.elTreenodes.replaceChildren()
this.populateFirstLevel()
}// }}}
populateFirstLevel() {//{{{
nodeStore.get(ROOT_NODE)
.then(node => node.fetchChildren())
.then(children => {
this.treeNodeComponents = {}
this.treeTrunk = []
for (const node of children) {
// The root node isn't supposed to be shown in the tree.
if (node.UUID === ROOT_NODE)
continue
if (node.ParentUUID === ROOT_NODE)
this.treeTrunk.push(node)
}
_mbus.dispatch('TREE_TRUNK_FETCHED')
})
.catch(e => {
console.error(e)
console.log(e.type, e.error)
alert(e.error)
})
}//}}}
getNodeExpanded(UUID) {//{{{
if (this.expandedNodes[UUID] === undefined)
this.expandedNodes[UUID] = false
@ -249,6 +224,8 @@ export class N2Sidebar extends CustomHTMLElement {
// Holding shift down does it recursively.
case Space:
case 'Enter':
if (n.UUID === ROOT_NODE)
return
const expanded = this.getNodeExpanded(n.UUID)
if (event.shiftKey) {
this.recursiveExpand(n, !expanded)
@ -302,7 +279,7 @@ export class N2Sidebar extends CustomHTMLElement {
return
const expanded = this.getNodeExpanded(n.UUID)
if (expanded && n.hasChildren()) {
if (expanded && n.hasChildren() && n.UUID !== ROOT_NODE) {
this.setNodeExpanded(n, false)
return
}
@ -452,15 +429,14 @@ export class N2Sidebar extends CustomHTMLElement {
if (!state)
await this.setNodeExpanded(node, false)
}//}}}
async makeVisible(node) {// {{{
async makeVisible(node, providedAncestors) {// {{{
const treenode = this.treeNodeComponents[node.UUID]
const ancestors = await nodeStore.getNodeAncestry(node)
const ancestors = providedAncestors || await nodeStore.getNodeAncestry(node)
for (const ancestor of ancestors.reverse()) {
this.setNodeExpanded(ancestor, true)
}
// The ROOT_NODE for example hasn't got a treenode.
treenode?.scrollIntoView({ block: 'nearest' })
}// }}}
}
@ -517,33 +493,25 @@ export class N2TreeNode extends CustomHTMLElement {
this.elExpandToggle.addEventListener('click', () => this.sidebar.setNodeExpanded(this.node, !this.sidebar.getNodeExpanded(this.node.UUID)))
this.elName.addEventListener('click', () => _mbus.dispatch('TREE_NODE_SELECTED', this.node))
_mbus.subscribe(`NODE_CHILDREN_FETCHED_${node.UUID}`, () => {
this.render(true)
})
_mbus.subscribe(`NODE_EXPAND_${node.UUID}`, _state => {
this.render(true)
})
if (this.node.Level === 0 || this.sidebar.getNodeExpanded(this.node.UUID))
this.fetchChildren()
}// }}}
async fetchChildren() {//{{{
async fetchChildren(force_fetch) {//{{{
if (this.children_populated && !force_fetch)
return
await this.node.fetchChildren()
this.children_populated = true
}//}}}
render(force_update) {//{{{
async render(force_update, force_refetch_children) {//{{{
if (this.rendered && force_update !== true)
return this
// Fetch the next level of children if the parent tree node is expanded and our children thus will be visible.
const expanded = this.node.hasChildren() && this.sidebar.getNodeExpanded(this.node.UUID)
if (this.sidebar.getNodeExpanded(this.node.UUID))
await this.fetchChildren()
if (!this.children_populated && this.sidebar.getNodeExpanded(this.parent?.node.UUID)) {
this.node.fetchChildren().then(() => this.children_populated = true)
}
// Update the name and selected status
// Update the name and selected status.
this.elName.querySelector('span').innerText = this.node.get('Name')
if (this.sidebar.isSelected(this.node))
@ -552,6 +520,7 @@ export class N2TreeNode extends CustomHTMLElement {
this.elName.classList.remove('selected')
// Update expansion state
const expanded = this.node.hasChildren() && this.sidebar.getNodeExpanded(this.node.UUID)
if (expanded) {
this.elChildren.classList.add('expanded')
this.elChildren.classList.remove('collapsed')
@ -571,7 +540,6 @@ export class N2TreeNode extends CustomHTMLElement {
this.setImgSrc(this.elExpand, `/images/${window._VERSION}/collapsed.svg`)
// Should children be rendered?
this.elChildren.innerHTML = ''
let children = []
if (expanded)
children = this.node.Children.map(node => {
@ -579,13 +547,14 @@ export class N2TreeNode extends CustomHTMLElement {
if (treenode === undefined) {
treenode = new N2TreeNode(this.sidebar, node, this)
this.sidebar.treeNodeComponents[node.UUID] = treenode
_mbus.dispatch(`NODE_COMPONENT_EXIST_${node.UUID}`)
}
return treenode
})
const renderedChildren = []
for (const c of children)
this.elChildren.appendChild(c.render())
renderedChildren.push(await c.render())
this.elChildren.replaceChildren(...renderedChildren)
this.rendered = true
return this