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 536826c84..ae36779dd 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 @@ -142,4 +142,6 @@ public class News { private String latestVersionId; private NotePageProperties properties; + + private boolean fromDraft; } diff --git a/content-service/src/main/java/io/meeds/news/rest/NewsRest.java b/content-service/src/main/java/io/meeds/news/rest/NewsRest.java index 47765bf4c..63de074de 100644 --- a/content-service/src/main/java/io/meeds/news/rest/NewsRest.java +++ b/content-service/src/main/java/io/meeds/news/rest/NewsRest.java @@ -20,6 +20,7 @@ package io.meeds.news.rest; import static io.meeds.news.utils.NewsUtils.NewsObjectType.ARTICLE; +import static io.meeds.news.utils.NewsUtils.NewsObjectType.EXISTING_PAGE; import java.util.ArrayList; import java.util.HashMap; @@ -634,12 +635,13 @@ public ResponseEntity scheduleNews(@Parameter(description = "News object t } org.exoplatform.services.security.Identity currentIdentity = ConversationState.getCurrent().getIdentity(); try { - News news = newsService.getNewsById(scheduledNews.getId(), currentIdentity, false, newsObjectType); - if (news == null) { - return ResponseEntity.notFound().build(); + if (!newsObjectType.equalsIgnoreCase(EXISTING_PAGE.name())) { + News news = newsService.getNewsById(scheduledNews.getId(), currentIdentity, false, newsObjectType); + if (news == null) { + return ResponseEntity.notFound().build(); + } } - news = newsService.scheduleNews(scheduledNews, currentIdentity, newsObjectType); - return ResponseEntity.ok(news); + return ResponseEntity.ok(newsService.scheduleNews(scheduledNews, currentIdentity, newsObjectType)); } catch (IllegalAccessException e) { LOG.warn("User '{}' is not autorized to schedule news", currentIdentity.getUserId(), e); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); diff --git a/content-service/src/main/java/io/meeds/news/service/NewsService.java b/content-service/src/main/java/io/meeds/news/service/NewsService.java index e504eb05b..adf9371c3 100644 --- a/content-service/src/main/java/io/meeds/news/service/NewsService.java +++ b/content-service/src/main/java/io/meeds/news/service/NewsService.java @@ -284,7 +284,7 @@ News scheduleNews(News news, /** * Checks if the user can schedule publishinga News - * + * * @param space target space * @param currentIdentity current user identity * @param article target article @@ -303,7 +303,7 @@ News scheduleNews(News news, /** * Shares a news item into a dedicated space - * + * * @param news {@link News} to share * @param space {@link Space} to share with, the news * @param userIdentity {@link Identity} of user making the modification @@ -325,6 +325,16 @@ News createDraftArticleForNewPage(News draftArticle, String draftArticleCreator, long creationDate) throws Exception; + /** + * Create an article from exiting page + * + * @param article article object + * @param creator article creator + * @return {@link News} + * @throws Exception + */ + News createArticleFromExistingPage(News article, String creator) throws Exception; + /** * @param newsArticle {@link News} news article to be created * @param newsArticleCreator 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 f9df93f03..fb3170a8d 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 @@ -23,7 +23,6 @@ import static io.meeds.news.utils.NewsUtils.NewsObjectType.LATEST_DRAFT; import static io.meeds.news.utils.NewsUtils.NewsUpdateType.CONTENT_AND_TITLE; -import java.text.ParseException; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -240,6 +239,8 @@ public News createNews(News news, Identity currentIdentity) throws Exception { public News postNews(News news, String poster) throws Exception { if (news.getPublicationState().equals(STAGED) || news.getSchedulePostDate() != null) { news = postScheduledArticle(news); + } else if (!news.isFromDraft() && noteService.getNoteById(news.getId()) != null) { + news = createArticleFromExistingPage(news, poster); } else { news = createNewsArticlePage(news, poster); } @@ -750,6 +751,8 @@ public News scheduleNews(News news, Identity currentIdentity, String newsObjectT // it will be posted and published by the news schedule job or the edit // scheduling. news = createNewsArticlePage(news, currentIdentity.getUserId()); + } else if (newsObjectType.equalsIgnoreCase(NewsObjectType.EXISTING_PAGE.name())) { + news = createArticleFromExistingPage(news, currentIdentity.getUserId()); } else if (newsObjectType.equalsIgnoreCase(ARTICLE.name())) { updateArticle(news, currentIdentity, NewsUtils.NewsUpdateType.SCHEDULE.name().toLowerCase()); } @@ -957,6 +960,21 @@ public News createDraftArticleForNewPage(News draftArticle, return null; } + /** + * {@inheritDoc} + */ + @Override + public News createArticleFromExistingPage(News article, String creator) throws Exception { + Page articlePage = noteService.getNoteById(article.getId()); + Space space = spaceService.getSpaceById(article.getSpaceId()); + if (articlePage != null && space != null) { + PageVersion pageVersion = noteService.getPublishedVersionByPageIdAndLang(Long.parseLong(articlePage.getId()), null); + article.setIllustrationURL(NewsUtils.buildIllustrationUrl(articlePage.getProperties(), articlePage.getLang())); + buildNewArticleProperties(article, articlePage, creator, space.getId(), pageVersion.getId()); + } + return article; + } + /** * {@inheritDoc} */ @@ -1010,44 +1028,8 @@ public News createNewsArticlePage(News newsArticle, String newsArticleCreator) t 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, - pageVersion.getId(), - null, - Long.parseLong(space.getId())); - String newsArticleMetadataItemCreatorIdentityId = identityManager.getOrCreateUserIdentity(newsArticleCreator).getId(); - Map newsArticleVersionMetadataItemProperties = new HashMap<>(); - - // create the page version metadata item - metadataService.createMetadataItem(newsArticleVersionMetaDataObject, - NEWS_METADATA_KEY, - newsArticleVersionMetadataItemProperties, - Long.parseLong(newsArticleMetadataItemCreatorIdentityId), - false); - - // create metadata item page - NewsPageObject newsPageObject = new NewsPageObject(NEWS_METADATA_PAGE_OBJECT_TYPE, - newsArticlePage.getId(), - null, - Long.parseLong(space.getId())); - Map newsPageProperties = new HashMap<>(); - if (StringUtils.isNotEmpty(newsArticle.getAudience())) { - newsPageProperties.put(NEWS_AUDIENCE, newsArticle.getAudience()); - } - - setScheduleProperties(newsArticle, newsPageProperties); - if (StringUtils.isNotEmpty(newsArticle.getPublicationState())) { - newsPageProperties.put(NEWS_PUBLICATION_STATE, newsArticle.getPublicationState()); - } - newsPageProperties.put(NEWS_ACTIVITY_POSTED, String.valueOf(newsArticle.isActivityPosted())); - newsPageProperties.put(PUBLISHED, String.valueOf(newsArticle.isPublished())); - newsPageProperties.put(NEWS_DELETED, String.valueOf(newsArticlePage.isDeleted())); - metadataService.createMetadataItem(newsPageObject, - NEWS_METADATA_KEY, - newsPageProperties, - Long.parseLong(newsArticleMetadataItemCreatorIdentityId), - false); + buildNewArticleProperties(newsArticle, newsArticlePage, newsArticleCreator, space.getId(), pageVersion.getId()); // delete the draft deleteDraftArticle(draftNewsId, poster.getUserId()); return newsArticle; @@ -1178,6 +1160,48 @@ public void deleteDraftArticle(String draftArticleId, String draftArticleCreator public List getArticleLanguages(String articleId, boolean withDrafts) throws WikiException { return noteService.getPageAvailableTranslationLanguages(Long.parseLong(articleId), withDrafts); } + + private void buildNewArticleProperties(News article, + Page articlePage, + String creator, + String spaceId, + String versionId) throws Exception { + NewsPageVersionObject articleVersionMetaDataObject = new NewsPageVersionObject(NEWS_METADATA_PAGE_VERSION_OBJECT_TYPE, + versionId, + null, + Long.parseLong(spaceId)); + String creatorIdentityId = identityManager.getOrCreateUserIdentity(creator).getId(); + Map newsArticleVersionMetadataItemProperties = new HashMap<>(); + // create the page version metadata item + metadataService.createMetadataItem(articleVersionMetaDataObject, + NEWS_METADATA_KEY, + newsArticleVersionMetadataItemProperties, + Long.parseLong(creatorIdentityId), + false); + + // create metadata item page + NewsPageObject newsPageObject = new NewsPageObject(NEWS_METADATA_PAGE_OBJECT_TYPE, + articlePage.getId(), + null, + Long.parseLong(spaceId)); + Map newsPageProperties = new HashMap<>(); + if (StringUtils.isNotEmpty(article.getAudience())) { + newsPageProperties.put(NEWS_AUDIENCE, article.getAudience()); + } + setScheduleProperties(article, newsPageProperties); + + if (StringUtils.isNotEmpty(article.getPublicationState())) { + newsPageProperties.put(NEWS_PUBLICATION_STATE, article.getPublicationState()); + } + newsPageProperties.put(NEWS_ACTIVITY_POSTED, String.valueOf(article.isActivityPosted())); + newsPageProperties.put(PUBLISHED, String.valueOf(article.isPublished())); + newsPageProperties.put(NEWS_DELETED, String.valueOf(articlePage.isDeleted())); + metadataService.createMetadataItem(newsPageObject, + NEWS_METADATA_KEY, + newsPageProperties, + Long.parseLong(creatorIdentityId), + false); + } private News updateDraftArticleForNewPage(News draftArticle, String draftArticleUpdater, Space space) throws WikiException, IllegalAccessException { @@ -1897,7 +1921,7 @@ private News buildArticle(String newsId, String lang, boolean fetchOriginal) thr articlePage.getId(), null, Long.parseLong(space.getId())); - MetadataItem metadataItem = metadataService.getMetadataItemsByMetadataAndObject(NEWS_METADATA_KEY, newsPageObject).get(0); + MetadataItem metadataItem = metadataService.getMetadataItemsByMetadataAndObject(NEWS_METADATA_KEY, newsPageObject).getFirst(); buildArticleProperties(news, currentUsername, metadataItem); news.setDeleted(articlePage.isDeleted()); news.setPublicationDate(articlePage.getCreatedDate()); @@ -1914,14 +1938,6 @@ private News buildArticle(String newsId, String lang, boolean fetchOriginal) thr news.setIllustrationURL(NewsUtils.buildIllustrationUrl(news.getProperties(), pageVersion.getLang())); } - - NewsPageVersionObject newsPageVersionObject = new NewsPageVersionObject(NEWS_METADATA_PAGE_VERSION_OBJECT_TYPE, - pageVersion.getId(), - null, - Long.parseLong(space.getId())); - List newsPageVersionMetadataItems = - metadataService.getMetadataItemsByMetadataAndObject(NEWS_METADATA_KEY, - newsPageVersionObject); return news; } } @@ -2031,7 +2047,7 @@ private void processPageContent(Page page, News news) throws Exception { } private String parseAndNormalizeScheduleDate(String date, String timeZoneId) { - if(StringUtils.isBlank(date)) { + if(StringUtils.isBlank(date) || date.equals("0")) { return null; } ZoneId userTimeZone = StringUtils.isBlank(timeZoneId) ? ZoneId.of("UTC") : ZoneId.of(timeZoneId); diff --git a/content-service/src/main/java/io/meeds/news/utils/NewsUtils.java b/content-service/src/main/java/io/meeds/news/utils/NewsUtils.java index 8331399f1..6c2e973d0 100644 --- a/content-service/src/main/java/io/meeds/news/utils/NewsUtils.java +++ b/content-service/src/main/java/io/meeds/news/utils/NewsUtils.java @@ -100,7 +100,7 @@ public class NewsUtils { public static final String UPDATE_CONTENT_PERMISSIONS = "content.update.permissions"; public enum NewsObjectType { - DRAFT, LATEST_DRAFT, ARTICLE; + DRAFT, LATEST_DRAFT, ARTICLE, EXISTING_PAGE } public enum NewsUpdateType { diff --git a/content-webapp/src/main/webapp/WEB-INF/gatein-resources.xml b/content-webapp/src/main/webapp/WEB-INF/gatein-resources.xml index fbbacf4b3..6b7c95e85 100644 --- a/content-webapp/src/main/webapp/WEB-INF/gatein-resources.xml +++ b/content-webapp/src/main/webapp/WEB-INF/gatein-resources.xml @@ -587,4 +587,32 @@ $ + + + NotePublishExtensions + + + vue + + + vuetify + + + eXoVueI18n + + + jquery + $ + + + extensionRegistry + + + commonVueComponents + + + 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 3dfedf787..5d747d34f 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 @@ -509,6 +509,7 @@ export default { audience: this.article.audience, draftPage: this.article.publicationState === 'draft', scheduleUnpublishDate: this.article.scheduleUnpublishDate, + fromDraft: true, properties: this.article?.properties }; diff --git a/content-webapp/src/main/webapp/vue-app/news-extensions/note-publish-extensions/main.js b/content-webapp/src/main/webapp/vue-app/news-extensions/note-publish-extensions/main.js new file mode 100644 index 000000000..41053a796 --- /dev/null +++ b/content-webapp/src/main/webapp/vue-app/news-extensions/note-publish-extensions/main.js @@ -0,0 +1,14 @@ +import * as newsTargetingService from '../../services/newsTargetingService.js'; +import * as newsService from '../../services/newsServices.js'; + + +if (!Vue.prototype.$newsTargetingService) { + window.Object.defineProperty(Vue.prototype, '$newsTargetingService', { + value: newsTargetingService, + }); +} +if (!Vue.prototype.$newsService) { + window.Object.defineProperty(Vue.prototype, '$newsService', { + value: newsService, + }); +} diff --git a/content-webapp/src/main/webapp/vue-app/services/newsServices.js b/content-webapp/src/main/webapp/vue-app/services/newsServices.js index 051755fc7..4dbf000cd 100644 --- a/content-webapp/src/main/webapp/vue-app/services/newsServices.js +++ b/content-webapp/src/main/webapp/vue-app/services/newsServices.js @@ -31,8 +31,6 @@ export function getNewsById(id, editMode, type, lang) { } else if ( resp.status === 401) { return resp.status; } - }).catch((error) => { - return error; }); } diff --git a/content-webapp/webpack.common.js b/content-webapp/webpack.common.js index f551d6d70..715fc6330 100644 --- a/content-webapp/webpack.common.js +++ b/content-webapp/webpack.common.js @@ -22,7 +22,8 @@ let config = { newsAnalyticsExtensions: './src/main/webapp/vue-app/news-extensions/analytics-extensions/main.js', newsNotificationExtensions: './src/main/webapp/vue-app/news-extensions/notification-extensions/main.js', engagementCenterExtensions: './src/main/webapp/vue-app/engagementCenterExtensions/extensions.js', - contentTranslationMenu: './src/main/webapp/vue-app/newsTranslationMenu/main.js' + contentTranslationMenu: './src/main/webapp/vue-app/newsTranslationMenu/main.js', + notePublishExtensions: './src/main/webapp/vue-app/news-extensions/note-publish-extensions/main.js', }, output: { filename: 'js/[name].bundle.js',