From 9ca30450e0abea1ad5dc9e6e1a34df914f78e273 Mon Sep 17 00:00:00 2001 From: Helmi Akermi <70575401+hakermi@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:12:38 +0100 Subject: [PATCH] fix: Treeview menu loading perf issue- EXO-73169 - Meeds-io/MIPs#129 (#1115) Treeview menu loading perf issue --- .../exoplatform/wiki/jpa/JPADataStorage.java | 7 +- .../wiki/jpa/dao/DraftPageDAO.java | 5 + .../wiki/jpa/entity/DraftPageEntity.java | 1 + .../wiki/jpa/entity/PageEntity.java | 2 +- .../exoplatform/wiki/service/DataStorage.java | 16 ++- .../exoplatform/wiki/service/NoteService.java | 16 +++ .../wiki/service/impl/NoteServiceImpl.java | 20 +++- .../wiki/service/rest/NotesRestService.java | 7 +- .../exoplatform/wiki/tree/JsonNodeData.java | 3 +- .../exoplatform/wiki/tree/PageTreeNode.java | 15 ++- .../wiki/tree/WikiHomeTreeNode.java | 3 +- .../wiki/tree/utils/TreeUtils.java | 23 +++-- .../service/rest/NotesRestServiceTest.java | 1 + .../javascript/eXo/wiki/notesService.js | 18 +++- .../main/webapp/skin/less/notes/notes.less | 20 ++++ .../notes/components/NoteContentTableItem.vue | 2 +- .../notes/components/NoteTreeviewDrawer.vue | 19 ++-- .../notes/components/NotesOverview.vue | 99 ++++++++++++++----- 18 files changed, 211 insertions(+), 66 deletions(-) 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 991861afd5..26380bfbba 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 @@ -332,10 +332,15 @@ public List getChildrenPageOf(Page page, boolean withDrafts) throws WikiEx } @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 fbd201a691..0aabbba168 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 @@ -111,4 +111,9 @@ public DraftPageEntity findLatestDraftPageByTargetPageAndLang(Long targetPageId, } } + 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 c71646b6fd..1739ba12de 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 @@ -52,6 +52,7 @@ @NamedQuery(name = "wikiDraftPage.findLatestDraftPageByTargetPage", query = "SELECT d FROM WikiDraftPageEntity d WHERE d.targetPage.id = :targetPageId ORDER BY d.updatedDate DESC"), @NamedQuery(name = "wikiDraftPage.findDraftPageByTargetPage", query = "SELECT d FROM WikiDraftPageEntity d WHERE d.targetPage.id = :targetPageId"), @NamedQuery(name = "wikiDraftPage.findDraftPagesByParentPage", query = "SELECT d FROM WikiDraftPageEntity d WHERE d.parentPage.id = :parentPageId"), + @NamedQuery(name = "wikiDraftPage.countDraftPagesByParentPage", query = "SELECT count(*) FROM WikiDraftPageEntity d WHERE d.parentPage.id = :parentPageId"), @NamedQuery(name = "wikiDraftPage.findLatestDraftPageByTargetPageAndLang", query = "SELECT d FROM WikiDraftPageEntity d WHERE d.targetPage.id = :targetPageId AND " + "((:lang IS NULL AND d.lang IS NULL) OR (:lang IS NOT NULL AND d.lang = :lang)) ORDER BY d.updatedDate DESC"), @NamedQuery(name = "wikiDraftPage.deleteOrphanDraftPagesByParentPage", query = "DELETE FROM WikiDraftPageEntity d WHERE d.targetPage IS NULL AND d.parentPage.id=:id")}) 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 4ac0983b4a..1fe23bbb13 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 05dff8ae55..66ea3bb961 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 @@ -86,7 +86,21 @@ public interface DataStorage { */ public List getChildrenPageOf(Page page, boolean withDrafts) throws WikiException; - public boolean hasChildren(long noteId) throws WikiException; + /** + * Check whether the page has children or not + * + * @param noteId target note id + * @return true if it has page and false if not + */ + public boolean hasChildren(long noteId); + + /** + * Check if page has drafts + * + * @param noteId target note id + * @return true if 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 19a1876868..99257558c5 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 @@ -277,6 +277,22 @@ Page getNoteOfNoteBookByName(String noteType, */ List getChildrenNoteOf(Page note, boolean withDrafts, boolean withChild) throws WikiException; + /** + * Check if the given page has children or not + * + * @param pageId note page id + * @return true if the given page has children and false if not + */ + boolean hasChildren(long pageId); + + /** + * Check if the given page has drafts or not + * + * @param pageId note page id + * @return true if the given 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 4ef030fb70..0ccc2ae9f6 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 @@ -761,12 +761,28 @@ public List getChildrenNoteOf(Page note, boolean withDrafts, boolean withC 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} */ 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 13ee9d30c4..6dac31cd61 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 @@ -1287,12 +1287,13 @@ public Response getFullTreeData(@Parameter(description = "Note path", required = List finalTree = new ArrayList<>(); responseData = getJsonTree(noteParam, context); - JsonNodeData rootNodeData = responseData.get(0); + JsonNodeData rootNodeData = responseData.getFirst(); rootNodeData.setHasDraftDescendant(true); 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 { @@ -1360,7 +1361,7 @@ public Response getFullTreeData(@Parameter(description = "Note path", required = || Boolean.TRUE.equals(jsonNodeData.isHasDraftDescendant())) .collect(Collectors.toList()); } - while (bottomChildren.size() > 1 || (bottomChildren.size() == 1 && bottomChildren.get(0).getParentPageId() != null)) { + while (bottomChildren.size() > 1 || (bottomChildren.size() == 1 && bottomChildren.getFirst().getParentPageId() != null)) { for (JsonNodeData bottomChild : bottomChildren) { String parentPageId = bottomChild.getParentPageId(); Optional parentOptional = finalTree.stream() 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 86f77144de..1c54e4798a 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 @@ -99,14 +99,13 @@ 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)) { Page page = ((PageTreeNode) treeNode).getPage(); this.isDraftPage = page.isDraftPage(); this.parentPageId = page.getParentPageId(); - this.lang = page.getLang(); this.url = page.getUrl(); this.lang = page.getLang(); boolean withDrafts = context.containsKey(TreeNode.WITH_DRAFTS) && (boolean) context.get(TreeNode.WITH_DRAFTS); 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 d49625458a..208b22427d 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 @@ -23,6 +23,8 @@ 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; @@ -39,6 +41,8 @@ public class PageTreeNode extends TreeNode { private static final Log log = ExoLogger.getLogger(PageTreeNode.class); + @Setter + @Getter private Page page; private NoteService noteService; @@ -55,15 +59,8 @@ public PageTreeNode(Page page) throws Exception { this.page = page; this.id = page.getId(); this.path = buildPath(); - this.hasChild = !page.isDraftPage() && !noteService.getChildrenNoteOf(page, 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 cacca60280..5cb2a6349b 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 @@ -61,7 +61,8 @@ public WikiHomeTreeNode(Page wikiHome) throws Exception { this.wikiHome = wikiHome; this.path = this.buildPath(); - this.hasChild = !wikiHome.isDraftPage() && !noteService.getChildrenNoteOf(wikiHome, 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 65623d482e..2ff183e566 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 { @@ -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 a2bace2990..ca30c2f91a 100644 --- a/notes-webapp/src/main/webapp/skin/less/notes/notes.less +++ b/notes-webapp/src/main/webapp/skin/less/notes/notes.less @@ -1242,3 +1242,23 @@ ul.note-manual-child { .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 443dcb4ad1..88d8751291 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 @@ -140,16 +140,16 @@