feat: use async / await where it makes sense
This commit is contained in:
@ -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) {
|
||||
|
@ -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 &&
|
||||
|
@ -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')})
|
||||
},
|
||||
},
|
||||
}
|
@ -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()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
@ -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()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
@ -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,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
Reference in New Issue
Block a user