More work on special pages
This commit is contained in:
parent
da7999fb24
commit
15bd742ef7
3 changed files with 158 additions and 69 deletions
61
static/images/leaf_orphaned.svg
Normal file
61
static/images/leaf_orphaned.svg
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="24.000015"
|
||||
height="23.999998"
|
||||
viewBox="0 0 6.350004 6.3499995"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
sodipodi:docname="leaf_orphaned.svg"
|
||||
inkscape:version="1.4.2 (ebf0e94, 2025-05-08)"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="3.2924659"
|
||||
inkscape:cy="15.600543"
|
||||
inkscape:window-width="1916"
|
||||
inkscape:window-height="1161"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false" /><defs
|
||||
id="defs1" /><g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-107.95,-148.16667)"><title
|
||||
id="title1">folder-open</title><title
|
||||
id="title1-1">folder-open-outline</title><title
|
||||
id="title1-5">notebook-outline</title><title
|
||||
id="title1-8">text-box-outline</title><path
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
d="m 108.3015,148.56838 h 3.95851 v 3.96688 h -3.95851 z"
|
||||
id="path3"
|
||||
sodipodi:nodetypes="ccccc" /><path
|
||||
d="m 108.47917,148.16667 c -0.29369,0 -0.52917,0.23548 -0.52917,0.52917 V 152.4 c 0,0.29369 0.23548,0.52917 0.52917,0.52917 h 3.70416 c 0.29369,0 0.52917,-0.23548 0.52917,-0.52917 v -3.70416 c 0,-0.29369 -0.23548,-0.52917 -0.52917,-0.52917 h -3.70416 m 0,0.52917 h 3.70416 V 152.4 h -3.70416 v -3.70416"
|
||||
id="path1"
|
||||
style="fill:#ababab;fill-opacity:1;stroke-width:0.264583"
|
||||
sodipodi:nodetypes="cssssssscccccc" /><path
|
||||
d="m 109.00833,149.225 v 0.52917 h 2.64584 V 149.225 h -2.64584 m 0,1.05834 v 0.52916 h 2.64584 v -0.52916 h -2.64584 m 0,1.05833 v 0.52917 h 1.85209 v -0.52917 z"
|
||||
id="path2"
|
||||
style="fill:#c7c7c7;fill-opacity:1;stroke-width:0.264583"
|
||||
sodipodi:nodetypes="ccccccccccccccc" /><title
|
||||
id="title1-9">delete-circle</title><title
|
||||
id="title1-53">ghost</title><path
|
||||
d="m 112.39499,150.28334 a 1.9050024,1.9050024 0 0 0 -1.905,1.905 v 2.32833 l 0.635,-0.635 0.635,0.635 0.635,-0.635 0.635,0.635 0.635,-0.635 0.63501,0.635 v -2.32833 a 1.9050024,1.9050024 0 0 0 -1.90501,-1.905 m -0.635,1.27 a 0.42333387,0.42333387 0 0 1 0.42334,0.42333 0.42333387,0.42333387 0 0 1 -0.42334,0.42334 0.42333387,0.42333387 0 0 1 -0.42333,-0.42334 0.42333387,0.42333387 0 0 1 0.42333,-0.42333 m 1.27,0 a 0.42333387,0.42333387 0 0 1 0.42334,0.42333 0.42333387,0.42333387 0 0 1 -0.42334,0.42334 0.42333387,0.42333387 0 0 1 -0.42333,-0.42334 0.42333387,0.42333387 0 0 1 0.42333,-0.42333 z"
|
||||
id="path1-5"
|
||||
style="fill:#005190;fill-opacity:1;stroke-width:0.264583" /></g></svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue