Handle page resizes on history, bumped to v12

This commit is contained in:
Magnus Åhall 2026-06-07 11:48:10 +02:00
parent 7002a00972
commit 9c07611f95
6 changed files with 108 additions and 195 deletions

View file

@ -23,7 +23,7 @@ import (
"text/template" "text/template"
) )
const VERSION = "v11" const VERSION = "v12"
const CONTEXT_USER = 1 const CONTEXT_USER = 1
const SYNC_PAGINATION = 200 const SYNC_PAGINATION = 200

View file

@ -32,31 +32,55 @@ button {
min-height: 100vh; min-height: 100vh;
display: grid; display: grid;
grid-template-areas:
"tree-expander tree pad1 crumbs crumbs pad2"
"tree-expander tree pad1 name functions pad2"
"tree-expander tree pad1 content content pad2"
;
grid-template-columns: &.page-node {
/* Tree-expander */ grid-template-areas:
var(--tree-expander) "tree-expander tree pad1 crumbs crumbs pad2"
/* Tree */ "tree-expander tree pad1 name functions pad2"
min-content minmax(32px, 1fr) "tree-expander tree pad1 content content pad2"
/* Sync */ ;
minmax(min-content, calc(var(--content-width) - var(--functions-width)))
/* Functions */ grid-template-columns:
var(--functions-width) /* Tree-expander */
/* Content */ var(--tree-expander)
minmax(32px, 1fr); /* Tree */
min-content minmax(32px, 1fr)
/* Sync */
minmax(min-content, calc(var(--content-width) - var(--functions-width)))
/* Functions */
var(--functions-width)
/* Content */
minmax(32px, 1fr);
grid-template-rows:
/* Crumbs */
min-content
/* Name */
min-content
/* Content */
1fr;
}
&.page-history {
grid-template-areas:
"tree-expander tree pad1 n2-pagehistory pad2"
;
grid-template-columns:
/* Tree-expander */
var(--tree-expander)
/* Tree */
min-content
/* pad1 */
32px
/* Content */
1fr
/* pad2 */
32px;
grid-template-rows: 1fr;
}
grid-template-rows:
/* Crumbs */
min-content
/* Name */
min-content
/* Content */
1fr;
/* Tree expander is collapsed as default */ /* Tree expander is collapsed as default */
--tree-expander: 0px; --tree-expander: 0px;
@ -223,11 +247,10 @@ button {
&.history { &.history {
#page-history { #page-history {
display: contents; display: grid;
grid-area: n2-pagehistory;
n2-pagehistory { n2-pagehistory {}
grid-area: content;
}
} }
} }
} }
@ -515,143 +538,3 @@ dialog.op {
} }
} }
} }
n2-pagehistory {
.back,
.node-name {
display: grid;
grid-template-columns: min-content 1fr;
grid-gap: 8px;
align-items: center;
margin-bottom: 16px;
}
.group-label {
font-weight: bold;
background-color: #444;
color: #fff;
padding: 8px 32px;
display: inline-block;
margin-left: 32px;
transform: translateY(14px);
border-radius: 6px;
}
.group {
border: 1px solid #ccc;
padding: 32px;
margin-bottom: 32px;
border-radius: 8px;
background-color: #fafafa;
box-shadow:
rgba(0, 0, 0, 0.4) 0px 2px 4px,
rgba(0, 0, 0, 0.3) 0px 7px 13px -3px,
rgba(0, 0, 0, 0.2) 0px -3px 0px inset;
}
.el-stats {
margin-bottom: 16px;
display: grid;
grid-template-columns: min-content 1fr;
grid-gap: 8px 12px;
white-space: nowrap;
}
.el-fetch-history-progress {
margin-top: 16px;
}
.el-back-image,
.el-back-text {
cursor: pointer;
}
.el-node-name {
margin-left: 8px;
}
.el-nodes {
grid-column: 1 / -1;
display: grid;
grid-template-columns: min-content minmax(min-content, max-content) min-content 1fr;
background-color: var(--line-color);
gap: 1px;
border: 1px solid var(--line-color);
n2-pagehistorynode>* {
padding: 8px 12px;
background-color: #fff;
white-space: nowrap;
}
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;
}
.el-updated {
white-space: initial;
}
.el-date {
white-space: nowrap;
font-weight: bold;
}
.el-time {
white-space: nowrap;
color: #555;
}
.el-name {
white-space: initial;
/*overflow-wrap: anywhere;*/
word-break: break-all;
color: var(--color1);
}
}
}
}
.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

@ -30,11 +30,18 @@ export class App {
}) })
_mbus.subscribe('SHOW_PAGE', ({ detail: { data: { page } } }) => { _mbus.subscribe('SHOW_PAGE', ({ detail: { data: { page } } }) => {
const classList = document.querySelector('#main-page').classList let classList = document.querySelector('#main-page').classList
classList.forEach(e => classList.forEach(e =>
classList.remove(e) classList.remove(e)
) )
classList.add(page) classList.add(page)
classList = document.querySelector('#notes2').classList
classList.forEach(e => {
if (e.startsWith('page-'))
classList.remove(e)
})
classList.add('page-'+page)
}) })
window.addEventListener('keydown', event => this.keyHandler(event)) window.addEventListener('keydown', event => this.keyHandler(event))

View file

@ -24,35 +24,39 @@ export class N2PageHistory extends CustomHTMLElement {
<h1 data-el="node-name"></h1> <h1 data-el="node-name"></h1>
</div> </div>
<div class="group-label">Actions</div> <div class="column-1">
<div class="group"> <div class="group-label">Actions</div>
<button data-el="download-history">Fetch all history from server</button> <div class="group">
<div data-el="fetch-history-progress"></div> <button data-el="download-history">Fetch all history from server</button>
</div> <div data-el="fetch-history-progress"></div>
<div class="group-label">History</div>
<div class="group">
<div data-el="stats">
<div>History on server:</div>
<div data-el="stats-on-server"></div>
<div>History on client:</div>
<div data-el="stats-on-client"></div>
</div> </div>
<div data-el="nodes"></div>
<div data-el="pagination"> <div class="group-label">History</div>
<div data-el="prev">&lt;</div> <div class="group">
<div data-el="page"></div> <div data-el="stats">
<div data-el="next">&gt;</div> <div>History on server:</div>
<div data-el="stats-on-server"></div>
<div>History on client:</div>
<div data-el="stats-on-client"></div>
</div>
<div data-el="nodes"></div>
<div data-el="pagination">
<div data-el="prev">&lt;</div>
<div data-el="page"></div>
<div data-el="next">&gt;</div>
</div>
</div> </div>
</div> </div>
<div class="group-label">Document</div> <div class="column-2">
<div class="group"> <div class="group-label">Document</div>
<div data-el="node-markdown"></div> <div class="group">
<div data-el="node-markdown"></div>
</div>
</div> </div>
` `
}// }}} }// }}}
@ -129,23 +133,35 @@ export class N2PageHistory extends CustomHTMLElement {
this.pages = Math.ceil(this.nodesTotal / N2PageHistory.PAGESIZE) this.pages = Math.ceil(this.nodesTotal / N2PageHistory.PAGESIZE)
}// }}} }// }}}
keyHandler(event) {// {{{ keyHandler(event) {// {{{
let handled = true
switch (event.key) { switch (event.key) {
case 'ArrowLeft': case 'ArrowLeft':
this.prevPage() this.prevPage()
break break
case 'ArrowRight': case 'ArrowRight':
this.nextPage() this.nextPage()
break break
case 'ArrowUp': case 'ArrowUp':
const prevNode = this.selectedNode?.previousElementSibling const prevNode = this.selectedNode?.previousElementSibling
if (prevNode) if (prevNode)
prevNode.select() prevNode.select()
break break
case 'ArrowDown': case 'ArrowDown':
const nextNode = this.selectedNode?.nextElementSibling const nextNode = this.selectedNode?.nextElementSibling
if (nextNode) if (nextNode)
nextNode.select() nextNode.select()
break break
default:
handled = false
}
if (handled) {
event.stopPropagation()
event.preventDefault()
} }
}// }}} }// }}}

View file

@ -6,6 +6,7 @@ const CACHED_ASSETS = [
'/css/{{ .VERSION }}/main.css', '/css/{{ .VERSION }}/main.css',
'/css/{{ .VERSION }}/markdown.css', '/css/{{ .VERSION }}/markdown.css',
'/css/{{ .VERSION }}/notes2.css', '/css/{{ .VERSION }}/notes2.css',
'/css/{{ .VERSION }}/page_history.css',
'/css/{{ .VERSION }}/theme.css', '/css/{{ .VERSION }}/theme.css',
'/images/{{ .VERSION }}/collapsed.svg', '/images/{{ .VERSION }}/collapsed.svg',
@ -119,9 +120,13 @@ self.addEventListener('activate', event => {
}) })
self.addEventListener('fetch', event => { self.addEventListener('fetch', event => {
// console.debug('SERVICE WORKER: fetch', event.request.url) // The fetch event is also seeing requests to other domains.
// Just let the browser handle those for itself.
const ourDomain = event.request.url.startsWith(self.location.origin)
if (!ourDomain)
return event
if ({{ .DevMode }}) if (`{{ .DevMode }}` == 'true')
return event return event
event.respondWith(fetchAsset(event)) event.respondWith(fetchAsset(event))

View file

@ -1,5 +1,6 @@
{{ define "page" }} {{ define "page" }}
<div id="notes2"> <!-- page-node -->
<div id="notes2" class="page-history">
<div id="tree-expander" onclick="window._mbus.dispatch('TREE_EXPANSION', { expand: true })">&gt;</div> <div id="tree-expander" onclick="window._mbus.dispatch('TREE_EXPANSION', { expand: true })">&gt;</div>
<div id="tree" tabindex=0></div> <div id="tree" tabindex=0></div>
@ -24,6 +25,7 @@
</div> </div>
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/notes2.css"> <link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/notes2.css">
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/page_history.css">
<script type="module"> <script type="module">
import {NodeStore} from '/js/{{ .VERSION }}/node_store.mjs' import {NodeStore} from '/js/{{ .VERSION }}/node_store.mjs'