Quick add magic for tasks (#570)
Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/570 Co-authored-by: konrad <konrad@kola-entertainments.de> Co-committed-by: konrad <konrad@kola-entertainments.de>
This commit is contained in:
124
src/components/tasks/mixins/createTask.js
Normal file
124
src/components/tasks/mixins/createTask.js
Normal file
@ -0,0 +1,124 @@
|
||||
import {parseTaskText} from '@/helpers/parseTaskText'
|
||||
import TaskModel from '@/models/task'
|
||||
import {formatISO} from 'date-fns'
|
||||
import LabelTask from '@/models/labelTask'
|
||||
import LabelModel from '@/models/label'
|
||||
import LabelTaskService from '@/services/labelTask'
|
||||
import {mapState} from 'vuex'
|
||||
import UserService from '@/services/user'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
labelTaskService: LabelTaskService,
|
||||
userService: UserService,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.labelTaskService = new LabelTaskService()
|
||||
this.userService = new UserService()
|
||||
},
|
||||
computed: mapState({
|
||||
labels: state => state.labels.labels,
|
||||
}),
|
||||
methods: {
|
||||
createNewTask(newTaskTitle, bucketId = 0, lId = 0) {
|
||||
const parsedTask = parseTaskText(newTaskTitle)
|
||||
const assignees = []
|
||||
|
||||
let listId = null
|
||||
if (parsedTask.list !== null) {
|
||||
const list = this.$store.getters['lists/findListByExactname'](parsedTask.list)
|
||||
listId = list === null ? null : list.id
|
||||
}
|
||||
if (listId === null) {
|
||||
listId = lId !== 0 ? lId : this.$route.params.listId
|
||||
}
|
||||
|
||||
// Separate closure because we need to wait for the results of the user search if users were entered in the
|
||||
// task create request. Because _that_ happens in a promise, we'll need something to call when it resolves.
|
||||
const createTask = () => {
|
||||
const task = new TaskModel({
|
||||
title: parsedTask.text,
|
||||
listId: listId,
|
||||
dueDate: parsedTask.date !== null ? formatISO(parsedTask.date) : null, // I don't know why, but it all goes up in flames when I just pass in the date normally.
|
||||
priority: parsedTask.priority,
|
||||
assignees: assignees,
|
||||
bucketId: bucketId,
|
||||
})
|
||||
return this.taskService.create(task)
|
||||
.then(task => {
|
||||
|
||||
if (parsedTask.labels.length > 0) {
|
||||
|
||||
const labelAddsToWaitFor = []
|
||||
|
||||
const addLabelToTask = label => {
|
||||
const labelTask = new LabelTask({
|
||||
taskId: task.id,
|
||||
labelId: label.id,
|
||||
})
|
||||
return this.labelTaskService.create(labelTask)
|
||||
.then(result => {
|
||||
task.labels.push(label)
|
||||
return Promise.resolve(result)
|
||||
})
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
|
||||
// Then do everything that is involved in finding, creating and adding the label to the task
|
||||
parsedTask.labels.forEach(labelTitle => {
|
||||
// Check if the label exists
|
||||
const label = Object.values(this.labels).find(l => {
|
||||
return l.title.toLowerCase() === labelTitle.toLowerCase()
|
||||
})
|
||||
|
||||
// Label found, use it
|
||||
if (typeof label !== 'undefined') {
|
||||
labelAddsToWaitFor.push(addLabelToTask(label))
|
||||
} else {
|
||||
// label not found, create it
|
||||
const label = new LabelModel({title: labelTitle})
|
||||
labelAddsToWaitFor.push(this.$store.dispatch('labels/createLabel', label)
|
||||
.then(res => {
|
||||
return addLabelToTask(res)
|
||||
})
|
||||
.catch(e => Promise.reject(e))
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
// This waits until all labels are created and added to the task
|
||||
return Promise.all(labelAddsToWaitFor)
|
||||
.then(() => {
|
||||
return Promise.resolve(task)
|
||||
})
|
||||
}
|
||||
|
||||
return Promise.resolve(task)
|
||||
})
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
|
||||
if (parsedTask.assignees.length > 0) {
|
||||
const searches = []
|
||||
parsedTask.assignees.forEach(a => {
|
||||
searches.push(this.userService.getAll({}, {s: a})
|
||||
.then(users => {
|
||||
const user = users.find(u => u.username.toLowerCase() === a.toLowerCase())
|
||||
if (typeof user !== 'undefined') {
|
||||
assignees.push(user)
|
||||
}
|
||||
return Promise.resolve(users)
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
return Promise.all(searches)
|
||||
.then(() => createTask())
|
||||
}
|
||||
|
||||
return createTask()
|
||||
},
|
||||
},
|
||||
}
|
82
src/components/tasks/partials/quick-add-magic.vue
Normal file
82
src/components/tasks/partials/quick-add-magic.vue
Normal file
@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<div>
|
||||
<p class="help has-text-grey">
|
||||
{{ $t('task.quickAddMagic.hint') }}.
|
||||
<a @click="() => visible = true">{{ $t('task.quickAddMagic.what') }}</a>
|
||||
</p>
|
||||
<transition name="fade">
|
||||
<div class="modal-mask hint-modal" v-if="visible">
|
||||
<div @click.self="() => visible = false" class="modal-container">
|
||||
<div class="modal-content">
|
||||
<card class="has-background-white has-no-shadow" :title="$t('task.quickAddMagic.title')">
|
||||
<p>{{ $t('task.quickAddMagic.intro') }}</p>
|
||||
|
||||
<h3>{{ $t('task.attributes.labels') }}</h3>
|
||||
<p>
|
||||
{{ $t('task.quickAddMagic.label1', {prefix: '~'}) }}
|
||||
{{ $t('task.quickAddMagic.label2') }}
|
||||
{{ $t('task.quickAddMagic.multiple') }}
|
||||
</p>
|
||||
<p>
|
||||
{{ $t('task.quickAddMagic.label3') }}
|
||||
{{ $t('task.quickAddMagic.label4', {prefix: '~'}) }}
|
||||
</p>
|
||||
|
||||
<h3>{{ $t('task.attributes.priority') }}</h3>
|
||||
<p>
|
||||
{{ $t('task.quickAddMagic.priority1', {prefix: '!'}) }}
|
||||
{{ $t('task.quickAddMagic.priority2') }}
|
||||
</p>
|
||||
|
||||
<h3>{{ $t('task.attributes.assignees') }}</h3>
|
||||
<p>
|
||||
{{ $t('task.quickAddMagic.assignees') }}
|
||||
{{ $t('task.quickAddMagic.multiple') }}
|
||||
</p>
|
||||
|
||||
<h3>{{ $t('list.list.title') }}</h3>
|
||||
<p>
|
||||
{{ $t('task.quickAddMagic.list1', {prefix: '*'}) }}
|
||||
{{ $t('task.quickAddMagic.list2') }}
|
||||
</p>
|
||||
|
||||
<h3>{{ $t('task.quickAddMagic.dateAndTime') }}</h3>
|
||||
<p>
|
||||
{{ $t('task.quickAddMagic.date') }}
|
||||
</p>
|
||||
<ul>
|
||||
<!-- Not localized because these only work in english -->
|
||||
<li>Today</li>
|
||||
<li>Tomorrow</li>
|
||||
<li>Next monday</li>
|
||||
<li>This weekend</li>
|
||||
<li>Later this week</li>
|
||||
<li>Later next week</li>
|
||||
<li>Next week</li>
|
||||
<li>Next month</li>
|
||||
<li>End of month</li>
|
||||
<li>In 5 days [hours/weeks/months]</li>
|
||||
<li>Tuesday ({{ $t('task.quickAddMagic.dateWeekday') }})</li>
|
||||
<li>17/02/2021</li>
|
||||
<li>Feb 17 ({{ $t('task.quickAddMagic.dateCurrentYear') }})</li>
|
||||
<li>17th ({{ $t('task.quickAddMagic.dateNth', {day: '17'}) }})</li>
|
||||
</ul>
|
||||
<p>{{ $t('task.quickAddMagic.dateTime', {time: 'at 17:00', timePM: '5pm'}) }}</p>
|
||||
</card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'quick-add-magic',
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user