add getAllArticles getter
This commit is contained in:
parent
806e5efd7a
commit
034a1ce597
7 changed files with 111 additions and 71 deletions
|
@ -1,9 +1,16 @@
|
||||||
|
/* global axios */
|
||||||
import ApiClient from '../ApiClient';
|
import ApiClient from '../ApiClient';
|
||||||
|
|
||||||
class PortalsAPI extends ApiClient {
|
class PortalsAPI extends ApiClient {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('portals', { accountScoped: true });
|
super('portals', { accountScoped: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getArticles({ pageNumber, portalSlug, locale }) {
|
||||||
|
return axios.get(
|
||||||
|
`${this.url}/${portalSlug}/articles?page=${pageNumber}&locale=${locale}`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new PortalsAPI();
|
export default new PortalsAPI();
|
||||||
|
|
|
@ -4,7 +4,18 @@
|
||||||
"FILTER": "Filter by",
|
"FILTER": "Filter by",
|
||||||
"SORT": "Sort by",
|
"SORT": "Sort by",
|
||||||
"SETTINGS_BUTTON": "Settings",
|
"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": {
|
"EDIT_HEADER": {
|
||||||
"PUBLISH_BUTTON": "Publish",
|
"PUBLISH_BUTTON": "Publish",
|
||||||
|
@ -15,23 +26,58 @@
|
||||||
"SAVING": "Draft saving...",
|
"SAVING": "Draft saving...",
|
||||||
"SAVED": "Draft saved"
|
"SAVED": "Draft saved"
|
||||||
},
|
},
|
||||||
"PORTAL": {
|
"TABLE": {
|
||||||
"ACTIVE_BADGE": "active",
|
"LOADING_MESSAGE": "Loading articles...",
|
||||||
"CHOOSE_LOCALE_LABEL": "Choose a locale",
|
"404": "No articles matches your search 🔍",
|
||||||
"ARTICLES_LABEL": "articles",
|
"NO_ARTICLES": "There are no available articles",
|
||||||
"ADD_NEW_LOCALE": "Add a new locale",
|
"HEADERS": {
|
||||||
"POPOVER": {
|
"TITLE": "Title",
|
||||||
"TITLE": "Portals",
|
"CATEGORY": "Category",
|
||||||
"NEW_PORTAL_LINK": "New Portal",
|
"READ_COUNT": "Read count",
|
||||||
"SUBTITLE": "You have multiple portals and can have different locales for each portal.",
|
"STATUS": "Status",
|
||||||
"CANCEL_BUTTON_LABEL": "Cancel",
|
"LAST_EDITED": "Last edited"
|
||||||
"CHOOSE_LOCALE_BUTTON": "Choose Locale"
|
},
|
||||||
|
"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"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,21 +7,19 @@
|
||||||
@newArticlePage="newArticlePage"
|
@newArticlePage="newArticlePage"
|
||||||
/>
|
/>
|
||||||
<article-table :articles="articles" :article-count="articles.length" />
|
<article-table :articles="articles" :article-count="articles.length" />
|
||||||
<empty-state
|
<div v-if="isFetchingArticles" class="articles--loader">
|
||||||
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">
|
|
||||||
<spinner />
|
<spinner />
|
||||||
<span>{{ $t('HELP_CENTER.TABLE.LOADING_MESSAGE') }}</span>
|
<span>{{ $t('HELP_CENTER.TABLE.LOADING_MESSAGE') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<empty-state
|
||||||
|
v-else-if="!isFetchingArticles && !articles.length"
|
||||||
|
:title="$t('HELP_CENTER.TABLE.NO_ARTICLES')"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
import Spinner from 'shared/components/Spinner.vue';
|
import Spinner from 'shared/components/Spinner.vue';
|
||||||
import ArticleHeader from 'dashboard/components/helpCenter/Header/ArticleHeader';
|
import ArticleHeader from 'dashboard/components/helpCenter/Header/ArticleHeader';
|
||||||
import EmptyState from 'dashboard/components/widgets/EmptyState.vue';
|
import EmptyState from 'dashboard/components/widgets/EmptyState.vue';
|
||||||
|
@ -35,45 +33,17 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// Dummy data will remove once the state is implemented.
|
pageNumber: 1,
|
||||||
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,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
articleCount: 12,
|
articleCount: 12,
|
||||||
isLoading: false,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
showSearchEmptyState() {
|
...mapGetters({
|
||||||
|
articles: 'articles/allArticles',
|
||||||
|
uiFlags: 'articles/uiFlags',
|
||||||
|
isFetchingArticles: 'articles/isFetchingArticles',
|
||||||
|
}),
|
||||||
|
showEmptyState() {
|
||||||
return this.articles.length === 0;
|
return this.articles.length === 0;
|
||||||
},
|
},
|
||||||
articleType() {
|
articleType() {
|
||||||
|
@ -92,10 +62,20 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetchArticles({ pageNumber: this.pageNumber });
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
newArticlePage() {
|
newArticlePage() {
|
||||||
this.$router.push({ name: 'new_article' });
|
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>
|
</script>
|
||||||
|
|
|
@ -35,6 +35,7 @@ import teamMembers from './modules/teamMembers';
|
||||||
import teams from './modules/teams';
|
import teams from './modules/teams';
|
||||||
import userNotificationSettings from './modules/userNotificationSettings';
|
import userNotificationSettings from './modules/userNotificationSettings';
|
||||||
import webhooks from './modules/webhooks';
|
import webhooks from './modules/webhooks';
|
||||||
|
import articles from './modules/helpCenterArticles';
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
|
@ -73,5 +74,6 @@ export default new Vuex.Store({
|
||||||
teams,
|
teams,
|
||||||
userNotificationSettings,
|
userNotificationSettings,
|
||||||
webhooks,
|
webhooks,
|
||||||
|
articles,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -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 { throwErrorMessage } from 'dashboard/store/utils/api';
|
||||||
import types from '../../mutation-types';
|
import types from '../../mutation-types';
|
||||||
export const actions = {
|
export const actions = {
|
||||||
index: async ({ commit }) => {
|
index: async ({ commit }, { pageNumber, portalSlug, locale }) => {
|
||||||
try {
|
try {
|
||||||
commit(types.SET_UI_FLAG, { isFetching: true });
|
commit(types.SET_UI_FLAG, { isFetching: true });
|
||||||
const { data } = await articlesAPI.get();
|
const {
|
||||||
const articleIds = data.map(article => article.id);
|
data: { payload },
|
||||||
commit(types.ADD_MANY_ARTICLES, data);
|
} = 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);
|
commit(types.ADD_MANY_ARTICLES_ID, articleIds);
|
||||||
return articleIds;
|
return articleIds;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
export const getters = {
|
export const getters = {
|
||||||
uiFlagsIn: state => helpCenterId => {
|
uiFlags: state => helpCenterId => {
|
||||||
const uiFlags = state.articles.uiFlags.byId[helpCenterId];
|
const uiFlags = state.articles.uiFlags.byId[helpCenterId];
|
||||||
if (uiFlags) return uiFlags;
|
if (uiFlags) return uiFlags;
|
||||||
return { isFetching: false, isUpdating: false, isDeleting: false };
|
return { isFetching: false, isUpdating: false, isDeleting: false };
|
||||||
},
|
},
|
||||||
isFetchingHelpCenterArticles: state => state.uiFlags.isFetching,
|
isFetchingArticles: state => state.uiFlags.isFetching,
|
||||||
articleById: (...getterArguments) => articleId => {
|
articleById: (...getterArguments) => articleId => {
|
||||||
const [state] = getterArguments;
|
const [state] = getterArguments;
|
||||||
const article = state.articles.byId[articleId];
|
const article = state.articles.byId.allArticles[articleId];
|
||||||
|
|
||||||
if (!article) return undefined;
|
if (!article) return undefined;
|
||||||
|
|
||||||
return article;
|
return article;
|
||||||
},
|
},
|
||||||
allArticles: (...getterArguments) => {
|
allArticles: (...getterArguments) => {
|
||||||
|
|
Loading…
Reference in a new issue