feat: Articles store integration (#5133)
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<div class="row--article-block">
|
||||
<div class="article-block">
|
||||
<h6 class="sub-block-title text-truncate">
|
||||
<router-link class="article-name" :to="articlePath">
|
||||
<router-link class="article-name" :to="articleUrl(id)">
|
||||
{{ title }}
|
||||
</router-link>
|
||||
</h6>
|
||||
@@ -24,16 +24,20 @@
|
||||
</tr>
|
||||
</template>
|
||||
<script>
|
||||
import { frontendURL } from 'dashboard/helper/URLHelper';
|
||||
import Label from 'dashboard/components/ui/Label';
|
||||
import timeMixin from 'dashboard/mixins/time';
|
||||
import portalMixin from '../mixins/portalMixin';
|
||||
export default {
|
||||
components: {
|
||||
Label,
|
||||
},
|
||||
mixins: [timeMixin],
|
||||
mixins: [timeMixin, portalMixin],
|
||||
|
||||
props: {
|
||||
id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
@@ -79,9 +83,6 @@ export default {
|
||||
return 'success';
|
||||
}
|
||||
},
|
||||
articlePath() {
|
||||
return frontendURL(`accounts/${this.accountId}/hc/articles/${this.id}`);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -16,20 +16,22 @@
|
||||
<tbody>
|
||||
<ArticleItem
|
||||
v-for="article in articles"
|
||||
:id="article.id"
|
||||
:key="article.id"
|
||||
:title="article.title"
|
||||
:author="article.author"
|
||||
:category="article.category"
|
||||
:read-count="article.readCount"
|
||||
:status="article.status"
|
||||
:updated-at="article.updatedAt"
|
||||
:updated-at="article.updated_at"
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
<table-footer
|
||||
:on-page-change="onPageChange"
|
||||
:current-page="Number(currentPage)"
|
||||
:total-count="articleCount"
|
||||
:total-count="totalCount"
|
||||
:page-size="pageSize"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -47,7 +49,7 @@ export default {
|
||||
type: Array,
|
||||
default: () => {},
|
||||
},
|
||||
articleCount: {
|
||||
totalCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
@@ -55,10 +57,14 @@ export default {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 15,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onPageChange() {
|
||||
this.$emit('onPageChange');
|
||||
onPageChange(page) {
|
||||
this.$emit('on-page-change', page);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -66,6 +66,12 @@ export default {
|
||||
...mapGetters({
|
||||
accountId: 'getCurrentAccountId',
|
||||
}),
|
||||
portalSlug() {
|
||||
return this.$route.params.portalSlug;
|
||||
},
|
||||
locale() {
|
||||
return this.$route.params.locale;
|
||||
},
|
||||
accessibleMenuItems() {
|
||||
return [
|
||||
{
|
||||
@@ -74,7 +80,7 @@ export default {
|
||||
key: 'list_all_locale_articles',
|
||||
count: 199,
|
||||
toState: frontendURL(
|
||||
`accounts/${this.accountId}/portals/:portalSlug/:locale/articles`
|
||||
`accounts/${this.accountId}/portals/${this.portalSlug}/${this.locale}/articles`
|
||||
),
|
||||
toolTip: 'All Articles',
|
||||
toStateName: 'list_all_locale_articles',
|
||||
@@ -85,7 +91,7 @@ export default {
|
||||
key: 'mine_articles',
|
||||
count: 112,
|
||||
toState: frontendURL(
|
||||
`accounts/${this.accountId}/portals/:portalSlug/:locale/articles/mine`
|
||||
`accounts/${this.accountId}/portals/${this.portalSlug}/${this.locale}/articles/mine`
|
||||
),
|
||||
toolTip: 'My articles',
|
||||
toStateName: 'mine_articles',
|
||||
@@ -96,7 +102,7 @@ export default {
|
||||
key: 'list_draft_articles',
|
||||
count: 32,
|
||||
toState: frontendURL(
|
||||
`accounts/${this.accountId}/portals/:portalSlug/:locale/articles/draft`
|
||||
`accounts/${this.accountId}/portals/${this.portalSlug}/${this.locale}/articles/draft`
|
||||
),
|
||||
toolTip: 'Draft',
|
||||
toStateName: 'list_draft_articles',
|
||||
@@ -107,7 +113,7 @@ export default {
|
||||
key: 'list_archived_articles',
|
||||
count: 10,
|
||||
toState: frontendURL(
|
||||
`accounts/${this.accountId}/portals/:portalSlug/:locale/articles/archived`
|
||||
`accounts/${this.accountId}/portals/${this.portalSlug}/${this.locale}/articles/archived`
|
||||
),
|
||||
toolTip: 'Archived',
|
||||
toStateName: 'list_archived_articles',
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { mapGetters } from 'vuex';
|
||||
import { frontendURL } from 'dashboard/helper/URLHelper';
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters({ accountId: 'getCurrentAccountId' }),
|
||||
portalSlug() {
|
||||
return this.$route.params.portalSlug;
|
||||
},
|
||||
locale() {
|
||||
return this.$route.params.locale;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
articleUrl(id) {
|
||||
return frontendURL(
|
||||
`accounts/${this.accountId}/portals/${this.portalSlug}/${this.locale}/articles/${id}`
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import portalMixin from '../portalMixin';
|
||||
import Vuex from 'vuex';
|
||||
import VueRouter from 'vue-router';
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
localVue.use(VueRouter);
|
||||
import ListAllArticles from '../../pages/portals/ListAllPortals.vue';
|
||||
|
||||
const router = new VueRouter({
|
||||
routes: [
|
||||
{
|
||||
path: ':portalSlug/:locale/articles',
|
||||
name: 'list_all_locale_articles',
|
||||
component: ListAllArticles,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
describe('portalMixin', () => {
|
||||
let getters;
|
||||
let store;
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
getters = {
|
||||
getCurrentAccountId: () => 1,
|
||||
};
|
||||
const Component = {
|
||||
render() {},
|
||||
title: 'TestComponent',
|
||||
mixins: [portalMixin],
|
||||
router,
|
||||
};
|
||||
store = new Vuex.Store({ getters });
|
||||
wrapper = shallowMount(Component, { store, localVue });
|
||||
});
|
||||
|
||||
it('return account id', () => {
|
||||
expect(wrapper.vm.accountId).toBe(1);
|
||||
});
|
||||
|
||||
it('returns portal url', () => {
|
||||
router.push({
|
||||
name: 'list_all_locale_articles',
|
||||
params: { portalSlug: 'fur-rent', locale: 'en' },
|
||||
});
|
||||
expect(wrapper.vm.articleUrl(1)).toBe(
|
||||
'/app/accounts/1/portals/fur-rent/en/articles/1'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns portal locale', () => {
|
||||
router.push({
|
||||
name: 'list_all_locale_articles',
|
||||
params: { portalSlug: 'fur-rent', locale: 'es' },
|
||||
});
|
||||
expect(wrapper.vm.portalSlug).toBe('fur-rent');
|
||||
});
|
||||
|
||||
it('returns portal slug', () => {
|
||||
router.push({
|
||||
name: 'list_all_locale_articles',
|
||||
params: { portalSlug: 'campaign', locale: 'es' },
|
||||
});
|
||||
expect(wrapper.vm.portalSlug).toBe('campaign');
|
||||
});
|
||||
});
|
||||
@@ -2,26 +2,30 @@
|
||||
<div class="container">
|
||||
<article-header
|
||||
:header-title="headerTitle"
|
||||
:count="articleCount"
|
||||
:count="meta.count"
|
||||
selected-value="Published"
|
||||
@newArticlePage="newArticlePage"
|
||||
/>
|
||||
<article-table :articles="articles" :article-count="articles.length" />
|
||||
<empty-state
|
||||
v-if="showSearchEmptyState"
|
||||
:title="$t('HELP_CENTER.TABLE.404')"
|
||||
<article-table
|
||||
:articles="articles"
|
||||
:article-count="articles.length"
|
||||
:current-page="Number(meta.currentPage)"
|
||||
:total-count="meta.count"
|
||||
@on-page-change="onPageChange"
|
||||
/>
|
||||
<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="isFetching" class="articles--loader">
|
||||
<spinner />
|
||||
<span>{{ $t('HELP_CENTER.TABLE.LOADING_MESSAGE') }}</span>
|
||||
</div>
|
||||
<empty-state
|
||||
v-else-if="!isFetching && !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/routes/dashboard/helpcenter/components/Header/ArticleHeader';
|
||||
import EmptyState from 'dashboard/components/widgets/EmptyState';
|
||||
@@ -35,45 +39,18 @@ 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,
|
||||
},
|
||||
],
|
||||
articleCount: 12,
|
||||
isLoading: false,
|
||||
pageNumber: 1,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
showSearchEmptyState() {
|
||||
...mapGetters({
|
||||
articles: 'articles/allArticles',
|
||||
uiFlags: 'articles/uiFlags',
|
||||
meta: 'articles/getMeta',
|
||||
isFetching: 'articles/isFetching',
|
||||
}),
|
||||
|
||||
showEmptyState() {
|
||||
return this.articles.length === 0;
|
||||
},
|
||||
articleType() {
|
||||
@@ -92,10 +69,23 @@ 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,
|
||||
});
|
||||
},
|
||||
onPageChange(page) {
|
||||
this.fetchArticles({ pageNumber: page });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user