1
0

feat: use async / await where it makes sense

This commit is contained in:
Dominik Pschenitschni
2021-10-11 19:37:20 +02:00
parent a776e1d2f3
commit bb94c1ba3a
74 changed files with 1458 additions and 1662 deletions

View File

@ -78,7 +78,7 @@ export default {
},
actions: {
// Logs a user in with a set of credentials.
login(ctx, credentials) {
async login(ctx, credentials) {
const HTTP = HTTPFactory()
ctx.commit(LOADING, true, {root: true})
@ -94,53 +94,51 @@ export default {
data.totp_passcode = credentials.totpPasscode
}
return HTTP.post('login', data)
.then(response => {
// Save the token to local storage for later use
saveToken(response.data.token, true)
try {
const response = await HTTP.post('login', data)
// Save the token to local storage for later use
saveToken(response.data.token, true)
// Tell others the user is autheticated
ctx.dispatch('checkAuth')
} catch(e) {
if (
e.response &&
e.response.data.code === 1017 &&
!credentials.totpPasscode
) {
ctx.commit('needsTotpPasscode', true)
}
// Tell others the user is autheticated
ctx.dispatch('checkAuth')
})
.catch(e => {
if (
e.response &&
e.response.data.code === 1017 &&
!credentials.totpPasscode
) {
ctx.commit('needsTotpPasscode', true)
}
throw e
})
.finally(() => {
ctx.commit(LOADING, false, {root: true})
})
throw e
} finally {
ctx.commit(LOADING, false, {root: true})
}
},
// Registers a new user and logs them in.
// Not sure if this is the right place to put the logic in, maybe a seperate js component would be better suited.
register(ctx, credentials) {
async register(ctx, credentials) {
const HTTP = HTTPFactory()
return HTTP.post('register', {
username: credentials.username,
email: credentials.email,
password: credentials.password,
})
.then(() => {
return ctx.dispatch('login', credentials)
try {
await HTTP.post('register', {
username: credentials.username,
email: credentials.email,
password: credentials.password,
})
.catch(e => {
if (e.response && e.response.data && e.response.data.message) {
ctx.commit(ERROR_MESSAGE, e.response.data.message, {root: true})
}
return ctx.dispatch('login', credentials)
} catch(e) {
if (e.response && e.response.data && e.response.data.message) {
ctx.commit(ERROR_MESSAGE, e.response.data.message, {root: true})
}
throw e
})
.finally(() => {
ctx.commit(LOADING, false, {root: true})
})
throw e
} finally {
ctx.commit(LOADING, false, {root: true})
}
},
openIdAuth(ctx, {provider, code}) {
async openIdAuth(ctx, {provider, code}) {
const HTTP = HTTPFactory()
ctx.commit(LOADING, true, {root: true})
@ -150,29 +148,28 @@ export default {
// Delete an eventually preexisting old token
removeToken()
return HTTP.post(`/auth/openid/${provider}/callback`, data)
.then(response => {
// Save the token to local storage for later use
saveToken(response.data.token, true)
// Tell others the user is autheticated
ctx.dispatch('checkAuth')
})
.finally(() => {
ctx.commit(LOADING, false, {root: true})
})
try {
const response = await HTTP.post(`/auth/openid/${provider}/callback`, data)
// Save the token to local storage for later use
saveToken(response.data.token, true)
// Tell others the user is autheticated
ctx.dispatch('checkAuth')
} finally {
ctx.commit(LOADING, false, {root: true})
}
},
linkShareAuth(ctx, {hash, password}) {
async linkShareAuth(ctx, {hash, password}) {
const HTTP = HTTPFactory()
return HTTP.post('/shares/' + hash + '/auth', {
const response = await HTTP.post('/shares/' + hash + '/auth', {
password: password,
})
.then(r => {
saveToken(r.data.token, false)
ctx.dispatch('checkAuth')
return r.data
})
saveToken(response.data.token, false)
ctx.dispatch('checkAuth')
return response.data
},
// Populates user information from jwt token saved in local storage in store
checkAuth(ctx) {
@ -205,54 +202,54 @@ export default {
ctx.dispatch('config/redirectToProviderIfNothingElseIsEnabled', null, {root: true})
}
},
refreshUserInfo(ctx) {
async refreshUserInfo(ctx) {
const jwt = getToken()
if (!jwt) {
return
}
const HTTP = HTTPFactory()
// We're not returning the promise here to prevent blocking the initial ui render if the user is
// accessing the site with a token in local storage
HTTP.get('user', {
headers: {
Authorization: `Bearer ${jwt}`,
},
})
.then(r => {
const info = new UserModel(r.data)
info.type = ctx.state.info.type
info.email = ctx.state.info.email
info.exp = ctx.state.info.exp
try {
ctx.commit('info', info)
ctx.commit('lastUserRefresh')
})
.catch(e => {
throw new Error('Error while refreshing user info:', { cause: e })
const response = await HTTP.get('user', {
headers: {
Authorization: `Bearer ${jwt}`,
},
})
const info = new UserModel(response.data)
info.type = ctx.state.info.type
info.email = ctx.state.info.email
info.exp = ctx.state.info.exp
ctx.commit('info', info)
ctx.commit('lastUserRefresh')
return info
} catch(e) {
throw new Error('Error while refreshing user info:', { cause: e })
}
},
// Renews the api token and saves it to local storage
renewToken(ctx) {
// Timeout to avoid race conditions when authenticated as a user (=auth token in localStorage) and as a
// FIXME: Timeout to avoid race conditions when authenticated as a user (=auth token in localStorage) and as a
// link share in another tab. Without the timeout both the token renew and link share auth are executed at
// the same time and one might win over the other.
setTimeout(() => {
setTimeout(async () => {
if (!ctx.state.authenticated) {
return
}
refreshToken(!ctx.state.isLinkShareAuth)
.then(() => {
ctx.dispatch('checkAuth')
})
.catch(e => {
// Don't logout on network errors as the user would then get logged out if they don't have
// internet for a short period of time - such as when the laptop is still reconnecting
if (e.request.status) {
ctx.dispatch('logout')
}
})
try {
await refreshToken(!ctx.state.isLinkShareAuth)
ctx.dispatch('checkAuth')
} catch(e) {
// Don't logout on network errors as the user would then get logged out if they don't have
// internet for a short period of time - such as when the laptop is still reconnecting
if (e.request.status) {
ctx.dispatch('logout')
}
}
}, 5000)
},
logout(ctx) {

View File

@ -60,15 +60,14 @@ export default {
},
},
actions: {
update(ctx) {
async update(ctx) {
const HTTP = HTTPFactory()
return HTTP.get('info')
.then(r => {
ctx.commit(CONFIG, r.data)
return r
})
const { data: info } = await HTTP.get('info')
ctx.commit(CONFIG, info)
return info
},
redirectToProviderIfNothingElseIsEnabled(ctx) {
if (ctx.state.auth.local.enabled === false &&
ctx.state.auth.openidConnect.enabled &&

View File

@ -209,7 +209,7 @@ export default {
},
actions: {
loadBucketsForList(ctx, {listId, params}) {
async loadBucketsForList(ctx, {listId, params}) {
const cancel = setLoading(ctx, 'kanban')
// Clear everything to prevent having old buckets in the list if loading the buckets from this list takes a few moments
@ -218,13 +218,14 @@ export default {
params.per_page = TASKS_PER_BUCKET
const bucketService = new BucketService()
return bucketService.getAll({listId: listId}, params)
.then(r => {
ctx.commit('setBuckets', r)
ctx.commit('setListId', listId)
return r
})
.finally(() => cancel())
try {
const response = await bucketService.getAll({listId: listId}, params)
ctx.commit('setBuckets', response)
ctx.commit('setListId', listId)
return response
} finally {
cancel()
}
},
async loadNextTasksForBucket(ctx, {listId, ps = {}, bucketId}) {
@ -270,48 +271,50 @@ export default {
params.per_page = TASKS_PER_BUCKET
const taskService = new TaskCollectionService()
return taskService.getAll({listId: listId}, params, page)
.then(r => {
ctx.commit('addTasksToBucket', {tasks: r, bucketId: bucketId})
ctx.commit('setTasksLoadedForBucketPage', {bucketId, page})
if (taskService.totalPages <= page) {
ctx.commit('setAllTasksLoadedForBucket', bucketId)
}
return r
})
.finally(() => {
cancel()
ctx.commit('setBucketLoading', {bucketId: bucketId, loading: false})
})
try {
const tasks = await taskService.getAll({listId: listId}, params, page)
ctx.commit('addTasksToBucket', {tasks, bucketId: bucketId})
ctx.commit('setTasksLoadedForBucketPage', {bucketId, page})
if (taskService.totalPages <= page) {
ctx.commit('setAllTasksLoadedForBucket', bucketId)
}
return tasks
} finally {
cancel()
ctx.commit('setBucketLoading', {bucketId: bucketId, loading: false})
}
},
createBucket(ctx, bucket) {
async createBucket(ctx, bucket) {
const cancel = setLoading(ctx, 'kanban')
const bucketService = new BucketService()
return bucketService.create(bucket)
.then(r => {
ctx.commit('addBucket', r)
return r
})
.finally(() => cancel())
try {
const createdBucket = await bucketService.create(bucket)
ctx.commit('addBucket', createdBucket)
return createdBucket
} finally {
cancel()
}
},
deleteBucket(ctx, {bucket, params}) {
async deleteBucket(ctx, {bucket, params}) {
const cancel = setLoading(ctx, 'kanban')
const bucketService = new BucketService()
return bucketService.delete(bucket)
.then(r => {
ctx.commit('removeBucket', bucket)
// We reload all buckets because tasks are being moved from the deleted bucket
ctx.dispatch('loadBucketsForList', {listId: bucket.listId, params: params})
return r
})
.finally(() => cancel())
try {
const response = await bucketService.delete(bucket)
ctx.commit('removeBucket', bucket)
// We reload all buckets because tasks are being moved from the deleted bucket
ctx.dispatch('loadBucketsForList', {listId: bucket.listId, params: params})
return response
} finally {
cancel()
}
},
updateBucket(ctx, updatedBucketData) {
async updateBucket(ctx, updatedBucketData) {
const cancel = setLoading(ctx, 'kanban')
const bucketIndex = findIndexById(ctx.state.buckets, updatedBucketData.id)
@ -324,22 +327,22 @@ export default {
ctx.commit('setBucketByIndex', {bucketIndex, bucket: updatedBucket})
const bucketService = new BucketService()
return bucketService.update(updatedBucket)
.then(r => {
ctx.commit('setBucketByIndex', {bucketIndex, bucket: r})
Promise.resolve(r)
})
.catch(e => {
// restore original state
ctx.commit('setBucketByIndex', {bucketIndex, bucket: oldBucket})
const bucketService = new BucketService()
try {
const returnedBucket = await bucketService.update(updatedBucket)
ctx.commit('setBucketByIndex', {bucketIndex, bucket: returnedBucket})
return returnedBucket
} catch(e) {
// restore original state
ctx.commit('setBucketByIndex', {bucketIndex, bucket: oldBucket})
throw e
})
.finally(() => cancel())
throw e
} finally {
cancel()
}
},
updateBucketTitle(ctx, { id, title }) {
async updateBucketTitle(ctx, { id, title }) {
const bucket = findById(ctx.state.buckets, id)
if (bucket.title === title) {
@ -352,9 +355,8 @@ export default {
title,
}
ctx.dispatch('updateBucket', updatedBucketData).then(() => {
success({message: i18n.global.t('list.kanban.bucketTitleSavedSuccess')})
})
await ctx.dispatch('updateBucket', updatedBucketData)
success({message: i18n.global.t('list.kanban.bucketTitleSavedSuccess')})
},
},
}

View File

@ -42,65 +42,70 @@ export default {
isFavorite: !list.isFavorite,
})
},
createList(ctx, list) {
async createList(ctx, list) {
const cancel = setLoading(ctx, 'lists')
const listService = new ListService()
return listService.create(list)
.then(r => {
r.namespaceId = list.namespaceId
ctx.commit('namespaces/addListToNamespace', r, {root: true})
ctx.commit('setList', r)
return r
})
.finally(() => cancel())
try {
const createdList = await listService.create(list)
createdList.namespaceId = list.namespaceId
ctx.commit('namespaces/addListToNamespace', createdList, {root: true})
ctx.commit('setList', createdList)
return createdList
} finally {
cancel()
}
},
updateList(ctx, list) {
async updateList(ctx, list) {
const cancel = setLoading(ctx, 'lists')
const listService = new ListService()
return listService.update(list)
.then(() => {
ctx.commit('setList', list)
ctx.commit('namespaces/setListInNamespaceById', list, {root: true})
// the returned list from listService.update is the same!
// in order to not validate vuex mutations we have to create a new copy
const newList = {
...list,
namespaceId: FavoriteListsNamespace,
}
if (list.isFavorite) {
ctx.commit('namespaces/addListToNamespace', newList, {root: true})
} else {
ctx.commit('namespaces/removeListFromNamespaceById', newList, {root: true})
}
ctx.dispatch('namespaces/loadNamespacesIfFavoritesDontExist', null, {root: true})
ctx.dispatch('namespaces/removeFavoritesNamespaceIfEmpty', null, {root: true})
return newList
try {
await listService.update(list)
ctx.commit('setList', list)
ctx.commit('namespaces/setListInNamespaceById', list, {root: true})
// the returned list from listService.update is the same!
// in order to not validate vuex mutations we have to create a new copy
const newList = {
...list,
namespaceId: FavoriteListsNamespace,
}
if (list.isFavorite) {
ctx.commit('namespaces/addListToNamespace', newList, {root: true})
} else {
ctx.commit('namespaces/removeListFromNamespaceById', newList, {root: true})
}
ctx.dispatch('namespaces/loadNamespacesIfFavoritesDontExist', null, {root: true})
ctx.dispatch('namespaces/removeFavoritesNamespaceIfEmpty', null, {root: true})
return newList
} catch(e) {
// Reset the list state to the initial one to avoid confusion for the user
ctx.commit('setList', {
...list,
isFavorite: !list.isFavorite,
})
.catch(e => {
// Reset the list state to the initial one to avoid confusion for the user
ctx.commit('setList', {
...list,
isFavorite: !list.isFavorite,
})
throw e
})
.finally(() => cancel())
throw e
} finally {
cancel()
}
},
deleteList(ctx, list) {
async deleteList(ctx, list) {
const cancel = setLoading(ctx, 'lists')
const listService = new ListService()
return listService.delete(list)
.then(r => {
ctx.commit('removeListById', list)
ctx.commit('namespaces/removeListFromNamespaceById', list, {root: true})
removeListFromHistory({id: list.id})
return r
})
.finally(() => cancel())
try {
const response = await listService.delete(list)
ctx.commit('removeListById', list)
ctx.commit('namespaces/removeListFromNamespaceById', list, {root: true})
removeListFromHistory({id: list.id})
return response
} finally{
cancel()
}
},
},
}

View File

@ -94,63 +94,63 @@ export default {
},
},
actions: {
loadNamespaces(ctx) {
async loadNamespaces(ctx) {
const cancel = setLoading(ctx, 'namespaces')
const namespaceService = new NamespaceService()
// We always load all namespaces and filter them on the frontend
return namespaceService.getAll({}, {is_archived: true})
.then(r => {
ctx.commit('namespaces', r)
// Put all lists in the list state
const lists = []
r.forEach(n => {
n.lists.forEach(l => {
lists.push(l)
})
})
ctx.commit('lists/setLists', lists, {root: true})
return r
})
.finally(() => {
cancel()
})
try {
// We always load all namespaces and filter them on the frontend
const namespaces = await namespaceService.getAll({}, {is_archived: true})
ctx.commit('namespaces', namespaces)
// Put all lists in the list state
const lists = namespaces.flatMap(({lists}) => lists)
ctx.commit('lists/setLists', lists, {root: true})
return namespaces
} finally {
cancel()
}
},
loadNamespacesIfFavoritesDontExist(ctx) {
// The first namespace should be the one holding all favorites
if (ctx.state.namespaces[0].id !== -2) {
return ctx.dispatch('loadNamespaces')
}
},
removeFavoritesNamespaceIfEmpty(ctx) {
if (ctx.state.namespaces[0].id === -2 && ctx.state.namespaces[0].lists.length === 0) {
ctx.state.namespaces.splice(0, 1)
}
},
deleteNamespace(ctx, namespace) {
async deleteNamespace(ctx, namespace) {
const cancel = setLoading(ctx, 'namespaces')
const namespaceService = new NamespaceService()
return namespaceService.delete(namespace)
.then(r => {
ctx.commit('removeNamespaceById', namespace.id)
return r
})
.finally(() => cancel())
try {
const response = await namespaceService.delete(namespace)
ctx.commit('removeNamespaceById', namespace.id)
return response
} finally {
cancel()
}
},
createNamespace(ctx, namespace) {
async createNamespace(ctx, namespace) {
const cancel = setLoading(ctx, 'namespaces')
const namespaceService = new NamespaceService()
return namespaceService.create(namespace)
.then(r => {
ctx.commit('addNamespace', r)
return r
})
.finally(() => cancel())
try {
const createdNamespace = await namespaceService.create(namespace)
ctx.commit('addNamespace', createdNamespace)
return createdNamespace
} finally {
cancel()
}
},
},
}

View File

@ -34,17 +34,15 @@ function validateLabel(labels, label) {
return findPropertyByValue(labels, 'title', label)
}
function addLabelToTask(task, label) {
async function addLabelToTask(task, label) {
const labelTask = new LabelTask({
taskId: task.id,
labelId: label.id,
})
const labelTaskService = new LabelTaskService()
return labelTaskService.create(labelTask)
.then(result => {
task.labels.push(label)
return result
})
const response = await labelTaskService.create(labelTask)
task.labels.push(label)
return response
}
async function findAssignees(parsedTaskAssignees) {
@ -67,41 +65,39 @@ export default {
namespaced: true,
state: () => ({}),
actions: {
loadTasks(ctx, params) {
async loadTasks(ctx, params) {
const taskService = new TaskService()
const cancel = setLoading(ctx, 'tasks')
return taskService.getAll({}, params)
.then(r => {
ctx.commit(HAS_TASKS, r.length > 0, {root: true})
return r
})
.finally(() => {
cancel()
})
try {
const tasks = await taskService.getAll({}, params)
ctx.commit(HAS_TASKS, tasks.length > 0, {root: true})
return tasks
} finally {
cancel()
}
},
update(ctx, task) {
async update(ctx, task) {
const cancel = setLoading(ctx, 'tasks')
const taskService = new TaskService()
return taskService.update(task)
.then(t => {
ctx.commit('kanban/setTaskInBucket', t, {root: true})
return t
})
.finally(() => {
cancel()
})
try {
const updatedTask = await taskService.update(task)
ctx.commit('kanban/setTaskInBucket', updatedTask, {root: true})
return updatedTask
} finally {
cancel()
}
},
delete(ctx, task) {
async delete(ctx, task) {
const taskService = new TaskService()
return taskService.delete(task)
.then(t => {
ctx.commit('kanban/removeTaskInBucket', task, {root: true})
return t
})
const response = await taskService.delete(task)
ctx.commit('kanban/removeTaskInBucket', task, {root: true})
return response
},
// Adds a task attachment in store.
// This is an action to be able to commit other mutations
addTaskAttachment(ctx, {taskId, attachment}) {
@ -124,106 +120,97 @@ export default {
ctx.commit('attachments/add', attachment, {root: true})
},
addAssignee(ctx, {user, taskId}) {
async addAssignee(ctx, {user, taskId}) {
const taskAssignee = new TaskAssigneeModel({userId: user.id, taskId: taskId})
const taskAssigneeService = new TaskAssigneeService()
return taskAssigneeService.create(taskAssignee)
.then(r => {
const t = ctx.rootGetters['kanban/getTaskById'](taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not add assignee to task in kanban, task not found', t)
return r
}
// FIXME: direct store manipulation (task)
t.task.assignees.push(user)
ctx.commit('kanban/setTaskInBucketByIndex', t, {root: true})
return r
})
const r = await taskAssigneeService.create(taskAssignee)
const t = ctx.rootGetters['kanban/getTaskById'](taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not add assignee to task in kanban, task not found', t)
return r
}
// FIXME: direct store manipulation (task)
t.task.assignees.push(user)
ctx.commit('kanban/setTaskInBucketByIndex', t, { root: true })
return r
},
removeAssignee(ctx, {user, taskId}) {
async removeAssignee(ctx, {user, taskId}) {
const taskAssignee = new TaskAssigneeModel({userId: user.id, taskId: taskId})
const taskAssigneeService = new TaskAssigneeService()
return taskAssigneeService.delete(taskAssignee)
.then(r => {
const t = ctx.rootGetters['kanban/getTaskById'](taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not remove assignee from task in kanban, task not found', t)
return r
}
const response = await taskAssigneeService.delete(taskAssignee)
const t = ctx.rootGetters['kanban/getTaskById'](taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not remove assignee from task in kanban, task not found', t)
return response
}
for (const a in t.task.assignees) {
if (t.task.assignees[a].id === user.id) {
// FIXME: direct store manipulation (task)
t.task.assignees.splice(a, 1)
break
}
}
ctx.commit('kanban/setTaskInBucketByIndex', t, {root: true})
return r
})
},
addLabel(ctx, {label, taskId}) {
const labelTask = new LabelTaskModel({taskId: taskId, labelId: label.id})
const labelTaskService = new LabelTaskService()
return labelTaskService.create(labelTask)
.then(r => {
const t = ctx.rootGetters['kanban/getTaskById'](taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not add label to task in kanban, task not found', t)
return r
}
for (const a in t.task.assignees) {
if (t.task.assignees[a].id === user.id) {
// FIXME: direct store manipulation (task)
t.task.labels.push(label)
ctx.commit('kanban/setTaskInBucketByIndex', t, {root: true})
t.task.assignees.splice(a, 1)
break
}
}
ctx.commit('kanban/setTaskInBucketByIndex', t, {root: true})
return response
return r
})
},
removeLabel(ctx, {label, taskId}) {
async addLabel(ctx, {label, taskId}) {
const labelTask = new LabelTaskModel({taskId: taskId, labelId: label.id})
const labelTaskService = new LabelTaskService()
return labelTaskService.delete(labelTask)
.then(r => {
const t = ctx.rootGetters['kanban/getTaskById'](taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not remove label from task in kanban, task not found', t)
return r
}
const r = await labelTaskService.create(labelTask)
const t = ctx.rootGetters['kanban/getTaskById'](taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not add label to task in kanban, task not found', t)
return r
}
// FIXME: direct store manipulation (task)
t.task.labels.push(label)
ctx.commit('kanban/setTaskInBucketByIndex', t, { root: true })
return r
},
// Remove the label from the list
for (const l in t.task.labels) {
if (t.task.labels[l].id === label.id) {
// FIXME: direct store manipulation (task)
t.task.labels.splice(l, 1)
break
}
}
async removeLabel(ctx, {label, taskId}) {
const labelTask = new LabelTaskModel({taskId: taskId, labelId: label.id})
ctx.commit('kanban/setTaskInBucketByIndex', t, {root: true})
const labelTaskService = new LabelTaskService()
const response = await labelTaskService.delete(labelTask)
const t = ctx.rootGetters['kanban/getTaskById'](taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not remove label from task in kanban, task not found', t)
return response
}
return r
})
// Remove the label from the list
for (const l in t.task.labels) {
if (t.task.labels[l].id === label.id) {
// FIXME: direct store manipulation (task)
t.task.labels.splice(l, 1)
break
}
}
ctx.commit('kanban/setTaskInBucketByIndex', t, {root: true})
return response
},
// Do everything that is involved in finding, creating and adding the label to the task
@ -308,11 +295,11 @@ export default {
})
const taskService = new TaskService()
return taskService.create(task)
.then(task => dispatch('addLabelsToTask', {
task,
parsedLabels:parsedTask.labels,
}))
const createdTask = await taskService.create(task)
return dispatch('addLabelsToTask', {
task: createdTask,
parsedLabels:parsedTask.labels,
})
},
},
}