diff --git a/static/images/leaf_orphaned.svg b/static/images/leaf_orphaned.svg new file mode 100644 index 0000000..8b1cc37 --- /dev/null +++ b/static/images/leaf_orphaned.svg @@ -0,0 +1,61 @@ + + + +folder-openfolder-open-outlinenotebook-outlinetext-box-outlinedelete-circleghost diff --git a/static/js/node_store.mjs b/static/js/node_store.mjs index 488294f..6be8f82 100644 --- a/static/js/node_store.mjs +++ b/static/js/node_store.mjs @@ -15,6 +15,8 @@ export class NodeStore { this.sendQueue = null this.nodesHistory = null this.files = null + + this.initializeSpecialNodes() }//}}} initializeDB() {//{{{ return new Promise((resolve, reject) => { @@ -86,9 +88,11 @@ export class NodeStore { } }) }//}}} - purgeCache() {//{{{ - this.nodes = {} - }//}}} + initializeSpecialNodes() {// {{{ + this.nodes[ROOT_NODE] = new Node({ UUID: ROOT_NODE, Name: 'Start', Special: true }, -1) + this.nodes[DELETED_NODE] = new Node({ UUID: DELETED_NODE, Name: 'Deleted nodes', Special: true }, -1) + this.nodes[ORPHANED_NODE] = new Node({ UUID: ORPHANED_NODE, Name: 'Orphaned nodes', Special: true }, -1) + }// }}} node(uuid, dataIfUndefined, newLevel) {//{{{ let n = this.nodes[uuid] @@ -244,14 +248,9 @@ export class NodeStore { return new Promise((resolve, reject) => { switch (uuid) { case ROOT_NODE: - const rootNode = new Node({ UUID: ROOT_NODE, Name: 'Start', Special: true }, -1) - this.nodes[ROOT_NODE] = rootNode - resolve(rootNode) - return case DELETED_NODE: - const deletedNode = new Node({ UUID: DELETED_NODE, Name: 'Deleted nodes', Special: true }, -1) - this.nodes[DELETED_NODE] = deletedNode - resolve(deletedNode) + case ORPHANED_NODE: + resolve(this.nodes[uuid]) return } @@ -261,73 +260,78 @@ export class NodeStore { let nodeStore = suppliedNodestore if (nodeStore === undefined) { - trx = this.db.transaction('nodes', 'readonly') - nodeStore = trx.objectStore('nodes') - } - - const getRequest = nodeStore.get(uuid) - - getRequest.onsuccess = (event) => { - // Node not found in IndexedDB. - if (event.target.result === undefined) { - reject("No such node") - return + trx = this.db.transaction('nodes', 'readonly') + nodeStore = trx.objectStore('nodes') } - const node = this.node(uuid, event.target.result, -1) - resolve(node) - } - }) -}//}}} -getNodeAncestry(node, accumulated) {//{{{ - return new Promise((resolve, reject) => { - if (accumulated === undefined) - accumulated = [] - const nodeParentIndex = this.db - .transaction('nodes', 'readonly') - .objectStore('nodes') + const getRequest = nodeStore.get(uuid) - if (node.UUID === ROOT_NODE || node.ParentUUID === ROOT_NODE) { - resolve(accumulated) - return - } + getRequest.onsuccess = (event) => { + // Node not found in IndexedDB. + if (event.target.result === undefined) { + reject("No such node") + return + } + const node = this.node(uuid, event.target.result, -1) + resolve(node) + } + }) + }//}}} + getNodeAncestry(node, accumulated) {//{{{ + return new Promise((resolve, reject) => { + if (accumulated === undefined) + accumulated = [] - if (node.UUID === DELETED_NODE || node.ParentUUID === DELETED_NODE) { - resolve(accumulated) - return - } + const nodeParentIndex = this.db + .transaction('nodes', 'readonly') + .objectStore('nodes') - const getRequest = nodeParentIndex.get(node.ParentUUID) - getRequest.onsuccess = (event) => { - // Node not found in IndexedDB. - // Not expected to happen. - const parentNodeData = event.target.result - if (parentNodeData === undefined) { - reject("No such node") + if (node.UUID === ROOT_NODE || node.ParentUUID === ROOT_NODE) { + resolve(accumulated) return } - const parentNode = this.node(parentNodeData.UUID, parentNodeData, -1) - this.getNodeAncestry(parentNode, accumulated.concat(parentNode)) - .then(accumulated => resolve(accumulated)) - } - }) + if (node.UUID === DELETED_NODE || node.ParentUUID === DELETED_NODE) { + resolve(accumulated) + return + } -}//}}} -newTransaction(objectStore, mode) {// {{{ - return this.db.transaction(objectStore, mode) -}// }}} + if (node.UUID === ORPHANED_NODE || node.ParentUUID === ORPHANED_NODE) { + resolve(accumulated) + return + } -nodeCount() {//{{{ - return new Promise((resolve, reject) => { - const t = this.db.transaction('nodes', 'readwrite') - const nodeStore = t.objectStore('nodes') - const countReq = nodeStore.count() - countReq.onsuccess = event => { - resolve(event.target.result) - } - }) -}//}}} + const getRequest = nodeParentIndex.get(node.ParentUUID) + getRequest.onsuccess = (event) => { + // Node not found in IndexedDB. + // Not expected to happen. + const parentNodeData = event.target.result + if (parentNodeData === undefined) { + reject("No such node") + return + } + + const parentNode = this.node(parentNodeData.UUID, parentNodeData, -1) + this.getNodeAncestry(parentNode, accumulated.concat(parentNode)) + .then(accumulated => resolve(accumulated)) + } + }) + + }//}}} + newTransaction(objectStore, mode) {// {{{ + return this.db.transaction(objectStore, mode) + }// }}} + + nodeCount() {//{{{ + return new Promise((resolve, reject) => { + const t = this.db.transaction('nodes', 'readwrite') + const nodeStore = t.objectStore('nodes') + const countReq = nodeStore.count() + countReq.onsuccess = event => { + resolve(event.target.result) + } + }) + }//}}} } class SimpleNodeStore { diff --git a/static/js/sidebar.mjs b/static/js/sidebar.mjs index 4162208..06b2943 100644 --- a/static/js/sidebar.mjs +++ b/static/js/sidebar.mjs @@ -1,4 +1,4 @@ -import { ROOT_NODE, ORPHANED_NODE , DELETED_NODE} from 'node_store' +import { ROOT_NODE, ORPHANED_NODE, DELETED_NODE } from 'node_store' import { Node } from 'node' import { CustomHTMLElement } from './lib/custom_html_element.mjs' import { Color, Solver } from './lib/css_colorize.mjs' @@ -161,11 +161,22 @@ export class N2Sidebar extends CustomHTMLElement { const deletednode = await nodeStore.get(DELETED_NODE) const deletedtreenode = new SpecialNodeDeleted(this, deletednode, null) + const orphanednode = await nodeStore.get(ORPHANED_NODE) + const orphanedtreenode = new SpecialNodeOrphaned(this, orphanednode, null) + + startnode._sibling_after = deletednode + deletednode._sibling_before = startnode + + deletednode._sibling_after = orphanednode + orphanednode._sibling_before = deletednode + this.treeNodeComponents[startnode.UUID] = starttreenode this.treeNodeComponents[deletednode.UUID] = deletedtreenode + this.treeNodeComponents[orphanednode.UUID] = orphanedtreenode this.elTreenodes.appendChild(await starttreenode.render()) this.elTreenodes.appendChild(await deletedtreenode.render()) + this.elTreenodes.appendChild(await orphanedtreenode.render()) // Notify the application that the initial tree is rendered (with children) // and that initial node selection can take place. App will check URL to @@ -677,11 +688,16 @@ export class N2TreeNode extends CustomHTMLElement { if (this.node.UUID === ROOT_NODE) this.setImgSrc(this.elExpand, `/images/${window._VERSION}/icon_home.svg`) - else if (this.node.UUID === '00000000-0000-0000-0000-000000000002') { + else if (this.node.UUID === DELETED_NODE) { this.setImgSrc(this.elExpand, `/images/${window._VERSION}/leaf_deleted.svg`) this.elExpand.classList.add('deleted') } + else if (this.node.UUID === ORPHANED_NODE) { + this.setImgSrc(this.elExpand, `/images/${window._VERSION}/leaf_orphaned.svg`) + this.elExpand.classList.add('deleted') + } + else if (!this.node.hasChildren()) this.setImgSrc(this.elExpand, `/images/${window._VERSION}/leaf.svg`) else if (this.sidebar.getNodeExpanded(this.node.UUID)) @@ -724,8 +740,16 @@ class SpecialNodeDeleted extends N2TreeNode { }//}}} } +class SpecialNodeOrphaned extends N2TreeNode { + constructor(sidebar, node, parent) {//{{{ + super(sidebar, node, parent) + this.removeAttribute('draggable') + }//}}} +} + customElements.define('n2-sidebar', N2Sidebar) customElements.define('n2-treenode', N2TreeNode) customElements.define('n2-specialnodedeleted', SpecialNodeDeleted) +customElements.define('n2-specialnodeorphaned', SpecialNodeOrphaned) // vim: foldmethod=marker