feat: Add the ability to delete/archive articles (#5319)

This commit is contained in:
Muhsin Keloth 2022-09-01 10:55:59 +05:30 committed by GitHub
parent c8d01a84ce
commit 6e945dd61e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 123 additions and 14 deletions

View file

@ -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();

View file

@ -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'
);
});
});
});

View file

@ -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"
},

View file

@ -10,7 +10,7 @@
color-scheme="secondary"
icon="settings"
size="small"
@click="openPortalPage"
@click="openPortalArticles"
>
{{ $t('HELP_CENTER.PORTAL.POPOVER.PORTAL_SETTINGS') }}
</woot-button>
@ -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,
},
});
},
},

View file

@ -127,7 +127,7 @@ export default {
props: {
article: {
type: Object,
required: true,
default: () => ({}),
},
},
data() {

View file

@ -27,6 +27,17 @@
v-if="showArticleSettings"
:article="article"
@save-article="saveArticle"
@delete-article="openDeletePopup"
@archive-article="archiveArticle"
/>
<woot-delete-modal
:show.sync="showDeleteConfirmationPopup"
:on-close="closeDeletePopup"
:on-confirm="confirmDeletion"
:title="$t('HELP_CENTER.DELETE_ARTICLE.MODAL.CONFIRM.TITLE')"
:message="$t('HELP_CENTER.DELETE_ARTICLE.MODAL.CONFIRM.MESSAGE')"
:confirm-text="$t('HELP_CENTER.DELETE_ARTICLE.MODAL.CONFIRM.YES')"
:reject-text="$t('HELP_CENTER.DELETE_ARTICLE.MODAL.CONFIRM.NO')"
/>
</div>
</template>
@ -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;
},

View file

@ -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;

View file

@ -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 => {

View file

@ -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([
[