Download history to client

This commit is contained in:
Magnus Åhall 2026-06-06 14:29:22 +02:00
parent 65a0225d74
commit 9506b89453
5 changed files with 249 additions and 75 deletions

View file

@ -456,7 +456,24 @@ class NodeHistoryStore extends SimpleNodeStore {
request.onerror = (event) => reject(event.target.error)
})
}//}}}
retrievePage(uuid, perPage, page) {
hasNode(uuid, updated) {
return new Promise((resolve, reject) => {
const req = this.db
.transaction(['nodes', this.storeName], 'readonly')
.objectStore(this.storeName)
.getKey([uuid, updated])
req.onsuccess = (event) => {
resolve(event.target.result !== undefined)
}
req.onerror = (event) => {
console.log(event.target.error)
reject(event.target.error)
}
})
}
retrievePage(uuid, perPage, page) {// {{{
return new Promise((resolve, _reject) => {
const cursor = this.db
.transaction(['nodes', this.storeName], 'readonly')
@ -497,10 +514,10 @@ class NodeHistoryStore extends SimpleNodeStore {
}
}
})
}
}// }}}
}
export function uuidv7() {
export function uuidv7() {// {{{
// random bytes
const value = new Uint8Array(16)
crypto.getRandomValues(value)
@ -524,6 +541,6 @@ export function uuidv7() {
.map((b) => b.toString(16).padStart(2, "0"))
.join("")
return `${str.slice(0, 8)}-${str.slice(8, 12)}-${str.slice(12, 16)}-${str.slice(16, 20)}-${str.slice(20)}`
}
}// }}}
// vim: foldmethod=marker

View file

@ -1,7 +1,8 @@
import { CustomHTMLElement } from './lib/custom_html_element.mjs'
import { Node } from './page_node.mjs'
export class N2PageHistory extends CustomHTMLElement {
static PAGESIZE = 25
static PAGESIZE = 15
static {
this.tmpl = document.createElement('template')
@ -9,22 +10,30 @@ export class N2PageHistory extends CustomHTMLElement {
<style>
n2-pagehistory {
margin-top: 32px;
.layout {
}
}
</style>
<div class="layout">
<div class="back">
<img data-el="back-image" src="/images/${_VERSION}/icon_back.svg" class="colorize">
<div data-el="back-text">Back to node</div>
</div>
<div class="node-name">
<img src="/images/${_VERSION}/icon_history.svg" class="colorize">
<h1 data-el="node-name"></h1>
</div>
<div class="group-label">Actions</div>
<div class="group">
<button data-el="download-history">Fetch all history from server</button>
</div>
<div class="group-label">History</div>
<div class="group">
<div data-el="nodes"></div>
<div class="pagination">
<div data-el="pagination">
<div data-el="prev">&lt;</div>
<div data-el="page"></div>
<div data-el="next">&gt;</div>
@ -44,6 +53,7 @@ export class N2PageHistory extends CustomHTMLElement {
this.elBackText.addEventListener('click', () => _mbus.dispatch('SHOW_PAGE', { page: 'node' }))
this.elPrev.addEventListener('click', () => this.prevPage())
this.elNext.addEventListener('click', () => this.nextPage())
this.elDownloadHistory.addEventListener('click', () => this.downloadHistory())
_mbus.subscribe('NODE_UI_OPEN', async (event) => {
await this.useNode(event.detail.data)
@ -104,6 +114,11 @@ export class N2PageHistory extends CustomHTMLElement {
this.elNodeName.innerText = this.node.get('Name')
this.elPage.innerText = `${this.page} / ${this.pages}`
if (this.nodesTotal <= N2PageHistory.PAGESIZE)
this.elPagination.style.display = 'none'
else
this.elPagination.style.display = ''
let nodes = await nodeStore.nodesHistory.retrievePage(this.node.UUID, N2PageHistory.PAGESIZE, this.page)
let i = 0
let divs = nodes.map(n => {
@ -124,5 +139,50 @@ export class N2PageHistory extends CustomHTMLElement {
})
this.elNodes.replaceChildren(...divs)
}
async downloadHistory() {
try {
const nodes = []
let offset = 0
let hasMore = true
while (hasMore) {
const history = await this.downloadHistoryPage(offset)
hasMore = history.HasMore
for (const nodeData of history.Nodes) {
nodes.push(new Node(nodeData))
}
offset = nodes.length
}
let num = 0
for (const node of nodes) {
const ok = await nodeStore.nodesHistory.hasNode(node.UUID, node.get('Updated'))
if (ok) num++
await nodeStore.nodesHistory.add(node)
}
console.log(num)
} catch (e) {
console.error(e)
alert(e)
}
}
async downloadHistoryPage(offset) {
const res = await fetch(`/node/history/retrieve/${this.node.UUID}/${offset}`, {
headers: {
"Authorization": 'Bearer ' + localStorage.getItem('token'),
}
})
const json = await res.json()
if (!json.OK) {
alert(json.Error)
return
}
return json
}
}
customElements.define('n2-pagehistory', N2PageHistory)