add getAllArticles getter

This commit is contained in:
Muhsin Keloth 2022-07-27 15:39:52 +05:30
parent 806e5efd7a
commit 034a1ce597
7 changed files with 111 additions and 71 deletions

View file

@ -1,9 +1,16 @@
/* global axios */
import ApiClient from '../ApiClient';
class PortalsAPI extends ApiClient {
constructor() {
super('portals', { accountScoped: true });
}
getArticles({ pageNumber, portalSlug, locale }) {
return axios.get(
`${this.url}/${portalSlug}/articles?page=${pageNumber}&locale=${locale}`
);
}
}
export default new PortalsAPI();

View file

@ -4,7 +4,18 @@
"FILTER": "Filter by",
"SORT": "Sort by",
"SETTINGS_BUTTON": "Settings",
"NEW_BUTTON": "New Article"
"NEW_BUTTON": "New Article",
"DROPDOWN_OPTIONS": {
"PUBLISHED": "Published",
"DRAFT": "Draft",
"ARCHIVED": "Archived"
},
"TITLES": {
"ALL_ARTICLES": "All Articles",
"MINE": "My Articles",
"DRAFT": "Draft Articles",
"ARCHIVED": "Archived Articles"
}
},
"EDIT_HEADER": {
"PUBLISH_BUTTON": "Publish",
@ -15,23 +26,58 @@
"SAVING": "Draft saving...",
"SAVED": "Draft saved"
},
"PORTAL": {
"ACTIVE_BADGE": "active",
"CHOOSE_LOCALE_LABEL": "Choose a locale",
"ARTICLES_LABEL": "articles",
"ADD_NEW_LOCALE": "Add a new locale",
"POPOVER": {
"TITLE": "Portals",
"NEW_PORTAL_LINK": "New Portal",
"SUBTITLE": "You have multiple portals and can have different locales for each portal.",
"CANCEL_BUTTON_LABEL": "Cancel",
"CHOOSE_LOCALE_BUTTON": "Choose Locale"
"TABLE": {
"LOADING_MESSAGE": "Loading articles...",
"404": "No articles matches your search 🔍",
"NO_ARTICLES": "There are no available articles",
"HEADERS": {
"TITLE": "Title",
"CATEGORY": "Category",
"READ_COUNT": "Read count",
"STATUS": "Status",
"LAST_EDITED": "Last edited"
},
"COLUMNS": {
"BY": "by"
}
},
"EDIT_ARTICLE": {
"TITLE_PLACEHOLDER": "Article title goes here",
"CONTENT_PLACEHOLDER": "Write your article here"
},
"SIDEBAR": {
"SEARCH": {
"PLACEHOLDER": "Search for articles"
}
},
"CATEGORY": {
"ADD": {
"TITLE": "Create a category",
"SUB_TITLE": "The category will be used in the public facing portal to categorize articles.",
"PORTAL": "Portal",
"LOCALE": "Locale",
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Category name",
"HELP_TEXT": "The category name will be used in the public facing portal to categorize articles.",
"ERROR": "Name is required"
},
"SLUG": {
"LABEL": "Slug",
"PLACEHOLDER": "Category slug for urls",
"HELP_TEXT": "app.chatwoot.com/portal/my-portal/en-US/categories/my-slug",
"ERROR": "Slug is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Give a short description about the category.",
"ERROR": "Description is required"
},
"BUTTONS": {
"CREATE": "Create category",
"CANCEL": "Cancel"
}
}
}
},
"TABLE": {
"COLUMNS": {
"BY": "by"
}
}
}

View file

@ -7,21 +7,19 @@
@newArticlePage="newArticlePage"
/>
<article-table :articles="articles" :article-count="articles.length" />
<empty-state
v-if="showSearchEmptyState"
:title="$t('HELP_CENTER.TABLE.404')"
/>
<empty-state
v-else-if="!isLoading && !articles.length"
:title="$t('CONTACTS_PAGE.LIST.NO_CONTACTS')"
/>
<div v-if="isLoading" class="articles--loader">
<div v-if="isFetchingArticles" class="articles--loader">
<spinner />
<span>{{ $t('HELP_CENTER.TABLE.LOADING_MESSAGE') }}</span>
</div>
<empty-state
v-else-if="!isFetchingArticles && !articles.length"
:title="$t('HELP_CENTER.TABLE.NO_ARTICLES')"
/>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import Spinner from 'shared/components/Spinner.vue';
import ArticleHeader from 'dashboard/components/helpCenter/Header/ArticleHeader';
import EmptyState from 'dashboard/components/widgets/EmptyState.vue';
@ -35,45 +33,17 @@ export default {
},
data() {
return {
// Dummy data will remove once the state is implemented.
articles: [
{
title: 'Setup your account',
author: {
name: 'John Doe',
},
readCount: 13,
category: 'Getting started',
status: 'published',
updatedAt: 1657255863,
},
{
title: 'Docker Configuration',
author: {
name: 'Sam Manuel',
},
readCount: 13,
category: 'Engineering',
status: 'draft',
updatedAt: 1656658046,
},
{
title: 'Campaigns',
author: {
name: 'Sam Manuel',
},
readCount: 28,
category: 'Engineering',
status: 'archived',
updatedAt: 1657590446,
},
],
pageNumber: 1,
articleCount: 12,
isLoading: false,
};
},
computed: {
showSearchEmptyState() {
...mapGetters({
articles: 'articles/allArticles',
uiFlags: 'articles/uiFlags',
isFetchingArticles: 'articles/isFetchingArticles',
}),
showEmptyState() {
return this.articles.length === 0;
},
articleType() {
@ -92,10 +62,20 @@ export default {
}
},
},
mounted() {
this.fetchArticles({ pageNumber: this.pageNumber });
},
methods: {
newArticlePage() {
this.$router.push({ name: 'new_article' });
},
fetchArticles({ pageNumber }) {
this.$store.dispatch('articles/index', {
pageNumber,
portalSlug: this.$route.params.portalSlug,
locale: this.$route.params.locale,
});
},
},
};
</script>

View file

@ -35,6 +35,7 @@ import teamMembers from './modules/teamMembers';
import teams from './modules/teams';
import userNotificationSettings from './modules/userNotificationSettings';
import webhooks from './modules/webhooks';
import articles from './modules/helpCenterArticles';
Vue.use(Vuex);
export default new Vuex.Store({
@ -73,5 +74,6 @@ export default new Vuex.Store({
teams,
userNotificationSettings,
webhooks,
articles,
},
});

View file

@ -1,13 +1,20 @@
import articlesAPI from 'dashboard/api/helpCenter/articles.js';
import portalAPI from 'dashboard/api/helpCenter/portals';
import articlesAPI from 'dashboard/api/helpCenter/articles';
import { throwErrorMessage } from 'dashboard/store/utils/api';
import types from '../../mutation-types';
export const actions = {
index: async ({ commit }) => {
index: async ({ commit }, { pageNumber, portalSlug, locale }) => {
try {
commit(types.SET_UI_FLAG, { isFetching: true });
const { data } = await articlesAPI.get();
const articleIds = data.map(article => article.id);
commit(types.ADD_MANY_ARTICLES, data);
const {
data: { payload },
} = await portalAPI.getArticles({
pageNumber,
portalSlug,
locale,
});
const articleIds = payload.map(article => article.id);
commit(types.ADD_MANY_ARTICLES, payload);
commit(types.ADD_MANY_ARTICLES_ID, articleIds);
return articleIds;
} catch (error) {

View file

@ -1,16 +1,14 @@
export const getters = {
uiFlagsIn: state => helpCenterId => {
uiFlags: state => helpCenterId => {
const uiFlags = state.articles.uiFlags.byId[helpCenterId];
if (uiFlags) return uiFlags;
return { isFetching: false, isUpdating: false, isDeleting: false };
},
isFetchingHelpCenterArticles: state => state.uiFlags.isFetching,
isFetchingArticles: state => state.uiFlags.isFetching,
articleById: (...getterArguments) => articleId => {
const [state] = getterArguments;
const article = state.articles.byId[articleId];
const article = state.articles.byId.allArticles[articleId];
if (!article) return undefined;
return article;
},
allArticles: (...getterArguments) => {