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);