frontend/src/components/tasks/add-task.vue

216 lines
5.5 KiB
Vue

<template>
<div class="field is-grouped">
<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>
</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
};
},
components: {},
props: {
listId: {
type: Number,
required: false
}
},
created() {
this.listService = new ListService();
this.taskService = new TaskService();
this.labelService = new LabelService();
this.labelTaskService = new LabelTaskService();
},
methods: {
addTask() {
if (this.newTaskText === "") {
this.showError = true;
return;
}
this.showError = false;
let task = new TaskModel({
title: this.newTaskText,
listId: this.listId
});
if (this.listId === undefined) {
// TODO: Have a default list in settings.
task.listId = 1;
}
this.taskService
.create(task)
.then(task => {
// this.tasks.push(task);
// this.sortTasks();
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(updatedTask => {
// this.updateTasks(updatedTask);
// this.$store.commit(HAS_TASKS, true);
// })
.then(() => {
this.$store.commit(HAS_TASKS, true);
})
.catch(e => {
this.error(e, this);
});
});
}
this.$emit("taskAdded", task);
})
.catch(e => {
this.error(e, this);
});
}
}
};
</script>