diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/rest/NotesRestService.java b/notes-service/src/main/java/org/exoplatform/wiki/service/rest/NotesRestService.java index 10f9630f4..c4e81abaa 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/rest/NotesRestService.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/rest/NotesRestService.java @@ -761,8 +761,8 @@ public Response updateNoteById(@Parameter(description = "Note id", required = tr } note_ = noteService.updateNote(note_, PageUpdateType.EDIT_PAGE_CONTENT_AND_TITLE, identity); } else { - note_.setLang(note.getLang()); note_ = noteService.updateNote(note_, PageUpdateType.EDIT_PAGE_CONTENT_AND_TITLE, identity); + note_.setLang(note.getLang()); note_.setTitle(note.getTitle()); note_.setContent(note.getContent()); note_.setProperties(notePageProperties); @@ -783,8 +783,8 @@ public Response updateNoteById(@Parameter(description = "Note id", required = tr note_.setProperties(notePageProperties); note_ = noteService.updateNote(note_, PageUpdateType.EDIT_PAGE_TITLE, identity); } else { - note_.setLang(note.getLang()); note_ = noteService.updateNote(note_, PageUpdateType.EDIT_PAGE_TITLE, identity); + note_.setLang(note.getLang()); note_.setTitle(note.getTitle()); note_.setProperties(notePageProperties); } @@ -799,8 +799,8 @@ public Response updateNoteById(@Parameter(description = "Note id", required = tr note_.setProperties(notePageProperties); note_ = noteService.updateNote(note_, PageUpdateType.EDIT_PAGE_CONTENT, identity); } else { - note_.setLang(note.getLang()); note_ = noteService.updateNote(note_, PageUpdateType.EDIT_PAGE_CONTENT, identity); + note_.setLang(note.getLang()); note_.setContent(note.getContent()); note_.setProperties(notePageProperties); } @@ -815,8 +815,8 @@ public Response updateNoteById(@Parameter(description = "Note id", required = tr note_.setProperties(notePageProperties); note_ = noteService.updateNote(note_, PageUpdateType.EDIT_PAGE_PROPERTIES, identity); } else { - note_.setLang(note.getLang()); note_ = noteService.updateNote(note_, PageUpdateType.EDIT_PAGE_PROPERTIES, identity); + note_.setLang(note.getLang()); note_.setProperties(notePageProperties); } noteService.createVersionOfNote(note_, identity.getUserId()); diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_en.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_en.properties index 0a5cdf5b7..8dba53fa5 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_en.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_en.properties @@ -54,7 +54,7 @@ notes.save.success.message=Note saved successfully notes.view.label=View notes.metadata.properties.label=Properties -notes.metadata.featuredImage.label=Featured images +notes.metadata.featuredImage.label=Featured image notes.metadata.featuredImage.add.label=Add an image notes.metadata.featuredImage.alt=Featured image notes.metadata.summary.label=Summary @@ -66,6 +66,13 @@ notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB +notes.publication.publish.label=Publication +notes.publication.label=Choose your publication options +notes.publication.check.properties.label=Check the teaser +notes.publication.publish.next.label=Next +notes.publication.post.in.feed.label=Post in Activity stream of +notes.publication.publish.save.label=Publish + popup.confirm=Confirm popup.msg.confirmation=Confirmation popup.confirmation.delete=Delete the note diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fr.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fr.properties index db7ddf35b..989e371a8 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fr.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fr.properties @@ -65,6 +65,13 @@ notes.featuredImage.remove.error.message=Erreur lors de la suppression de l'illu notes.featuredImage.remove.success.message=Illustration supprimée avec succès notes.featuredImage.size.error.message=La taille de l'illustration doit être inférieure ou égale à 20Mo +notes.publication.publish.label=Publication +notes.publication.label=Choisir les options de publication +notes.publication.check.properties.label=Vérifier l'accroche +notes.publication.publish.next.label=Suivant +notes.publication.post.in.feed.label=Publier dans le fil d'activités de +notes.publication.publish.save.label=Publier + popup.confirm=Confirmer popup.msg.confirmation=Confirmation popup.confirmation.delete=Supprimer la note diff --git a/notes-webapp/src/main/webapp/WEB-INF/gatein-resources.xml b/notes-webapp/src/main/webapp/WEB-INF/gatein-resources.xml index 41917e491..fbb9ee85e 100644 --- a/notes-webapp/src/main/webapp/WEB-INF/gatein-resources.xml +++ b/notes-webapp/src/main/webapp/WEB-INF/gatein-resources.xml @@ -86,6 +86,9 @@ + + NotesPublication + commonVueComponents @@ -114,6 +117,32 @@ + + NotesPublication + NotesGRP + + + commonVueComponents + + + extensionRegistry + + + vue + + + vuetify + + + eXoVueI18n + + + imageCropper + + + NotesEditor diff --git a/notes-webapp/src/main/webapp/skin/less/notes/notes.less b/notes-webapp/src/main/webapp/skin/less/notes/notes.less index ca30c2f91..80cf009d0 100644 --- a/notes-webapp/src/main/webapp/skin/less/notes/notes.less +++ b/notes-webapp/src/main/webapp/skin/less/notes/notes.less @@ -212,7 +212,14 @@ } } -#editorMetadataDrawer { +#editorPublicationDrawer { + .post-feed-target { + max-width: 335px; + } + +} + +#editorMetadataDrawer, #editorPublicationDrawer { .add-image-area, .image-preview { background-color: @primaryBackground !important; diff --git a/notes-webapp/src/main/webapp/vue-app/notes-editor/components/NotesEditorDashboard.vue b/notes-webapp/src/main/webapp/vue-app/notes-editor/components/NotesEditorDashboard.vue index 2e3bf4cc0..72c0417d1 100644 --- a/notes-webapp/src/main/webapp/vue-app/notes-editor/components/NotesEditorDashboard.vue +++ b/notes-webapp/src/main/webapp/vue-app/notes-editor/components/NotesEditorDashboard.vue @@ -281,7 +281,7 @@ export default { this.note.content = noteObject.content; this.note.properties = noteObject.properties; }, - postNote(toPublish) { + postNote() { this.postingNote = true; clearTimeout(this.saveDraft); const properties = this.note?.properties; @@ -297,7 +297,7 @@ export default { wikiOwner: this.note.wikiOwner, content: this.$noteUtils.getContentToSave('notesContent', this.oembedMinWidth) || this.note.content, parentPageId: this.note?.draftPage && this.note?.targetPageId === this.parentPageId ? null : this.parentPageId, - toBePublished: toPublish, + toBePublished: false, appName: this.appName, properties: properties }; @@ -550,7 +550,7 @@ export default { if (draftNote.properties) { draftNote.properties.draft = true; if (this.newTranslation && !this.featuredImageUpdated) { - draftNote.properties.featuredImage = null; + draftNote.properties.featuredImage = {}; } } this.$notesService.saveDraftNote(draftNote, this.parentPageId).then(savedDraftNote => { diff --git a/notes-webapp/src/main/webapp/vue-app/notes-publication/components/NotePublicationDrawer.vue b/notes-webapp/src/main/webapp/vue-app/notes-publication/components/NotePublicationDrawer.vue new file mode 100644 index 000000000..f707dce70 --- /dev/null +++ b/notes-webapp/src/main/webapp/vue-app/notes-publication/components/NotePublicationDrawer.vue @@ -0,0 +1,291 @@ + + + + + diff --git a/notes-webapp/src/main/webapp/vue-app/notes-publication/initComponents.js b/notes-webapp/src/main/webapp/vue-app/notes-publication/initComponents.js new file mode 100644 index 000000000..7c7fc54b7 --- /dev/null +++ b/notes-webapp/src/main/webapp/vue-app/notes-publication/initComponents.js @@ -0,0 +1,11 @@ +import NotePublicationDrawer from './components/NotePublicationDrawer.vue'; +import NoteMetadataPropertiesForm from '../notes-rich-editor/components/note-properties/NoteMetadataPropertiesForm.vue'; + +const components = { + 'note-publication-drawer': NotePublicationDrawer, + 'note-metadata-properties-form': NoteMetadataPropertiesForm +}; + +for (const key in components) { + Vue.component(key, components[key]); +} diff --git a/notes-webapp/src/main/webapp/vue-app/notes-publication/main.js b/notes-webapp/src/main/webapp/vue-app/notes-publication/main.js new file mode 100644 index 000000000..73ebc6d78 --- /dev/null +++ b/notes-webapp/src/main/webapp/vue-app/notes-publication/main.js @@ -0,0 +1,11 @@ +import './initComponents.js'; + +// get overrided components if exists +if (extensionRegistry) { + const components = extensionRegistry.loadComponents('notesPublication'); + if (components && components.length > 0) { + components.forEach(cmp => { + Vue.component(cmp.componentName, cmp.componentOptions); + }); + } +} diff --git a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorMetadataDrawer.vue b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorMetadataDrawer.vue deleted file mode 100644 index 970319b5b..000000000 --- a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorMetadataDrawer.vue +++ /dev/null @@ -1,310 +0,0 @@ - - - - - diff --git a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteFullRichEditor.vue b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteFullRichEditor.vue index 7a5b434f8..53415268e 100644 --- a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteFullRichEditor.vue +++ b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteFullRichEditor.vue @@ -30,7 +30,7 @@ :selected-language="selectedLanguage" :translations="translations" :is-mobile="isMobile" - :post-key="postKey" + :post-key="postKey + enablePostKeys" :draft-saving-status="draftSavingStatus" :publish-button-text="publishButtonText" :lang-button-tooltip-text="langButtonTooltipText" @@ -78,6 +78,16 @@ ref="featuredImageDrawer" :note="noteObject" :has-featured-image="hasFeaturedImage" /> + @@ -90,7 +100,9 @@ export default { initialized: false, instanceReady: false, noteTitleMaxLength: 500, - updatingProperties: null + updatingProperties: false, + enablePostKeys: 0, + isPublishing: false }; }, props: { @@ -189,14 +201,19 @@ export default { imagesDownloadFolder: { type: String, default: 'DRIVE_ROOT_NODE/notes/images' + }, + canPublish: { + type: Boolean, + default: false + }, + spaceId: { + type: String, + default: null } }, watch: { 'noteObject.title': function(newVal, oldVal) { - if (newVal.length > this.noteTitleMaxLength) { - this.displayNoteTitleMaxLengthCheckAlert(); - this.noteObject.title = oldVal; - } + this.displayNoteTitleMaxLengthCheckAlert(newVal, oldVal); this.updateData(); }, 'noteObject.content': function () { @@ -228,6 +245,18 @@ export default { }, saveNoteButtonDisabled() { return this.updatingProperties || this.saveButtonDisabled; + }, + newPageDraft() { + return !this.noteObject?.id || (this.noteObject?.draftPage && !this.noteObject?.targetPageId); + }, + editMode() { + return this.noteObject?.id && !this.newPageDraft; + }, + isTranslation() { + return !!this.noteObject?.lang; + }, + newPublicationDrawerEnabled() { + return eXo?.env?.portal?.newPublicationDrawerEnabled; } }, created() { @@ -249,7 +278,7 @@ export default { this.autoSave(); this.waitForNoteMetadataUpdate(); } else { - this.updatingProperties = null; + this.updatingProperties = false; } }, editorClosed(){ @@ -335,8 +364,20 @@ export default { }, 200); } }, - postNote(toPublish) { - this.$emit('post-note', toPublish); + postNote() { + if (this.newPublicationDrawerEnabled && this.canPublish + && !this.isTranslation && !this.editMode) { + this.openPublicationDrawer(this.noteObject); + return; + } + this.postAndPublishNote(); + }, + postAndPublishNote(note, publicationSettings) { + if (this.newPublicationDrawerEnabled) { + this.noteObject = note; + this.updateData(); + } + this.$emit('post-note', publicationSettings); }, resetEditorData() { this.noteObject.title = null; @@ -508,6 +549,12 @@ export default { isImageDrawerClosed() { return this.$refs.featuredImageDrawer.isClosed(); }, + openPublicationDrawer() { + this.$refs.editorPublicationDrawer.open(this.noteObject); + }, + publicationDrawerClosed() { + this.enablePostKeys ++; + }, openMetadataDrawer() { this.$refs.editorMetadataDrawer.open(this.noteObject); }, @@ -517,18 +564,23 @@ export default { alertMessage: detail?.message, }})); }, - displayNoteTitleMaxLengthCheckAlert(){ - const messageObject = { - type: 'warning', - message: this.$t('notes.title.max.length.warning.message', {0: this.noteTitleMaxLength}) - }; - this.displayAlert(messageObject); + displayNoteTitleMaxLengthCheckAlert(newTitle, oldTitle) { + if (newTitle?.length > this.noteTitleMaxLength) { + this.noteObject.title = oldTitle; + this.displayAlert({ + type: 'warning', + message: this.$t('notes.title.max.length.warning.message', {0: this.noteTitleMaxLength}) + }); + } }, waitForNoteMetadataUpdate() { setTimeout(() => { - this.updatingProperties = null; + this.updatingProperties = false; }, 1000); - } + }, + setPublishing(publishing) { + this.isPublishing = publishing; + }, } }; diff --git a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorFeaturedImageDrawer.vue b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/note-properties/NoteEditorFeaturedImageDrawer.vue similarity index 100% rename from notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorFeaturedImageDrawer.vue rename to notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/note-properties/NoteEditorFeaturedImageDrawer.vue diff --git a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/note-properties/NoteEditorMetadataDrawer.vue b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/note-properties/NoteEditorMetadataDrawer.vue new file mode 100644 index 000000000..89fd086cb --- /dev/null +++ b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/note-properties/NoteEditorMetadataDrawer.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/note-properties/NoteMetadataPropertiesForm.vue b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/note-properties/NoteMetadataPropertiesForm.vue new file mode 100644 index 000000000..498ab83a1 --- /dev/null +++ b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/note-properties/NoteMetadataPropertiesForm.vue @@ -0,0 +1,272 @@ + + + + diff --git a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/initComponents.js b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/initComponents.js index 91112ea13..b98d5b607 100644 --- a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/initComponents.js +++ b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/initComponents.js @@ -3,8 +3,9 @@ import TranslationsEditBar from '../notes-rich-editor/components/TranslationsEdi import NoteTreeviewDrawer from '../notes/components/NoteTreeviewDrawer.vue'; import NoteEditorTopBar from '../notes-rich-editor/components/NoteEditorTopBar.vue'; import NoteFullRichEditor from './components/NoteFullRichEditor.vue'; -import NoteEditorMetadataDrawer from './components/NoteEditorMetadataDrawer.vue'; -import NoteEditorFeaturedImageDrawer from './components/NoteEditorFeaturedImageDrawer.vue'; +import NoteEditorMetadataDrawer from './components/note-properties/NoteEditorMetadataDrawer.vue'; +import NoteEditorFeaturedImageDrawer from './components/note-properties/NoteEditorFeaturedImageDrawer.vue'; +import NoteMetadataPropertiesForm from './components/note-properties/NoteMetadataPropertiesForm.vue'; const components = { 'note-custom-plugins': NoteCustomPlugins, @@ -13,7 +14,8 @@ const components = { 'note-editor-top-bar': NoteEditorTopBar, 'note-full-rich-editor': NoteFullRichEditor, 'note-editor-metadata-drawer': NoteEditorMetadataDrawer, - 'note-editor-featured-image-drawer': NoteEditorFeaturedImageDrawer + 'note-editor-featured-image-drawer': NoteEditorFeaturedImageDrawer, + 'note-metadata-properties-form': NoteMetadataPropertiesForm }; for (const key in components) { diff --git a/notes-webapp/webpack.prod.js b/notes-webapp/webpack.prod.js index 022fdf509..a896dc3f8 100644 --- a/notes-webapp/webpack.prod.js +++ b/notes-webapp/webpack.prod.js @@ -19,7 +19,9 @@ const config = { engagementCenterExtensions: './src/main/webapp/vue-app/engagementCenterExtensions/extensions.js', connectorEventExtensions: './src/main/webapp/vue-app/connectorEventExtensions/extensions.js', notePageView: './src/main/webapp/vue-app/note-page-view/main.js', - notesNotificationExtension: './src/main/webapp/vue-app/notification-extensions/main.js' + notesNotificationExtension: './src/main/webapp/vue-app/notification-extensions/main.js', + notesPublication: './src/main/webapp/vue-app/notes-publication/main.js', + }, output: { publicPath: '',