frontend/src/components/tasks/add-task.vue
2021-06-02 15:32:13 -07:00

218 lines
5.6 KiB
Vue

<template>
<div class="field is-grouped" v-if="validListIdAvailable">
<p
:class="{ 'is-loading': taskService.loading }"
class="control has-icons-left is-expanded"
>
<input
:class="{ disabled: taskService.loading }"
@keyup.enter="addTask()"
class="input"
placeholder="Add a new task..."
type="text"
v-focus
v-model="newTaskText"
ref="newTaskInput"
/>
<span class="icon is-small is-left">
<icon icon="tasks" />
</span>
</p>
<p class="control">
<x-button
:disabled="newTaskText.length === 0"
@click="addTask()"
icon="plus"
>
Add
</x-button>
</p>
<p class="help is-warning" v-if="!validListIdAvailable">
No default list set. Please go to settings and specify default list.
</p>
</div>
</template>
<script>
import LabelTask from '../../models/labelTask'
import LabelModel from '../../models/label'
import { HAS_TASKS } from '@/store/mutation-types'
// import Nothing from "@/components/misc/nothing";
import ListService from '../../services/list'
import TaskService from '../../services/task'
import TaskModel from '../../models/task'
import LabelService from '../../services/label'
import LabelTaskService from '../../services/labelTask'
export default {
name: 'add-task',
data() {
return {
newTaskText: '',
listService: ListService,
taskService: TaskService,
labelService: LabelService,
labelTaskService: LabelTaskService,
listIdForNewTask: undefined,
validListIdAvailable: false,
}
},
components: {},
props: {
listId: {
type: Number,
required: false,
},
},
created() {
this.listService = new ListService()
this.taskService = new TaskService()
this.labelService = new LabelService()
this.labelTaskService = new LabelTaskService()
},
beforeMount() {
console.log(this.listId)
if (this.listId !== undefined) {
this.listIdForNewTask = this.listId
this.validListIdAvailable = true
}
},
methods: {
addTask() {
if (this.newTaskText === '') {
this.showError = true
return
}
this.showError = false
const task = new TaskModel({
title: this.newTaskText,
listId: this.listIdForNewTask,
})
this.taskService
.create(task)
.then(task => {
this.newTaskText = ''
// Check if the task has words starting with ~ in the title and make them to labels
const parts = task.title.split(' ~')
// The first element will always contain the title, even if there is no occurrence of ~
if (parts.length > 1) {
// First, create an unresolved promise for each entry in the array to wait
// until all labels are added to update the task title once again
let labelAddings = []
let labelAddsToWaitFor = []
parts.forEach((p, index) => {
if (index < 1) {
return
}
labelAddsToWaitFor.push(
new Promise((resolve, reject) => {
labelAddings.push({ resolve: resolve, reject: reject })
}),
)
})
// Then do everything that is involved in finding, creating and adding the label to the task
parts.forEach((p, index) => {
if (index < 1) {
return
}
// The part up until the next space
const labelTitle = p.split(' ')[0]
// Don't create an empty label
if (labelTitle === '') {
return
}
// Check if the label exists
this.labelService
.getAll({}, { s: labelTitle })
.then(res => {
// Label found, use it
if (res.length > 0 && res[0].title === labelTitle) {
const labelTask = new LabelTask({
taskId: task.id,
labelId: res[0].id,
})
this.labelTaskService
.create(labelTask)
.then(result => {
task.labels.push(res[0])
// Remove the label text from the task title
task.title = task.title.replace(` ~${labelTitle}`, '')
// Make the promise done (the one with the index 0 does not exist)
labelAddings[index - 1].resolve(result)
})
.catch(e => {
this.error(e, this)
})
} else {
// label not found, create it
const label = new LabelModel({ title: labelTitle })
this.labelService
.create(label)
.then(res => {
const labelTask = new LabelTask({
taskId: task.id,
labelId: res.id,
})
this.labelTaskService
.create(labelTask)
.then(result => {
task.labels.push(res)
// Remove the label text from the task title
task.title = task.title.replace(
` ~${labelTitle}`,
'',
)
// Make the promise done (the one with the index 0 does not exist)
labelAddings[index - 1].resolve(result)
})
.catch(e => {
this.error(e, this)
})
})
.catch(e => {
this.error(e, this)
})
}
})
.catch(e => {
this.error(e, this)
})
})
// This waits to update the task until all labels have been added and the title has
// been modified to remove each label text
Promise.all(labelAddsToWaitFor).then(() => {
this.taskService
.update(task)
.then(() => {
this.$store.commit(HAS_TASKS, true)
})
.catch(e => {
this.error(e, this)
})
})
}
this.$emit('taskAdded', task)
})
.catch(e => {
this.error(e, this)
})
},
},
}
</script>