From a776e1d2f30fc4889430d8e8d8dbe376a76e28f8 Mon Sep 17 00:00:00 2001 From: Dominik Pschenitschni Date: Sat, 9 Oct 2021 16:34:57 +0200 Subject: [PATCH] chore: don't resolve when returning from promise & improve list store module --- src/components/misc/api-config.vue | 14 ++--- src/helpers/auth.ts | 2 +- src/i18n/index.js | 15 +++-- src/services/abstractService.js | 33 +++++----- src/services/attachment.js | 6 +- src/services/list.js | 2 +- src/services/passwordReset.js | 4 +- src/services/totp.js | 7 +-- src/store/modules/auth.js | 24 ++++---- src/store/modules/config.js | 2 +- src/store/modules/kanban.js | 8 +-- src/store/modules/labels.js | 96 +++++++++++++++--------------- src/store/modules/lists.js | 6 +- src/store/modules/namespaces.js | 7 +-- src/store/modules/tasks.js | 39 ++++++------ src/views/labels/ListLabels.vue | 15 +---- 16 files changed, 130 insertions(+), 150 deletions(-) diff --git a/src/components/misc/api-config.vue b/src/components/misc/api-config.vue index 06312ca30..acf36df8c 100644 --- a/src/components/misc/api-config.vue +++ b/src/components/misc/api-config.vue @@ -106,7 +106,7 @@ export default { window.API_URL = urlToCheck.toString() return this.$store.dispatch('config/update') } - return Promise.reject(e) + throw e }) .catch((e) => { // Check if it has a port and if not check if it is reachable at https @@ -115,7 +115,7 @@ export default { window.API_URL = urlToCheck.toString() return this.$store.dispatch('config/update') } - return Promise.reject(e) + throw e }) .catch((e) => { // Check if it is reachable at /api/v1 and https @@ -128,7 +128,7 @@ export default { window.API_URL = urlToCheck.toString() return this.$store.dispatch('config/update') } - return Promise.reject(e) + throw e }) .catch((e) => { // Check if it is reachable at port API_DEFAULT_PORT and https @@ -138,7 +138,7 @@ export default { window.API_URL = urlToCheck.toString() return this.$store.dispatch('config/update') } - return Promise.reject(e) + throw e }) .catch((e) => { // Check if it is reachable at :API_DEFAULT_PORT and /api/v1 and https @@ -151,7 +151,7 @@ export default { window.API_URL = urlToCheck.toString() return this.$store.dispatch('config/update') } - return Promise.reject(e) + throw e }) .catch((e) => { // Check if it is reachable at port API_DEFAULT_PORT and http @@ -161,7 +161,7 @@ export default { window.API_URL = urlToCheck.toString() return this.$store.dispatch('config/update') } - return Promise.reject(e) + throw e }) .catch((e) => { // Check if it is reachable at :API_DEFAULT_PORT and /api/v1 and http @@ -174,7 +174,7 @@ export default { window.API_URL = urlToCheck.toString() return this.$store.dispatch('config/update') } - return Promise.reject(e) + throw e }) .catch(() => { // Still not found, url is still invalid diff --git a/src/helpers/auth.ts b/src/helpers/auth.ts index 60a5f70b3..b3297bde6 100644 --- a/src/helpers/auth.ts +++ b/src/helpers/auth.ts @@ -50,7 +50,7 @@ export const refreshToken = (persist: boolean): Promise => { }) .then(r => { saveToken(r.data.token, persist) - return Promise.resolve(r) + return r }) .catch(e => { throw new Error('Error renewing token: ', { cause: e }) diff --git a/src/i18n/index.js b/src/i18n/index.js index 6b21f2a98..006234024 100644 --- a/src/i18n/index.js +++ b/src/i18n/index.js @@ -27,14 +27,13 @@ const setI18nLanguage = lang => { } export const loadLanguageAsync = lang => { - // If the same language - if (i18n.locale === lang) { - return Promise.resolve(setI18nLanguage(lang)) - } - - // If the language was already loaded - if (loadedLanguages.includes(lang)) { - return Promise.resolve(setI18nLanguage(lang)) + if ( + // If the same language + i18n.locale === lang || + // If the language was already loaded + loadedLanguages.includes(lang) + ) { + return setI18nLanguage(lang) } // If the language hasn't been loaded yet diff --git a/src/services/abstractService.js b/src/services/abstractService.js index f61a337d3..2bb58be08 100644 --- a/src/services/abstractService.js +++ b/src/services/abstractService.js @@ -295,7 +295,7 @@ export default class AbstractService { .then(response => { const result = this.modelGetFactory(response.data) result.maxRight = Number(response.headers['x-max-right']) - return Promise.resolve(result) + return result }) .finally(() => { cancel() @@ -338,14 +338,12 @@ export default class AbstractService { this.totalPages = Number(response.headers['x-pagination-total-pages']) if (Array.isArray(response.data)) { - return Promise.resolve(response.data.map(entry => { - return this.modelGetAllFactory(entry) - })) + return response.data.map(entry => this.modelGetAllFactory(entry)) } if (response.data === null) { - return Promise.resolve([]) + return [] } - return Promise.resolve(this.modelGetAllFactory(response.data)) + return this.modelGetAllFactory(response.data) }) .finally(() => { cancel() @@ -371,7 +369,7 @@ export default class AbstractService { if (typeof model.maxRight !== 'undefined') { result.maxRight = model.maxRight } - return Promise.resolve(result) + return result }) .finally(() => { cancel() @@ -394,7 +392,7 @@ export default class AbstractService { if (typeof model.maxRight !== 'undefined') { result.maxRight = model.maxRight } - return Promise.resolve(result) + return result }) .finally(() => { cancel() @@ -420,7 +418,7 @@ export default class AbstractService { * @param model * @returns {Q.Promise} */ - delete(model) { + async delete(model) { if (this.paths.delete === '') { throw new Error('This model is not able to delete data.') } @@ -428,13 +426,12 @@ export default class AbstractService { const cancel = this.setLoading() const finalUrl = this.getReplacedRoute(this.paths.delete, model) - return this.http.delete(finalUrl, model) - .then(response => { - return Promise.resolve(response.data) - }) - .finally(() => { - cancel() - }) + try { + const {data} = await this.http.delete(finalUrl, model) + return data + } finally { + cancel() + } } /** @@ -485,9 +482,7 @@ export default class AbstractService { }, }, ) - .then(response => { - return Promise.resolve(this.modelCreateFactory(response.data)) - }) + .then(response => this.modelCreateFactory(response.data)) .finally(() => { this.uploadProgress = 0 cancel() diff --git a/src/services/attachment.js b/src/services/attachment.js index afd28cdc4..098d5ef6f 100644 --- a/src/services/attachment.js +++ b/src/services/attachment.js @@ -37,9 +37,9 @@ export default class AttachmentService extends AbstractService { return AbstractService.prototype.getBlobUrl.call(this, '/tasks/' + model.taskId + '/attachments/' + model.id) } - download(model) { - this.getBlobUrl(model) - .then(url => downloadBlob(url, model.file.name)) + async download(model) { + const url = await this.getBlobUrl(model) + return downloadBlob(url, model.file.name) } /** diff --git a/src/services/list.js b/src/services/list.js index b720df9fb..925773ddc 100644 --- a/src/services/list.js +++ b/src/services/list.js @@ -46,7 +46,7 @@ export default class ListService extends AbstractService { background(list) { if (list.background === null) { - return Promise.resolve('') + return '' } return this.http({ diff --git a/src/services/passwordReset.js b/src/services/passwordReset.js index 95b2c94d6..023f7c752 100644 --- a/src/services/passwordReset.js +++ b/src/services/passwordReset.js @@ -19,7 +19,7 @@ export default class PasswordResetService extends AbstractService { const cancel = this.setLoading() return this.http.post(this.paths.reset, model) .then(response => { - return Promise.resolve(this.modelFactory(response.data)) + return this.modelFactory(response.data) }) .finally(() => { cancel() @@ -30,7 +30,7 @@ export default class PasswordResetService extends AbstractService { const cancel = this.setLoading() return this.http.post(this.paths.requestReset, model) .then(response => { - return Promise.resolve(this.modelFactory(response.data)) + return this.modelFactory(response.data) }) .finally(() => { cancel() diff --git a/src/services/totp.js b/src/services/totp.js index 021d68e07..93367ab38 100644 --- a/src/services/totp.js +++ b/src/services/totp.js @@ -26,13 +26,12 @@ export default class TotpService extends AbstractService { return this.post(`${this.urlPrefix}/disable`, model) } - qrcode() { - return this.http({ + async qrcode() { + const response = await this.http({ url: `${this.urlPrefix}/qrcode`, method: 'GET', responseType: 'blob', - }).then(response => { - return Promise.resolve(new Blob([response.data])) }) + return new Blob([response.data]) } } \ No newline at end of file diff --git a/src/store/modules/auth.js b/src/store/modules/auth.js index 12795faf3..b7b9b652d 100644 --- a/src/store/modules/auth.js +++ b/src/store/modules/auth.js @@ -101,17 +101,17 @@ export default { // Tell others the user is autheticated ctx.dispatch('checkAuth') - return Promise.resolve() }) .catch(e => { - if (e.response) { - if (e.response.data.code === 1017 && !credentials.totpPasscode) { - ctx.commit('needsTotpPasscode', true) - return Promise.reject(e) - } + if ( + e.response && + e.response.data.code === 1017 && + !credentials.totpPasscode + ) { + ctx.commit('needsTotpPasscode', true) } - return Promise.reject(e) + throw e }) .finally(() => { ctx.commit(LOADING, false, {root: true}) @@ -134,7 +134,7 @@ export default { ctx.commit(ERROR_MESSAGE, e.response.data.message, {root: true}) } - return Promise.reject(e) + throw e }) .finally(() => { ctx.commit(LOADING, false, {root: true}) @@ -157,7 +157,6 @@ export default { // Tell others the user is autheticated ctx.dispatch('checkAuth') - return Promise.resolve() }) .finally(() => { ctx.commit(LOADING, false, {root: true}) @@ -180,7 +179,7 @@ export default { // This function can be called from multiple places at the same time and shortly after one another. // To prevent hitting the api too frequently or race conditions, we check at most once per minute. if (ctx.state.lastUserInfoRefresh !== null && ctx.state.lastUserInfoRefresh > (new Date()).setMinutes((new Date()).getMinutes() + 1)) { - return Promise.resolve() + return } const jwt = getToken() @@ -190,14 +189,13 @@ export default { .split('.')[1] .replace('-', '+') .replace('_', '/') - const info = new UserModel(JSON.parse(window.atob(base64))) + const info = new UserModel(JSON.parse(atob(base64))) const ts = Math.round((new Date()).getTime() / 1000) authenticated = info.exp >= ts ctx.commit('info', info) if (authenticated) { ctx.dispatch('refreshUserInfo') - ctx.commit('authenticated', authenticated) } } @@ -206,8 +204,6 @@ export default { ctx.commit('info', null) ctx.dispatch('config/redirectToProviderIfNothingElseIsEnabled', null, {root: true}) } - - return Promise.resolve() }, refreshUserInfo(ctx) { const jwt = getToken() diff --git a/src/store/modules/config.js b/src/store/modules/config.js index 7fe8f57bd..2e929711e 100644 --- a/src/store/modules/config.js +++ b/src/store/modules/config.js @@ -66,7 +66,7 @@ export default { return HTTP.get('info') .then(r => { ctx.commit(CONFIG, r.data) - return Promise.resolve(r) + return r }) }, redirectToProviderIfNothingElseIsEnabled(ctx) { diff --git a/src/store/modules/kanban.js b/src/store/modules/kanban.js index 87349c0cb..e01a83fa3 100644 --- a/src/store/modules/kanban.js +++ b/src/store/modules/kanban.js @@ -227,19 +227,19 @@ export default { .finally(() => cancel()) }, - loadNextTasksForBucket(ctx, {listId, ps = {}, bucketId}) { + async loadNextTasksForBucket(ctx, {listId, ps = {}, bucketId}) { const bucketIndex = findIndexById(ctx.state.buckets, bucketId) const isLoading = ctx.state.bucketLoading[bucketIndex] ?? false if (isLoading) { - return Promise.resolve() + return } const page = (ctx.state.taskPagesPerBucket[bucketIndex] ?? 1) + 1 const alreadyLoaded = ctx.state.allTasksLoadedForBucket[bucketIndex] ?? false if (alreadyLoaded) { - return Promise.resolve() + return } const cancel = setLoading(ctx, 'kanban') @@ -334,7 +334,7 @@ export default { // restore original state ctx.commit('setBucketByIndex', {bucketIndex, bucket: oldBucket}) - return Promise.reject(e) + throw e }) .finally(() => cancel()) }, diff --git a/src/store/modules/labels.js b/src/store/modules/labels.js index 3d113560e..104734f33 100644 --- a/src/store/modules/labels.js +++ b/src/store/modules/labels.js @@ -1,5 +1,7 @@ import LabelService from '@/services/label' import {setLoading} from '@/store/helper' +import { success } from '@/message' +import {i18n} from '@/i18n' /** * Returns the labels by id if found @@ -28,6 +30,18 @@ function getLabelsByIds(state, ids) { }) } +const labelService = new LabelService() + +const getAllLabels = async (page = 1) => { + const labels = await labelService.getAll({}, {}, page) + if (page < labelService.totalPages) { + const nextLabels = await getAllLabels(page + 1) + return labels.concat(nextLabels) + } else { + return labels + } +} + export default { namespaced: true, state: () => ({ @@ -60,71 +74,59 @@ export default { }, }, actions: { - loadAllLabels(ctx, {forceLoad} = {}) { + async loadAllLabels(ctx, {forceLoad} = {}) { if (ctx.state.loaded && !forceLoad) { - return Promise.resolve() + return } const cancel = setLoading(ctx, 'labels') - const labelService = new LabelService() - const getAllLabels = (page = 1) => { - return labelService.getAll({}, {}, page) - .then(labels => { - if (page < labelService.totalPages) { - return getAllLabels(page + 1) - .then(nextLabels => { - return labels.concat(nextLabels) - }) - } else { - return labels - } - }) - .catch(e => { - return Promise.reject(e) - }) + try { + const labels = await getAllLabels() + ctx.commit('setLabels', labels) + ctx.commit('setLoaded', true) + return labels + } finally { + cancel() } - - return getAllLabels() - .then(r => { - ctx.commit('setLabels', r) - ctx.commit('setLoaded', true) - return Promise.resolve(r) - }) - .finally(() => cancel()) }, - deleteLabel(ctx, label) { + async deleteLabel(ctx, label) { const cancel = setLoading(ctx, 'labels') const labelService = new LabelService() - return labelService.delete(label) - .then(r => { - ctx.commit('removeLabelById', label) - return Promise.resolve(r) - }) - .finally(() => cancel()) + try { + const result = await labelService.delete(label) + ctx.commit('removeLabelById', label) + success({message: i18n.global.t('label.deleteSuccess')}) + return result + } finally { + cancel() + } }, - updateLabel(ctx, label) { + async updateLabel(ctx, label) { const cancel = setLoading(ctx, 'labels') const labelService = new LabelService() - return labelService.update(label) - .then(r => { - ctx.commit('setLabel', r) - return Promise.resolve(r) - }) - .finally(() => cancel()) + try { + const newLabel = await labelService.update(label) + ctx.commit('setLabel', newLabel) + success({message: i18n.global.t('label.edit.success')}) + return newLabel + } finally { + cancel() + } }, - createLabel(ctx, label) { + async createLabel(ctx, label) { const cancel = setLoading(ctx, 'labels') const labelService = new LabelService() - return labelService.create(label) - .then(r => { - ctx.commit('setLabel', r) - return Promise.resolve(r) - }) - .finally(() => cancel()) + try { + const newLabel = await labelService.create(label) + ctx.commit('setLabel', newLabel) + return newLabel + } finally { + cancel() + } }, }, } diff --git a/src/store/modules/lists.js b/src/store/modules/lists.js index aae097a61..e70588356 100644 --- a/src/store/modules/lists.js +++ b/src/store/modules/lists.js @@ -51,7 +51,7 @@ export default { r.namespaceId = list.namespaceId ctx.commit('namespaces/addListToNamespace', r, {root: true}) ctx.commit('setList', r) - return Promise.resolve(r) + return r }) .finally(() => cancel()) }, @@ -77,7 +77,7 @@ export default { } ctx.dispatch('namespaces/loadNamespacesIfFavoritesDontExist', null, {root: true}) ctx.dispatch('namespaces/removeFavoritesNamespaceIfEmpty', null, {root: true}) - return Promise.resolve(newList) + return newList }) .catch(e => { // Reset the list state to the initial one to avoid confusion for the user @@ -85,7 +85,7 @@ export default { ...list, isFavorite: !list.isFavorite, }) - return Promise.reject(e) + throw e }) .finally(() => cancel()) }, diff --git a/src/store/modules/namespaces.js b/src/store/modules/namespaces.js index 2bbe8dcda..b27225d6a 100644 --- a/src/store/modules/namespaces.js +++ b/src/store/modules/namespaces.js @@ -113,7 +113,7 @@ export default { ctx.commit('lists/setLists', lists, {root: true}) - return Promise.resolve(r) + return r }) .finally(() => { cancel() @@ -128,7 +128,6 @@ export default { removeFavoritesNamespaceIfEmpty(ctx) { if (ctx.state.namespaces[0].id === -2 && ctx.state.namespaces[0].lists.length === 0) { ctx.state.namespaces.splice(0, 1) - return Promise.resolve() } }, deleteNamespace(ctx, namespace) { @@ -138,7 +137,7 @@ export default { return namespaceService.delete(namespace) .then(r => { ctx.commit('removeNamespaceById', namespace.id) - return Promise.resolve(r) + return r }) .finally(() => cancel()) }, @@ -149,7 +148,7 @@ export default { return namespaceService.create(namespace) .then(r => { ctx.commit('addNamespace', r) - return Promise.resolve(r) + return r }) .finally(() => cancel()) }, diff --git a/src/store/modules/tasks.js b/src/store/modules/tasks.js index ddc628aff..29b1271fb 100644 --- a/src/store/modules/tasks.js +++ b/src/store/modules/tasks.js @@ -43,23 +43,23 @@ function addLabelToTask(task, label) { return labelTaskService.create(labelTask) .then(result => { task.labels.push(label) - return Promise.resolve(result) + return result }) } -function findAssignees(parsedTaskAssignees) { +async function findAssignees(parsedTaskAssignees) { if (parsedTaskAssignees.length <= 0) { - return Promise.resolve([]) + return [] } const userService = new UserService() - const assignees = parsedTaskAssignees.map(a => - userService.getAll({}, {s: a}) - .then(users => validateUsername(users, a)), - - ) + const assignees = parsedTaskAssignees.map(async a => { + const users = await userService.getAll({}, {s: a}) + return validateUsername(users, a) + }) - return Promise.all(assignees).filter((item) => Boolean(item)) + const validatedUsers = await Promise.all(assignees) + return validatedUsers.filter((item) => Boolean(item)) } @@ -136,7 +136,7 @@ export default { // 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 Promise.resolve(r) + return r } // FIXME: direct store manipulation (task) t.task.assignees.push(user) @@ -157,7 +157,7 @@ export default { // 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 Promise.resolve(r) + return r } for (const a in t.task.assignees) { @@ -186,7 +186,7 @@ export default { // 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 Promise.resolve(r) + return r } // FIXME: direct store manipulation (task) t.task.labels.push(label) @@ -208,7 +208,7 @@ export default { // 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 Promise.resolve(r) + return r } // Remove the label from the list @@ -234,22 +234,21 @@ export default { const {labels} = rootState.labels - const labelAddsToWaitFor = parsedLabels.map(labelTitle => new Promise((resolve) => { + const labelAddsToWaitFor = parsedLabels.map(async labelTitle => { let label = validateLabel(labels, labelTitle) if (typeof label !== 'undefined') { - return resolve(label) + return label } // label not found, create it const labelModel = new LabelModel({title: labelTitle}) - return dispatch('labels/createLabel', labelModel).then(() => resolve(label)) + await dispatch('labels/createLabel', labelModel) + addLabelToTask(task, label) }) - .then((label) => addLabelToTask(task, label)) - .catch(e => Promise.reject(e)), - ) // This waits until all labels are created and added to the task - return Promise.all(labelAddsToWaitFor).then(() => task) + await Promise.all(labelAddsToWaitFor) + return task }, findListId({ rootGetters }, { list, listId }) { diff --git a/src/views/labels/ListLabels.vue b/src/views/labels/ListLabels.vue index f49baafea..e7ce816a5 100644 --- a/src/views/labels/ListLabels.vue +++ b/src/views/labels/ListLabels.vue @@ -119,7 +119,7 @@ export default { } }, created() { - this.loadLabels() + this.$store.dispatch('labels/loadAllLabels') }, mounted() { this.setTitle(this.$t('label.title')) @@ -131,20 +131,11 @@ export default { loading: state => state[LOADING] && state[LOADING_MODULE] === 'labels', }), methods: { - loadLabels() { - this.$store.dispatch('labels/loadAllLabels') - }, deleteLabel(label) { - this.$store.dispatch('labels/deleteLabel', label) - .then(() => { - this.$message.success({message: this.$t('label.deleteSuccess')}) - }) + return this.$store.dispatch('labels/deleteLabel', label) }, editLabelSubmit() { - this.$store.dispatch('labels/updateLabel', this.labelEditLabel) - .then(() => { - this.$message.success({message: this.$t('label.edit.success')}) - }) + return this.$store.dispatch('labels/updateLabel', this.labelEditLabel) }, editLabel(label) { if (label.createdBy.id !== this.userInfo.id) {