Skip to content

Commit

Permalink
feat: Implement publish note - EXO-73041 - Meeds-io/MIPs#161 (#1212)
Browse files Browse the repository at this point in the history
Implement publish note
  • Loading branch information
hakermi authored and exo-swf committed Nov 19, 2024
1 parent e692405 commit 7cb0b71
Show file tree
Hide file tree
Showing 14 changed files with 331 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ notes.publication.schedule.publish.now.tooltip=By scheduling only a end date you
notes.publication.advanced.option.label=Advanced options
notes.publication.hide.author.label=Hide author
notes.publication.hide.reaction.label=Hide reaction
notes.publication.success.message=Note successfully published

popup.confirm=Confirm
popup.msg.confirmation=Confirmation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ notes.publication.schedule.publish.now.tooltip=En programmant uniquement une dat
notes.publication.advanced.option.label=Options avancées
notes.publication.hide.author.label=Masquer l'auteur
notes.publication.hide.reaction.label=Masquer la réaction
notes.publication.success.message=Note publi\u00E9e avec succ\u00E8s

popup.confirm=Confirmer
popup.msg.confirmation=Confirmation
Expand Down
9 changes: 9 additions & 0 deletions notes-webapp/src/main/webapp/WEB-INF/gatein-resources.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@
<minify>false</minify>
<path>/javascript/notes.bundle.js</path>
</script>
<depends>
<module>NotePublishExtensions</module>
</depends>
<depends>
<module>NotesPublication</module>
</depends>
<depends>
<module>imageCropper</module>
</depends>
<depends>
<module>html2canvas</module>
</depends>
Expand Down
76 changes: 76 additions & 0 deletions notes-webapp/src/main/webapp/javascript/eXo/wiki/notesService.js
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,79 @@ export function removeNoteFeaturedImage(noteId, isDraft, lang) {
}
});
}

export async function getNotePublishTargets() {
const targets = await Vue.prototype.$newsTargetingService.getAllowedTargets();
return targets.map(target => ({
name: target.name,
label: target?.properties?.label,
tooltipInfo: `${target?.properties?.label}: ${target?.properties?.description || ''}`,
description: target?.properties?.description,
restrictedAudience: target?.restrictedAudience,
}));
}

export function saveNoteArticle(article) {
if (article?.schedulePostDate) {
article.publicationState = 'staged';
}
if (article.scheduleUnpublishDate || article?.schedulePostDate) {
article.timeZoneId = new window.Intl.DateTimeFormat().resolvedOptions().timeZone;
}
if (article.publicationState === 'staged') {
return Vue.prototype.$newsService.scheduleNews(article, 'existing_page');
} else {
return Vue.prototype.$newsService.saveNews(article);
}
}

export function canPublish(spaceId) {
return Vue.prototype.$newsService.canPublishNews(spaceId);
}

export function canSchedule(spaceId, articleId) {
return Vue.prototype.$newsService.canScheduleNews(spaceId, articleId);
}

export async function getSavedNotePublicationSettings(id, lang) {
try {
const article = await Vue.prototype.$newsService.getNewsById(id, false, 'article', lang);
if (!article || article.status === 404) {
return null;
}
return {
activityPosted: article.activityPosted,
published: article.published,
targets: article.targets,
audience: article.audience,
schedulePostDate: article.schedulePostDate,
scheduleUnpublishDate: article.scheduleUnpublishDate,
properties: article.properties ?? {}
};
} catch (error) {
console.error(error);
throw error;
}
}

export function updateNotePublication(editScheduleAction, scheduleSettings, article) {
article.timeZoneId = new window.Intl.DateTimeFormat().resolvedOptions().timeZone;
switch (editScheduleAction) {
case 'schedule':
article.publicationState = scheduleSettings?.postDate ? 'staged' : '';
return Vue.prototype.$newsService.scheduleNews(article, 'article');
case 'cancel_schedule':
article.schedulePostDate = 0;
article.publicationState = 'draft';
return Vue.prototype.$newsService.saveNews(article);
case 'publish_now':
article.schedulePostDate = 0;
article.publicationState = 'posted';
return Vue.prototype.$newsService.saveNews(article);
default:
article.publicationState = 'posted';
return Vue.prototype.$newsService.updateNews(article, article.activityPosted, 'article', 'POSTING_AND_PUBLISHING');
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ export default {
return;
}
this.$emit('metadata-updated', this.noteObject.properties);
this.$emit('publish', this.noteObject, this.publicationSettings);
this.$emit('publish', this.publicationSettings, this.noteObject,);
},
updateCurrentNoteObjectProperties(properties) {
this.noteObject.properties.noteId = Number(properties.noteId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ export default {
}
this.postAndPublishNote();
},
postAndPublishNote(note, publicationSettings) {
postAndPublishNote(publicationSettings, note) {
if (this.newPublicationDrawerEnabled) {
this.noteObject = note;
this.updateData();
Expand Down
20 changes: 20 additions & 0 deletions notes-webapp/src/main/webapp/vue-app/notes-rich-editor/js/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,23 @@ export function isSameContent(content, originalContent) {
function getString(body) {
return new DOMParser().parseFromString(body, 'text/html').documentElement.textContent.replace(/&nbsp;/g, '').trim();
}

export function noteToArticle(note, spaceId) {
return {
id: note.id,
title: note.title,
body: note.content,
author: note.author,
published: note.published,
targets: note.targets,
spaceId: spaceId,
publicationState: 'posted',
schedulePostDate: note.schedulePostDate,
timeZoneId: null,
activityPosted: note.activityPosted,
audience: note.audience,
draftPage: false,
scheduleUnpublishDate: note.scheduleUnpublishDate,
properties: note?.properties
};
}
121 changes: 104 additions & 17 deletions notes-webapp/src/main/webapp/vue-app/notes/components/NotesOverview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -279,15 +279,23 @@
</a>
</div>
</div>
<exo-confirm-dialog
ref="DeleteNoteDialog"
:message="confirmMessage"
:title="hasDraft ? $t('popup.confirmation.delete.draft') : $t('popup.confirmation.delete')"
:ok-label="$t('notes.button.delete')"
:cancel-label="$t('notes.button.cancel')"
persistent
@ok="deleteNote()"
@dialog-opened="$emit('confirmDialogOpened')"
@dialog-closed="$emit('confirmDialogClosed')" />
<notes-actions-menu
v-if="!isMobile"
:note="note"
:default-path="defaultPath" />
:note="note" />
<notes-mobile-action-menu
v-else
ref="notesMobileActionMenu"
:note="note"
:default-path="defaultPath" />
:note="note" />
<note-treeview-drawer
ref="notesBreadcrumb"
:selected-translation="selectedTranslation.value" />
Expand All @@ -301,21 +309,28 @@
ref="noteVersionsHistoryDrawer" />
<note-import-drawer
ref="noteImportDrawer" />
<exo-confirm-dialog
ref="DeleteNoteDialog"
:message="confirmMessage"
:title="hasDraft ? $t('popup.confirmation.delete.draft') : $t('popup.confirmation.delete')"
:ok-label="$t('notes.button.delete')"
:cancel-label="$t('notes.button.cancel')"
persistent
@ok="deleteNote()"
@dialog-opened="$emit('confirmDialogOpened')"
@dialog-closed="$emit('confirmDialogClosed')" />
<note-featured-image-drawer
ref="featuredImageDrawer"
:note="note"
:has-featured-image="hasFeaturedImage" />
<note-publication-drawer
v-if="newPublicationDrawerEnabled"
ref="publicationDrawer"
:has-featured-image="hasFeaturedImage"
:is-publishing="isPublishing"
:params="{
spaceId: spaceId,
allowedTargets: publishTargets,
canPublish: canPublish,
canSchedule: canScheduleNotePublication
}"
:edit-mode="published"
@publish="publishNote" />
</v-app>
</template>
<script>
import { notesConstants } from '../../../javascript/eXo/wiki/notesConstants.js';
import {notesConstants} from '../../../javascript/eXo/wiki/notesConstants.js';
import html2canvas from 'html2canvas';
import JSPDF from 'jspdf';
Expand Down Expand Up @@ -376,12 +391,19 @@ export default {
illustrationBaseUrl: `${eXo.env.portal.context}/${eXo.env.portal.rest}/notes/illustration/`,
initialized: false,
overviewExtensions: [],
isPublishing: false,
publishTargets: [],
canPublish: false,
canSchedule: false,
published: false
};
},
watch: {
note() {
if (!this.note.draftPage) {
this.getNoteVersionByNoteId(this.note.id);
this.getSavedNotePublicationSettings(this.note.id);
this.getCanSchedule();
}
if ( this.note && this.note.breadcrumb && this.note.breadcrumb.length ) {
this.note.breadcrumb[0].title = this.getHomeTitle(this.note.breadcrumb[0].title);
Expand Down Expand Up @@ -413,6 +435,9 @@ export default {
}
},
computed: {
newPublicationDrawerEnabled() {
return eXo?.env?.portal?.newPublicationDrawerEnabled;
},
extensionParams() {
return {
entityId: this.entityId,
Expand Down Expand Up @@ -575,10 +600,18 @@ export default {
appName() {
const uris = eXo.env.portal.selectedNodeUri.split('/');
return uris[uris.length - 1];
},
isNoteAuthor() {
return !this.published && this?.note.author === eXo.env.portal.userName;
},
canScheduleNotePublication() {
return this.isNoteAuthor || this.canSchedule || this.canPublish;
}
},
created() {
this.getAvailableLanguages();
this.getPublishTargets();
this.getCanPublish();
const queryPath = window.location.search;
const urlParams = new URLSearchParams(queryPath);
if (urlParams.has('translation')) {
Expand Down Expand Up @@ -637,9 +670,9 @@ export default {
this.$root.$on('open-note-history', this.openNoteVersionsHistoryDrawer);
this.$root.$on('open-note-treeview-export', this.openNoteTreeView);
this.$root.$on('open-note-import-drawer', this.openImportDrawer);
this.$root.$on('open-publish-drawer', this.openPublishDrawer);
document.addEventListener('notes-extensions-updated', this.refreshOverviewExtensions);
this.refreshOverviewExtensions();
},
mounted() {
this.handleChangePages();
Expand All @@ -648,9 +681,62 @@ export default {
});
},
methods: {
getSavedNotePublicationSettings(id, lang) {
return this.$notesService.getSavedNotePublicationSettings(id, lang).then(settings => {
if (settings) {
this.note = Object.assign(this.note, settings);
}
this.published = !!settings;
});
},
getCanPublish() {
this.$notesService.canPublish(this.spaceId).then(canPublish => {
this.canPublish = canPublish;
});
},
getCanSchedule() {
this.$notesService.canSchedule(this.spaceId, this.note?.id).then(canSchedule => {
this.canSchedule = canSchedule;
});
},
getPublishTargets() {
this.$notesService.getNotePublishTargets().then(targets => {
this.publishTargets = targets;
});
},
publishNote(publicationSettings, note) {
const scheduleSettings = publicationSettings?.scheduleSettings;
const article = structuredClone(note || this.note);
article.schedulePostDate = scheduleSettings?.postDate;
article.scheduleUnpublishDate = scheduleSettings?.unpublishDate;
article.activityPosted = publicationSettings?.post;
article.published = publicationSettings?.publish;
article.targets = publicationSettings?.selectedTargets;
article.audience = publicationSettings?.selectedAudience;
this.isPublishing = true;
if (note) {
this.$notesService.updateNoteById(note).then(() => {
this.$notesService.saveNoteArticle(this.$noteUtils.noteToArticle(article, this.spaceId)).then(() => {
this.isPublishing = false;
this.$refs.publicationDrawer.close();
this.$root.$emit('show-alert', {type: 'success', message: this.$t('notes.publication.success.message')});
});
});
} else {
const editScheduleAction = scheduleSettings?.editScheduleAction;
this.$notesService.updateNotePublication(editScheduleAction, scheduleSettings,
this.$noteUtils.noteToArticle(article, this.spaceId)).then(() => {
this.isPublishing = false;
this.$root.$emit('show-alert', {type: 'success', message: this.$t('notes.publication.success.message')});
});
}
},
openPublishDrawer() {
this.$refs.publicationDrawer.open(this.note);
},
closeMobileActionMenu() {
setTimeout(() => {
this.$refs.notesMobileActionMenu.close();
this.$refs.notesMobileActionMenu?.close();
}, 200);
},
openNoteTreeView(note, action) {
Expand Down Expand Up @@ -1010,6 +1096,7 @@ export default {
openNoteChild(item) {
const noteName = item.path.split('%2F').pop();
this.$root.$emit('open-note-by-name', noteName);
this.getSavedNotePublicationSettings(item.noteId);
},
updateNote(noteParam) {
const note = {
Expand Down
Loading

0 comments on commit 7cb0b71

Please sign in to comment.