diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java index a548c9d19f..ee6f01b290 100644 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java +++ b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java @@ -152,7 +152,7 @@ private MenuElement buildDashboardItem() { String mainMenuDisplayName = mainMenuEntryService.getNameInCurrentLocale(); String mainMenuIcon = mainMenuEntryService.getMenuIcon(); - var subItemDashboards = getSubItemDashboards(); + List subItemDashboards = getSubItemDashboards(); if (subItemDashboards.size() > 1) { return buildDashboardGroupMenu(subItemDashboards, dashboardTitle, mainMenuDisplayName, mainMenuIcon, currentLanguage, dashboardLink); @@ -173,8 +173,8 @@ private String determineDashboardLink() { } private List getSubItemDashboards() { - var dashboards = getDashboardCache().dashboards; - return dashboards.stream().filter(dashboard -> !dashboard.getIsTopMenu()).toList(); + List dashboards = DashboardUtils.getDashboardsWithoutMenuItem(); + return dashboards; } private MenuElement buildDashboardGroupMenu(List subItemDashboards, String defaultTitle, @@ -252,37 +252,13 @@ private MenuElement buildSingleDashboardMenu(String dashboardTitle, String dashb return dashboardMenu; } - - public PortalDashboardItemWrapper getDashboardCache() { - String sessionUserId = getSessionUserId(); - IvyCacheService cacheService = IvyCacheService.getInstance(); - PortalDashboardItemWrapper portalDashboardItemWrapper = null; - try { - portalDashboardItemWrapper = getPortalDashboardItemWrapper(sessionUserId, cacheService); - } catch (ClassCastException e) { - cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_MENU, sessionUserId); - } - - if (portalDashboardItemWrapper == null) { - synchronized(PortalDashboardItemWrapper.class) { - portalDashboardItemWrapper = new PortalDashboardItemWrapper(DashboardUtils.collectDashboards()); - cacheService.setSessionCache(IvyCacheIdentifier.PORTAL_DASHBOARDS, sessionUserId, portalDashboardItemWrapper); - } - } - return portalDashboardItemWrapper; - } - public void updateDashboardCache(List dashboards) { String sessionUserId = getSessionUserId(); IvyCacheService cacheService = IvyCacheService.getInstance(); - synchronized (PortalDashboardItemWrapper.class) { - cacheService.setSessionCache(IvyCacheIdentifier.PORTAL_DASHBOARDS, sessionUserId, - new PortalDashboardItemWrapper(dashboards)); - } + cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_PUBLIC_DASHBOARD, sessionUserId); + cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_PRIVATE_DASHBOARD, sessionUserId); - cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_MENU, sessionUserId); - cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_DASHBOARD_CONVERTER_DATA, sessionUserId); } private String getSessionUserId() { @@ -293,10 +269,6 @@ private String getSessionUserId() { return (String) session().getAttribute(sessionIdAttribute); } - private PortalDashboardItemWrapper getPortalDashboardItemWrapper(String sessionUserId, IvyCacheService cacheService) { - return (PortalDashboardItemWrapper) cacheService.getSessionCacheValue(IvyCacheIdentifier.PORTAL_DASHBOARDS, sessionUserId).orElse(null); - } - public String getDashboardLink() { return PortalNavigator.getDashboardLink(); } @@ -519,9 +491,6 @@ private IWorkflowSession session() { return Ivy.session(); } - public record PortalDashboardItemWrapper(List dashboards) { - } - private void buildBreadCrumbForNotification() { setPortalHomeMenuToBreadcrumbModel(); breadcrumbModel.getElements().add(buildGenericMenuItem("/ch.ivy.addon.portalkit.ui.jsf/notifications/notificationTitle")); diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuNavigator.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuNavigator.java index fd071c0c74..db2468c77e 100644 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuNavigator.java +++ b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuNavigator.java @@ -9,7 +9,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.Map; import javax.faces.context.FacesContext; @@ -107,8 +106,8 @@ public static List getThirdPartyApps() { } public static List callSubMenuItemsProcess() { - - subMenuItems = getSubmenuList(); + List subMenuItems = new ArrayList<>(); + subMenuItems = getSubmenuList(); return subMenuItems; } @@ -126,9 +125,6 @@ public static void navigateToTargetPage(boolean isClickOnBreadcrumb, String dest navigateToTargetPage(params); } - private record PortalSubMenuItemWrapper(Locale loadedLocale, List portalSubMenuItems) { - } - private static List getSubmenuList() { String currentLanguage = UserUtils.getUserLanguage(); List subMenuItems = new ArrayList<>(); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardBean.java index a27f088470..586c4ba0c4 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardBean.java @@ -22,7 +22,6 @@ import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.service.DeepLTranslationService; -import ch.addon.portal.generic.menu.MenuView; import ch.ivy.addon.portal.generic.navigation.PortalNavigator; import ch.ivy.addon.portalkit.constant.PortalConstants; import ch.ivy.addon.portalkit.dto.DisplayName; @@ -44,7 +43,6 @@ import ch.ivy.addon.portalkit.enums.TaskEmptyMessage; import ch.ivy.addon.portalkit.exporter.Exporter; import ch.ivy.addon.portalkit.ivydata.service.impl.LanguageService; -import ch.ivy.addon.portalkit.jsf.ManagedBeans; import ch.ivy.addon.portalkit.service.GlobalSettingService; import ch.ivy.addon.portalkit.service.WidgetFilterService; import ch.ivy.addon.portalkit.support.HtmlParser; @@ -89,12 +87,6 @@ public void init() { currentDashboardIndex = 0; dashboards = collectDashboards(); - - if (isReadOnlyMode) { - MenuView menuView = (MenuView) ManagedBeans.get("menuView"); - menuView.updateDashboardCache(dashboards); - } - if (CollectionUtils.isNotEmpty(DashboardUtils.getDashboardsWithoutMenuItem())) { updateSelectedDashboardIdFromSessionAttribute(); currentDashboardIndex = findIndexOfDashboardById(selectedDashboardId); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/IvyCacheIdentifier.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/IvyCacheIdentifier.java index 24faff26a5..6bcd5d2022 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/IvyCacheIdentifier.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/IvyCacheIdentifier.java @@ -9,10 +9,8 @@ public final class IvyCacheIdentifier { public static final String ROLES_IN_SECURITY_CONTEXT = "ROLES_IN_SECURITY_CONTEXT"; public static final String PORTAL_MENU = "PORTAL_MENU"; public static final String PORTAL_CUSTOM_MENU = "PORTAL_CUSTOM_MENU"; - public static final String PORTAL_DASHBOARDS = "PORTAL_DASHBOARDS"; - public static final String PORTAL_DASHBOARDS_MENU_ITEM = "PORTAL_DASHBOARDS_MENU_ITEM"; - public static final String PORTAL_DASHBOARD_CONVERTER_DATA = "PORTAL_DASHBOARD_CONVERTER_DATA"; - + public static final String PORTAL_PUBLIC_DASHBOARD = "PORTAL_PUBLIC_DASHBOARD"; + public static final String PORTAL_PRIVATE_DASHBOARD = "PORTAL_PRIVATE_DASHBOARD"; // for caching locales public static final String PORTAL_CONTENT_LOCALES = "PORTAL_CONTENT_LOCALES"; public static final String PORTAL_FORMATTING_LOCALES = "PORTAL_FORMATTING_LOCALES"; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/Dashboard.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/Dashboard.java index 0896ec2dc6..3134cd3d51 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/Dashboard.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/Dashboard.java @@ -139,7 +139,7 @@ public void setTemplateId(String templateId) { } public Boolean getIsTopMenu() { - return isTopMenu; + return isTopMenu != null ? isTopMenu : false; } public void setIsTopMenu(Boolean isTopMenu) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java index 6981e399f1..61f1a53baa 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.UUID; import java.util.function.Consumer; @@ -21,12 +22,14 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import ch.ivy.addon.portalkit.constant.IvyCacheIdentifier; import ch.ivy.addon.portalkit.dto.dashboard.Dashboard; import ch.ivy.addon.portalkit.dto.dashboard.DashboardOrder; import ch.ivy.addon.portalkit.dto.dashboard.DashboardTemplate; import ch.ivy.addon.portalkit.enums.PortalVariable; import ch.ivy.addon.portalkit.enums.SessionAttribute; import ch.ivy.addon.portalkit.persistence.converter.BusinessEntityConverter; +import ch.ivy.addon.portalkit.service.IvyCacheService; import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.security.ISecurityConstants; import ch.ivyteam.ivy.security.IUser; @@ -49,17 +52,72 @@ public class DashboardUtils { public final static String DEFAULT_CASE_LIST_DASHBOARD = "default-case-list-dashboard"; public static List getPublicDashboards() { - String dashboardJson = Ivy.var().get(PortalVariable.DASHBOARD.key); - List dashboards = jsonToDashboards(dashboardJson); - addDefaultTaskCaseListDashboardsIfMissing(dashboards); - setDashboardAsPublic(dashboards); - return dashboards; + Locale requestLocale = Ivy.session().getContentLocale(); + String sessionIdAttribute = SessionAttribute.SESSION_IDENTIFIER.toString(); + if (Ivy.session().getAttribute(sessionIdAttribute) == null) { + Ivy.session().setAttribute(sessionIdAttribute, UUID.randomUUID().toString()); + } + String sessionUserId = (String) Ivy.session().getAttribute(sessionIdAttribute); + IvyCacheService cacheService = IvyCacheService.getInstance(); + PortalPublicDashboardWrapper portalPublicDashboardWrapper = null; + try { + portalPublicDashboardWrapper = (PortalPublicDashboardWrapper) cacheService + .getSessionCacheValue(IvyCacheIdentifier.PORTAL_PUBLIC_DASHBOARD, sessionUserId).orElse(null); + } catch (ClassCastException e) { + cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_PUBLIC_DASHBOARD, sessionUserId); + } + + if (portalPublicDashboardWrapper == null || !requestLocale.equals(portalPublicDashboardWrapper.loadedLocale)) { + synchronized (PortalPublicDashboardWrapper.class) { + List dashboards = new ArrayList<>(); + try { + String dashboardJson = Ivy.var().get(PortalVariable.DASHBOARD.key); + dashboards = jsonToDashboards(dashboardJson); + ensureDefaultIsTopMenu(dashboards); + addDefaultTaskCaseListDashboardsIfMissing(dashboards); + setDashboardAsPublic(dashboards); + } catch (Exception e) { + Ivy.log().error("Cannot load Public Dashboards {0}", e.getMessage()); + } + portalPublicDashboardWrapper = new PortalPublicDashboardWrapper(requestLocale, dashboards); + cacheService.setSessionCache(IvyCacheIdentifier.PORTAL_PUBLIC_DASHBOARD, sessionUserId, + portalPublicDashboardWrapper); + } + } + return portalPublicDashboardWrapper.dashboards(); } public static List getPrivateDashboards() { - String dashboardInUserProperty = readDashboardBySessionUser(); - List dashboards = jsonToDashboards(dashboardInUserProperty); - return dashboards; + Locale requestLocale = Ivy.session().getContentLocale(); + String sessionIdAttribute = SessionAttribute.SESSION_IDENTIFIER.toString(); + if (Ivy.session().getAttribute(sessionIdAttribute) == null) { + Ivy.session().setAttribute(sessionIdAttribute, UUID.randomUUID().toString()); + } + String sessionUserId = (String) Ivy.session().getAttribute(sessionIdAttribute); + IvyCacheService cacheService = IvyCacheService.getInstance(); + PortalPrivateDashboardWrapper portalPrivateDashboardWrapper = null; + try { + portalPrivateDashboardWrapper = (PortalPrivateDashboardWrapper) cacheService + .getSessionCacheValue(IvyCacheIdentifier.PORTAL_PRIVATE_DASHBOARD, sessionUserId).orElse(null); + } catch (ClassCastException e) { + cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_PRIVATE_DASHBOARD, sessionUserId); + } + + if (portalPrivateDashboardWrapper == null || !requestLocale.equals(portalPrivateDashboardWrapper.loadedLocale)) { + synchronized (PortalPublicDashboardWrapper.class) { + List dashboards = new ArrayList<>(); + try { + String dashboardInUserProperty = readDashboardBySessionUser(); + dashboards = jsonToDashboards(dashboardInUserProperty); + } catch (Exception e) { + Ivy.log().error("Cannot load Public Dashboards {0}", e.getMessage()); + } + portalPrivateDashboardWrapper = new PortalPrivateDashboardWrapper(requestLocale, dashboards); + cacheService.setSessionCache(IvyCacheIdentifier.PORTAL_PRIVATE_DASHBOARD, sessionUserId, + portalPrivateDashboardWrapper); + } + } + return portalPrivateDashboardWrapper.dashboards(); } public static List getVisibleDashboards(boolean isPublic) { @@ -81,7 +139,7 @@ public static List collectDashboards() { Dashboard currentDashboard = idToDashboard.remove(dashboardOrder.getDashboardId()); if (dashboardOrder.isVisible() && currentDashboard != null) { collectedDashboards.add(currentDashboard); - } + } } collectedDashboards.addAll(idToDashboard.values()); addDefaultTaskCaseListDashboardsIfMissing(collectedDashboards); @@ -102,7 +160,7 @@ public static void highlightDashboardMenuItem(String selectedDashboardId) { private static List jsonToDashboards(String dashboardJson) { if (StringUtils.isBlank(dashboardJson)) { - return new ArrayList<>(); + return new ArrayList<>(); } try { ObjectMapper mapper = new ObjectMapper(); @@ -122,7 +180,7 @@ private static Consumer initDefaultPermission() { ArrayList defaultPermissions = new ArrayList<>(); defaultPermissions.add(ISecurityConstants.TOP_LEVEL_ROLE_NAME); dashboard.setPermissions(defaultPermissions); - } + } }; } @@ -191,26 +249,21 @@ public static void updateSelectedDashboardToSession(String selectedMenuItemId) { } public static void storeDashboardInSession(String dashboardId) { - Ivy.log().error("ADADA1" + dashboardId); - boolean isMain = isMainDashboard(dashboardId, true); + boolean isMain = isMainDashboard(dashboardId, false); storeDashboardInSession(dashboardId, isMain); } public static void storeDashboardInSession(String dashboardId, boolean isMainDashboard) { Ivy.session().setAttribute(SessionAttribute.SELECTED_DASHBOARD_ID.toString(), dashboardId); - if (!isMainDashboard) { - Ivy.session().setAttribute(SessionAttribute.SELECTED_SUB_DASHBOARD_ID.toString(), dashboardId); } } public static boolean isMainDashboard(String dashboardId, boolean defaultValue) { if (StringUtils.isEmpty(dashboardId)) { - return false; } - return collectMainDashboards().stream().filter(dashboard -> dashboardId.equals(dashboard.getId())) .map(Dashboard::getIsTopMenu).findFirst().orElse(defaultValue); } @@ -263,4 +316,20 @@ public static void updatePropertiesToNullIfCurrentValueIsDefaultValue(List dashboards) { + if (dashboards != null) { + dashboards.forEach(dashboard -> { + if (dashboard.getIsTopMenu() == null) { + dashboard.setIsTopMenu(false); + } + }); + } + } + + private record PortalPrivateDashboardWrapper(Locale loadedLocale, List dashboards) { + } + private record PortalPublicDashboardWrapper(Locale loadedLocale, List dashboards) { + } + }