feat: use async / await where it makes sense
This commit is contained in:
@ -195,6 +195,7 @@ export default {
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
// FIXME: async action in beforeCreate, might be unfinished when component mounts
|
||||
this.$store.dispatch('namespaces/loadNamespaces')
|
||||
.then(namespaces => {
|
||||
namespaces.forEach(n => {
|
||||
@ -248,7 +249,8 @@ export default {
|
||||
|
||||
this.$store.commit('namespaces/setNamespaceById', newNamespace)
|
||||
},
|
||||
saveListPosition(e, namespaceIndex) {
|
||||
|
||||
async saveListPosition(e, namespaceIndex) {
|
||||
const listsActive = this.activeLists[namespaceIndex]
|
||||
const list = listsActive[e.newIndex]
|
||||
const listBefore = listsActive[e.newIndex - 1] ?? null
|
||||
@ -257,14 +259,15 @@ export default {
|
||||
|
||||
const position = calculateItemPosition(listBefore !== null ? listBefore.position : null, listAfter !== null ? listAfter.position : null)
|
||||
|
||||
// create a copy of the list in order to not violate vuex mutations
|
||||
this.$store.dispatch('lists/updateList', {
|
||||
...list,
|
||||
position,
|
||||
})
|
||||
.finally(() => {
|
||||
this.listUpdating[list.id] = false
|
||||
try {
|
||||
// create a copy of the list in order to not violate vuex mutations
|
||||
await this.$store.dispatch('lists/updateList', {
|
||||
...list,
|
||||
position,
|
||||
})
|
||||
} finally {
|
||||
this.listUpdating[list.id] = false
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ export default {
|
||||
// dom tree. If we're calling this right after setting this.preview it could be the images were
|
||||
// not already made available.
|
||||
// Some docs at https://stackoverflow.com/q/62865160/10924593
|
||||
this.$nextTick(() => {
|
||||
this.$nextTick(async () => {
|
||||
const attachmentImage = document.getElementsByClassName('attachment-image')
|
||||
if (attachmentImage) {
|
||||
for (const img of attachmentImage) {
|
||||
@ -254,11 +254,9 @@ export default {
|
||||
this.attachmentService = new AttachmentService()
|
||||
}
|
||||
|
||||
this.attachmentService.getBlobUrl(attachment)
|
||||
.then(url => {
|
||||
img.src = url
|
||||
this.loadedAttachments[cacheKey] = url
|
||||
})
|
||||
const url = await this.attachmentService.getBlobUrl(attachment)
|
||||
img.src = url
|
||||
this.loadedAttachments[cacheKey] = url
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,7 +468,7 @@ export default {
|
||||
this.filters.done = true
|
||||
}
|
||||
},
|
||||
prepareRelatedObjectFilter(kind, filterName = null, servicePrefix = null) {
|
||||
async prepareRelatedObjectFilter(kind, filterName = null, servicePrefix = null) {
|
||||
if (filterName === null) {
|
||||
filterName = kind
|
||||
}
|
||||
@ -478,12 +478,11 @@ export default {
|
||||
}
|
||||
|
||||
this.prepareSingleValue(filterName)
|
||||
if (typeof this.filters[filterName] !== 'undefined' && this.filters[filterName] !== '') {
|
||||
this[`${servicePrefix}Service`].getAll({}, {s: this.filters[filterName]})
|
||||
.then(r => {
|
||||
this[kind] = r
|
||||
})
|
||||
if (typeof this.filters[filterName] === 'undefined' || this.filters[filterName] === '') {
|
||||
return
|
||||
}
|
||||
|
||||
this[kind] = await this[`${servicePrefix}Service`].getAll({}, {s: this.filters[filterName]})
|
||||
},
|
||||
setDoneFilter() {
|
||||
if (this.filters.done) {
|
||||
@ -523,17 +522,16 @@ export default {
|
||||
clear(kind) {
|
||||
this[`found${kind}`] = []
|
||||
},
|
||||
find(kind, query) {
|
||||
async find(kind, query) {
|
||||
|
||||
if (query === '') {
|
||||
this.clear(kind)
|
||||
}
|
||||
|
||||
this[`${kind}Service`].getAll({}, {s: query})
|
||||
.then(response => {
|
||||
// Filter users from the results who are already assigned
|
||||
this[`found${kind}`] = response.filter(({id}) => !includesById(this[kind], id))
|
||||
})
|
||||
const response = await this[`${kind}Service`].getAll({}, {s: query})
|
||||
|
||||
// Filter users from the results who are already assigned
|
||||
this[`found${kind}`] = response.filter(({id}) => !includesById(this[kind], id))
|
||||
},
|
||||
add(kind, filterName) {
|
||||
this.$nextTick(() => {
|
||||
|
@ -56,7 +56,7 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadBackground() {
|
||||
async loadBackground() {
|
||||
if (this.list === null || !this.list.backgroundInformation || this.backgroundLoading) {
|
||||
return
|
||||
}
|
||||
@ -64,11 +64,11 @@ export default {
|
||||
this.backgroundLoading = true
|
||||
|
||||
const listService = new ListService()
|
||||
listService.background(this.list)
|
||||
.then(b => {
|
||||
this.background = b
|
||||
})
|
||||
.finally(() => this.backgroundLoading = false)
|
||||
try {
|
||||
this.background = await listService.background(this.list)
|
||||
} finally {
|
||||
this.backgroundLoading = false
|
||||
}
|
||||
},
|
||||
toggleFavoriteList(list) {
|
||||
// The favorites pseudo list is always favorite
|
||||
|
@ -141,43 +141,32 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getAuthUrl() {
|
||||
this.migrationService.getAuthUrl()
|
||||
.then(r => {
|
||||
this.authUrl = r.url
|
||||
})
|
||||
async getAuthUrl() {
|
||||
const { url } = this.migrationService.getAuthUrl()
|
||||
this.authUrl = url
|
||||
},
|
||||
migrate() {
|
||||
|
||||
async migrate() {
|
||||
this.isMigrating = true
|
||||
this.lastMigrationDate = null
|
||||
this.message = ''
|
||||
|
||||
let migrationConfig = { code: this.migratorAuthCode }
|
||||
|
||||
if (this.isFileMigrator) {
|
||||
return this.migrateFile()
|
||||
if (this.$refs.uploadInput.files.length === 0) {
|
||||
return
|
||||
}
|
||||
migrationConfig = this.$refs.uploadInput.files[0]
|
||||
}
|
||||
|
||||
this.migrationService.migrate({code: this.migratorAuthCode})
|
||||
.then(r => {
|
||||
this.message = r.message
|
||||
this.$store.dispatch('namespaces/loadNamespaces')
|
||||
})
|
||||
.finally(() => {
|
||||
this.isMigrating = false
|
||||
})
|
||||
},
|
||||
migrateFile() {
|
||||
if (this.$refs.uploadInput.files.length === 0) {
|
||||
return
|
||||
try {
|
||||
const { message } = await this.migrationService.migrate(migrationConfig)
|
||||
this.message = message
|
||||
return this.$store.dispatch('namespaces/loadNamespaces')
|
||||
} finally {
|
||||
this.isMigrating = false
|
||||
}
|
||||
|
||||
this.migrationService.migrate(this.$refs.uploadInput.files[0])
|
||||
.then(r => {
|
||||
this.message = r.message
|
||||
this.$store.dispatch('namespaces/loadNamespaces')
|
||||
})
|
||||
.finally(() => {
|
||||
this.isMigrating = false
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -89,27 +89,23 @@ export default {
|
||||
this.unsubscribe()
|
||||
}
|
||||
},
|
||||
subscribe() {
|
||||
async subscribe() {
|
||||
const subscription = new SubscriptionModel({
|
||||
entity: this.entity,
|
||||
entityId: this.entityId,
|
||||
})
|
||||
this.subscriptionService.create(subscription)
|
||||
.then(() => {
|
||||
this.$emit('change', subscription)
|
||||
this.$message.success({message: this.$t('task.subscription.subscribeSuccess', {entity: this.entity})})
|
||||
})
|
||||
await this.subscriptionService.create(subscription)
|
||||
this.$emit('change', subscription)
|
||||
this.$message.success({message: this.$t('task.subscription.subscribeSuccess', {entity: this.entity})})
|
||||
},
|
||||
unsubscribe() {
|
||||
async unsubscribe() {
|
||||
const subscription = new SubscriptionModel({
|
||||
entity: this.entity,
|
||||
entityId: this.entityId,
|
||||
})
|
||||
this.subscriptionService.delete(subscription)
|
||||
.then(() => {
|
||||
this.$emit('change', null)
|
||||
this.$message.success({message: this.$t('task.subscription.unsubscribeSuccess', {entity: this.entity})})
|
||||
})
|
||||
await this.subscriptionService.delete(subscription)
|
||||
this.$emit('change', null)
|
||||
this.$message.success({message: this.$t('task.subscription.unsubscribeSuccess', {entity: this.entity})})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -93,11 +93,8 @@ export default {
|
||||
closeWhenClickedOutside(e, this.$refs.popup, () => this.showNotifications = false)
|
||||
}
|
||||
},
|
||||
loadNotifications() {
|
||||
this.notificationService.getAll()
|
||||
.then(r => {
|
||||
this.allNotifications = r
|
||||
})
|
||||
async loadNotifications() {
|
||||
this.allNotifications = await this.notificationService.getAll()
|
||||
},
|
||||
to(n, index) {
|
||||
const to = {
|
||||
@ -124,16 +121,13 @@ export default {
|
||||
break
|
||||
}
|
||||
|
||||
return () => {
|
||||
return async () => {
|
||||
if (to.name !== '') {
|
||||
this.$router.push(to)
|
||||
}
|
||||
|
||||
n.read = true
|
||||
this.notificationService.update(n)
|
||||
.then(r => {
|
||||
this.allNotifications[index] = r
|
||||
})
|
||||
this.allNotifications[index] = await this.notificationService.update(n)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -282,20 +282,17 @@ export default {
|
||||
this.taskSearchTimeout = null
|
||||
}
|
||||
|
||||
this.taskSearchTimeout = setTimeout(() => {
|
||||
this.taskService.getAll({}, {s: query})
|
||||
.then(r => {
|
||||
r = r.map(t => {
|
||||
t.type = TYPE_TASK
|
||||
const list = this.$store.getters['lists/getListById'](t.listId) === null ? null : this.$store.getters['lists/getListById'](t.listId)
|
||||
if (list !== null) {
|
||||
t.title = `${t.title} (${list.title})`
|
||||
}
|
||||
this.taskSearchTimeout = setTimeout(async () => {
|
||||
const r = await this.taskService.getAll({}, {s: query})
|
||||
this.foundTasks = r.map(t => {
|
||||
t.type = TYPE_TASK
|
||||
const list = this.$store.getters['lists/getListById'](t.listId)
|
||||
if (list !== null) {
|
||||
t.title = `${t.title} (${list.title})`
|
||||
}
|
||||
|
||||
return t
|
||||
})
|
||||
this.foundTasks = r
|
||||
})
|
||||
return t
|
||||
})
|
||||
}, 150)
|
||||
},
|
||||
searchTeams() {
|
||||
@ -318,15 +315,12 @@ export default {
|
||||
this.teamSearchTimeout = null
|
||||
}
|
||||
|
||||
this.teamSearchTimeout = setTimeout(() => {
|
||||
this.teamService.getAll({}, {s: query})
|
||||
.then(r => {
|
||||
r = r.map(t => {
|
||||
t.title = t.name
|
||||
return t
|
||||
})
|
||||
this.foundTeams = r
|
||||
})
|
||||
this.teamSearchTimeout = setTimeout(async () => {
|
||||
const r = await this.teamService.getAll({}, {s: query})
|
||||
this.foundTeams = r.map(t => {
|
||||
t.title = t.name
|
||||
return t
|
||||
})
|
||||
}, 150)
|
||||
},
|
||||
closeQuickActions() {
|
||||
@ -378,22 +372,20 @@ export default {
|
||||
break
|
||||
}
|
||||
},
|
||||
newTask() {
|
||||
async newTask() {
|
||||
if (this.currentList === null) {
|
||||
return
|
||||
}
|
||||
|
||||
this.$store.dispatch('tasks/createNewTask', {
|
||||
const task = await this.$store.dispatch('tasks/createNewTask', {
|
||||
title: this.query,
|
||||
listId: this.currentList.id,
|
||||
})
|
||||
.then(r => {
|
||||
this.$message.success({message: this.$t('task.createSuccess')})
|
||||
this.$router.push({name: 'task.detail', params: {id: r.id}})
|
||||
this.closeQuickActions()
|
||||
})
|
||||
this.$message.success({message: this.$t('task.createSuccess')})
|
||||
this.$router.push({name: 'task.detail', params: {id: task.id}})
|
||||
this.closeQuickActions()
|
||||
},
|
||||
newList() {
|
||||
async newList() {
|
||||
if (this.currentList === null) {
|
||||
return
|
||||
}
|
||||
@ -402,33 +394,27 @@ export default {
|
||||
title: this.query,
|
||||
namespaceId: this.currentList.namespaceId,
|
||||
})
|
||||
this.$store.dispatch('lists/createList', newList)
|
||||
.then(r => {
|
||||
this.$message.success({message: this.$t('list.create.createdSuccess')})
|
||||
this.$router.push({name: 'list.index', params: {listId: r.id}})
|
||||
this.closeQuickActions()
|
||||
})
|
||||
const list = await this.$store.dispatch('lists/createList', newList)
|
||||
this.$message.success({message: this.$t('list.create.createdSuccess')})
|
||||
this.$router.push({name: 'list.index', params: {listId: list.id}})
|
||||
this.closeQuickActions()
|
||||
},
|
||||
newNamespace() {
|
||||
async newNamespace() {
|
||||
const newNamespace = new NamespaceModel({title: this.query})
|
||||
|
||||
this.$store.dispatch('namespaces/createNamespace', newNamespace)
|
||||
.then(() => {
|
||||
this.$message.success({message: this.$t('namespace.create.success')})
|
||||
this.closeQuickActions()
|
||||
})
|
||||
await this.$store.dispatch('namespaces/createNamespace', newNamespace)
|
||||
this.$message.success({message: this.$t('namespace.create.success')})
|
||||
this.closeQuickActions()
|
||||
},
|
||||
newTeam() {
|
||||
async newTeam() {
|
||||
const newTeam = new TeamModel({name: this.query})
|
||||
this.teamService.create(newTeam)
|
||||
.then(r => {
|
||||
this.$router.push({
|
||||
name: 'teams.edit',
|
||||
params: {id: r.id},
|
||||
})
|
||||
this.$message.success({message: this.$t('team.create.success')})
|
||||
this.closeQuickActions()
|
||||
})
|
||||
const team = await this.teamService.create(newTeam)
|
||||
this.$router.push({
|
||||
name: 'teams.edit',
|
||||
params: {id: team.id},
|
||||
})
|
||||
this.$message.success({message: this.$t('team.create.success')})
|
||||
this.closeQuickActions()
|
||||
},
|
||||
select(parentIndex, index) {
|
||||
|
||||
|
@ -215,50 +215,41 @@ export default {
|
||||
frontendUrl: (state) => state.config.frontendUrl,
|
||||
}),
|
||||
methods: {
|
||||
load(listId) {
|
||||
async load(listId) {
|
||||
// If listId == 0 the list on the calling component wasn't already loaded, so we just bail out here
|
||||
if (listId === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
this.linkShareService
|
||||
.getAll({listId})
|
||||
.then((r) => {
|
||||
this.linkShares = r
|
||||
})
|
||||
this.linkShares = await this.linkShareService.getAll({listId})
|
||||
},
|
||||
add(listId) {
|
||||
async add(listId) {
|
||||
const newLinkShare = new LinkShareModel({
|
||||
right: this.selectedRight,
|
||||
listId,
|
||||
name: this.name,
|
||||
password: this.password,
|
||||
})
|
||||
this.linkShareService
|
||||
.create(newLinkShare)
|
||||
.then(() => {
|
||||
this.selectedRight = rights.READ
|
||||
this.name = ''
|
||||
this.password = ''
|
||||
this.showNewForm = false
|
||||
this.$message.success({message: this.$t('list.share.links.createSuccess')})
|
||||
this.load(listId)
|
||||
})
|
||||
await this.linkShareService.create(newLinkShare)
|
||||
this.selectedRight = rights.READ
|
||||
this.name = ''
|
||||
this.password = ''
|
||||
this.showNewForm = false
|
||||
this.$message.success({message: this.$t('list.share.links.createSuccess')})
|
||||
await this.load(listId)
|
||||
},
|
||||
remove(listId) {
|
||||
async remove(listId) {
|
||||
const linkshare = new LinkShareModel({
|
||||
id: this.linkIdToDelete,
|
||||
listId,
|
||||
})
|
||||
this.linkShareService
|
||||
.delete(linkshare)
|
||||
.then(() => {
|
||||
this.$message.success({message: this.$t('list.share.links.deleteSuccess')})
|
||||
this.load(listId)
|
||||
})
|
||||
.finally(() => {
|
||||
this.showDeleteModal = false
|
||||
})
|
||||
try {
|
||||
await this.linkShareService.delete(linkshare)
|
||||
this.$message.success({message: this.$t('list.share.links.deleteSuccess')})
|
||||
await this.load(listId)
|
||||
} finally {
|
||||
this.showDeleteModal = false
|
||||
}
|
||||
},
|
||||
copy,
|
||||
getShareLink(hash) {
|
||||
|
@ -272,39 +272,34 @@ export default {
|
||||
this.load()
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
this.stuffService
|
||||
.getAll(this.stuffModel)
|
||||
.then((r) => {
|
||||
this.sharables = r
|
||||
r.forEach((s) =>
|
||||
this.selectedRight[s.id] = s.right,
|
||||
)
|
||||
})
|
||||
async load() {
|
||||
this.sharables = await this.stuffService.getAll(this.stuffModel)
|
||||
this.sharables.forEach((s) =>
|
||||
this.selectedRight[s.id] = s.right,
|
||||
)
|
||||
},
|
||||
deleteSharable() {
|
||||
|
||||
async deleteSharable() {
|
||||
if (this.shareType === 'user') {
|
||||
this.stuffModel.userId = this.sharable.username
|
||||
} else if (this.shareType === 'team') {
|
||||
this.stuffModel.teamId = this.sharable.id
|
||||
}
|
||||
|
||||
this.stuffService
|
||||
.delete(this.stuffModel)
|
||||
.then(() => {
|
||||
this.showDeleteModal = false
|
||||
for (const i in this.sharables) {
|
||||
if (
|
||||
(this.sharables[i].username === this.stuffModel.userId && this.shareType === 'user') ||
|
||||
(this.sharables[i].id === this.stuffModel.teamId && this.shareType === 'team')
|
||||
) {
|
||||
this.sharables.splice(i, 1)
|
||||
}
|
||||
}
|
||||
this.$message.success({message: this.$t('list.share.userTeam.removeSuccess', {type: this.shareTypeName, sharable: this.sharableName})})
|
||||
})
|
||||
await this.stuffService.delete(this.stuffModel)
|
||||
this.showDeleteModal = false
|
||||
for (const i in this.sharables) {
|
||||
if (
|
||||
(this.sharables[i].username === this.stuffModel.userId && this.shareType === 'user') ||
|
||||
(this.sharables[i].id === this.stuffModel.teamId && this.shareType === 'team')
|
||||
) {
|
||||
this.sharables.splice(i, 1)
|
||||
}
|
||||
}
|
||||
this.$message.success({message: this.$t('list.share.userTeam.removeSuccess', {type: this.shareTypeName, sharable: this.sharableName})})
|
||||
},
|
||||
add(admin) {
|
||||
|
||||
async add(admin) {
|
||||
if (admin === null) {
|
||||
admin = false
|
||||
}
|
||||
@ -319,14 +314,12 @@ export default {
|
||||
this.stuffModel.teamId = this.sharable.id
|
||||
}
|
||||
|
||||
this.stuffService
|
||||
.create(this.stuffModel)
|
||||
.then(() => {
|
||||
this.$message.success({message: this.$t('list.share.userTeam.addedSuccess', {type: this.shareTypeName})})
|
||||
this.load()
|
||||
})
|
||||
await this.stuffService.create(this.stuffModel)
|
||||
this.$message.success({message: this.$t('list.share.userTeam.addedSuccess', {type: this.shareTypeName})})
|
||||
await this.load()
|
||||
},
|
||||
toggleType(sharable) {
|
||||
|
||||
async toggleType(sharable) {
|
||||
if (
|
||||
this.selectedRight[sharable.id] !== rights.ADMIN &&
|
||||
this.selectedRight[sharable.id] !== rights.READ &&
|
||||
@ -342,35 +335,30 @@ export default {
|
||||
this.stuffModel.teamId = sharable.id
|
||||
}
|
||||
|
||||
this.stuffService
|
||||
.update(this.stuffModel)
|
||||
.then((r) => {
|
||||
for (const i in this.sharables) {
|
||||
if (
|
||||
(this.sharables[i].username ===
|
||||
this.stuffModel.userId &&
|
||||
this.shareType === 'user') ||
|
||||
(this.sharables[i].id === this.stuffModel.teamId &&
|
||||
this.shareType === 'team')
|
||||
) {
|
||||
this.sharables[i].right = r.right
|
||||
}
|
||||
}
|
||||
this.$message.success({message: this.$t('list.share.userTeam.updatedSuccess', {type: this.shareTypeName})})
|
||||
})
|
||||
const r = await this.stuffService.update(this.stuffModel)
|
||||
for (const i in this.sharables) {
|
||||
if (
|
||||
(this.sharables[i].username ===
|
||||
this.stuffModel.userId &&
|
||||
this.shareType === 'user') ||
|
||||
(this.sharables[i].id === this.stuffModel.teamId &&
|
||||
this.shareType === 'team')
|
||||
) {
|
||||
this.sharables[i].right = r.right
|
||||
}
|
||||
}
|
||||
this.$message.success({message: this.$t('list.share.userTeam.updatedSuccess', {type: this.shareTypeName})})
|
||||
},
|
||||
find(query) {
|
||||
|
||||
async find(query) {
|
||||
if (query === '') {
|
||||
this.clearAll()
|
||||
return
|
||||
}
|
||||
|
||||
this.searchService
|
||||
.getAll({}, {s: query})
|
||||
.then((response) => {
|
||||
this.found = response
|
||||
})
|
||||
this.found = await this.searchService.getAll({}, {s: query})
|
||||
},
|
||||
|
||||
clearAll() {
|
||||
this.found = []
|
||||
},
|
||||
|
@ -82,7 +82,7 @@ export default {
|
||||
this.initialTextAreaHeight = this.$refs.newTaskInput.scrollHeight + INPUT_BORDER_PX
|
||||
},
|
||||
methods: {
|
||||
addTask() {
|
||||
async addTask() {
|
||||
if (this.newTaskTitle === '') {
|
||||
this.errorMessage = this.$t('list.create.addTitleRequired')
|
||||
return
|
||||
@ -93,37 +93,31 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
const newTasks = []
|
||||
this.newTaskTitle.split(/[\r\n]+/).forEach(t => {
|
||||
const newTasks = this.newTaskTitle.split(/[\r\n]+/).map(async t => {
|
||||
const title = cleanupTitle(t)
|
||||
if (title === '') {
|
||||
return
|
||||
}
|
||||
|
||||
newTasks.push(
|
||||
this.$store.dispatch('tasks/createNewTask', {
|
||||
title: this.newTaskTitle,
|
||||
listId: this.$store.state.auth.settings.defaultListId,
|
||||
position: this.defaultPosition,
|
||||
})
|
||||
.then(task => {
|
||||
this.$emit('taskAdded', task)
|
||||
return task
|
||||
}),
|
||||
)
|
||||
const task = await this.$store.dispatch('tasks/createNewTask', {
|
||||
title: this.newTaskTitle,
|
||||
listId: this.$store.state.auth.settings.defaultListId,
|
||||
position: this.defaultPosition,
|
||||
})
|
||||
this.$emit('taskAdded', task)
|
||||
return task
|
||||
})
|
||||
|
||||
return Promise.all(newTasks)
|
||||
.then(() => {
|
||||
this.newTaskTitle = ''
|
||||
})
|
||||
.catch(e => {
|
||||
if (e.message === 'NO_LIST') {
|
||||
this.errorMessage = this.$t('list.create.addListRequired')
|
||||
return
|
||||
}
|
||||
throw e
|
||||
})
|
||||
try {
|
||||
await Promise.all(newTasks)
|
||||
this.newTaskTitle = ''
|
||||
} catch(e) {
|
||||
if (e.message === 'NO_LIST') {
|
||||
this.errorMessage = this.$t('list.create.addListRequired')
|
||||
return
|
||||
}
|
||||
throw e
|
||||
}
|
||||
},
|
||||
handleEnter(e) {
|
||||
// when pressing shift + enter we want to continue as we normally would. Otherwise, we want to create
|
||||
|
@ -134,14 +134,10 @@ export default {
|
||||
this.editorActive = false
|
||||
this.$nextTick(() => (this.editorActive = true))
|
||||
},
|
||||
editTaskSubmit() {
|
||||
this.taskService
|
||||
.update(this.taskEditTask)
|
||||
.then((r) => {
|
||||
this.taskEditTask = r
|
||||
this.initTaskFields()
|
||||
this.$message.success({message: this.$t('task.detail.updateSuccess')})
|
||||
})
|
||||
async editTaskSubmit() {
|
||||
this.taskEditTask = await this.taskService.update(this.taskEditTask)
|
||||
this.initTaskFields()
|
||||
this.$message.success({message: this.$t('task.detail.updateSuccess')})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -297,48 +297,41 @@ export default {
|
||||
console.debug('prepareGanttDays; years:', years)
|
||||
this.days = years
|
||||
},
|
||||
|
||||
parseTasks() {
|
||||
this.setDates()
|
||||
this.loadTasks()
|
||||
},
|
||||
loadTasks() {
|
||||
|
||||
async loadTasks() {
|
||||
this.theTasks = []
|
||||
this.tasksWithoutDates = []
|
||||
|
||||
const getAllTasks = (page = 1) => {
|
||||
return this.taskCollectionService
|
||||
.getAll({listId: this.listId}, this.params, page)
|
||||
.then((tasks) => {
|
||||
if (page < this.taskCollectionService.totalPages) {
|
||||
return getAllTasks(page + 1).then((nextTasks) => {
|
||||
return tasks.concat(nextTasks)
|
||||
})
|
||||
} else {
|
||||
return tasks
|
||||
}
|
||||
})
|
||||
const getAllTasks = async (page = 1) => {
|
||||
const tasks = await this.taskCollectionService.getAll({listId: this.listId}, this.params, page)
|
||||
if (page < this.taskCollectionService.totalPages) {
|
||||
const nextTasks = await getAllTasks(page + 1)
|
||||
return tasks.concat(nextTasks)
|
||||
}
|
||||
return tasks
|
||||
}
|
||||
|
||||
getAllTasks()
|
||||
.then((tasks) => {
|
||||
this.theTasks = tasks
|
||||
.filter((t) => {
|
||||
if (t.startDate === null && !t.done) {
|
||||
this.tasksWithoutDates.push(t)
|
||||
}
|
||||
return (
|
||||
t.startDate >= this.startDate &&
|
||||
t.endDate <= this.endDate
|
||||
)
|
||||
})
|
||||
.map((t) => {
|
||||
return this.addGantAttributes(t)
|
||||
})
|
||||
.sort(function (a, b) {
|
||||
if (a.startDate < b.startDate) return -1
|
||||
if (a.startDate > b.startDate) return 1
|
||||
return 0
|
||||
})
|
||||
const tasks = await getAllTasks()
|
||||
this.theTasks = tasks
|
||||
.filter((t) => {
|
||||
if (t.startDate === null && !t.done) {
|
||||
this.tasksWithoutDates.push(t)
|
||||
}
|
||||
return (
|
||||
t.startDate >= this.startDate &&
|
||||
t.endDate <= this.endDate
|
||||
)
|
||||
})
|
||||
.map((t) => this.addGantAttributes(t))
|
||||
.sort(function (a, b) {
|
||||
if (a.startDate < b.startDate) return -1
|
||||
if (a.startDate > b.startDate) return 1
|
||||
return 0
|
||||
})
|
||||
},
|
||||
addGantAttributes(t) {
|
||||
@ -351,7 +344,7 @@ export default {
|
||||
t.offsetDays = Math.floor((t.startDate - this.startDate) / 1000 / 60 / 60 / 24)
|
||||
return t
|
||||
},
|
||||
resizeTask(taskDragged, newRect) {
|
||||
async resizeTask(taskDragged, newRect) {
|
||||
if (this.isTaskEdit) {
|
||||
return
|
||||
}
|
||||
@ -392,31 +385,28 @@ export default {
|
||||
offsetDays: newTask.offsetDays,
|
||||
}
|
||||
|
||||
this.taskService
|
||||
.update(newTask)
|
||||
.then(r => {
|
||||
r.endDate = ganttData.endDate
|
||||
r.durationDays = ganttData.durationDays
|
||||
r.offsetDays = ganttData.offsetDays
|
||||
const r = await this.taskService.update(newTask)
|
||||
r.endDate = ganttData.endDate
|
||||
r.durationDays = ganttData.durationDays
|
||||
r.offsetDays = ganttData.offsetDays
|
||||
|
||||
// If the task didn't have dates before, we'll update the list
|
||||
if (didntHaveDates) {
|
||||
for (const t in this.tasksWithoutDates) {
|
||||
if (this.tasksWithoutDates[t].id === r.id) {
|
||||
this.tasksWithoutDates.splice(t, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.theTasks.push(this.addGantAttributes(r))
|
||||
} else {
|
||||
for (const tt in this.theTasks) {
|
||||
if (this.theTasks[tt].id === r.id) {
|
||||
this.theTasks[tt] = this.addGantAttributes(r)
|
||||
break
|
||||
}
|
||||
}
|
||||
// If the task didn't have dates before, we'll update the list
|
||||
if (didntHaveDates) {
|
||||
for (const t in this.tasksWithoutDates) {
|
||||
if (this.tasksWithoutDates[t].id === r.id) {
|
||||
this.tasksWithoutDates.splice(t, 1)
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
this.theTasks.push(this.addGantAttributes(r))
|
||||
} else {
|
||||
for (const tt in this.theTasks) {
|
||||
if (this.theTasks[tt].id === r.id) {
|
||||
this.theTasks[tt] = this.addGantAttributes(r)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
editTask(task) {
|
||||
this.taskToEdit = task
|
||||
@ -436,7 +426,7 @@ export default {
|
||||
this.$nextTick(() => (this.newTaskFieldActive = false))
|
||||
}
|
||||
},
|
||||
addNewTask() {
|
||||
async addNewTask() {
|
||||
if (!this.newTaskFieldActive) {
|
||||
return
|
||||
}
|
||||
@ -444,13 +434,10 @@ export default {
|
||||
title: this.newTaskTitle,
|
||||
listId: this.listId,
|
||||
})
|
||||
this.taskService
|
||||
.create(task)
|
||||
.then((r) => {
|
||||
this.tasksWithoutDates.push(this.addGantAttributes(r))
|
||||
this.newTaskTitle = ''
|
||||
this.hideCrateNewTask()
|
||||
})
|
||||
const r = await this.taskService.create(task)
|
||||
this.tasksWithoutDates.push(this.addGantAttributes(r))
|
||||
this.newTaskTitle = ''
|
||||
this.hideCrateNewTask()
|
||||
},
|
||||
formatYear(date) {
|
||||
return this.format(date, 'MMMM, yyyy')
|
||||
|
@ -38,7 +38,7 @@ export default {
|
||||
'$route.path': 'loadTasksOnSavedFilter',
|
||||
},
|
||||
methods: {
|
||||
loadTasks(
|
||||
async loadTasks(
|
||||
page,
|
||||
search = '',
|
||||
params = null,
|
||||
@ -76,14 +76,9 @@ export default {
|
||||
}
|
||||
|
||||
this.tasks = []
|
||||
|
||||
this.taskCollectionService.getAll(list, params, page)
|
||||
.then(r => {
|
||||
this.tasks = r
|
||||
this.currentPage = page
|
||||
|
||||
this.loadedList = JSON.parse(JSON.stringify(currentList))
|
||||
})
|
||||
this.tasks = await this.taskCollectionService.getAll(list, params, page)
|
||||
this.currentPage = page
|
||||
this.loadedList = JSON.parse(JSON.stringify(currentList))
|
||||
},
|
||||
|
||||
loadTasksForPage(e) {
|
||||
|
@ -218,21 +218,19 @@ export default {
|
||||
uploadFiles(files) {
|
||||
uploadFiles(this.attachmentService, this.taskId, files)
|
||||
},
|
||||
deleteAttachment() {
|
||||
this.attachmentService
|
||||
.delete(this.attachmentToDelete)
|
||||
.then((r) => {
|
||||
this.$store.commit(
|
||||
'attachments/removeById',
|
||||
this.attachmentToDelete.id,
|
||||
)
|
||||
this.$message.success(r)
|
||||
})
|
||||
.finally(() => {
|
||||
this.showDeleteModal = false
|
||||
})
|
||||
async deleteAttachment() {
|
||||
try {
|
||||
const r = await this.attachmentService.delete(this.attachmentToDelete)
|
||||
this.$store.commit(
|
||||
'attachments/removeById',
|
||||
this.attachmentToDelete.id,
|
||||
)
|
||||
this.$message.success(r)
|
||||
} finally{
|
||||
this.showDeleteModal = false
|
||||
}
|
||||
},
|
||||
viewOrDownload(attachment) {
|
||||
async viewOrDownload(attachment) {
|
||||
if (
|
||||
attachment.file.name.endsWith('.jpg') ||
|
||||
attachment.file.name.endsWith('.png') ||
|
||||
@ -240,9 +238,7 @@ export default {
|
||||
attachment.file.name.endsWith('.gif')
|
||||
) {
|
||||
this.showImageModal = true
|
||||
this.attachmentService.getBlobUrl(attachment).then((url) => {
|
||||
this.attachmentImageBlobUrl = url
|
||||
})
|
||||
this.attachmentImageBlobUrl = await this.attachmentService.getBlobUrl(attachment)
|
||||
} else {
|
||||
this.downloadAttachment(attachment)
|
||||
}
|
||||
|
@ -134,9 +134,9 @@
|
||||
|
||||
<transition name="modal">
|
||||
<modal
|
||||
@close="showDeleteModal = false"
|
||||
@submit="deleteComment()"
|
||||
v-if="showDeleteModal"
|
||||
@close="showDeleteModal = false"
|
||||
@submit="() => deleteComment(commentToDelete)"
|
||||
>
|
||||
<template #header><span>{{ $t('task.comment.delete') }}</span></template>
|
||||
|
||||
@ -186,7 +186,6 @@ export default {
|
||||
taskCommentService: new TaskCommentService(),
|
||||
newComment: new TaskCommentModel(),
|
||||
editorActive: true,
|
||||
actions: {},
|
||||
|
||||
saved: null,
|
||||
saving: null,
|
||||
@ -195,40 +194,46 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
taskId: {
|
||||
handler(taskId) {
|
||||
if (!this.enabled) {
|
||||
return
|
||||
}
|
||||
|
||||
this.loadComments()
|
||||
this.newComment.taskId = taskId
|
||||
this.commentEdit.taskId = taskId
|
||||
this.commentToDelete.taskId = taskId
|
||||
},
|
||||
handler: 'loadComments',
|
||||
immediate: true,
|
||||
},
|
||||
canWrite() {
|
||||
this.makeActions()
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
userAvatar: state => state.auth.info.getAvatarUrl(48),
|
||||
enabled: state => state.config.taskCommentsEnabled,
|
||||
}),
|
||||
actions() {
|
||||
if (!this.canWrite) {
|
||||
return {}
|
||||
}
|
||||
return Object.fromEntries(this.comments.map((c) => ([
|
||||
c.id,
|
||||
[{
|
||||
action: () => this.toggleDelete(c.id),
|
||||
title: this.$t('misc.delete'),
|
||||
}],
|
||||
])))
|
||||
},
|
||||
},
|
||||
computed: mapState({
|
||||
userAvatar: state => state.auth.info.getAvatarUrl(48),
|
||||
enabled: state => state.config.taskCommentsEnabled,
|
||||
}),
|
||||
|
||||
methods: {
|
||||
attachmentUpload(...args) {
|
||||
return uploadFile(this.taskId, ...args)
|
||||
},
|
||||
|
||||
loadComments() {
|
||||
this.taskCommentService
|
||||
.getAll({taskId: this.taskId})
|
||||
.then(r => {
|
||||
this.comments = r
|
||||
this.makeActions()
|
||||
})
|
||||
async loadComments(taskId) {
|
||||
if (!this.enabled) {
|
||||
return
|
||||
}
|
||||
|
||||
this.newComment.taskId = taskId
|
||||
this.commentEdit.taskId = taskId
|
||||
this.commentToDelete.taskId = taskId
|
||||
this.comments = await this.taskCommentService.getAll({taskId})
|
||||
},
|
||||
addComment() {
|
||||
|
||||
async addComment() {
|
||||
if (this.newComment.comment === '') {
|
||||
return
|
||||
}
|
||||
@ -242,27 +247,27 @@ export default {
|
||||
this.$nextTick(() => (this.editorActive = true))
|
||||
this.creating = true
|
||||
|
||||
this.taskCommentService
|
||||
.create(this.newComment)
|
||||
.then((r) => {
|
||||
this.comments.push(r)
|
||||
this.newComment.comment = ''
|
||||
this.$message.success({message: this.$t('task.comment.addedSuccess')})
|
||||
this.makeActions()
|
||||
})
|
||||
.finally(() => {
|
||||
this.creating = false
|
||||
})
|
||||
try {
|
||||
const comment = await this.taskCommentService.create(this.newComment)
|
||||
this.comments.push(comment)
|
||||
this.newComment.comment = ''
|
||||
this.$message.success({message: this.$t('task.comment.addedSuccess')})
|
||||
} finally {
|
||||
this.creating = false
|
||||
}
|
||||
},
|
||||
|
||||
toggleEdit(comment) {
|
||||
this.isCommentEdit = !this.isCommentEdit
|
||||
this.commentEdit = comment
|
||||
},
|
||||
|
||||
toggleDelete(commentId) {
|
||||
this.showDeleteModal = !this.showDeleteModal
|
||||
this.commentToDelete.id = commentId
|
||||
},
|
||||
editComment() {
|
||||
|
||||
async editComment() {
|
||||
if (this.commentEdit.comment === '') {
|
||||
return
|
||||
}
|
||||
@ -270,48 +275,30 @@ export default {
|
||||
this.saving = this.commentEdit.id
|
||||
|
||||
this.commentEdit.taskId = this.taskId
|
||||
this.taskCommentService
|
||||
.update(this.commentEdit)
|
||||
.then((r) => {
|
||||
for (const c in this.comments) {
|
||||
if (this.comments[c].id === this.commentEdit.id) {
|
||||
this.comments[c] = r
|
||||
}
|
||||
try {
|
||||
const comment = this.taskCommentService.update(this.commentEdit)
|
||||
for (const c in this.comments) {
|
||||
if (this.comments[c].id === this.commentEdit.id) {
|
||||
this.comments[c] = comment
|
||||
}
|
||||
this.saved = this.commentEdit.id
|
||||
setTimeout(() => {
|
||||
this.saved = null
|
||||
}, 2000)
|
||||
})
|
||||
.finally(() => {
|
||||
this.isCommentEdit = false
|
||||
this.saving = null
|
||||
})
|
||||
}
|
||||
this.saved = this.commentEdit.id
|
||||
setTimeout(() => {
|
||||
this.saved = null
|
||||
}, 2000)
|
||||
} finally {
|
||||
this.isCommentEdit = false
|
||||
this.saving = null
|
||||
}
|
||||
},
|
||||
deleteComment() {
|
||||
this.taskCommentService
|
||||
.delete(this.commentToDelete)
|
||||
.then(() => {
|
||||
for (const a in this.comments) {
|
||||
if (this.comments[a].id === this.commentToDelete.id) {
|
||||
this.comments.splice(a, 1)
|
||||
}
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.showDeleteModal = false
|
||||
})
|
||||
},
|
||||
makeActions() {
|
||||
if (this.canWrite) {
|
||||
this.comments.forEach((c) => {
|
||||
this.actions[c.id] = [
|
||||
{
|
||||
action: () => this.toggleDelete(c.id),
|
||||
title: this.$t('misc.delete'),
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
async deleteComment(commentToDelete) {
|
||||
try {
|
||||
await this.taskCommentService.delete(commentToDelete)
|
||||
const index = this.comments.findIndex(({id}) => id === commentToDelete.id)
|
||||
this.comments.splice(index, 1)
|
||||
} finally {
|
||||
this.showDeleteModal = false
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -112,7 +112,8 @@ export default {
|
||||
this.dueDate = this.dueDate.setDate(this.dueDate.getDate() + days)
|
||||
this.updateDueDate()
|
||||
},
|
||||
updateDueDate() {
|
||||
|
||||
async updateDueDate() {
|
||||
if (!this.dueDate) {
|
||||
return
|
||||
}
|
||||
@ -122,13 +123,10 @@ export default {
|
||||
}
|
||||
|
||||
this.task.dueDate = new Date(this.dueDate)
|
||||
this.taskService
|
||||
.update(this.task)
|
||||
.then((r) => {
|
||||
this.lastValue = r.dueDate
|
||||
this.task = r
|
||||
this.$emit('update:modelValue', r)
|
||||
})
|
||||
const task = await this.taskService.update(this.task)
|
||||
this.lastValue = task.dueDate
|
||||
this.task = task
|
||||
this.$emit('update:modelValue', task)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -71,21 +71,19 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
save() {
|
||||
async save() {
|
||||
this.saving = true
|
||||
|
||||
this.$store.dispatch('tasks/update', this.task)
|
||||
.then(t => {
|
||||
this.task = t
|
||||
this.$emit('update:modelValue', t)
|
||||
this.saved = true
|
||||
setTimeout(() => {
|
||||
this.saved = false
|
||||
}, 2000)
|
||||
})
|
||||
.finally(() => {
|
||||
this.saving = false
|
||||
})
|
||||
try {
|
||||
this.task = await this.$store.dispatch('tasks/update', this.task)
|
||||
this.$emit('update:modelValue', this.task)
|
||||
this.saved = true
|
||||
setTimeout(() => {
|
||||
this.saved = false
|
||||
}, 2000)
|
||||
} finally {
|
||||
this.saving = false
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -78,40 +78,40 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
addAssignee(user) {
|
||||
this.$store.dispatch('tasks/addAssignee', {user: user, taskId: this.taskId})
|
||||
.then(() => {
|
||||
this.$emit('update:modelValue', this.assignees)
|
||||
this.$message.success({message: this.$t('task.assignee.assignSuccess')})
|
||||
})
|
||||
async addAssignee(user) {
|
||||
await this.$store.dispatch('tasks/addAssignee', {user: user, taskId: this.taskId})
|
||||
this.$emit('update:modelValue', this.assignees)
|
||||
this.$message.success({message: this.$t('task.assignee.assignSuccess')})
|
||||
},
|
||||
removeAssignee(user) {
|
||||
this.$store.dispatch('tasks/removeAssignee', {user: user, taskId: this.taskId})
|
||||
.then(() => {
|
||||
// Remove the assignee from the list
|
||||
for (const a in this.assignees) {
|
||||
if (this.assignees[a].id === user.id) {
|
||||
this.assignees.splice(a, 1)
|
||||
}
|
||||
}
|
||||
this.$message.success({message: this.$t('task.assignee.unassignSuccess')})
|
||||
})
|
||||
|
||||
async removeAssignee(user) {
|
||||
await this.$store.dispatch('tasks/removeAssignee', {user: user, taskId: this.taskId})
|
||||
|
||||
// Remove the assignee from the list
|
||||
for (const a in this.assignees) {
|
||||
if (this.assignees[a].id === user.id) {
|
||||
this.assignees.splice(a, 1)
|
||||
}
|
||||
}
|
||||
this.$message.success({message: this.$t('task.assignee.unassignSuccess')})
|
||||
},
|
||||
findUser(query) {
|
||||
|
||||
async findUser(query) {
|
||||
if (query === '') {
|
||||
this.clearAllFoundUsers()
|
||||
return
|
||||
}
|
||||
|
||||
this.listUserService.getAll({listId: this.listId}, {s: query})
|
||||
.then(response => {
|
||||
// Filter the results to not include users who are already assigned
|
||||
this.foundUsers = response.filter(({id}) => !includesById(this.assignees, id))
|
||||
})
|
||||
const response = await this.listUserService.getAll({listId: this.listId}, {s: query})
|
||||
|
||||
// Filter the results to not include users who are already assigned
|
||||
this.foundUsers = response.filter(({id}) => !includesById(this.assignees, id))
|
||||
},
|
||||
|
||||
clearAllFoundUsers() {
|
||||
this.foundUsers = []
|
||||
},
|
||||
|
||||
focus() {
|
||||
this.$refs.multiselect.focus()
|
||||
},
|
||||
|
@ -93,7 +93,8 @@ export default {
|
||||
findLabel(query) {
|
||||
this.query = query
|
||||
},
|
||||
addLabel(label, showNotification = true) {
|
||||
|
||||
async addLabel(label, showNotification = true) {
|
||||
const bubble = () => {
|
||||
this.$emit('update:modelValue', this.labels)
|
||||
this.$emit('change', this.labels)
|
||||
@ -104,15 +105,14 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
this.$store.dispatch('tasks/addLabel', {label: label, taskId: this.taskId})
|
||||
.then(() => {
|
||||
bubble()
|
||||
if (showNotification) {
|
||||
this.$message.success({message: this.$t('task.label.addSuccess')})
|
||||
}
|
||||
})
|
||||
await this.$store.dispatch('tasks/addLabel', {label: label, taskId: this.taskId})
|
||||
bubble()
|
||||
if (showNotification) {
|
||||
this.$message.success({message: this.$t('task.label.addSuccess')})
|
||||
}
|
||||
},
|
||||
removeLabel(label) {
|
||||
|
||||
async removeLabel(label) {
|
||||
const removeFromState = () => {
|
||||
for (const l in this.labels) {
|
||||
if (this.labels[l].id === label.id) {
|
||||
@ -128,24 +128,21 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
this.$store.dispatch('tasks/removeLabel', {label: label, taskId: this.taskId})
|
||||
.then(() => {
|
||||
removeFromState()
|
||||
this.$message.success({message: this.$t('task.label.removeSuccess')})
|
||||
})
|
||||
await this.$store.dispatch('tasks/removeLabel', {label: label, taskId: this.taskId})
|
||||
removeFromState()
|
||||
this.$message.success({message: this.$t('task.label.removeSuccess')})
|
||||
},
|
||||
createAndAddLabel(title) {
|
||||
|
||||
async createAndAddLabel(title) {
|
||||
if (this.taskId === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const newLabel = new LabelModel({title: title})
|
||||
this.$store.dispatch('labels/createLabel', newLabel)
|
||||
.then(r => {
|
||||
this.addLabel(r, false)
|
||||
this.labels.push(r)
|
||||
this.$message.success({message: this.$t('task.label.addCreateSuccess')})
|
||||
})
|
||||
const label = await this.$store.dispatch('labels/createLabel', newLabel)
|
||||
this.addLabel(label, false)
|
||||
this.labels.push(label)
|
||||
this.$message.success({message: this.$t('task.label.addCreateSuccess')})
|
||||
},
|
||||
|
||||
},
|
||||
|
@ -58,7 +58,7 @@ export default {
|
||||
emits: ['update:modelValue'],
|
||||
|
||||
methods: {
|
||||
save(title) {
|
||||
async save(title) {
|
||||
// We only want to save if the title was actually changed.
|
||||
// Because the contenteditable does not have a change event
|
||||
// we're building it ourselves and only continue
|
||||
@ -74,17 +74,17 @@ export default {
|
||||
title,
|
||||
}
|
||||
|
||||
this.$store.dispatch('tasks/update', newTask)
|
||||
.then((task) => {
|
||||
this.$emit('update:modelValue', task)
|
||||
this.showSavedMessage = true
|
||||
setTimeout(() => {
|
||||
this.showSavedMessage = false
|
||||
}, 2000)
|
||||
})
|
||||
.finally(() => {
|
||||
this.saving = false
|
||||
})
|
||||
try {
|
||||
const task = await this.$store.dispatch('tasks/update', newTask)
|
||||
this.$emit('update:modelValue', task)
|
||||
this.showSavedMessage = true
|
||||
setTimeout(() => {
|
||||
this.showSavedMessage = false
|
||||
}, 2000)
|
||||
}
|
||||
finally {
|
||||
this.saving = false
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -6,9 +6,9 @@
|
||||
'has-light-text': !colorIsDark(task.hexColor) && task.hexColor !== `#${task.defaultColor}` && task.hexColor !== task.defaultColor,
|
||||
}"
|
||||
:style="{'background-color': task.hexColor !== '#' && task.hexColor !== `#${task.defaultColor}` ? task.hexColor : false}"
|
||||
@click.ctrl="() => markTaskAsDone(task)"
|
||||
@click.ctrl="() => toggleTaskDone(task)"
|
||||
@click.exact="() => $router.push({ name: 'task.kanban.detail', params: { id: task.id } })"
|
||||
@click.meta="() => markTaskAsDone(task)"
|
||||
@click.meta="() => toggleTaskDone(task)"
|
||||
class="task loader-container draggable"
|
||||
>
|
||||
<span class="task-id">
|
||||
@ -93,20 +93,19 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
markTaskAsDone(task) {
|
||||
async toggleTaskDone(task) {
|
||||
this.loadingInternal = true
|
||||
this.$store.dispatch('tasks/update', {
|
||||
...task,
|
||||
done: !task.done,
|
||||
})
|
||||
.then(() => {
|
||||
if (task.done) {
|
||||
playPop()
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadingInternal = false
|
||||
try {
|
||||
await this.$store.dispatch('tasks/update', {
|
||||
...task,
|
||||
done: !task.done,
|
||||
})
|
||||
if (task.done) {
|
||||
playPop()
|
||||
}
|
||||
} finally {
|
||||
this.loadingInternal = false
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -50,25 +50,25 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
findLists(query) {
|
||||
async findLists(query) {
|
||||
if (query === '') {
|
||||
this.clearAll()
|
||||
return
|
||||
}
|
||||
|
||||
this.listSerivce.getAll({}, {s: query})
|
||||
.then(response => {
|
||||
this.foundLists = response
|
||||
})
|
||||
this.foundLists = await this.listSerivce.getAll({}, {s: query})
|
||||
},
|
||||
|
||||
clearAll() {
|
||||
this.foundLists = []
|
||||
},
|
||||
|
||||
select(list) {
|
||||
this.list = list
|
||||
this.$emit('selected', list)
|
||||
this.$emit('update:modelValue', list)
|
||||
},
|
||||
|
||||
namespace(namespaceId) {
|
||||
const namespace = this.$store.getters['namespaces/getNamespaceById'](namespaceId)
|
||||
if (namespace !== null) {
|
||||
|
@ -188,58 +188,59 @@ export default {
|
||||
async findTasks(query) {
|
||||
this.foundTasks = await this.taskService.getAll({}, {s: query})
|
||||
},
|
||||
addTaskRelation() {
|
||||
let rel = new TaskRelationModel({
|
||||
|
||||
async addTaskRelation() {
|
||||
const rel = new TaskRelationModel({
|
||||
taskId: this.taskId,
|
||||
otherTaskId: this.newTaskRelationTask.id,
|
||||
relationKind: this.newTaskRelationKind,
|
||||
})
|
||||
this.taskRelationService.create(rel)
|
||||
.then(() => {
|
||||
if (!this.relatedTasks[this.newTaskRelationKind]) {
|
||||
this.relatedTasks[this.newTaskRelationKind] = []
|
||||
}
|
||||
this.relatedTasks[this.newTaskRelationKind].push(this.newTaskRelationTask)
|
||||
this.newTaskRelationTask = null
|
||||
this.saved = true
|
||||
this.showNewRelationForm = false
|
||||
setTimeout(() => {
|
||||
this.saved = false
|
||||
}, 2000)
|
||||
})
|
||||
await this.taskRelationService.create(rel)
|
||||
if (!this.relatedTasks[this.newTaskRelationKind]) {
|
||||
this.relatedTasks[this.newTaskRelationKind] = []
|
||||
}
|
||||
this.relatedTasks[this.newTaskRelationKind].push(this.newTaskRelationTask)
|
||||
this.newTaskRelationTask = null
|
||||
this.saved = true
|
||||
this.showNewRelationForm = false
|
||||
setTimeout(() => {
|
||||
this.saved = false
|
||||
}, 2000)
|
||||
},
|
||||
removeTaskRelation() {
|
||||
|
||||
async removeTaskRelation() {
|
||||
const rel = new TaskRelationModel({
|
||||
relationKind: this.relationToDelete.relationKind,
|
||||
taskId: this.taskId,
|
||||
otherTaskId: this.relationToDelete.otherTaskId,
|
||||
})
|
||||
this.taskRelationService.delete(rel)
|
||||
.then(() => {
|
||||
Object.keys(this.relatedTasks).forEach(relationKind => {
|
||||
for (const t in this.relatedTasks[relationKind]) {
|
||||
if (this.relatedTasks[relationKind][t].id === this.relationToDelete.otherTaskId && relationKind === this.relationToDelete.relationKind) {
|
||||
this.relatedTasks[relationKind].splice(t, 1)
|
||||
}
|
||||
}
|
||||
})
|
||||
this.saved = true
|
||||
setTimeout(() => {
|
||||
this.saved = false
|
||||
}, 2000)
|
||||
})
|
||||
.finally(() => {
|
||||
this.showDeleteModal = false
|
||||
try {
|
||||
await this.taskRelationService.delete(rel)
|
||||
|
||||
Object.entries(this.relatedTasks).some(([relationKind, t]) => {
|
||||
const found = this.relatedTasks[relationKind][t].id === this.relationToDelete.otherTaskId &&
|
||||
relationKind === this.relationToDelete.relationKind
|
||||
if (!found) return false
|
||||
|
||||
this.relatedTasks[relationKind].splice(t, 1)
|
||||
return true
|
||||
})
|
||||
|
||||
this.saved = true
|
||||
setTimeout(() => {
|
||||
this.saved = false
|
||||
}, 2000)
|
||||
} finally {
|
||||
this.showDeleteModal = false
|
||||
}
|
||||
},
|
||||
createAndRelateTask(title) {
|
||||
|
||||
async createAndRelateTask(title) {
|
||||
const newTask = new TaskModel({title: title, listId: this.listId})
|
||||
this.taskService.create(newTask)
|
||||
.then(r => {
|
||||
this.newTaskRelationTask = r
|
||||
this.addTaskRelation()
|
||||
})
|
||||
this.newTaskRelationTask = await this.taskService.create(newTask)
|
||||
await this.addTaskRelation()
|
||||
},
|
||||
|
||||
relationKindTitle(kind, length) {
|
||||
return this.$tc(`task.relation.kinds.${kind}`, length)
|
||||
},
|
||||
|
@ -166,50 +166,47 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
markAsDone(checked) {
|
||||
const updateFunc = () => {
|
||||
this.taskService.update(this.task)
|
||||
.then(t => {
|
||||
if (this.task.done) {
|
||||
playPop()
|
||||
}
|
||||
this.task = t
|
||||
this.$emit('task-updated', t)
|
||||
this.$message.success({
|
||||
message: this.task.done ?
|
||||
this.$t('task.doneSuccess') :
|
||||
this.$t('task.undoneSuccess'),
|
||||
}, [{
|
||||
title: 'Undo',
|
||||
callback: () => {
|
||||
this.task.done = !this.task.done
|
||||
this.markAsDone(!checked)
|
||||
},
|
||||
}])
|
||||
})
|
||||
async markAsDone(checked) {
|
||||
const updateFunc = async () => {
|
||||
const task = await this.taskService.update(this.task)
|
||||
if (this.task.done) {
|
||||
playPop()
|
||||
}
|
||||
this.task = task
|
||||
this.$emit('task-updated', task)
|
||||
this.$message.success({
|
||||
message: this.task.done ?
|
||||
this.$t('task.doneSuccess') :
|
||||
this.$t('task.undoneSuccess'),
|
||||
}, [{
|
||||
title: 'Undo',
|
||||
callback() {
|
||||
this.task.done = !this.task.done
|
||||
this.markAsDone(!checked)
|
||||
},
|
||||
}])
|
||||
}
|
||||
|
||||
if (checked) {
|
||||
setTimeout(updateFunc, 300) // Delay it to show the animation when marking a task as done
|
||||
} else {
|
||||
updateFunc() // Don't delay it when un-marking it as it doesn't have an animation the other way around
|
||||
await updateFunc() // Don't delay it when un-marking it as it doesn't have an animation the other way around
|
||||
}
|
||||
},
|
||||
toggleFavorite() {
|
||||
|
||||
async toggleFavorite() {
|
||||
this.task.isFavorite = !this.task.isFavorite
|
||||
this.taskService.update(this.task)
|
||||
.then(t => {
|
||||
this.task = t
|
||||
this.$emit('task-updated', t)
|
||||
this.$store.dispatch('namespaces/loadNamespacesIfFavoritesDontExist')
|
||||
})
|
||||
this.task = await this.taskService.update(this.task)
|
||||
this.$emit('task-updated', this.task)
|
||||
this.$store.dispatch('namespaces/loadNamespacesIfFavoritesDontExist')
|
||||
},
|
||||
hideDeferDueDatePopup(e) {
|
||||
if (this.showDefer) {
|
||||
closeWhenClickedOutside(e, this.$refs.deferDueDate.$el, () => {
|
||||
this.showDefer = false
|
||||
})
|
||||
if (!this.showDefer) {
|
||||
return
|
||||
}
|
||||
closeWhenClickedOutside(e, this.$refs.deferDueDate.$el, () => {
|
||||
this.showDefer = false
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -91,34 +91,34 @@ export default {
|
||||
const { avatarProvider } = await this.avatarService.get({})
|
||||
this.avatarProvider = avatarProvider
|
||||
},
|
||||
updateAvatarStatus() {
|
||||
|
||||
async updateAvatarStatus() {
|
||||
const avatarStatus = new AvatarModel({avatarProvider: this.avatarProvider})
|
||||
this.avatarService.update(avatarStatus)
|
||||
.then(() => {
|
||||
this.$message.success({message: this.$t('user.settings.avatar.statusUpdateSuccess')})
|
||||
this.$store.commit('auth/reloadAvatar')
|
||||
})
|
||||
await this.avatarService.update(avatarStatus)
|
||||
this.$message.success({message: this.$t('user.settings.avatar.statusUpdateSuccess')})
|
||||
this.$store.commit('auth/reloadAvatar')
|
||||
},
|
||||
uploadAvatar() {
|
||||
|
||||
async uploadAvatar() {
|
||||
this.loading = true
|
||||
const {canvas} = this.$refs.cropper.getResult()
|
||||
|
||||
if (canvas) {
|
||||
canvas.toBlob(blob => {
|
||||
this.avatarService.create(blob)
|
||||
.then(() => {
|
||||
this.$message.success({message: this.$t('user.settings.avatar.setSuccess')})
|
||||
this.$store.commit('auth/reloadAvatar')
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
this.isCropAvatar = false
|
||||
})
|
||||
})
|
||||
} else {
|
||||
if (!canvas) {
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const blob = await new Promise(resolve => canvas.toBlob(blob => resolve(blob)))
|
||||
await this.avatarService.create(blob)
|
||||
this.$message.success({message: this.$t('user.settings.avatar.setSuccess')})
|
||||
this.$store.commit('auth/reloadAvatar')
|
||||
} finally {
|
||||
this.loading = false
|
||||
this.isCropAvatar = false
|
||||
}
|
||||
},
|
||||
|
||||
cropAvatar() {
|
||||
const avatar = this.$refs.avatarUploadInput.files
|
||||
|
||||
|
@ -43,27 +43,22 @@ export default {
|
||||
name: 'data-export',
|
||||
data() {
|
||||
return {
|
||||
dataExportService: DataExportService,
|
||||
dataExportService: new DataExportService(),
|
||||
password: '',
|
||||
errPasswordRequired: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.dataExportService = new DataExportService()
|
||||
},
|
||||
methods: {
|
||||
requestDataExport() {
|
||||
async requestDataExport() {
|
||||
if (this.password === '') {
|
||||
this.errPasswordRequired = true
|
||||
this.$refs.passwordInput.focus()
|
||||
return
|
||||
}
|
||||
|
||||
this.dataExportService.request(this.password)
|
||||
.then(() => {
|
||||
this.$message.success({message: this.$t('user.export.success')})
|
||||
this.password = ''
|
||||
})
|
||||
await this.dataExportService.request(this.password)
|
||||
this.$message.success({message: this.$t('user.export.success')})
|
||||
this.password = ''
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -101,32 +101,29 @@ export default {
|
||||
deletionScheduledAt: state => parseDateOrNull(state.auth.info.deletionScheduledAt),
|
||||
}),
|
||||
methods: {
|
||||
deleteAccount() {
|
||||
async deleteAccount() {
|
||||
if (this.password === '') {
|
||||
this.errPasswordRequired = true
|
||||
this.$refs.passwordInput.focus()
|
||||
return
|
||||
}
|
||||
|
||||
this.accountDeleteService.request(this.password)
|
||||
.then(() => {
|
||||
this.$message.success({message: this.$t('user.deletion.requestSuccess')})
|
||||
this.password = ''
|
||||
})
|
||||
await this.accountDeleteService.request(this.password)
|
||||
this.$message.success({message: this.$t('user.deletion.requestSuccess')})
|
||||
this.password = ''
|
||||
},
|
||||
cancelDeletion() {
|
||||
|
||||
async cancelDeletion() {
|
||||
if (this.password === '') {
|
||||
this.errPasswordRequired = true
|
||||
this.$refs.passwordInput.focus()
|
||||
return
|
||||
}
|
||||
|
||||
this.accountDeleteService.cancel(this.password)
|
||||
.then(() => {
|
||||
this.$message.success({message: this.$t('user.deletion.scheduledCancelSuccess')})
|
||||
this.$store.dispatch('auth/refreshUserInfo')
|
||||
this.password = ''
|
||||
})
|
||||
await this.accountDeleteService.cancel(this.password)
|
||||
this.$message.success({message: this.$t('user.deletion.scheduledCancelSuccess')})
|
||||
this.$store.dispatch('auth/refreshUserInfo')
|
||||
this.password = ''
|
||||
},
|
||||
},
|
||||
}
|
||||
|
Reference in New Issue
Block a user