Task lists WIP:
* some front end work.
This commit is contained in:
parent
d91cbb9e25
commit
22617def5e
@ -1,6 +1,7 @@
|
|||||||
import { CustomElement } from 'shared/components/element.js'
|
import { CustomElement } from 'shared/components/element.js'
|
||||||
import { api } from '@converse/headless/core'
|
import { api } from '@converse/headless/core'
|
||||||
import tplMucTaskList from './templates/muc-task-list'
|
import tplMucTaskList from './templates/muc-task-list'
|
||||||
|
import { __ } from 'i18n'
|
||||||
|
|
||||||
export default class MUCTaskListView extends CustomElement {
|
export default class MUCTaskListView extends CustomElement {
|
||||||
static get properties () {
|
static get properties () {
|
||||||
@ -18,7 +19,27 @@ export default class MUCTaskListView extends CustomElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return tplMucTaskList(this.model)
|
return tplMucTaskList(this, this.model)
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteTaskList (ev) {
|
||||||
|
ev?.preventDefault?.()
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
const i18nConfirmDelete = __(LOC_task_list_delete_confirm)
|
||||||
|
|
||||||
|
// FIXME: when tasks are in a modal, api.confirm replaces the modal. This is not ok.
|
||||||
|
// const result = await api.confirm(i18nConfirmDelete)
|
||||||
|
const result = confirm(i18nConfirmDelete)
|
||||||
|
if (!result) { return }
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.model.deleteItem()
|
||||||
|
} catch (err) {
|
||||||
|
api.alert(
|
||||||
|
'error', __('Error'), [__('Error')]
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,10 @@ class ChatRoomTaskList extends Model {
|
|||||||
list: taskListId
|
list: taskListId
|
||||||
}) ?? []
|
}) ?? []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteItem () {
|
||||||
|
return this.collection.chatroom.taskManager.deleteItem(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
import { Collection } from '@converse/skeletor/src/collection.js'
|
import { Collection } from '@converse/skeletor/src/collection.js'
|
||||||
import { ChatRoomTaskList } from './task-list'
|
import { ChatRoomTaskList } from './task-list'
|
||||||
import { XMLNS_TASKLIST } from './constants'
|
|
||||||
import { initStorage } from '@converse/headless/utils/storage.js'
|
import { initStorage } from '@converse/headless/utils/storage.js'
|
||||||
import { converse, api } from '@converse/headless/core'
|
|
||||||
const { $build } = converse.env
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of {@link _converse.ChatRoomTaskList} instances, representing task lists associated to a MUC.
|
* A list of {@link _converse.ChatRoomTaskList} instances, representing task lists associated to a MUC.
|
||||||
@ -37,9 +34,7 @@ class ChatRoomTaskLists extends Collection {
|
|||||||
if (!name) { throw new Error('Missing name') }
|
if (!name) { throw new Error('Missing name') }
|
||||||
|
|
||||||
console.log('Creating task list ' + name + '...')
|
console.log('Creating task list ' + name + '...')
|
||||||
const item = $build('item').c('tasklist', { xmlns: XMLNS_TASKLIST })
|
await this.chatroom.taskManager.createItem(this, { name })
|
||||||
item.c('name').t(name)
|
|
||||||
await api.pubsub.publish(this.chatroom.get('jid'), 'livechat-tasks', item)
|
|
||||||
console.log('Task list ' + name + ' created.')
|
console.log('Task list ' + name + ' created.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
import { html } from 'lit'
|
import { html } from 'lit'
|
||||||
import { repeat } from 'lit/directives/repeat.js'
|
import { repeat } from 'lit/directives/repeat.js'
|
||||||
|
import { __ } from 'i18n'
|
||||||
|
|
||||||
export default function tplMucTaskList (tasklist) {
|
export default function tplMucTaskList (el, tasklist) {
|
||||||
const tasks = tasklist.getTasks()
|
const tasks = tasklist.getTasks()
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
const i18nDelete = __(LOC_task_list_delete)
|
||||||
return html`
|
return html`
|
||||||
<div class="">
|
<div class="">
|
||||||
Tasklist: ${tasklist.get('name')}
|
Tasklist: ${tasklist.get('name')}
|
||||||
|
<a class="" title="${i18nDelete}"
|
||||||
|
@click=${el.deleteTaskList}
|
||||||
|
>
|
||||||
|
<converse-icon class="fa fa-trash-alt" size="1em"></converse-icon>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="">
|
<div class="">
|
||||||
${
|
${
|
||||||
|
@ -14,6 +14,13 @@ export default function tplMucTaskLists (el, tasklists) {
|
|||||||
const i18nTaskListName = __(LOC_task_list_name)
|
const i18nTaskListName = __(LOC_task_list_name)
|
||||||
|
|
||||||
return html`
|
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>
|
||||||
<form class="converse-form" @submit=${el.submitCreateTaskList}>
|
<form class="converse-form" @submit=${el.submitCreateTaskList}>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>
|
<label>
|
||||||
@ -26,12 +33,5 @@ export default function tplMucTaskLists (el, tasklists) {
|
|||||||
: html`<div class="invalid-feedback d-block">${el.create_tasklist_error_message}</div>`
|
: html`<div class="invalid-feedback d-block">${el.create_tasklist_error_message}</div>`
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>`
|
||||||
<div class="">
|
|
||||||
${
|
|
||||||
repeat(tasklists, (tasklist) => tasklist.get('id'), (tasklist) => {
|
|
||||||
return html`<livechat-converse-muc-task-list .model=${tasklist}></livechat-converse-muc-task-list>`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>`
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { converse, _converse, api } from '../../../src/headless/core.js'
|
import { converse, _converse, api } from '../../../src/headless/core.js'
|
||||||
const { Strophe, $iq, sizzle } = converse.env
|
const { $build, Strophe, $iq, sizzle } = converse.env
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class helps to manage some objects that are stored on pubsub nodes.
|
* This class helps to manage some objects that are stored on pubsub nodes.
|
||||||
@ -80,6 +80,61 @@ export class PubSubManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created a new item
|
||||||
|
* @param collection The collection handling this object.
|
||||||
|
* @param data Object data
|
||||||
|
*/
|
||||||
|
async createItem (collection, data) {
|
||||||
|
const type = this._typeFromCollection(collection)
|
||||||
|
if (!type) {
|
||||||
|
throw new Error('Collection not found in manager')
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Creating item...')
|
||||||
|
const attributes = { xmlns: type.xmlns }
|
||||||
|
|
||||||
|
for (const attrName in type.attributes ?? []) {
|
||||||
|
if (!(attrName in data)) { continue }
|
||||||
|
attributes[attrName] = data[attrName]
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
await api.pubsub.publish(this.roomJID, this.node, item)
|
||||||
|
console.log(`Node ${this.node} created on ${this.roomJID}.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteItem (item) {
|
||||||
|
const id = item.get('id')
|
||||||
|
if (!id) {
|
||||||
|
throw new Error('Can\'t delete an empty without ID')
|
||||||
|
}
|
||||||
|
|
||||||
|
const type = this._typeFromCollection(item.collection)
|
||||||
|
if (!type) {
|
||||||
|
throw new Error('Can\'t get type definition from item collection')
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Deleting item ' + id + ' on node ' + this.node + ' for room ' + this.roomJID + '...')
|
||||||
|
|
||||||
|
const stanza = $iq({
|
||||||
|
from: _converse.bare_jid,
|
||||||
|
type: 'set',
|
||||||
|
to: this.roomJID
|
||||||
|
}).c('pubsub', { xmlns: Strophe.NS.PUBSUB })
|
||||||
|
.c('retract', { node: this.node })
|
||||||
|
.c('item', { id })
|
||||||
|
|
||||||
|
await api.sendIQ(stanza)
|
||||||
|
console.log('Item deleted.')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribed to the pubsub node.
|
* Subscribed to the pubsub node.
|
||||||
*/
|
*/
|
||||||
@ -245,4 +300,8 @@ export class PubSubManager {
|
|||||||
default: return v // dont know what to do
|
default: return v // dont know what to do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_typeFromCollection (collection) {
|
||||||
|
return Object.values(this.types).find(type => type.collection === collection)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@ const locKeys = [
|
|||||||
'tasks',
|
'tasks',
|
||||||
'task_list_create',
|
'task_list_create',
|
||||||
'task_list_create_error',
|
'task_list_create_error',
|
||||||
'task_list_name'
|
'task_list_name',
|
||||||
|
'task_list_delete',
|
||||||
|
'task_list_delete_confirm'
|
||||||
]
|
]
|
||||||
|
|
||||||
module.exports = locKeys
|
module.exports = locKeys
|
||||||
|
@ -438,4 +438,6 @@ login_external_auth_alert_message: "Authentication failed"
|
|||||||
tasks: 'Tasks'
|
tasks: 'Tasks'
|
||||||
task_list_create: 'Create new task list:'
|
task_list_create: 'Create new task list:'
|
||||||
task_list_create_error: 'Error when saving the task list'
|
task_list_create_error: 'Error when saving the task list'
|
||||||
task_list_name: 'Task list name'
|
task_list_name: 'Task list name'
|
||||||
|
task_list_delete: 'Delete task list'
|
||||||
|
task_list_delete_confirm: 'Are you sure you want to delete this task list?'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user