diff --git a/app/javascript/dashboard/components-next/HelpCenter/Pages/ArticleEditorPage/ArticleEditor.vue b/app/javascript/dashboard/components-next/HelpCenter/Pages/ArticleEditorPage/ArticleEditor.vue
index f15135737..f5b925fbe 100644
--- a/app/javascript/dashboard/components-next/HelpCenter/Pages/ArticleEditorPage/ArticleEditor.vue
+++ b/app/javascript/dashboard/components-next/HelpCenter/Pages/ArticleEditorPage/ArticleEditor.vue
@@ -27,6 +27,7 @@ const props = defineProps({
const emit = defineEmits([
'saveArticle',
+ 'saveArticleAsync',
'goBack',
'setAuthor',
'setCategory',
@@ -35,19 +36,37 @@ const emit = defineEmits([
const { t } = useI18n();
-const saveArticle = debounce(value => emit('saveArticle', value), 600, false);
+const saveAndSync = value => {
+ emit('saveArticle', value);
+};
+
+// this will only send the data to the backend
+// but will not update the local state preventing unnecessary re-renders
+// since the data is already saved and we keep the editor text as the source of truth
+const quickSave = debounce(
+ value => emit('saveArticleAsync', value),
+ 400,
+ false
+);
+
+// 2.5 seconds is enough to know that the user has stopped typing and is taking a pause
+// so we can save the data to the backend and retrieve the updated data
+// this will update the local state with response data
+const saveAndSyncDebounced = debounce(saveAndSync, 2500, false);
const articleTitle = computed({
get: () => props.article.title,
set: value => {
- saveArticle({ title: value });
+ quickSave({ title: value });
+ saveAndSyncDebounced({ title: value });
},
});
const articleContent = computed({
get: () => props.article.content,
set: content => {
- saveArticle({ content });
+ quickSave({ content });
+ saveAndSyncDebounced({ content });
},
});
@@ -93,7 +112,7 @@ const previewArticle = () => {
/>
diff --git a/app/javascript/dashboard/routes/dashboard/helpcenter/pages/PortalsArticlesEditPage.vue b/app/javascript/dashboard/routes/dashboard/helpcenter/pages/PortalsArticlesEditPage.vue
index 736b34096..3bb868a58 100644
--- a/app/javascript/dashboard/routes/dashboard/helpcenter/pages/PortalsArticlesEditPage.vue
+++ b/app/javascript/dashboard/routes/dashboard/helpcenter/pages/PortalsArticlesEditPage.vue
@@ -34,10 +34,11 @@ const portalLink = computed(() => {
);
});
-const saveArticle = async ({ ...values }) => {
+const saveArticle = async ({ ...values }, isAsync = false) => {
+ const actionToDispatch = isAsync ? 'articles/updateAsync' : 'articles/update';
isUpdating.value = true;
try {
- await store.dispatch('articles/update', {
+ await store.dispatch(actionToDispatch, {
portalSlug,
articleId: articleSlug,
...values,
@@ -55,6 +56,10 @@ const saveArticle = async ({ ...values }) => {
}
};
+const saveArticleAsync = async ({ ...values }) => {
+ saveArticle({ ...values }, true);
+};
+
const isCategoryArticles = computed(() => {
return (
route.name === 'portals_categories_articles_index' ||
@@ -92,9 +97,7 @@ const previewArticle = () => {
});
};
-onMounted(() => {
- fetchArticleDetails();
-});
+onMounted(fetchArticleDetails);
@@ -103,6 +106,7 @@ onMounted(() => {
:is-updating="isUpdating"
:is-saved="isSaved"
@save-article="saveArticle"
+ @save-article-async="saveArticleAsync"
@preview-article="previewArticle"
@go-back="goBackToArticles"
/>
diff --git a/app/javascript/dashboard/store/modules/helpCenterArticles/actions.js b/app/javascript/dashboard/store/modules/helpCenterArticles/actions.js
index 8052cb133..e481ac2b0 100644
--- a/app/javascript/dashboard/store/modules/helpCenterArticles/actions.js
+++ b/app/javascript/dashboard/store/modules/helpCenterArticles/actions.js
@@ -69,6 +69,25 @@ export const actions = {
}
},
+ updateAsync: async ({ commit }, { portalSlug, articleId, ...articleObj }) => {
+ commit(types.UPDATE_ARTICLE_FLAG, {
+ uiFlags: { isUpdating: true },
+ articleId,
+ });
+
+ try {
+ await articlesAPI.updateArticle({ portalSlug, articleId, articleObj });
+ return articleId;
+ } catch (error) {
+ return throwErrorMessage(error);
+ } finally {
+ commit(types.UPDATE_ARTICLE_FLAG, {
+ uiFlags: { isUpdating: false },
+ articleId,
+ });
+ }
+ },
+
update: async ({ commit }, { portalSlug, articleId, ...articleObj }) => {
commit(types.UPDATE_ARTICLE_FLAG, {
uiFlags: {