diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/JPADataStorage.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/JPADataStorage.java index cdcae9d277..ebec68794a 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/JPADataStorage.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/JPADataStorage.java @@ -293,10 +293,15 @@ public List getChildrenPageOf(Page page, String userId, boolean withDrafts } @Override - public boolean hasChildren(long noteId) throws WikiException { + public boolean hasChildren(long noteId) { return pageDAO.countPageChildrenById(noteId) > 0; } + @Override + public boolean hasDrafts(long noteId) { + return draftPageDAO.countDraftPagesByParentPage(noteId) > 0; + } + @Override @ExoTransactional public void deletePage(String wikiType, String wikiOwner, String pageName) throws WikiException { diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/DraftPageDAO.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/DraftPageDAO.java index 63ec6a4e22..15d03dc7f0 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/DraftPageDAO.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/dao/DraftPageDAO.java @@ -116,4 +116,9 @@ public DraftPageEntity findLatestDraftPageByUserAndTargetPageAndLang(Long target } } + public Long countDraftPagesByParentPage(long parentPageId) { + return (Long) getEntityManager().createNamedQuery("wikiDraftPage.countDraftPagesByParentPage") + .setParameter("parentPageId", parentPageId) + .getSingleResult(); + } } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/DraftPageEntity.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/DraftPageEntity.java index 5c7ae6035b..6820a8e624 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/DraftPageEntity.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/DraftPageEntity.java @@ -31,6 +31,7 @@ @ExoEntity @Table(name = "WIKI_DRAFT_PAGES") @NamedQueries({ + @NamedQuery(name = "wikiDraftPage.countDraftPagesByParentPage", query = "SELECT count(*) FROM WikiDraftPageEntity d WHERE d.parentPage.id = :parentPageId"), @NamedQuery(name = "wikiDraftPage.findDraftPagesByUser", query = "SELECT d FROM WikiDraftPageEntity d WHERE d.author = :username ORDER BY d.updatedDate DESC"), @NamedQuery(name = "wikiDraftPage.findDraftPageByUserAndName", query = "SELECT d FROM WikiDraftPageEntity d WHERE d.author = :username AND d.name = :draftPageName ORDER BY d.updatedDate DESC"), @NamedQuery(name = "wikiDraftPage.findLatestDraftPageByUserAndTargetPage", query = "SELECT d FROM WikiDraftPageEntity d WHERE d.author = :username AND d.targetPage.id = :targetPageId ORDER BY d.updatedDate DESC"), diff --git a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageEntity.java b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageEntity.java index 6f849560d4..6cd643520a 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageEntity.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/jpa/entity/PageEntity.java @@ -44,7 +44,7 @@ @NamedQuery(name = "wikiPage.getPagesOfWiki", query = "SELECT p FROM WikiPageEntity p JOIN p.wiki w WHERE w.type = :type AND w.owner = :owner AND p.deleted = :deleted"), @NamedQuery(name = "wikiPage.getChildrenPages", query = "SELECT p FROM WikiPageEntity p WHERE p.parentPage.id = :id AND p.deleted = false ORDER BY p.name"), @NamedQuery(name = "wikiPage.getAllPagesBySyntax", query = "SELECT p FROM WikiPageEntity p WHERE p.syntax = :syntax OR p.syntax IS NULL ORDER BY p.updatedDate DESC"), - @NamedQuery(name = "wikiPage.countPageChildrenById", query = "SELECT COUNT(*) FROM WikiPageEntity p WHERE p.parentPage.id = :id"), + @NamedQuery(name = "wikiPage.countPageChildrenById", query = "SELECT COUNT(*) FROM WikiPageEntity p WHERE p.parentPage.id = :id AND p.deleted = false"), }) public class PageEntity extends BasePageEntity { diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/DataStorage.java b/notes-service/src/main/java/org/exoplatform/wiki/service/DataStorage.java index 5433cba72f..542bcba532 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/DataStorage.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/DataStorage.java @@ -77,7 +77,21 @@ public interface DataStorage { */ public List getChildrenPageOf(Page page, String userId, boolean withDrafts) throws WikiException; - public boolean hasChildren(long noteId) throws WikiException; + /** + * Check if the given note page has children or not + * + * @param noteId note page id + * @return true if the given note page has children and false if not + */ + public boolean hasChildren(long noteId); + + /** + * Check if the given note page has drafts or not + * + * @param noteId note page id + * @return true if the given note page has drafts and false if not + */ + boolean hasDrafts(long noteId); public void deletePage(String wikiType, String wikiOwner, String pageId) throws WikiException; diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/NoteService.java b/notes-service/src/main/java/org/exoplatform/wiki/service/NoteService.java index ab15ac88f9..ee76e82069 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/NoteService.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/NoteService.java @@ -191,6 +191,22 @@ Page getNoteOfNoteBookByName(String noteType, */ Page getParentNoteOf(Page note) throws WikiException; + /** + * Check if the given note page has children or not + * + * @param pageId note page id + * @return true if the given note page has children and false if not + */ + boolean hasChildren(long pageId); + + /** + * Check if the given note page has drafts or not + * + * @param pageId note page id + * @return true if the given note page has drafts and false if not + */ + boolean hasDrafts(long pageId); + /** * Get all the children notes of a note * diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/impl/NoteServiceImpl.java b/notes-service/src/main/java/org/exoplatform/wiki/service/impl/NoteServiceImpl.java index 41683f6539..f04186db00 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/impl/NoteServiceImpl.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/impl/NoteServiceImpl.java @@ -624,12 +624,31 @@ public List getChildrenNoteOf(Page note, String userId, boolean withDrafts if (withChild) { for (Page page : pages) { long pageId = Long.parseLong(page.getId()); - page.setHasChild(dataStorage.hasChildren(pageId)); + page.setHasChild(hasChildren(pageId)); } } return pages; } + /** + * {@inheritDoc} + */ + @Override + public boolean hasChildren(long pageId) { + return dataStorage.hasChildren(pageId); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean hasDrafts(long pageId) { + return dataStorage.hasDrafts(pageId); + } + + /** + * {@inheritDoc} + */ @Override public List getChildrenNoteOf(NoteToExport note, String userId) throws WikiException { 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 77ef48fdaf..2ae5ba11ed 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 @@ -1203,7 +1203,8 @@ public Response getFullTreeData(@Parameter(description = "Note path", required = finalTree.add(rootNodeData); context.put(TreeNode.DEPTH, "1"); - List children = new ArrayList<>(rootNodeData.getChildren()); + List listChildren = rootNodeData.getChildren(); + List children = listChildren != null ? new ArrayList<>(listChildren) : new ArrayList<>(); List parents = new ArrayList<>(); do { diff --git a/notes-service/src/main/java/org/exoplatform/wiki/tree/JsonNodeData.java b/notes-service/src/main/java/org/exoplatform/wiki/tree/JsonNodeData.java index c45156235f..294fbfd15b 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/tree/JsonNodeData.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/tree/JsonNodeData.java @@ -100,7 +100,7 @@ public JsonNodeData(TreeNode treeNode, this.children = TreeUtils.tranformToJson(treeNode, context); this.isSelected = treeNode.isSelected(); this.isRestricted = treeNode.isRetricted; - if (!this.children.isEmpty()) { + if (this.children != null && !this.children.isEmpty()) { this.isExpanded = true; } if (treeNode.getNodeType().equals(TreeNodeType.PAGE)) { diff --git a/notes-service/src/main/java/org/exoplatform/wiki/tree/PageTreeNode.java b/notes-service/src/main/java/org/exoplatform/wiki/tree/PageTreeNode.java index 73ce54bedc..dcfc2d6bce 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/tree/PageTreeNode.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/tree/PageTreeNode.java @@ -18,6 +18,12 @@ */ package org.exoplatform.wiki.tree; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; + +import lombok.Getter; +import lombok.Setter; import org.exoplatform.container.ExoContainerContext; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; @@ -36,6 +42,8 @@ public class PageTreeNode extends TreeNode { private static final Log log = ExoLogger.getLogger(PageTreeNode.class); + @Setter + @Getter private Page page; private NoteService noteService; @@ -48,15 +56,8 @@ public PageTreeNode(Page page) throws Exception { this.page = page; this.id = page.getId(); this.path = buildPath(); - this.hasChild = !page.isDraftPage() && !noteService.getChildrenNoteOf(page, ConversationState.getCurrent().getIdentity().getUserId(), true, false).isEmpty(); - } - - public Page getPage() { - return page; - } - - public void setPage(Page page) { - this.page = page; + this.hasChild = !page.isDraftPage() && (noteService.hasChildren(Long.parseLong(page.getId())) + || noteService.hasDrafts(Long.parseLong(page.getId()))); } @Override diff --git a/notes-service/src/main/java/org/exoplatform/wiki/tree/WikiHomeTreeNode.java b/notes-service/src/main/java/org/exoplatform/wiki/tree/WikiHomeTreeNode.java index 63c2a2d9ce..cd7feaf6e6 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/tree/WikiHomeTreeNode.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/tree/WikiHomeTreeNode.java @@ -55,7 +55,8 @@ public WikiHomeTreeNode(Page wikiHome) throws Exception { this.wikiHome = wikiHome; this.path = this.buildPath(); - this.hasChild = !wikiHome.isDraftPage() && !noteService.getChildrenNoteOf(wikiHome, ConversationState.getCurrent().getIdentity().getUserId(), true, true).isEmpty(); + this.hasChild = !wikiHome.isDraftPage() && (noteService.hasChildren(Long.parseLong(wikiHome.getId())) + || noteService.hasDrafts(Long.parseLong(wikiHome.getId()))); } @Override diff --git a/notes-service/src/main/java/org/exoplatform/wiki/tree/utils/TreeUtils.java b/notes-service/src/main/java/org/exoplatform/wiki/tree/utils/TreeUtils.java index 8cd2209244..12ee27e307 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/tree/utils/TreeUtils.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/tree/utils/TreeUtils.java @@ -100,14 +100,11 @@ public static List tranformToJson(TreeNode treeNode, HashMap children = new ArrayList(); + List children = new ArrayList<>(); for (TreeNode child : treeNode.getChildren()) { boolean isSelectable = true; - boolean isLastNode = false; - if (counter >= treeNode.getChildren().size()) { - isLastNode = true; - } - + boolean isLastNode = counter >= treeNode.getChildren().size(); + if (child.getNodeType().equals(TreeNodeType.WIKI)) { isSelectable = false; } else if (child.getNodeType().equals(TreeNodeType.PAGE)) { @@ -115,12 +112,13 @@ public static List tranformToJson(TreeNode treeNode, HashMap tranformToJson(TreeNode treeNode, HashMap TreeUtils.getPathFromPageParams(any())).thenCallRealMethod(); treeUtilsStatic.when(() -> TreeUtils.tranformToJson(any(), any())).thenCallRealMethod(); diff --git a/notes-webapp/src/main/webapp/javascript/eXo/wiki/notesService.js b/notes-webapp/src/main/webapp/javascript/eXo/wiki/notesService.js index e55ca232b0..e5ffb7ce9d 100644 --- a/notes-webapp/src/main/webapp/javascript/eXo/wiki/notesService.js +++ b/notes-webapp/src/main/webapp/javascript/eXo/wiki/notesService.js @@ -84,7 +84,10 @@ export function getSeparator(url) { } export function getNoteTree(noteBookType, noteBookOwner, noteId,treeType) { - return fetch(`${notesConstants.PORTAL}/${notesConstants.PORTAL_REST}/notes/tree/${treeType}?path=${noteBookType}/${noteBookOwner}/${noteId}`, { + if (noteBookOwner.indexOf('/') !== 0) { + noteBookOwner = `/${noteBookOwner}`; + } + return fetch(`${notesConstants.PORTAL}/${notesConstants.PORTAL_REST}/notes/tree/${treeType}?path=${noteBookType}${noteBookOwner}/${noteId}`, { method: 'GET', credentials: 'include', }).then(resp => { @@ -96,6 +99,19 @@ export function getNoteTree(noteBookType, noteBookOwner, noteId,treeType) { }); } +export function getNoteTreeLevel(path) { + return fetch(`${notesConstants.PORTAL}/${notesConstants.PORTAL_REST}/notes/tree/children?path=${path}`, { + method: 'GET', + credentials: 'include', + }).then(resp => { + if (!resp || !resp.ok) { + throw new Error('Error while getting note tree level'); + } else { + return resp.json(); + } + }); +} + export function getFullNoteTree(noteBookType, noteBookOwner, noteId, withDrafts, lang) { if (noteBookOwner.indexOf('/') !== 0) { noteBookOwner = `/${noteBookOwner}`; 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 bf06a2441b..d1b1a47e61 100644 --- a/notes-webapp/src/main/webapp/skin/less/notes/notes.less +++ b/notes-webapp/src/main/webapp/skin/less/notes/notes.less @@ -1144,11 +1144,22 @@ ul.note-manual-child { opacity: 0 !important; } -.remove-focus:focus::after { - opacity: 0 !important; -} - - - - +.notes-custom-treeview { + > .v-treeview-node { + > .v-treeview-node__root { + .v-treeview-node__toggle, + > .v-treeview-node__level:first-child { + display: none; + } + } + } + > .v-treeview-node__children { + > .v-treeview-node__root { + .v-treeview-node__toggle, + > .v-treeview-node__level:nth-child(2) { + display: none; + } + } + } +} diff --git a/notes-webapp/src/main/webapp/vue-app/notes/components/NoteContentTableItem.vue b/notes-webapp/src/main/webapp/vue-app/notes/components/NoteContentTableItem.vue index d09b736eaa..99f8e4a989 100644 --- a/notes-webapp/src/main/webapp/vue-app/notes/components/NoteContentTableItem.vue +++ b/notes-webapp/src/main/webapp/vue-app/notes/components/NoteContentTableItem.vue @@ -42,4 +42,4 @@ export default { } } }; - \ No newline at end of file + diff --git a/notes-webapp/src/main/webapp/vue-app/notes/components/NoteTreeviewDrawer.vue b/notes-webapp/src/main/webapp/vue-app/notes/components/NoteTreeviewDrawer.vue index 6ebf76c9b7..04b1b54bcf 100644 --- a/notes-webapp/src/main/webapp/vue-app/notes/components/NoteTreeviewDrawer.vue +++ b/notes-webapp/src/main/webapp/vue-app/notes/components/NoteTreeviewDrawer.vue @@ -613,6 +613,11 @@ export default { }); } }, + fetchChildren(note) { + return this.$notesService.getNoteTreeLevel(note.path, this.selectedTranslation?.value).then(data => { + note.children = data?.jsonList; + }); + }, retrieveNoteTree(noteType, noteOwner, noteName) { const withDrafts = this.filter === this.$t('notes.filter.label.drafts'); this.$notesService.getFullNoteTree(noteType, noteOwner , noteName, withDrafts, this.selectedTranslation).then(data => { diff --git a/notes-webapp/src/main/webapp/vue-app/notes/components/NotesOverview.vue b/notes-webapp/src/main/webapp/vue-app/notes/components/NotesOverview.vue index 0018c68756..1034efe0d6 100644 --- a/notes-webapp/src/main/webapp/vue-app/notes/components/NotesOverview.vue +++ b/notes-webapp/src/main/webapp/vue-app/notes/components/NotesOverview.vue @@ -202,11 +202,26 @@
+ v-if="noteChildren?.length" + ref="noteTreeview" + :items="noteChildren" + class="ps-1 notes-custom-treeview" + item-key="noteId" + expand-icon="" + dense> + @@ -321,6 +336,7 @@ export default { slectedLanguage: null, translationsMenu: false, originalVersion: { value: '', text: this.$t('notes.label.translation.originalVersion') }, + initialized: false }; }, watch: { @@ -334,7 +350,10 @@ export default { } this.noteTitle = !this.note.parentPageId && this.note.title==='Home' ? `${this.$t('notes.label.noteHome')}` : this.note.title; this.noteContent = this.note.content; - this.retrieveNoteTreeById(); + this.noteSummary = this.note?.properties?.summary; + if (this.hasEmptyContent || this.isHomeNoteDefaultContent) { + this.retrieveNoteTreeById(); + } }, actualVersion() { if (!this.isDraft && this.actualVersion) { @@ -363,10 +382,25 @@ export default { vTreeComponent: { template: ` + class="ps-1 notes-custom-treeview" + item-key="noteId" + expand-icon="" + dense> + @@ -390,13 +424,19 @@ export default { }); }, methods: { + fetchChildren(item, treeview) { + return this.$root.$children[0].fetchChildren(item, treeview); + }, + getNoteLanguages(noteId) { + return this.$root.$children[0].getNoteLanguages(noteId); + }, getNodeById(noteId, source, noteBookType, noteBookOwner) { return this.$notesService.getNoteById(noteId,this.selectedTranslation.value, source, noteBookType, noteBookOwner).then(data => { this.note = data || {}; - this.$notesService.getFullNoteTree(data.wikiType, data.wikiOwner, data.name, false,this.selectedTranslation.value).then(data => { - if (data && data.jsonList.length) { - const allNotesTreeview = data.jsonList; - this.noteChildItems = allNotesTreeview.filter(note => note.name === this.note.title)[0]?.children; + this.getNoteLanguages(noteId); + this.$notesService.getNoteTree(data.wikiType, data.wikiOwner, data.name, 'children', this.selectedTranslation?.value).then(data => { + if (data?.jsonList?.length) { + this.noteChildItems = data.jsonList; } }); }).catch(e => { @@ -428,43 +468,9 @@ export default { isHomeNoteDefaultContent() { return !this.note.parentPageId && ( this.noteContent===`

Welcome to Space ${this.spaceDisplayName} Notes Home

` || this.noteContent === ''); }, - lastNoteVersion() { - return this.noteVersions && this.noteVersions[0] && this.noteVersions[0].versionNumber; - - }, - NoteTranslations() { - return this.translations && this.noteVersions[0] && this.noteVersions[0].versionNumber; - - }, - lastNoteUpdatedBy() { - if (this.isDraft) { - return this.note.authorFullName; - } else { - if (this.displayLastVersion) { - return this.noteVersions && this.noteVersions[0] && this.noteVersions[0].authorFullName; - } else { - return this.actualVersion.authorFullName; - } - } - }, - noteAllChildren() { - return this.noteChildren && this.noteChildren.length && this.noteChildren[0].children; - }, - displayedDate() { - if (this.isDraft && this.note && this.note.updatedDate && this.note.updatedDate.time) { - return this.$dateUtil.formatDateObjectToDisplay(new Date(this.note.updatedDate.time), this.dateTimeFormat, this.lang) || ''; - } else { - if (this.displayLastVersion) { - return this.noteVersions && this.noteVersions[0] && this.noteVersions[0].updatedDate.time && this.$dateUtil.formatDateObjectToDisplay(new Date(this.noteVersions[0].updatedDate.time), this.dateTimeFormat, this.lang) || ''; - } else { - return this.$dateUtil.formatDateObjectToDisplay(new Date(this.actualVersion.updatedDate.time), this.dateTimeFormat, this.lang) || ''; - } - } - }, isMobile() { return this.$vuetify.breakpoint.name === 'xs'; }, - isAvailableNote() { return this.existingNote; }, @@ -478,7 +484,7 @@ export default { return !this.note?.content; }, hasChildren(){ - return this.noteChildren && this.noteChildren[0] && this.noteChildren[0].children?.length > 0; + return this.noteChildren?.length; }, isManager(){ return this.note?.canManage; @@ -724,7 +730,8 @@ export default { this.existingNote = false; }).finally(() => { this.$root.$applicationLoaded(); - this.$root.$emit('refresh-treeView-items', this.note); + this.refreshTreeView(); + this.initialized = true; }); }, importNotes(uploadId,overrideMode){ @@ -759,7 +766,8 @@ export default { this.existingNote = false; }).finally(() => { this.$root.$applicationLoaded(); - this.$root.$emit('refresh-treeView-items', this.note); + this.refreshTreeView(); + this.initialized = true; }); }, getDraftNote(noteId, viewNote) { @@ -779,7 +787,8 @@ export default { this.existingNote = false; }).finally(() => { this.$root.$applicationLoaded(); - this.$root.$emit('refresh-treeView-items', this.note); + this.refreshTreeView(); + this.initialized = true; }); }, confirmDeleteNote: function () { @@ -894,13 +903,26 @@ export default { this.$refs.noteVersionsHistoryDrawer.open(); } }, + fetchChildren(item, treeview) { + if (item.isOpen) { + treeview.updateOpen(item.noteId, false); + item.isOpen = false; + return; + } + item.isLoading = true; + return this.$notesService.getNoteTreeLevel(item.path, this.selectedTranslation?.value).then(data => { + item.children = data?.jsonList; + item.isLoading = false; + treeview.updateOpen(item.noteId, true); + item.isOpen = true; + }); + }, retrieveNoteTreeById() { this.note.wikiOwner = this.note.wikiOwner.substring(1); if (!this.note.draftPage) { - this.$notesService.getFullNoteTree(this.note.wikiType, this.note.wikiOwner , this.note.name, false,this.selectedTranslation.value).then(data => { - if (data && data.jsonList.length) { - const allnotesTreeview = data.jsonList; - this.noteChildren = allnotesTreeview.filter(note => note.name === this.note.title); + this.$notesService.getNoteTree(this.note.wikiType, this.note.wikiOwner , this.note.name, 'children' ,this.selectedTranslation.value).then(data => { + if (data?.jsonList?.length) { + this.noteChildren = data?.jsonList; } }); } @@ -992,7 +1014,9 @@ export default { } })); }, - + refreshTreeView() { + this.$root.$emit('refresh-treeView-items', this.note); + } } };