Selecting history nodes

This commit is contained in:
Magnus Åhall 2026-06-06 21:27:42 +02:00
parent aeca9d8559
commit 28111cc8eb
2 changed files with 140 additions and 48 deletions

View file

@ -21,7 +21,8 @@ html {
}
button {
font-size: 1e m;
font-size: 1em;
padding: 4px 8px;
}
/* ------------------------------------- *
@ -546,7 +547,7 @@ n2-pagehistory {
padding: 32px;
margin-bottom: 32px;
border-radius: 8px;
background-color: #f8f8f8;
background-color: #fafafa;
box-shadow:
rgba(0, 0, 0, 0.4) 0px 2px 4px,
@ -585,62 +586,72 @@ n2-pagehistory {
gap: 1px;
border: 1px solid var(--line-color);
&>div>div {
n2-pagehistorynode>* {
padding: 8px 12px;
background-color: #fff;
white-space: nowrap;
}
&.index {
n2-pagehistorynode {
&.selected .el-index:after {
position: absolute;
left: -20px;
content: '>';
color: var(--color1);
font-weight: bold;
margin-right: 8px;
}
.el-index {
position: relative;
text-align: right;
}
&.updated {
.el-updated {
white-space: initial;
}
.date {
.el-date {
white-space: nowrap;
font-weight: bold;
}
.time {
.el-time {
white-space: nowrap;
color: #555;
}
&.name {
.el-name {
white-space: initial;
/*overflow-wrap: anywhere;*/
word-break: break-all;
color: var(--color1);
}
}
.history-node {
display: contents;
}
}
.el-pagination {
grid-column: 1 / -1;
margin-top: 16px;
display: grid;
grid-template-columns: repeat(3, min-content);
grid-gap: 16px;
align-items: center;
white-space: nowrap;
user-select: none;
.el-prev,
.el-next {
font-weight: bold;
cursor: pointer;
border: 1px solid #aaa;
background-color: #eee;
padding: 8px 16px;
border-radius: 4px;
}
}
}
.el-pagination {
grid-column: 1 / -1;
margin-top: 16px;
display: grid;
grid-template-columns: repeat(3, min-content);
grid-gap: 16px;
align-items: center;
white-space: nowrap;
user-select: none;
.el-prev,
.el-next {
font-weight: bold;
cursor: pointer;
border: 1px solid #aaa;
background-color: #eee;
padding: 8px 16px;
border-radius: 4px;
}
}
}

View file

@ -1,5 +1,7 @@
import { CustomHTMLElement } from './lib/custom_html_element.mjs'
import { Node } from './page_node.mjs'
import { MarkedPosition } from './marked_position.mjs'
export class N2PageHistory extends CustomHTMLElement {
static PAGESIZE = 15
@ -47,11 +49,14 @@ export class N2PageHistory extends CustomHTMLElement {
<div data-el="next">&gt;</div>
</div>
</div>
<div data-el="markdown-content"></div>
`
}// }}}
constructor() {// {{{
super()
this.selectedNode = null
this.setAttribute('tabindex', '-1')
this.addEventListener('keydown', event => this.keyHandler(event))
@ -72,6 +77,10 @@ export class N2PageHistory extends CustomHTMLElement {
await this.useNode(event.detail.data)
this.render()
})
_mbus.subscribe('HISTORY_NODE_SELECTED', (event) => {
this.selectedNode = event.detail.data.historyNode
})
}// }}}
async render(keepFetchHistoryProgress) {// {{{
this.elNodeName.innerText = this.node.get('Name')
@ -88,24 +97,26 @@ export class N2PageHistory extends CustomHTMLElement {
let i = 0
let divs = nodes.map(n => {
i++
const date = n.get('Updated').slice(0, 10)
const time = n.get('Updated').slice(11, 19)
const div = document.createElement('div')
div.innerHTML = `
<div class="index">${1 + this.nodesTotal - (N2PageHistory.PAGESIZE * (this.page - 1) + i)}</div>
<div class="updated"><span class="date">${date}</span> <span class="time">${time}</span></div>
<div class="size">${this.formatSize(n.get('Content').length)}</div>
<div class="name">${n.get('Name')}</div>
`
div.classList.add('history-node')
const index = 1 + this.nodesTotal - (N2PageHistory.PAGESIZE * (this.page - 1) + i)
const div = new N2PageHistoryNode(n, index)
div.render()
return div
})
this.elNodes.replaceChildren(...divs)
if (!keepFetchHistoryProgress)
this.elFetchHistoryProgress.innerText = ''
// Select the first node.
if (!this.selectedNode) {
this.elNodes.firstElementChild?.select()
}
// Any selected history node is rendered with markdown.
/*
this.marked = new MarkedPosition()
this.elNodeMarkdown.innerHTML = this.marked.parse(this.elNodeContent.value)
*/
}// }}}
async useNode(node) {// {{{
@ -124,18 +135,33 @@ export class N2PageHistory extends CustomHTMLElement {
case 'ArrowRight':
this.nextPage()
break
case 'ArrowUp':
const prevNode = this.selectedNode?.previousElementSibling
if (prevNode)
prevNode.select()
break
case 'ArrowDown':
const nextNode = this.selectedNode?.nextElementSibling
if (nextNode)
nextNode.select()
break
}
}// }}}
prevPage() {// {{{
if (this.page == 1)
return
// Selecting a node on another page is wrong.
this.selectedNode = null
this.page--
this.render()
}// }}}
nextPage() {// {{{
if (this.page >= this.pages)
return
// Selecting a node on another page is wrong.
this.selectedNode = null
this.page++
this.render()
}// }}}
@ -199,6 +225,61 @@ export class N2PageHistory extends CustomHTMLElement {
return json
}// }}}
}
customElements.define('n2-pagehistory', N2PageHistory)
class N2PageHistoryNode extends CustomHTMLElement {
static {// {{{
this.tmpl = document.createElement('template')
this.tmpl.innerHTML = `
<div data-el="index"></div>
<div data-el="updated"><span data-el="date"></span> <span data-el="time"></span></div>
<div data-el="size"></div>
<div data-el="name"></div>
`
}// }}}
constructor(node, index) {// {{{
super()
this.node = node
this.index = index
this.style.display = 'contents'
this.selected = false
this.addEventListener('click', () => this.select())
// Another history node has been selected.
_mbus.subscribe('HISTORY_NODE_SELECTED', (event) => {
if (this.node.get('Updated') == event.detail.data.historyNode.node.get('Updated'))
return
this.selected = false
this.render()
})
}// }}}
select() {// {{{
this.selected = true
// Other nodes are told to unselect and rerender.
_mbus.dispatch('HISTORY_NODE_SELECTED', { historyNode: this })
this.render()
}// }}}
render() {// {{{
const date = this.node.get('Updated').slice(0, 10)
const time = this.node.get('Updated').slice(11, 19)
if (this.selected)
this.classList.add('selected')
else
this.classList.remove('selected')
this.elIndex.innerText = this.index
this.elDate.innerText = date
this.elTime.innerText = time
this.elSize.innerText = this.node.get('Content').length
this.elName.innerText = this.node.get('Name')
}// }}}
formatSize(s) {// {{{
let div = 1
let unit = 'B'
@ -215,4 +296,4 @@ export class N2PageHistory extends CustomHTMLElement {
}).format(Math.round(s / div)) + ' ' + unit
}// }}}
}
customElements.define('n2-pagehistory', N2PageHistory)
customElements.define('n2-pagehistorynode', N2PageHistoryNode)