diff --git a/design.drawio b/design.drawio
new file mode 100644
index 0000000..6118e3e
--- /dev/null
+++ b/design.drawio
@@ -0,0 +1,212 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/page.go b/page.go
index ee5c255..e8ab1af 100644
--- a/page.go
+++ b/page.go
@@ -29,6 +29,5 @@ func (p Page) GetLayout() string {
func (p Page) GetData() any {
p.Data["_dev"] = FlagDev
- p.Data["GRIS"] = "foo"
return p.Data
}
diff --git a/static/images/design.svg b/static/images/design.svg
index 4fe5ef9..6af2931 100644
--- a/static/images/design.svg
+++ b/static/images/design.svg
@@ -53,8 +53,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
- inkscape:cx="666.5"
- inkscape:cy="485"
+ inkscape:cx="647.5"
+ inkscape:cy="483"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
@@ -263,7 +263,7 @@
y="32.808334" />API.logout()}>Log out
- <${Tree} app=${this} />
+
+ <${Tree} ref=${this.tree} app=${this} />
`
}//}}}
setStartNode() {//{{{
@@ -26,7 +27,8 @@ export class Notes2 {
const req = {}
API.query('POST', '/node/tree', req)
.then(response => {
- console.log(response)
+ console.log(response.Nodes)
+ nodeStore.add(response.Nodes)
})
.catch(e => console.log(e.type, e.error))
}
@@ -51,8 +53,7 @@ class Tree extends Component {
}//}}}
retrieve(callback = null) {//{{{
- const req = { StartNodeID: 0 }
- API.query('POST', '/node/tree', req)
+ nodeStore.getTreeNodes()
.then(res => {
this.treeNodes = {}
this.treeNodeComponents = {}
@@ -63,7 +64,7 @@ class Tree extends Component {
// returned from the server to be sorted in such a way that
// a parent node always appears before a child node.
// The server uses a recursive SQL query delivering this.
- res.Nodes.forEach(nodeData => {
+ res.forEach(nodeData => {
let node = new Node(
this,
nodeData.ID,
diff --git a/static/js/key.mjs b/static/js/key.mjs
index 4cc8f28..1f8c40f 100644
--- a/static/js/key.mjs
+++ b/static/js/key.mjs
@@ -1,4 +1,3 @@
-import 'preact/devtools'
import { h, Component } from 'preact'
import htm from 'htm'
import Crypto from 'crypto'
diff --git a/static/js/node_store.mjs b/static/js/node_store.mjs
new file mode 100644
index 0000000..0a24dbe
--- /dev/null
+++ b/static/js/node_store.mjs
@@ -0,0 +1,87 @@
+export class NodeStore {
+ constructor() {
+ if (!('indexedDB' in window)) {
+ throw 'Missing IndexedDB'
+ }
+
+ this.db = null
+ }
+
+ async initializeDB() {
+ return new Promise((resolve, reject) => {
+ let req = indexedDB.open('notes', 2)
+
+
+ // Schema upgrades for IndexedDB.
+ // These can start from different points depending on updates to Notes2 since a device was online.
+ req.onupgradeneeded = (event) => {
+ var store
+ let db = event.target.result
+ let trx = event.target.transaction
+
+ for (let i = event.oldVersion + 1; i <= event.newVersion; i++) {
+ console.log(`Upgrade to schema ${i}`)
+
+ // The schema transformations.
+ switch (i) {
+ case 1:
+ store = db.createObjectStore('nodes', { keyPath: 'ID' })
+ store.createIndex('nameIndex', 'Name', { unique: false })
+ break
+ case 2:
+ trx.objectStore('nodes').createIndex('parentIndex', 'ParentID', { unique: false })
+ break
+ }
+ }
+ }
+
+ req.onsuccess = (event) => {
+ this.db = event.target.result
+ resolve()
+ }
+
+ req.onerror = (event) => {
+ reject(event.target.error)
+ }
+ })
+ }
+
+ async add(records) {
+ return new Promise((resolve, reject) => {
+ try {
+ let t = this.db.transaction('nodes', 'readwrite')
+ let nodeStore = t.objectStore('nodes')
+ t.onerror = (event) => {
+ console.log('transaction error', event.target.error)
+ reject(event.target.error)
+ }
+ t.oncomplete = () => {
+ resolve()
+ }
+
+ records.forEach(record => {
+ let addReq = nodeStore.add(record)
+ addReq.onsuccess = (event) => {
+ console.log('OK!', record.ID, record.Name)
+ }
+ addReq.onerror = (event) => {
+ console.log('Error!', event.target.error, record.ID)
+ }
+ })
+
+ } catch (e) {
+ console.log(e)
+ }
+ })
+ }
+
+ async getTreeNodes() {
+ return new Promise((resolve, reject)=>{
+ let trx = this.db.transaction('nodes', 'readonly')
+ let nodeStore = trx.objectStore('nodes')
+ let req = nodeStore.getAll()
+ req.onsuccess = (event)=>resolve(event.target.result)
+ req.onerror = (event)=>reject(event.target.error)
+ })
+ }
+}
diff --git a/views/layouts/main.gotmpl b/views/layouts/main.gotmpl
index 98bd8d0..1931f13 100644
--- a/views/layouts/main.gotmpl
+++ b/views/layouts/main.gotmpl
@@ -15,25 +15,23 @@
"imports": {
"preact": "/js/{{ .VERSION }}/lib/preact/preact.mjs",
"preact/hooks": "/js/{{ .VERSION }}/lib/preact/hooks.mjs",
+ {{- if .Data._dev }}
"preact/debug": "/js/{{ .VERSION }}/lib/preact/debug.mjs",
"preact/devtools": "/js/{{ .VERSION }}/lib/preact/devtools.mjs",
+ {{- end }}
"@preact/signals-core": "/js/{{ .VERSION }}/lib/signals/signals-core.mjs",
"preact/signals": "/js/{{ .VERSION }}/lib/signals/signals.mjs",
"htm": "/js/{{ .VERSION }}/lib/htm/htm.mjs",
- "api": "/js/{{ .VERSION }}/api.mjs",
- "key": "/js/{{ .VERSION }}/key.mjs",
- "checklist": "/js/{{ .VERSION }}/checklist.mjs",
- "crypto": "/js/{{ .VERSION }}/crypto.mjs",
- "node": "/js/{{ .VERSION }}/node.mjs"
+ "api": "/js/{{ .VERSION }}/api.mjs",
+ "key": "/js/{{ .VERSION }}/key.mjs",
+ "checklist": "/js/{{ .VERSION }}/checklist.mjs",
+ "crypto": "/js/{{ .VERSION }}/crypto.mjs",
+ "node_store": "/js/{{ .VERSION }}/node_store.mjs",
+ "node": "/js/{{ .VERSION }}/node.mjs"
{{/*
- "session": "/js/{{ .VERSION }}/session.mjs",
- "node": "/js/{{ .VERSION }}/node.mjs",
- "node_store": "/js/{{ .VERSION }}/node_store.mjs",
- "key": "/js/{{ .VERSION }}/key.mjs",
- "crypto": "/js/{{ .VERSION }}/crypto.mjs",
- "checklist": "/js/{{ .VERSION }}/checklist.mjs",
- "ws": "/_js/{{ .VERSION }}/websocket.mjs"
+ "session": "/js/{{ .VERSION }}/session.mjs",
+ "ws": "/_js/{{ .VERSION }}/websocket.mjs"
*/}}
}
}
diff --git a/views/pages/notes2.gotmpl b/views/pages/notes2.gotmpl
index b3e37e0..9894ce3 100644
--- a/views/pages/notes2.gotmpl
+++ b/views/pages/notes2.gotmpl
@@ -8,6 +8,7 @@ import htm from 'htm'
import 'preact/debug'
import 'preact/devtools'
{{- end }}
+import { NodeStore } from 'node_store'
import { Notes2 } from "/js/{{ .VERSION }}/app.mjs"
import { API } from 'api'
@@ -15,8 +16,15 @@ if (!API.hasAuthenticationToken()) {
location.href = '/login'
} else {
const html = htm.bind(h)
- window._notes2 = createRef()
- render(html`<${Notes2} ref=${window._notes2} />`, document.getElementById('app'))
+ try {
+ window.nodeStore = new NodeStore()
+ window.nodeStore.initializeDB().then(() => {
+ window._notes2 = createRef()
+ render(html`<${Notes2} ref=${window._notes2} />`, document.getElementById('app'))
+ })
+ } catch (e) {
+ alert(e)
+ }
}