From 6e945dd61e613c7de752cf2a0f0b70ef19678c69 Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Thu, 1 Sep 2022 10:55:59 +0530 Subject: [PATCH] feat: Add the ability to delete/archive articles (#5319) --- .../dashboard/api/helpCenter/articles.js | 4 ++ .../dashboard/api/specs/article.spec.js | 11 ++++ .../dashboard/i18n/locale/en/helpCenter.json | 20 ++++++ .../helpcenter/components/PortalPopover.vue | 12 +++- .../pages/articles/ArticleSettings.vue | 2 +- .../helpcenter/pages/articles/EditArticle.vue | 64 ++++++++++++++++++- .../modules/helpCenterArticles/actions.js | 5 +- .../modules/helpCenterArticles/getters.js | 8 ++- .../helpCenterArticles/specs/action.spec.js | 11 +++- 9 files changed, 123 insertions(+), 14 deletions(-) diff --git a/app/javascript/dashboard/api/helpCenter/articles.js b/app/javascript/dashboard/api/helpCenter/articles.js index 8bc960267..62328e8eb 100644 --- a/app/javascript/dashboard/api/helpCenter/articles.js +++ b/app/javascript/dashboard/api/helpCenter/articles.js @@ -42,6 +42,10 @@ class ArticlesAPI extends PortalsAPI { category_id, }); } + + deleteArticle({ articleId, portalSlug }) { + return axios.delete(`${this.url}/${portalSlug}/articles/${articleId}`); + } } export default new ArticlesAPI(); diff --git a/app/javascript/dashboard/api/specs/article.spec.js b/app/javascript/dashboard/api/specs/article.spec.js index e20e2e222..51e90318f 100644 --- a/app/javascript/dashboard/api/specs/article.spec.js +++ b/app/javascript/dashboard/api/specs/article.spec.js @@ -52,4 +52,15 @@ describe('#PortalAPI', () => { ); }); }); + describeWithAPIMock('API calls', context => { + it('#deleteArticle', () => { + articlesAPI.deleteArticle({ + articleId: 1, + portalSlug: 'room-rental', + }); + expect(context.axiosMock.delete).toHaveBeenCalledWith( + '/api/v1/portals/room-rental/articles/1' + ); + }); + }); }); diff --git a/app/javascript/dashboard/i18n/locale/en/helpCenter.json b/app/javascript/dashboard/i18n/locale/en/helpCenter.json index 03a425a9b..1ee5bb640 100644 --- a/app/javascript/dashboard/i18n/locale/en/helpCenter.json +++ b/app/javascript/dashboard/i18n/locale/en/helpCenter.json @@ -224,6 +224,26 @@ "ERROR": "Error while saving article" } }, + "ARCHIVE_ARTICLE": { + "API": { + "ERROR": "Error while archiving article", + "SUCCESS": "Article archived successfully" + } + }, + "DELETE_ARTICLE": { + "MODAL": { + "CONFIRM": { + "TITLE": "Confirm Deletion", + "MESSAGE": "Are you sure to delete the article?", + "YES": "Yes, Delete", + "NO": "No, Keep it" + } + }, + "API": { + "SUCCESS_MESSAGE": "Article deleted successfully", + "ERROR_MESSAGE": "Error while deleting article" + } + }, "CREATE_ARTICLE": { "ERROR_MESSAGE": "Please add the article heading and content then only you can update the settings" }, diff --git a/app/javascript/dashboard/routes/dashboard/helpcenter/components/PortalPopover.vue b/app/javascript/dashboard/routes/dashboard/helpcenter/components/PortalPopover.vue index 539c15e7d..c8a4c785e 100644 --- a/app/javascript/dashboard/routes/dashboard/helpcenter/components/PortalPopover.vue +++ b/app/javascript/dashboard/routes/dashboard/helpcenter/components/PortalPopover.vue @@ -10,7 +10,7 @@ color-scheme="secondary" icon="settings" size="small" - @click="openPortalPage" + @click="openPortalArticles" > {{ $t('HELP_CENTER.PORTAL.POPOVER.PORTAL_SETTINGS') }} @@ -62,10 +62,16 @@ export default { closePortalPopover() { this.$emit('close-popover'); }, - openPortalPage() { + openPortalArticles({ slug, locale }) { this.$emit('close-popover'); + const portal = this.portals.find(p => p.slug === slug); + this.$store.dispatch('portals/setPortalId', portal.id); this.$router.push({ - name: 'list_all_portals', + name: 'list_all_locale_articles', + params: { + portalSlug: slug, + locale: locale, + }, }); }, }, diff --git a/app/javascript/dashboard/routes/dashboard/helpcenter/pages/articles/ArticleSettings.vue b/app/javascript/dashboard/routes/dashboard/helpcenter/pages/articles/ArticleSettings.vue index 6817c175b..5dc08c5cb 100644 --- a/app/javascript/dashboard/routes/dashboard/helpcenter/pages/articles/ArticleSettings.vue +++ b/app/javascript/dashboard/routes/dashboard/helpcenter/pages/articles/ArticleSettings.vue @@ -127,7 +127,7 @@ export default { props: { article: { type: Object, - required: true, + default: () => ({}), }, }, data() { diff --git a/app/javascript/dashboard/routes/dashboard/helpcenter/pages/articles/EditArticle.vue b/app/javascript/dashboard/routes/dashboard/helpcenter/pages/articles/EditArticle.vue index f89e8b304..2d6402e62 100644 --- a/app/javascript/dashboard/routes/dashboard/helpcenter/pages/articles/EditArticle.vue +++ b/app/javascript/dashboard/routes/dashboard/helpcenter/pages/articles/EditArticle.vue @@ -27,6 +27,17 @@ v-if="showArticleSettings" :article="article" @save-article="saveArticle" + @delete-article="openDeletePopup" + @archive-article="archiveArticle" + /> + @@ -52,6 +63,7 @@ export default { isSaved: false, showArticleSettings: false, alertMessage: '', + showDeleteConfirmationPopup: false, }; }, computed: { @@ -82,6 +94,16 @@ export default { portalSlug: this.selectedPortalSlug, }); }, + openDeletePopup() { + this.showDeleteConfirmationPopup = true; + }, + closeDeletePopup() { + this.showDeleteConfirmationPopup = false; + }, + confirmDeletion() { + this.closeDeletePopup(); + this.deleteArticle(); + }, async saveArticle({ ...values }) { this.isUpdating = true; try { @@ -92,8 +114,7 @@ export default { }); } catch (error) { this.alertMessage = - error?.message || - this.$t('HELP_CENTER.EDIT_ARTICLE.API.ERROR_MESSAGE'); + error?.message || this.$t('HELP_CENTER.EDIT_ARTICLE.API.ERROR'); this.showAlert(this.alertMessage); } finally { setTimeout(() => { @@ -102,6 +123,45 @@ export default { }, 1500); } }, + async deleteArticle() { + try { + await this.$store.dispatch('articles/delete', { + portalSlug: this.selectedPortalSlug, + articleId: this.articleId, + }); + this.alertMessage = this.$t( + 'HELP_CENTER.DELETE_ARTICLE.API.SUCCESS_MESSAGE' + ); + this.$router.push({ + name: 'list_all_locale_articles', + params: { + portalSlug: this.selectedPortalSlug, + locale: this.locale, + }, + }); + } catch (error) { + this.alertMessage = + error?.message || + this.$t('HELP_CENTER.DELETE_ARTICLE.API.ERROR_MESSAGE'); + } finally { + this.showAlert(this.alertMessage); + } + }, + async archiveArticle() { + try { + await this.$store.dispatch('articles/update', { + portalSlug: this.selectedPortalSlug, + articleId: this.articleId, + status: 2, + }); + this.alertMessage = this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.SUCCESS'); + } catch (error) { + this.alertMessage = + error?.message || this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.ERROR'); + } finally { + this.showAlert(this.alertMessage); + } + }, openArticleSettings() { this.showArticleSettings = true; }, diff --git a/app/javascript/dashboard/store/modules/helpCenterArticles/actions.js b/app/javascript/dashboard/store/modules/helpCenterArticles/actions.js index b93195d40..e62901835 100644 --- a/app/javascript/dashboard/store/modules/helpCenterArticles/actions.js +++ b/app/javascript/dashboard/store/modules/helpCenterArticles/actions.js @@ -100,7 +100,7 @@ export const actions = { }); } }, - delete: async ({ commit }, articleId) => { + delete: async ({ commit }, { portalSlug, articleId }) => { commit(types.UPDATE_ARTICLE_FLAG, { uiFlags: { isDeleting: true, @@ -108,8 +108,7 @@ export const actions = { articleId, }); try { - await articlesAPI.delete(articleId); - + await articlesAPI.deleteArticle({ portalSlug, articleId }); commit(types.REMOVE_ARTICLE, articleId); commit(types.REMOVE_ARTICLE_ID, articleId); return articleId; diff --git a/app/javascript/dashboard/store/modules/helpCenterArticles/getters.js b/app/javascript/dashboard/store/modules/helpCenterArticles/getters.js index 35e32ee5e..edffc53c2 100644 --- a/app/javascript/dashboard/store/modules/helpCenterArticles/getters.js +++ b/app/javascript/dashboard/store/modules/helpCenterArticles/getters.js @@ -13,9 +13,11 @@ export const getters = { }, allArticles: (...getterArguments) => { const [state, _getters] = getterArguments; - const articles = state.articles.allIds.map(id => { - return _getters.articleById(id); - }); + const articles = state.articles.allIds + .map(id => { + return _getters.articleById(id); + }) + .filter(article => article !== undefined); return articles; }, getMeta: state => { diff --git a/app/javascript/dashboard/store/modules/helpCenterArticles/specs/action.spec.js b/app/javascript/dashboard/store/modules/helpCenterArticles/specs/action.spec.js index b0decf927..6fdfc5389 100644 --- a/app/javascript/dashboard/store/modules/helpCenterArticles/specs/action.spec.js +++ b/app/javascript/dashboard/store/modules/helpCenterArticles/specs/action.spec.js @@ -142,7 +142,11 @@ describe('#actions', () => { describe('#delete', () => { it('sends correct actions if API is success', async () => { axios.delete.mockResolvedValue({ data: articleList[0] }); - await actions.delete({ commit }, articleList[0].id); + await actions.delete( + { commit }, + { portalSlug: 'test', articleId: articleList[0].id } + ); + expect(commit.mock.calls).toEqual([ [ types.default.UPDATE_ARTICLE_FLAG, @@ -159,7 +163,10 @@ describe('#actions', () => { it('sends correct actions if API is error', async () => { axios.delete.mockRejectedValue({ message: 'Incorrect header' }); await expect( - actions.delete({ commit }, articleList[0].id) + actions.delete( + { commit }, + { portalSlug: 'test', articleId: articleList[0].id } + ) ).rejects.toThrow(Error); expect(commit.mock.calls).toEqual([ [