diff --git a/static/js/node.mjs b/static/js/node.mjs index 4db59a0..8648057 100644 --- a/static/js/node.mjs +++ b/static/js/node.mjs @@ -385,9 +385,7 @@ export class Node { if (this._children_fetched) return this.Children - this.Children = await nodeStore.getTreeNodes(this.UUID, this.Level + 1) - this._children_fetched = true // Children are sorted to allow for storing siblings befare and after. @@ -403,6 +401,9 @@ export class Node { this.Children[i]._parent = this } + // Notify the tree that all children are fetched and ready to process. + _notes2.current.tree.fetchChildrenOn(this.UUID) + return this.Children }//}}} hasChildren() {//{{{ diff --git a/static/js/notes2.mjs b/static/js/notes2.mjs index c4e2577..9eb9503 100644 --- a/static/js/notes2.mjs +++ b/static/js/notes2.mjs @@ -81,6 +81,11 @@ class Tree extends Component { this.expandedNodes = {} // keyed on UUID this.treeDiv = createRef() + // childrenFetchedCallbacks is keyed on a UUID and each + // item is an array with callbacks called when a UUID has + // had all children fetched. + this.childrenFetchedCallbacks = {} + this.props.app.tree = this this.populateFirstLevel() @@ -110,6 +115,20 @@ class Tree extends Component { this.setSelected(node) }//}}} + fetchChildrenNotify(uuid, fn) {//{{{ + if (this.childrenFetchedCallbacks[uuid] === undefined) + this.childrenFetchedCallbacks[uuid] = [fn] + else + this.childrenFetchedCallbacks[uuid].push(fn) + }//}}} + fetchChildrenOn(uuid) {//{{{ + if (this.childrenFetchedCallbacks[uuid] === undefined) + return + for (const fn of this.childrenFetchedCallbacks[uuid]) + fn(uuid) + delete this.childrenFetchedCallbacks[uuid] + }//}}} + populateFirstLevel(callback = null) {//{{{ nodeStore.get(ROOT_NODE) .then(node => node.fetchChildren()) @@ -142,7 +161,7 @@ class Tree extends Component { this.treeNodeComponents[node.UUID]?.current.forceUpdate() if (!dontExpand) - this.setNodeExpanded(node.UUID, true) + this.setNodeExpanded(node, true) }//}}} isSelected(node) {//{{{ return this.selectedNode?.UUID === node.UUID @@ -152,7 +171,7 @@ class Tree extends Component { const ancestry = await nodeStore.getNodeAncestry(node, []) for (const i in ancestry) { await nodeStore.node(ancestry[i].UUID).fetchChildren() - this.setNodeExpanded(ancestry[i].UUID, true) + this.setNodeExpanded(ancestry[i], true) } // Already a top node, no need to expand anything. @@ -160,17 +179,29 @@ class Tree extends Component { return // Start the chain of by expanding the top node. - this.setNodeExpanded(ancestry[ancestry.length - 1].UUID, true) + this.setNodeExpanded(ancestry[ancestry.length - 1], true) }//}}} getNodeExpanded(UUID) {//{{{ if (this.expandedNodes[UUID] === undefined) this.expandedNodes[UUID] = signal(false) return this.expandedNodes[UUID].value }//}}} - setNodeExpanded(UUID, value) {//{{{ - // Creating a default value if it doesn't exist already. - this.getNodeExpanded(UUID) - this.expandedNodes[UUID].value = value + async setNodeExpanded(node, value) {//{{{ + return new Promise((resolve, reject) => { + const work = uuid=>{ + // Creating a default value if it doesn't exist already. + this.getNodeExpanded(uuid) + this.expandedNodes[uuid].value = value + resolve() + } + + if (node.hasFetchedChildren()) { + work(node.UUID) + return + } else { + this.fetchChildrenNotify(node.UUID, uuid=>work(uuid)) + } + }) }//}}} getParentWithNextSibling(node) {//{{{ let currNode = node @@ -187,17 +218,33 @@ class Tree extends Component { return currNode }//}}} + async recursiveExpand(node, state) {//{{{ + if (state) + await this.setNodeExpanded(node, true) + + for (const child of node.Children) + await this.recursiveExpand(child, state) + + if (!state) + await this.setNodeExpanded(node, false) + }//}}} + async keyHandler(event) {//{{{ let handled = true const n = this.selectedNode const Space = ' ' switch (event.key) { - // Space is toggling expansion. + // Space and enter is toggling expansion. + // Holding shift down does it recursively. case Space: case 'Enter': const expanded = this.getNodeExpanded(n.UUID) - this.setNodeExpanded(n.UUID, !expanded) + if (event.shiftKey) { + this.recursiveExpand(n, !expanded) + } else { + this.setNodeExpanded(n, !expanded) + } break case 'g': @@ -246,7 +293,7 @@ class Tree extends Component { const expanded = this.getNodeExpanded(n.UUID) if (expanded && n.hasChildren()) { - this.setNodeExpanded(n.UUID, false) + this.setNodeExpanded(n, false) return } @@ -273,7 +320,7 @@ class Tree extends Component { const expanded = this.getNodeExpanded(n.UUID) if (!expanded && n.hasChildren()) { - this.setNodeExpanded(n.UUID, true) + this.setNodeExpanded(n, true) return } @@ -405,7 +452,7 @@ class TreeNode extends Component { return html`
-
{ tree.setNodeExpanded(node.UUID, !tree.getNodeExpanded(node.UUID)) }}>${expandImg}
+
{ tree.setNodeExpanded(node, !tree.getNodeExpanded(node.UUID)) }}>${expandImg}
window._notes2.current.goToNode(node.UUID)}>${node.get('Name')}
${children}
`