feat: Add the ability to delete/archive articles (#5319)
This commit is contained in:
parent
c8d01a84ce
commit
6e945dd61e
9 changed files with 123 additions and 14 deletions
|
@ -42,6 +42,10 @@ class ArticlesAPI extends PortalsAPI {
|
||||||
category_id,
|
category_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteArticle({ articleId, portalSlug }) {
|
||||||
|
return axios.delete(`${this.url}/${portalSlug}/articles/${articleId}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new ArticlesAPI();
|
export default new ArticlesAPI();
|
||||||
|
|
|
@ -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'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -224,6 +224,26 @@
|
||||||
"ERROR": "Error while saving article"
|
"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": {
|
"CREATE_ARTICLE": {
|
||||||
"ERROR_MESSAGE": "Please add the article heading and content then only you can update the settings"
|
"ERROR_MESSAGE": "Please add the article heading and content then only you can update the settings"
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
color-scheme="secondary"
|
color-scheme="secondary"
|
||||||
icon="settings"
|
icon="settings"
|
||||||
size="small"
|
size="small"
|
||||||
@click="openPortalPage"
|
@click="openPortalArticles"
|
||||||
>
|
>
|
||||||
{{ $t('HELP_CENTER.PORTAL.POPOVER.PORTAL_SETTINGS') }}
|
{{ $t('HELP_CENTER.PORTAL.POPOVER.PORTAL_SETTINGS') }}
|
||||||
</woot-button>
|
</woot-button>
|
||||||
|
@ -62,10 +62,16 @@ export default {
|
||||||
closePortalPopover() {
|
closePortalPopover() {
|
||||||
this.$emit('close-popover');
|
this.$emit('close-popover');
|
||||||
},
|
},
|
||||||
openPortalPage() {
|
openPortalArticles({ slug, locale }) {
|
||||||
this.$emit('close-popover');
|
this.$emit('close-popover');
|
||||||
|
const portal = this.portals.find(p => p.slug === slug);
|
||||||
|
this.$store.dispatch('portals/setPortalId', portal.id);
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'list_all_portals',
|
name: 'list_all_locale_articles',
|
||||||
|
params: {
|
||||||
|
portalSlug: slug,
|
||||||
|
locale: locale,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -127,7 +127,7 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
article: {
|
article: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -27,6 +27,17 @@
|
||||||
v-if="showArticleSettings"
|
v-if="showArticleSettings"
|
||||||
:article="article"
|
:article="article"
|
||||||
@save-article="saveArticle"
|
@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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -52,6 +63,7 @@ export default {
|
||||||
isSaved: false,
|
isSaved: false,
|
||||||
showArticleSettings: false,
|
showArticleSettings: false,
|
||||||
alertMessage: '',
|
alertMessage: '',
|
||||||
|
showDeleteConfirmationPopup: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -82,6 +94,16 @@ export default {
|
||||||
portalSlug: this.selectedPortalSlug,
|
portalSlug: this.selectedPortalSlug,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
openDeletePopup() {
|
||||||
|
this.showDeleteConfirmationPopup = true;
|
||||||
|
},
|
||||||
|
closeDeletePopup() {
|
||||||
|
this.showDeleteConfirmationPopup = false;
|
||||||
|
},
|
||||||
|
confirmDeletion() {
|
||||||
|
this.closeDeletePopup();
|
||||||
|
this.deleteArticle();
|
||||||
|
},
|
||||||
async saveArticle({ ...values }) {
|
async saveArticle({ ...values }) {
|
||||||
this.isUpdating = true;
|
this.isUpdating = true;
|
||||||
try {
|
try {
|
||||||
|
@ -92,8 +114,7 @@ export default {
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.alertMessage =
|
this.alertMessage =
|
||||||
error?.message ||
|
error?.message || this.$t('HELP_CENTER.EDIT_ARTICLE.API.ERROR');
|
||||||
this.$t('HELP_CENTER.EDIT_ARTICLE.API.ERROR_MESSAGE');
|
|
||||||
this.showAlert(this.alertMessage);
|
this.showAlert(this.alertMessage);
|
||||||
} finally {
|
} finally {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -102,6 +123,45 @@ export default {
|
||||||
}, 1500);
|
}, 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() {
|
openArticleSettings() {
|
||||||
this.showArticleSettings = true;
|
this.showArticleSettings = true;
|
||||||
},
|
},
|
||||||
|
|
|
@ -100,7 +100,7 @@ export const actions = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
delete: async ({ commit }, articleId) => {
|
delete: async ({ commit }, { portalSlug, articleId }) => {
|
||||||
commit(types.UPDATE_ARTICLE_FLAG, {
|
commit(types.UPDATE_ARTICLE_FLAG, {
|
||||||
uiFlags: {
|
uiFlags: {
|
||||||
isDeleting: true,
|
isDeleting: true,
|
||||||
|
@ -108,8 +108,7 @@ export const actions = {
|
||||||
articleId,
|
articleId,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await articlesAPI.delete(articleId);
|
await articlesAPI.deleteArticle({ portalSlug, articleId });
|
||||||
|
|
||||||
commit(types.REMOVE_ARTICLE, articleId);
|
commit(types.REMOVE_ARTICLE, articleId);
|
||||||
commit(types.REMOVE_ARTICLE_ID, articleId);
|
commit(types.REMOVE_ARTICLE_ID, articleId);
|
||||||
return articleId;
|
return articleId;
|
||||||
|
|
|
@ -13,9 +13,11 @@ export const getters = {
|
||||||
},
|
},
|
||||||
allArticles: (...getterArguments) => {
|
allArticles: (...getterArguments) => {
|
||||||
const [state, _getters] = getterArguments;
|
const [state, _getters] = getterArguments;
|
||||||
const articles = state.articles.allIds.map(id => {
|
const articles = state.articles.allIds
|
||||||
return _getters.articleById(id);
|
.map(id => {
|
||||||
});
|
return _getters.articleById(id);
|
||||||
|
})
|
||||||
|
.filter(article => article !== undefined);
|
||||||
return articles;
|
return articles;
|
||||||
},
|
},
|
||||||
getMeta: state => {
|
getMeta: state => {
|
||||||
|
|
|
@ -142,7 +142,11 @@ describe('#actions', () => {
|
||||||
describe('#delete', () => {
|
describe('#delete', () => {
|
||||||
it('sends correct actions if API is success', async () => {
|
it('sends correct actions if API is success', async () => {
|
||||||
axios.delete.mockResolvedValue({ data: articleList[0] });
|
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([
|
expect(commit.mock.calls).toEqual([
|
||||||
[
|
[
|
||||||
types.default.UPDATE_ARTICLE_FLAG,
|
types.default.UPDATE_ARTICLE_FLAG,
|
||||||
|
@ -159,7 +163,10 @@ describe('#actions', () => {
|
||||||
it('sends correct actions if API is error', async () => {
|
it('sends correct actions if API is error', async () => {
|
||||||
axios.delete.mockRejectedValue({ message: 'Incorrect header' });
|
axios.delete.mockRejectedValue({ message: 'Incorrect header' });
|
||||||
await expect(
|
await expect(
|
||||||
actions.delete({ commit }, articleList[0].id)
|
actions.delete(
|
||||||
|
{ commit },
|
||||||
|
{ portalSlug: 'test', articleId: articleList[0].id }
|
||||||
|
)
|
||||||
).rejects.toThrow(Error);
|
).rejects.toThrow(Error);
|
||||||
expect(commit.mock.calls).toEqual([
|
expect(commit.mock.calls).toEqual([
|
||||||
[
|
[
|
||||||
|
|
Loading…
Reference in a new issue