Task lists WIP:
* task list template + form
This commit is contained in:
parent
d16bdd9a87
commit
9d5d59e9bc
@ -6,11 +6,15 @@ import { __ } from 'i18n'
|
||||
export default class MUCTaskListView extends CustomElement {
|
||||
static get properties () {
|
||||
return {
|
||||
model: { type: Object, attribute: true }
|
||||
model: { type: Object, attribute: true },
|
||||
collapsed: { type: Boolean, attribute: false },
|
||||
edit: { type: Boolean, attribute: false }
|
||||
}
|
||||
}
|
||||
|
||||
async initialize () {
|
||||
this.collapsed = false
|
||||
this.edit = false
|
||||
if (!this.model) {
|
||||
return
|
||||
}
|
||||
@ -22,6 +26,34 @@ export default class MUCTaskListView extends CustomElement {
|
||||
return tplMucTaskList(this, this.model)
|
||||
}
|
||||
|
||||
async saveTaskList (ev) {
|
||||
ev?.preventDefault?.()
|
||||
|
||||
const name = ev.target.name.value.trim()
|
||||
|
||||
if ((name ?? '') === '') { return }
|
||||
|
||||
try {
|
||||
this.querySelectorAll('input[type=submit]').forEach(el => {
|
||||
el.setAttribute('disabled', true)
|
||||
el.classList.add('disabled')
|
||||
})
|
||||
|
||||
const tasklist = this.model
|
||||
tasklist.set('name', name)
|
||||
await tasklist.saveItem()
|
||||
|
||||
this.edit = false
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
} finally {
|
||||
this.querySelectorAll('input[type=submit]').forEach(el => {
|
||||
el.removeAttribute('disabled')
|
||||
el.classList.remove('disabled')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async deleteTaskList (ev) {
|
||||
ev?.preventDefault?.()
|
||||
|
||||
@ -41,6 +73,24 @@ export default class MUCTaskListView extends CustomElement {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
toggleTasks () {
|
||||
this.collapsed = !this.collapsed
|
||||
}
|
||||
|
||||
async toggleEdit () {
|
||||
this.edit = !this.edit
|
||||
if (this.edit) {
|
||||
await this.updateComplete
|
||||
const input = this.querySelector('input[name="name"]')
|
||||
if (input) {
|
||||
input.focus()
|
||||
// Placing cursor at the end:
|
||||
input.selectionStart = input.value.length
|
||||
input.selectionEnd = input.selectionStart
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
api.elements.define('livechat-converse-muc-task-list', MUCTaskListView)
|
||||
|
@ -3,6 +3,8 @@ import { api } from '@converse/headless/core'
|
||||
import tplMucTaskLists from './templates/muc-task-lists'
|
||||
import { __ } from 'i18n'
|
||||
|
||||
import './styles/muc-task-lists.scss'
|
||||
|
||||
export default class MUCTaskListsView extends CustomElement {
|
||||
static get properties () {
|
||||
return {
|
||||
|
33
conversejs/custom/plugins/tasks/styles/muc-task-lists.scss
Normal file
33
conversejs/custom/plugins/tasks/styles/muc-task-lists.scss
Normal file
@ -0,0 +1,33 @@
|
||||
.conversejs {
|
||||
livechat-converse-muc-task-lists {
|
||||
padding: 1em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
livechat-converse-muc-task-list {
|
||||
width: 100%;
|
||||
|
||||
.task-list-description {
|
||||
border: 1px solid var(--chatroom-head-bg-color);
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-around;
|
||||
padding: 0.25em;
|
||||
column-gap: 0.25em;
|
||||
width: 100%;
|
||||
|
||||
button {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.task-list-name {
|
||||
flex-grow: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.task-list-tasks {
|
||||
padding-left: 2em;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,12 @@ class ChatRoomTaskList extends Model {
|
||||
}) ?? []
|
||||
}
|
||||
|
||||
async saveItem () {
|
||||
console.log('Saving task list ' + this.get('id') + '...')
|
||||
await this.collection.chatroom.taskManager.saveItem(this, { name })
|
||||
console.log('Task list ' + this.get('id') + ' created.')
|
||||
}
|
||||
|
||||
async deleteItem () {
|
||||
return this.collection.chatroom.taskManager.deleteItem(this)
|
||||
}
|
||||
|
@ -7,17 +7,52 @@ export default function tplMucTaskList (el, tasklist) {
|
||||
// eslint-disable-next-line no-undef
|
||||
const i18nDelete = __(LOC_task_list_delete)
|
||||
return html`
|
||||
<div class="">
|
||||
Tasklist: ${tasklist.get('name')}
|
||||
<a class="" title="${i18nDelete}"
|
||||
@click=${el.deleteTaskList}
|
||||
>
|
||||
<converse-icon class="fa fa-trash-alt" size="1em"></converse-icon>
|
||||
</a>
|
||||
<div class="task-list-description">
|
||||
${el.collapsed
|
||||
? html`
|
||||
<button @click=${el.toggleTasks}>
|
||||
<converse-icon
|
||||
color="var(--muc-toolbar-btn-color)"
|
||||
class="fa fa-angle-double-up"
|
||||
size="1em"></converse-icon>
|
||||
</button>`
|
||||
: html`
|
||||
<button @click=${el.toggleTasks}>
|
||||
<converse-icon
|
||||
color="var(--muc-toolbar-btn-color)"
|
||||
class="fa fa-angle-double-down"
|
||||
size="1em"></converse-icon>
|
||||
</button>`
|
||||
}
|
||||
${!el.edit
|
||||
? html`
|
||||
<div class="task-list-name">
|
||||
${tasklist.get('name')}
|
||||
</div>
|
||||
<a title="${__('Edit')}"
|
||||
@click=${el.toggleEdit}
|
||||
>
|
||||
<converse-icon class="fa fa-edit" size="1em"></converse-icon>
|
||||
</a>
|
||||
<a title="${i18nDelete}"
|
||||
@click=${el.deleteTaskList}
|
||||
>
|
||||
<converse-icon class="fa fa-trash-alt" size="1em"></converse-icon>
|
||||
</a>`
|
||||
: html`
|
||||
<div class="task-list-name">
|
||||
<form @submit=${el.saveTaskList}>
|
||||
<input type="text" name="name" autofocus value=${tasklist.get('name')} />
|
||||
<input type="submit" class="btn btn-primary" value="${__('Ok')}" />
|
||||
<input type="reset" class="btn btn-secondary" value="${__('Cancel')}" @click=${el.toggleEdit} />
|
||||
</form>
|
||||
</div>`
|
||||
}
|
||||
</div>
|
||||
<div class="">
|
||||
${
|
||||
repeat(tasks, (task) => task.get('id'), (task) => {
|
||||
<div class="task-list-tasks">
|
||||
${el.collapsed
|
||||
? ''
|
||||
: repeat(tasks, (task) => task.get('id'), (task) => {
|
||||
return html`<livechat-converse-muc-task .model=${task}></livechat-converse-muc-task>`
|
||||
})
|
||||
}
|
||||
|
@ -14,13 +14,11 @@ export default function tplMucTaskLists (el, tasklists) {
|
||||
const i18nTaskListName = __(LOC_task_list_name)
|
||||
|
||||
return html`
|
||||
<div class="">
|
||||
${
|
||||
repeat(tasklists, (tasklist) => tasklist.get('id'), (tasklist) => {
|
||||
return html`<livechat-converse-muc-task-list .model=${tasklist}></livechat-converse-muc-task-list>`
|
||||
})
|
||||
}
|
||||
</div>
|
||||
${
|
||||
repeat(tasklists, (tasklist) => tasklist.get('id'), (tasklist) => {
|
||||
return html`<livechat-converse-muc-task-list .model=${tasklist}></livechat-converse-muc-task-list>`
|
||||
})
|
||||
}
|
||||
<form class="converse-form" @submit=${el.submitCreateTaskList}>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
|
@ -92,21 +92,31 @@ export class PubSubManager {
|
||||
}
|
||||
|
||||
console.log('Creating item...')
|
||||
const attributes = { xmlns: type.xmlns }
|
||||
await this._save(type, data)
|
||||
console.log(`Node ${this.node} created on ${this.roomJID}.`)
|
||||
}
|
||||
|
||||
for (const attrName in type.attributes ?? []) {
|
||||
if (!(attrName in data)) { continue }
|
||||
attributes[attrName] = data[attrName]
|
||||
async saveItem (item) {
|
||||
const id = item.get('id')
|
||||
if (!id) {
|
||||
throw new Error('Can\'t delete an empty without ID')
|
||||
}
|
||||
|
||||
const item = $build('item').c(type.itemTag, attributes)
|
||||
|
||||
for (const fieldName in type.fields ?? []) {
|
||||
if (!(fieldName in data)) { continue }
|
||||
item.c(fieldName).t(data[fieldName]).up()
|
||||
const type = this._typeFromCollection(item.collection)
|
||||
if (!type) {
|
||||
throw new Error('Collection not found in manager')
|
||||
}
|
||||
|
||||
await api.pubsub.publish(this.roomJID, this.node, item)
|
||||
const data = {}
|
||||
for (const attr in (type.attributes ?? [])) {
|
||||
data[attr] = item.get(attr)
|
||||
}
|
||||
for (const field in (type.fields ?? [])) {
|
||||
data[field] = item.get(field)
|
||||
}
|
||||
|
||||
console.log('Saving item...')
|
||||
await this._save(type, data, id)
|
||||
console.log(`Node ${this.node} created on ${this.roomJID}.`)
|
||||
}
|
||||
|
||||
@ -135,6 +145,29 @@ export class PubSubManager {
|
||||
console.log('Item deleted.')
|
||||
}
|
||||
|
||||
async _save (type, data, id) {
|
||||
const itemAttributes = {}
|
||||
if (id) {
|
||||
itemAttributes.id = id
|
||||
}
|
||||
|
||||
const attributes = { xmlns: type.xmlns }
|
||||
|
||||
for (const attrName in type.attributes ?? []) {
|
||||
if (!(attrName in data)) { continue }
|
||||
attributes[attrName] = data[attrName]
|
||||
}
|
||||
|
||||
const item = $build('item', itemAttributes).c(type.itemTag, attributes)
|
||||
|
||||
for (const fieldName in type.fields ?? []) {
|
||||
if (!(fieldName in data)) { continue }
|
||||
item.c(fieldName).t(data[fieldName]).up()
|
||||
}
|
||||
|
||||
await api.pubsub.publish(this.roomJID, this.node, item)
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribed to the pubsub node.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user