From bcf8ad84251dcb5c49844327e050fa5e33923ae3 Mon Sep 17 00:00:00 2001 From: Sofien Haj Chedhli Date: Thu, 10 Oct 2024 14:47:24 +0100 Subject: [PATCH] feat: Update content Editor and model to relay on note editor extensions - EXO-73275 - Meeds-io/meeds#2478 (#254) --- .../main/java/io/meeds/news/model/News.java | 2 + .../news/service/impl/NewsServiceImpl.java | 12 +++-- .../locale/portlet/news/News_en.properties | 1 + .../locale/portlet/news/News_fr.properties | 1 + .../service/impl/NewsServiceImplTest.java | 4 +- .../components/ContentRichEditor.vue | 53 +++++++++++++++++-- 6 files changed, 64 insertions(+), 9 deletions(-) diff --git a/content-service/src/main/java/io/meeds/news/model/News.java b/content-service/src/main/java/io/meeds/news/model/News.java index 3e18fa7b2..af83528bd 100644 --- a/content-service/src/main/java/io/meeds/news/model/News.java +++ b/content-service/src/main/java/io/meeds/news/model/News.java @@ -137,5 +137,7 @@ public class News { private String illustrationURL; + private String latestVersionId; + private NotePageProperties properties; } diff --git a/content-service/src/main/java/io/meeds/news/service/impl/NewsServiceImpl.java b/content-service/src/main/java/io/meeds/news/service/impl/NewsServiceImpl.java index 5cff10032..3174e254a 100644 --- a/content-service/src/main/java/io/meeds/news/service/impl/NewsServiceImpl.java +++ b/content-service/src/main/java/io/meeds/news/service/impl/NewsServiceImpl.java @@ -992,9 +992,10 @@ public News createNewsArticlePage(News newsArticle, String newsArticleCreator) t newsArticlePage.setAuthor(newsArticle.getAuthor()); newsArticlePage.setLang(null); newsArticlePage.setProperties(newsArticle.getProperties()); + if (newsArticlePage.getProperties() == null) { + newsArticlePage.setProperties(new NotePageProperties(Long.valueOf(draftNewsId), null, null, true)); + } newsArticlePage = noteService.createNote(wiki, newsArticlesRootNotePage.getName(), newsArticlePage, poster); - // create the version - noteService.createVersionOfNote(newsArticlePage, poster.getUserId()); if (newsArticlePage != null) { PageVersion pageVersion = noteService.getPublishedVersionByPageIdAndLang(Long.parseLong(newsArticlePage.getId()), null); // set properties @@ -1002,6 +1003,7 @@ public News createNewsArticlePage(News newsArticle, String newsArticleCreator) t newsArticle.setLang(newsArticlePage.getLang()); newsArticle.setCreationDate(pageVersion.getCreatedDate()); newsArticle.setProperties(newsArticlePage.getProperties()); + newsArticle.setLatestVersionId(pageVersion.getId()); newsArticle.setIllustrationURL(NewsUtils.buildIllustrationUrl(newsArticlePage.getProperties(), newsArticle.getLang())); NewsPageVersionObject newsArticleVersionMetaDataObject = new NewsPageVersionObject(NEWS_METADATA_PAGE_VERSION_OBJECT_TYPE, @@ -1827,6 +1829,7 @@ private News updateArticle(News news, Identity updater, String newsUpdateType) t // create the version if (newsUpdateType.equalsIgnoreCase(CONTENT_AND_TITLE.name())) { noteService.createVersionOfNote(existingPage, updater.getUserId()); + news.setLatestVersionId(noteService.getPublishedVersionByPageIdAndLang(Long.valueOf(news.getId()), news.getLang()).getId()); // remove the draft DraftPage draftPage = noteService.getLatestDraftPageByUserAndTargetPageAndLang(Long.parseLong(existingPage.getId()), updater.getUserId(), @@ -1908,6 +1911,7 @@ private News buildArticle(String newsId, String lang, boolean fetchOriginal) thr news.setUpdateDate(new Date(metadataItem.getUpdatedDate())); news.setProperties(pageVersion.getProperties()); news.setUrl(NewsUtils.buildNewsArticleUrl(news, currentUsername)); + news.setLatestVersionId(pageVersion.getId()); if (news.getProperties() != null && news.getProperties().getFeaturedImage() != null && news.getProperties().getFeaturedImage().getId() != 0) { news.setIllustrationURL(NewsUtils.buildIllustrationUrl(news.getProperties(), pageVersion.getLang())); @@ -1954,7 +1958,7 @@ private News updateDraftArticleForExistingPage(News news, String updater, Page p draftPage.setProperties(news.getProperties()); draftPage = noteService.updateDraftForExistPage(draftPage, page, null, System.currentTimeMillis(), updater); - + news.setId(draftPage.getId()); news.setDraftUpdateDate(draftPage.getUpdatedDate()); news.setDraftUpdater(draftPage.getAuthor()); news.setTargetPageId(draftPage.getTargetPageId()); @@ -2015,7 +2019,6 @@ private News buildLatestDraftArticle(String parentPageId, String currentIdentity } News draftArticle = buildDraftArticle(latestDraft.getId(), currentIdentityId); - draftArticle.setId(latestDraft.getId()); draftArticle.setTargetPageId(latestDraft.getTargetPageId()); draftArticle.setLang(latestDraft.getLang()); return draftArticle; @@ -2114,6 +2117,7 @@ private News addNewArticleVersionWithLang(News news, Identity versionCreator, Sp } existingPage.setProperties(properties); noteService.createVersionOfNote(existingPage, versionCreator.getUserId()); + news.setLatestVersionId(noteService.getPublishedVersionByPageIdAndLang(Long.valueOf(newsId), news.getLang()).getId()); news.setIllustrationURL(NewsUtils.buildIllustrationUrl(news.getProperties(), news.getLang())); DraftPage draftPage = noteService.getLatestDraftPageByTargetPageAndLang(Long.parseLong(newsId), news.getLang()); if (draftPage != null) { diff --git a/content-service/src/main/resources/locale/portlet/news/News_en.properties b/content-service/src/main/resources/locale/portlet/news/News_en.properties index f2b7f5f4a..37610424d 100644 --- a/content-service/src/main/resources/locale/portlet/news/News_en.properties +++ b/content-service/src/main/resources/locale/portlet/news/News_en.properties @@ -33,6 +33,7 @@ news.composer.placeholderSummaryInput=Summary news.composer.placeholderContentInput=Body news.composer.draft=My drafts ({0}) news.composer.draft.savingDraftStatus=Saving the draft... +content.draft.title.untitled=Untitled news.composer.draft.savedDraftStatus=Draft saved. news.composer.draft.delete.confirmation=Are you sure you want to delete this draft? news.composer.postArticle=Post an Article diff --git a/content-service/src/main/resources/locale/portlet/news/News_fr.properties b/content-service/src/main/resources/locale/portlet/news/News_fr.properties index 3857f1e5b..b73294cb0 100644 --- a/content-service/src/main/resources/locale/portlet/news/News_fr.properties +++ b/content-service/src/main/resources/locale/portlet/news/News_fr.properties @@ -33,6 +33,7 @@ news.composer.placeholderSummaryInput=Résumé news.composer.placeholderContentInput=Contenu news.composer.draft=Brouillons ({0}) news.composer.draft.savingDraftStatus=Sauvegarde en cours... +content.draft.title.untitled=Sans titre news.composer.draft.savedDraftStatus=Brouillon sauvegardé news.composer.draft.delete.confirmation=Etes-vous sûr de vouloir supprimer ce brouillon ? news.composer.postArticle=Publier un article diff --git a/content-service/src/test/java/io/meeds/news/service/impl/NewsServiceImplTest.java b/content-service/src/test/java/io/meeds/news/service/impl/NewsServiceImplTest.java index fe07e8278..97da70e03 100644 --- a/content-service/src/test/java/io/meeds/news/service/impl/NewsServiceImplTest.java +++ b/content-service/src/test/java/io/meeds/news/service/impl/NewsServiceImplTest.java @@ -522,6 +522,7 @@ public void testPostNews() throws Exception { newsArticlePage.setContent(newsArticle.getBody()); newsArticlePage.setParentPageId(rootPage.getId()); newsArticlePage.setAuthor(newsArticle.getAuthor()); + newsArticlePage.setProperties(new NotePageProperties(Long.valueOf(newsArticle.getId()), null, null, true)); newsArticlePage.setLang(null); Page createdPage = mock(Page.class); @@ -536,7 +537,6 @@ public void testPostNews() throws Exception { // Then verify(noteService, times(1)).createNote(wiki, rootPage.getName(), newsArticlePage, identity); - verify(noteService, times(1)).createVersionOfNote(createdPage, identity.getUserId()); verify(noteService, times(1)).getPublishedVersionByPageIdAndLang(1L, null); verify(metadataService, atLeast(1)).createMetadataItem(any(MetadataObject.class), any(MetadataKey.class), @@ -768,7 +768,7 @@ public void testUpdateNewsArticle() throws Exception { // Then verify(noteService, times(1)).updateNote(any(Page.class), any(), any()); verify(noteService, times(1)).createVersionOfNote(existingPage, identity.getUserId()); - verify(noteService, times(1)).getPublishedVersionByPageIdAndLang(1L, null); + verify(noteService, times(2)).getPublishedVersionByPageIdAndLang(1L, null); } @Test diff --git a/content-webapp/src/main/webapp/vue-app/news-activity-composer-app/components/ContentRichEditor.vue b/content-webapp/src/main/webapp/vue-app/news-activity-composer-app/components/ContentRichEditor.vue index 30f86f862..e2354901a 100644 --- a/content-webapp/src/main/webapp/vue-app/news-activity-composer-app/components/ContentRichEditor.vue +++ b/content-webapp/src/main/webapp/vue-app/news-activity-composer-app/components/ContentRichEditor.vue @@ -83,7 +83,8 @@ export default { content: '', body: '', properties: {}, - lang: '' + lang: '', + draftPage: '' }, originalArticle: { id: 0, @@ -127,6 +128,7 @@ export default { isSpaceMember: false, spacePrettyName: null, editorExtensions: null, + autosaveProcessedFromEditorExtension: false }; }, watch: { @@ -190,6 +192,7 @@ export default { document.addEventListener('automatic-translation-extensions-updated', () => { this.refreshTranslationExtensions(); }); + document.addEventListener('note-editor-extensions-data-updated', (evt) => this.processAutoSaveFromEditorExtension(evt)); this.$root.$on('display-treeview-items', filter => this.openTreeView(filter)); this.$root.$on('add-translation', this.addTranslation); this.$root.$on('lang-translation-changed', this.changeTranslation); @@ -200,6 +203,27 @@ export default { this.initEditor(); }, methods: { + processAutoSaveFromEditorExtension(event) { + if (event.detail.processAutoSave) { + this.article.title = this.article?.title || this.$t('content.draft.title.untitled'); + this.autosaveProcessedFromEditorExtension = true; + clearTimeout(this.saveDraft); + this.saveDraft = setTimeout(() => { + this.savingDraft = true; + this.draftSavingStatus = this.$t('news.composer.draft.savingDraftStatus'); + this.$nextTick(() => { + if (this.activityId) { + this.saveDraftForExistingArticle(); + } else { + this.saveArticleDraft(); + } + }); + }, this.autoSaveDelay); + } + else { + this.draftSavingStatus = this.$t('news.composer.draft.savedDraftStatus'); + } + }, editorClosed() { window.close(); }, @@ -296,9 +320,12 @@ export default { return this.$newsServices.updateNews(updatedArticle, false, this.articleType).then((createdArticle) => { this.spaceUrl = createdArticle.spaceUrl; this.articleId = this.article.id = createdArticle.id; + this.article.id = this.articleId; this.article.targetPageId = createdArticle.targetPageId; this.article.properties = createdArticle.properties; this.article.draftPage = true; + this.article.targetPageId = createdArticle.targetPageId; + this.article.publicationState = createdArticle.publicationState; this.article.lang = createdArticle.lang; if (this.article.body !== createdArticle.body) { this.imagesURLs = this.extractImagesURLsDiffs(this.article.body, createdArticle.body); @@ -311,6 +338,14 @@ export default { if (this.articleType === 'latest_draft' && this.selectedLanguage) { this.updateUrl(); } + if (this.autosaveProcessedFromEditorExtension) { + document.dispatchEvent(new CustomEvent('article-draft-auto-save-done', { + detail: { + draftId: this.article.id + } + })); + } + this.autosaveProcessedFromEditorExtension = false; }); }, updateAndPostArticle() { @@ -368,7 +403,8 @@ export default { published: false, spaceId: this.spaceId, publicationState: '', - properties: properties + properties: properties, + draftPage: true }; if (this.article.id) { if (this.article.title || this.article.body) { @@ -378,8 +414,9 @@ export default { if (this.article.body !== updatedArticle.body) { this.imagesURLs = this.extractImagesURLsDiffs(this.article.body, updatedArticle.body); } - this.article.properties = updatedArticle?.properties; this.article.draftPage = true; + this.article.id = updatedArticle.id; + this.article.properties = updatedArticle?.properties; }) .then(() => this.$emit('draftUpdated')) .then(() => { @@ -401,12 +438,21 @@ export default { this.draftSavingStatus = this.$t('news.composer.draft.savedDraftStatus'); this.article.id = createdArticle.id; this.article.draftPage = true; + this.article.lang = createdArticle.lang; this.article.properties = createdArticle?.properties; if (!this.articleId) { this.articleId = createdArticle.id; } this.$emit('draftCreated'); this.savingDraft = false; + if (this.autosaveProcessedFromEditorExtension) { + document.dispatchEvent(new CustomEvent('article-draft-auto-save-done', { + detail: { + draftId: this.article.id + } + })); + } + this.autosaveProcessedFromEditorExtension = false; }); } else { this.draftSavingStatus = ''; @@ -624,6 +670,7 @@ export default { this.article.spaceId = article.spaceId; this.article.publicationState = article.publicationState; this.article.draftPage = article.publicationState === 'draft'; + this.article.latestVersionId = article.latestVersionId; this.article.activityId = article.activityId; this.article.updater = article.updater; this.article.draftUpdaterDisplayName = article.draftUpdaterDisplayName;