95 lines
2.2 KiB
JavaScript
95 lines
2.2 KiB
JavaScript
|
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)
|
||
|
}//}}}
|
||
|
}
|