From efd6e9f64be7b153b48cd97fce0ed85e36cbb267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Sat, 7 Mar 2020 10:56:29 +0100 Subject: [PATCH 1/4] Add loading indicator and autofocus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- src/components/Controls.vue | 1 + src/components/board/Stack.vue | 43 +++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/components/Controls.vue b/src/components/Controls.vue index 3b5dab0a1..a4fc75653 100644 --- a/src/components/Controls.vue +++ b/src/components/Controls.vue @@ -36,6 +36,7 @@ -
+ -
@@ -108,6 +113,7 @@ export default { copiedStack: '', newCardTitle: '', showAddCard: false, + stateCardCreating: false, } }, computed: { @@ -160,15 +166,21 @@ export default { } this.editing = false }, - clickAddCard() { - const newCard = { - title: this.newCardTitle, - stackId: this.stack.id, - boardId: this.stack.boardId, + async clickAddCard() { + this.stateCardCreating = true + try { + await this.$store.dispatch('addCard', { + title: this.newCardTitle, + stackId: this.stack.id, + boardId: this.stack.boardId, + }) + this.newCardTitle = '' + this.showAddCard = false + } catch (e) { + OCP.Toast.error('Could not create card: ' + e.response.data.message) + } finally { + this.stateCardCreating = false } - this.$store.dispatch('addCard', newCard) - this.newCardTitle = '' - this.showAddCard = false }, }, } @@ -209,11 +221,14 @@ export default { .stack--card-add { display: flex; - margin-left: 3px; - margin-right: 3px; - box-shadow: 0 0 3px #aaa; + margin-bottom: 10px; + box-shadow: 0 0 3px var(--color-box-shadow); border-radius: 3px; - margin-bottom: 15px; + + &.icon-loading-small:after, + &.icon-loading-small-dark:after { + margin-left: calc(50% - 25px); + } input[type=text] { flex-grow: 1; From d577288ec8e718f0ae3d60c4cbf84e5ebe63ac69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Sat, 7 Mar 2020 10:56:49 +0100 Subject: [PATCH 2/4] Fix navigating to card without assigned users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- src/components/card/CardSidebar.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/card/CardSidebar.vue b/src/components/card/CardSidebar.vue index 775e8138a..6161e3485 100644 --- a/src/components/card/CardSidebar.vue +++ b/src/components/card/CardSidebar.vue @@ -227,6 +227,8 @@ export default { if (this.currentCard.assignedUsers.length > 0) { this.assignedUsers = this.currentCard.assignedUsers.map((item) => item.participant) + } else { + this.assignedUsers = [] } this.desc = this.currentCard.description From e69abd9be5c14e5daf16637ae685d04e6421dd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Sat, 7 Mar 2020 10:57:54 +0100 Subject: [PATCH 3/4] Unify mutations to modify card properties and move to async actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- src/components/cards/CardItem.vue | 2 +- src/store/card.js | 120 ++++++++++-------------------- 2 files changed, 39 insertions(+), 83 deletions(-) diff --git a/src/components/cards/CardItem.vue b/src/components/cards/CardItem.vue index e6029b5c1..dd2c632a5 100644 --- a/src/components/cards/CardItem.vue +++ b/src/components/cards/CardItem.vue @@ -178,7 +178,7 @@ export default { }, finishedEdit(card) { if (this.copiedCard.title !== card.title) { - this.$store.dispatch('updateCard', this.copiedCard) + this.$store.dispatch('updateCardTitle', this.copiedCard) } this.editing = false }, diff --git a/src/store/card.js b/src/store/card.js index a6e083cba..c29f56db2 100644 --- a/src/store/card.js +++ b/src/store/card.js @@ -119,12 +119,6 @@ export default { } } }, - updateTitle(state, card) { - const existingIndex = state.cards.findIndex(_card => _card.id === card.id) - if (existingIndex !== -1) { - state.cards[existingIndex].title = card.title - } - }, assignCardToUser(state, user) { const existingIndex = state.cards.findIndex(_card => _card.id === user.cardId) if (existingIndex !== -1) { @@ -140,44 +134,25 @@ export default { } } }, - updateCardDesc(state, card) { + updateCardProperty(state, { card, property }) { const existingIndex = state.cards.findIndex(_card => _card.id === card.id) if (existingIndex !== -1) { - state.cards[existingIndex].description = card.description - } - }, - updateCardDue(state, card) { - const existingIndex = state.cards.findIndex(_card => _card.id === card.id) - if (existingIndex !== -1) { - state.cards[existingIndex].duedate = card.duedate - } - }, - updateCardLabels(state, card) { - const existingIndex = state.cards.findIndex(_card => _card.id === card.id) - if (existingIndex !== -1) { - const existingCard = state.cards.find(_card => _card.id === card.id) - existingCard.labels = card.labels + Vue.set(state.cards[existingIndex], property, card[property]) } }, }, actions: { - addCard({ commit }, card) { - apiClient.addCard(card) - .then((createdCard) => { - commit('addCard', createdCard) - }) + async addCard({ commit }, card) { + const createdCard = await apiClient.addCard(card) + commit('addCard', createdCard) }, - updateCard({ commit }, card) { - apiClient.updateCard(card) - .then((updatedCard) => { - commit('updateTitle', updatedCard) - }) + async updateCardTitle({ commit }, card) { + const updatedCard = await apiClient.updateCard(card) + commit('updateCardProperty', { property: 'title', card: updatedCard }) }, - moveCard({ commit }, card) { - apiClient.updateCard(card) - .then((updatedCard) => { - commit('deleteCard', updatedCard) - }) + async moveCard({ commit }, card) { + const updatedCard = await apiClient.updateCard(card) + commit('deleteCard', updatedCard) }, async reorderCard({ commit, getters }, card) { let i = 0 @@ -196,66 +171,47 @@ export default { const cards = await apiClient.reorderCard(card) await commit('updateCardsReorder', Object.values(cards)) - }, - deleteCard({ commit }, card) { - apiClient.deleteCard(card.id) - .then((card) => { - commit('deleteCard', card) - }) + async deleteCard({ commit }, card) { + await apiClient.deleteCard(card.id) + commit('deleteCard', card) }, - archiveUnarchiveCard({ commit }, card) { + async archiveUnarchiveCard({ commit }, card) { let call = 'archiveCard' if (card.archived === false) { call = 'unArchiveCard' } - apiClient[call](card) - .then((card) => { - commit('deleteCard', card) - }) + const updatedCard = await apiClient[call](card) + commit('deleteCard', updatedCard) }, - assignCardToUser({ commit }, card) { - apiClient.assignUser(card) - .then((user) => { - commit('assignCardToUser', user) - }) + async assignCardToUser({ commit }, card) { + const user = await apiClient.assignUser(card) + commit('assignCardToUser', user) }, - removeUserFromCard({ commit }, card) { - apiClient.removeUser(card) - .then((user) => { - commit('removeUserFromCard', user) - }) + async removeUserFromCard({ commit }, card) { + const user = await apiClient.removeUser(card) + commit('removeUserFromCard', user) }, - addLabel({ commit }, data) { - apiClient.assignLabelToCard(data) - .then(() => { - commit('updateCardLabels', data.card) - }) + async addLabel({ commit }, data) { + await apiClient.assignLabelToCard(data) + commit('updateCardProperty', { property: 'labels', card: data.card }) }, - removeLabel({ commit }, data) { - apiClient.removeLabelFromCard(data) - .then(() => { - commit('updateCardLabels', data.card) - }) + async removeLabel({ commit }, data) { + await apiClient.removeLabelFromCard(data) + commit('updateCardProperty', { property: 'labels', card: data.card }) }, - cardUndoDelete({ commit }, card) { - apiClient.updateCard(card) - .then((card) => { - commit('addCard', card) - }) + async cardUndoDelete({ commit }, card) { + const updatedCard = await apiClient.updateCard(card) + commit('addCard', updatedCard) }, - updateCardDesc({ commit }, card) { - apiClient.updateCard(card) - .then((updatedCard) => { - commit('updateCardDesc', updatedCard) - }) + async updateCardDesc({ commit }, card) { + const updatedCard = await apiClient.updateCard(card) + commit('updateCardProperty', { property: 'description', card: updatedCard }) }, - updateCardDue({ commit }, card) { - apiClient.updateCard(card) - .then((card) => { - commit('updateCardDue', card) - }) + async updateCardDue({ commit }, card) { + const updatedCard = apiClient.updateCard(card) + commit('updateCardProperty', { property: 'duedate', card: updatedCard }) }, }, } From 498453e7a3022100ce155b0bebd2c09da765c845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Sat, 7 Mar 2020 10:58:19 +0100 Subject: [PATCH 4/4] Catch errors in vue app and emit message if provided by the response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- src/main.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main.js b/src/main.js index 6d8386747..6907f14b0 100644 --- a/src/main.js +++ b/src/main.js @@ -53,6 +53,14 @@ Vue.directive('focus', { }, }) +Vue.config.errorHandler = (err, vm, info) => { + if (err.response && err.response.data.message) { + const errorMessage = t('deck', 'Something went wrong') + OCP.Toast.error(`${errorMessage}: ${err.response.data.status} ${err.response.data.message}`) + } + throw err +} + /* eslint-disable-next-line no-new */ new Vue({ el: '#content',