feat: Adds the ability to publish an article (#5365)

* feat: Adds the ability to publish an article

* chore: Disabled publish button and dropdown when there is no article id

* chore: Review fixes

* chore: Review fixes

* Update app/javascript/dashboard/routes/dashboard/helpcenter/components/Header/EditArticleHeader.vue

* chore: Review fixes

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
Sivin Varghese 2022-09-02 12:53:18 +05:30 committed by GitHub
parent b16c5de7ca
commit 03c8251cc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 131 additions and 9 deletions

View file

@ -12,6 +12,11 @@ export default {
SNOOZED: 'snoozed',
ALL: 'all',
},
ARTICLE_STATUS_TYPES: {
DRAFT: 0,
PUBLISH: 1,
ARCHIVE: 2,
},
LAYOUT_TYPES: {
CONDENSED: 'condensed',
EXPANDED: 'expanded',

View file

@ -20,6 +20,7 @@
"EDIT_HEADER": {
"ALL_ARTICLES": "All Articles",
"PUBLISH_BUTTON": "Publish",
"MOVE_TO_ARCHIVE_BUTTON": "Move to archived",
"PREVIEW": "Preview",
"ADD_TRANSLATION": "Add translation",
"OPEN_SIDEBAR": "Open sidebar",
@ -143,7 +144,8 @@
}
},
"ADD": {
"CREATE_FLOW": [{
"CREATE_FLOW": [
{
"title": "Help center information",
"route": "new_portal_information",
"body": "Basic information about portal",
@ -286,6 +288,12 @@
"ERROR": "Error while saving article"
}
},
"PUBLISH_ARTICLE": {
"API": {
"ERROR": "Error while publishing article",
"SUCCESS": "Article publishied successfully"
}
},
"ARCHIVE_ARTICLE": {
"API": {
"ERROR": "Error while archiving article",

View file

@ -59,19 +59,58 @@
color-scheme="secondary"
@click="closeSidebar"
/>
<div class="article--buttons">
<div class="button-group">
<woot-button
class-names="article--buttons"
class-names="publish-button"
size="small"
color-scheme="primary"
:is-disabled="!articleSlug || isPublishedArticle"
@click="updateArticleStatus(ARTICLE_STATUS_TYPES.PUBLISH)"
>
{{ $t('HELP_CENTER.EDIT_HEADER.PUBLISH_BUTTON') }}
</woot-button>
<woot-button
ref="arrowDownButton"
size="small"
icon="chevron-down"
:is-disabled="!articleSlug || isArchivedArticle"
@click="openActionsDropdown"
/>
</div>
<div
v-if="showActionsDropdown"
v-on-clickaway="closeActionsDropdown"
class="dropdown-pane dropdown-pane--open"
>
<woot-dropdown-menu>
<woot-dropdown-item>
<woot-button
variant="clear"
color-scheme="secondary"
size="small"
icon="book-clock"
@click="updateArticleStatus(ARTICLE_STATUS_TYPES.ARCHIVE)"
>
{{ $t('HELP_CENTER.EDIT_HEADER.MOVE_TO_ARCHIVE_BUTTON') }}
</woot-button>
</woot-dropdown-item>
</woot-dropdown-menu>
</div>
</div>
</div>
</div>
</template>
<script>
import alertMixin from 'shared/mixins/alertMixin';
import { mixin as clickaway } from 'vue-clickaway';
import wootConstants from 'dashboard/constants.js';
const { ARTICLE_STATUS_TYPES } = wootConstants;
export default {
mixins: [alertMixin, clickaway],
props: {
backButtonLabel: {
type: String,
@ -97,6 +136,9 @@ export default {
data() {
return {
isSidebarOpen: false,
showActionsDropdown: false,
alertMessage: '',
ARTICLE_STATUS_TYPES: ARTICLE_STATUS_TYPES,
};
},
computed: {
@ -105,6 +147,21 @@ export default {
? this.$t('HELP_CENTER.EDIT_HEADER.SAVING')
: this.$t('HELP_CENTER.EDIT_HEADER.SAVED');
},
articleSlug() {
return this.$route.params.articleSlug;
},
currentPortalSlug() {
return this.$route.params.portalSlug;
},
currentArticleStatus() {
return this.$store.getters['articles/articleStatus'](this.articleSlug);
},
isPublishedArticle() {
return this.currentArticleStatus === 'published';
},
isArchivedArticle() {
return this.currentArticleStatus === 'archived';
},
},
methods: {
onClickGoBack() {
@ -116,6 +173,36 @@ export default {
onClickAdd() {
this.$emit('add');
},
async updateArticleStatus(status) {
try {
await this.$store.dispatch('articles/update', {
portalSlug: this.currentPortalSlug,
articleId: this.articleSlug,
status: status,
});
this.statusUpdateSuccessMessage(status);
this.closeActionsDropdown();
} catch (error) {
this.alertMessage =
error?.message || this.statusUpdateErrorMessage(status);
} finally {
this.showAlert(this.alertMessage);
}
},
statusUpdateSuccessMessage(status) {
if (status === this.ARTICLE_STATUS_TYPES.PUBLISH) {
this.alertMessage = this.$t('HELP_CENTER.PUBLISH_ARTICLE.API.SUCCESS');
} else if (status === this.ARTICLE_STATUS_TYPES.ARCHIVE) {
this.alertMessage = this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.SUCCESS');
}
},
statusUpdateErrorMessage(status) {
if (status === this.ARTICLE_STATUS_TYPES.PUBLISH) {
this.alertMessage = this.$t('HELP_CENTER.PUBLISH_ARTICLE.API.ERROR');
} else if (status === this.ARTICLE_STATUS_TYPES.ARCHIVE) {
this.alertMessage = this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.ERROR');
}
},
openSidebar() {
this.isSidebarOpen = true;
this.$emit('open');
@ -124,6 +211,12 @@ export default {
this.isSidebarOpen = false;
this.$emit('close');
},
openActionsDropdown() {
this.showActionsDropdown = !this.showActionsDropdown;
},
closeActionsDropdown() {
this.showActionsDropdown = false;
},
},
};
</script>
@ -149,6 +242,9 @@ export default {
}
.article--buttons {
margin-left: var(--space-smaller);
.dropdown-pane {
right: var(--space-smaller);
}
}
.draft-status {
margin-right: var(--space-smaller);

View file

@ -49,6 +49,9 @@ import ArticleSettings from './ArticleSettings.vue';
import Spinner from 'shared/components/Spinner';
import portalMixin from '../../mixins/portalMixin';
import alertMixin from 'shared/mixins/alertMixin';
import wootConstants from 'dashboard/constants';
const { ARTICLE_STATUS_TYPES } = wootConstants;
export default {
components: {
EditArticleHeader,
@ -152,7 +155,7 @@ export default {
await this.$store.dispatch('articles/update', {
portalSlug: this.selectedPortalSlug,
articleId: this.articleId,
status: 2,
status: ARTICLE_STATUS_TYPES.ARCHIVE,
});
this.alertMessage = this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.SUCCESS');
} catch (error) {

View file

@ -20,6 +20,12 @@ export const getters = {
.filter(article => article !== undefined);
return articles;
},
articleStatus: (...getterArguments) => articleId => {
const [state] = getterArguments;
const article = state.articles.byId[articleId];
if (!article) return undefined;
return article.status;
},
getMeta: state => {
return state.meta;
},

View file

@ -34,6 +34,10 @@ describe('#getters', () => {
});
});
it('articleStatus', () => {
expect(getters.articleStatus(state)(1)).toEqual('draft');
});
it('isFetchingArticles', () => {
expect(getters.isFetching(state)).toEqual(true);
});