Added checklists to database, rendering and toggling items
This commit is contained in:
parent
5c27f9ed1c
commit
f98a6ab863
9 changed files with 455 additions and 31 deletions
94
static/js/checklist.mjs
Normal file
94
static/js/checklist.mjs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import { h, Component, createRef } from 'preact'
|
||||
import htm from 'htm'
|
||||
import { signal } from 'preact/signals'
|
||||
const html = htm.bind(h)
|
||||
|
||||
export class ChecklistGroup {
|
||||
static sort(a, b) {//{{{
|
||||
if (a.Order < b.Order) return -1
|
||||
if (a.Order > b.Order) return 1
|
||||
return 0
|
||||
}//}}}
|
||||
constructor(data) {//{{{
|
||||
Object.keys(data).forEach(key => {
|
||||
if (key == 'Items')
|
||||
this.items = data[key].map(itemData =>
|
||||
new ChecklistItem(itemData)
|
||||
).sort(ChecklistItem.sort)
|
||||
else
|
||||
this[key] = data[key]
|
||||
})
|
||||
}//}}}
|
||||
}
|
||||
|
||||
export class ChecklistItem {
|
||||
static sort(a, b) {//{{{
|
||||
if (a.Order < b.Order) return -1
|
||||
if (a.Order > b.Order) return 1
|
||||
return 0
|
||||
}//}}}
|
||||
constructor(data) {//{{{
|
||||
Object.keys(data).forEach(key => {
|
||||
this[key] = data[key]
|
||||
})
|
||||
}//}}}
|
||||
}
|
||||
|
||||
export class Checklist extends Component {
|
||||
render({ groups }) {//{{{
|
||||
if (groups.length == 0)
|
||||
return
|
||||
|
||||
groups.sort(ChecklistGroup.sort)
|
||||
|
||||
let groupElements = groups.map(group => html`<${ChecklistGroupElement} group=${group} />`)
|
||||
|
||||
return html`
|
||||
<div id="checklist">
|
||||
<h1>Checklist</h1>
|
||||
${groupElements}
|
||||
</div>
|
||||
`
|
||||
}//}}}
|
||||
}
|
||||
|
||||
class ChecklistGroupElement extends Component {
|
||||
render({ group }) {//{{{
|
||||
let items = group.items.map(item => html`<${ChecklistItemElement} item=${item} />`)
|
||||
return html`
|
||||
<div class="checklist-group">${group.Label}</div>
|
||||
${items}
|
||||
`
|
||||
}//}}}
|
||||
}
|
||||
|
||||
class ChecklistItemElement extends Component {
|
||||
constructor(props) {//{{{
|
||||
super(props)
|
||||
this.state = {
|
||||
checked: props.item.Checked,
|
||||
}
|
||||
this.checkbox = createRef()
|
||||
}//}}}
|
||||
render({ item }, { checked }) {//{{{
|
||||
return html`
|
||||
<div class="checklist-item ${checked ? 'checked' : ''}">
|
||||
<input type="checkbox" ref=${this.checkbox} key="checkbox-${item.ID}" id="checkbox-${item.ID}" checked=${checked} onchange=${evt => this.update(evt.target.checked)} />
|
||||
<label for="checkbox-${item.ID}">${item.Label}</label>
|
||||
</div>
|
||||
`
|
||||
}//}}}
|
||||
update(checked) {//{{{
|
||||
this.setState({ checked })
|
||||
window._app.current.request('/node/checklist_item/state', {
|
||||
ChecklistItemID: this.props.item.ID,
|
||||
State: checked,
|
||||
})
|
||||
.then(res => {
|
||||
this.checkbox.current.classList.add('ok')
|
||||
setTimeout(()=>this.checkbox.current.classList.remove('ok'), 500)
|
||||
|
||||
})
|
||||
.catch(window._app.current.responseError)
|
||||
}//}}}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ import htm from 'htm'
|
|||
import { signal } from 'preact/signals'
|
||||
import { Keys, Key } from 'key'
|
||||
import Crypto from 'crypto'
|
||||
//import { marked } from 'marked'
|
||||
import { Checklist, ChecklistGroup } from 'checklist'
|
||||
const html = htm.bind(h)
|
||||
|
||||
export class NodeUI extends Component {
|
||||
|
|
@ -65,12 +65,14 @@ export class NodeUI extends Component {
|
|||
let padlock = ''
|
||||
if (node.CryptoKeyID > 0)
|
||||
padlock = html`<img src="/images/${window._VERSION}/padlock-black.svg" style="height: 24px;" />`
|
||||
|
||||
page = html`
|
||||
${children.length > 0 ? html`<div class="child-nodes">${children}</div>` : html``}
|
||||
<div class="node-name">
|
||||
${node.Name} ${padlock}
|
||||
</div>
|
||||
<${NodeContent} key=${node.ID} node=${node} ref=${this.nodeContent} />
|
||||
<${Checklist} groups=${node.ChecklistGroups} />
|
||||
<${NodeFiles} node=${this.node.value} />
|
||||
`
|
||||
}
|
||||
|
|
@ -342,16 +344,6 @@ class NodeContent extends Component {
|
|||
let textarea = document.getElementById('node-content')
|
||||
if (textarea)
|
||||
textarea.parentNode.dataset.replicatedValue = textarea.value
|
||||
|
||||
let crumbsEl = document.getElementById('crumbs')
|
||||
let markdown = document.getElementById('markdown')
|
||||
if (markdown) {
|
||||
let margins = (crumbsEl.clientWidth - 900) / 2.0
|
||||
if (margins < 0)
|
||||
margins = 0
|
||||
markdown.style.marginLeft = `${margins}px`
|
||||
markdown.style.marginRight = `${margins}px`
|
||||
}
|
||||
}//}}}
|
||||
unlock() {//{{{
|
||||
let pass = prompt(`Password for "${this.props.model.description}"`)
|
||||
|
|
@ -368,9 +360,9 @@ class NodeContent extends Component {
|
|||
}
|
||||
|
||||
class MarkdownContent extends Component {
|
||||
render({ content }) {
|
||||
render({ content }) {//{{{
|
||||
return html`<div id="markdown"></div>`
|
||||
}
|
||||
}//}}}
|
||||
componentDidMount() {//{{{
|
||||
const markdown = document.getElementById('markdown')
|
||||
if (markdown)
|
||||
|
|
@ -430,6 +422,7 @@ export class Node {
|
|||
this.Files = []
|
||||
this._decrypted = false
|
||||
this._expanded = false // start value for the TreeNode component,
|
||||
this.ChecklistGroups = {}
|
||||
// it doesn't control it afterwards.
|
||||
// Used to expand the crumbs upon site loading.
|
||||
}//}}}
|
||||
|
|
@ -446,6 +439,7 @@ export class Node {
|
|||
this.Files = res.Node.Files
|
||||
this.Markdown = res.Node.Markdown
|
||||
this.RenderMarkdown.value = this.Markdown
|
||||
this.initChecklist(res.Node.ChecklistGroups)
|
||||
callback(this)
|
||||
})
|
||||
.catch(this.app.responseError)
|
||||
|
|
@ -605,6 +599,13 @@ export class Node {
|
|||
this._decrypted = false
|
||||
return this._content
|
||||
}//}}}
|
||||
initChecklist(checklistData) {//{{{
|
||||
if (checklistData === undefined || checklistData === null)
|
||||
return
|
||||
this.ChecklistGroups = checklistData.map(groupData=>{
|
||||
return new ChecklistGroup(groupData)
|
||||
})
|
||||
}//}}}
|
||||
}
|
||||
|
||||
class Menu extends Component {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue