diff --git a/component/api/src/main/java/io/meeds/social/navigation/model/SidebarConfiguration.java b/component/api/src/main/java/io/meeds/social/navigation/model/SidebarConfiguration.java index 3e7b6a29127..4ef44e4d3a7 100644 --- a/component/api/src/main/java/io/meeds/social/navigation/model/SidebarConfiguration.java +++ b/component/api/src/main/java/io/meeds/social/navigation/model/SidebarConfiguration.java @@ -36,6 +36,8 @@ public class SidebarConfiguration implements Cloneable { private SidebarMode defaultMode; + private SidebarMode userMode; + private List allowedModes; private List items; @@ -44,6 +46,7 @@ public class SidebarConfiguration implements Cloneable { public SidebarConfiguration clone() { // NOSONAR return new SidebarConfiguration(allowUserCustomHome, defaultMode, + userMode, new ArrayList<>(allowedModes), new ArrayList<>(items)); } diff --git a/component/core/src/main/java/io/meeds/social/navigation/service/NavigationConfigurationInitService.java b/component/core/src/main/java/io/meeds/social/navigation/service/NavigationConfigurationInitService.java index ad74caf1a11..78f8bbff23b 100644 --- a/component/core/src/main/java/io/meeds/social/navigation/service/NavigationConfigurationInitService.java +++ b/component/core/src/main/java/io/meeds/social/navigation/service/NavigationConfigurationInitService.java @@ -95,6 +95,7 @@ private NavigationConfiguration buildDefaultNavigationConfiguration() { getDefaultTopbarApplications()); SidebarConfiguration sidebarConfiguration = new SidebarConfiguration(allowUserCustomHome, defaultMode, + null, Arrays.asList(SidebarMode.values()), getDefaultNavigations()); return new NavigationConfiguration(topbarConfiguration, sidebarConfiguration); diff --git a/component/core/src/main/java/io/meeds/social/navigation/service/NavigationConfigurationService.java b/component/core/src/main/java/io/meeds/social/navigation/service/NavigationConfigurationService.java index 515d7b1c2c5..473cbeb0e9a 100644 --- a/component/core/src/main/java/io/meeds/social/navigation/service/NavigationConfigurationService.java +++ b/component/core/src/main/java/io/meeds/social/navigation/service/NavigationConfigurationService.java @@ -21,10 +21,12 @@ import java.util.List; import java.util.Locale; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import io.meeds.social.navigation.constant.SidebarItemType; +import io.meeds.social.navigation.constant.SidebarMode; import io.meeds.social.navigation.model.NavigationConfiguration; import io.meeds.social.navigation.model.SidebarConfiguration; import io.meeds.social.navigation.model.SidebarItem; @@ -100,7 +102,33 @@ public TopbarConfiguration getTopbarConfiguration(String username, Locale locale * settings */ public SidebarConfiguration getSidebarConfiguration(String username, Locale locale) { - return getConfiguration(username, locale, true).getSidebar(); + SidebarConfiguration sidebarConfiguration = getConfiguration(username, locale, true).getSidebar(); + if (StringUtils.isNotBlank(username)) { + SidebarMode mode = getSidebarUserMode(username, sidebarConfiguration); + sidebarConfiguration.setUserMode(mode); + } + return sidebarConfiguration; + } + + /** + * Retrieves the preferred mode of sidebar by a user + * + * @param username User name as identifier + * @return preferred {@link SidebarMode} or default if not set by user yet + */ + public SidebarMode getSidebarUserMode(String username) { + NavigationConfiguration configuration = navigationConfigurationStorage.getConfiguration(defaultTopbarApplications); + return getSidebarUserMode(username, configuration.getSidebar()); + } + + /** + * Updates the preferred mode of sidebar by the user + * + * @param username User name as identifier + * @param mode Preferred {@link SidebarMode} by the user + */ + public void updateSidebarUserMode(String username, SidebarMode mode) { + navigationConfigurationStorage.updateSidebarUserMode(username, mode); } /** @@ -112,6 +140,16 @@ public void updateConfiguration(NavigationConfiguration navigationConfiguration) navigationConfigurationStorage.updateConfiguration(navigationConfiguration); } + private SidebarMode getSidebarUserMode(String username, SidebarConfiguration sidebarConfiguration) { + SidebarMode mode = navigationConfigurationStorage.getSidebarUserMode(username); + if (sidebarConfiguration != null + && (mode == null + || !sidebarConfiguration.getAllowedModes().contains(mode))) { + mode = sidebarConfiguration.getDefaultMode(); + } + return mode; + } + @SneakyThrows private SidebarItem expandSidebarItem(SidebarItem item, String username, Locale locale) { return getPlugin(item.getType()).resolveProperties(item, username, locale); diff --git a/component/core/src/main/java/io/meeds/social/navigation/storage/NavigationConfigurationStorage.java b/component/core/src/main/java/io/meeds/social/navigation/storage/NavigationConfigurationStorage.java index 9ddbd8ea05e..8fe134d961d 100644 --- a/component/core/src/main/java/io/meeds/social/navigation/storage/NavigationConfigurationStorage.java +++ b/component/core/src/main/java/io/meeds/social/navigation/storage/NavigationConfigurationStorage.java @@ -31,6 +31,7 @@ import org.exoplatform.commons.api.settings.data.Context; import org.exoplatform.commons.api.settings.data.Scope; +import io.meeds.social.navigation.constant.SidebarMode; import io.meeds.social.navigation.constant.TopbarItemType; import io.meeds.social.navigation.model.NavigationConfiguration; import io.meeds.social.navigation.model.TopbarApplication; @@ -41,10 +42,12 @@ public class NavigationConfigurationStorage { private static final String SETTING_KEY = "configuration"; - private static final Scope SETTING_GLOBAL_SCOPE = Scope.GLOBAL.id("NavigationConfiguration"); + private static final String SETTING_USER_MODE_KEY = "sidebarMode"; private static final Context SETTING_GLOBAL_CONTEXT = Context.GLOBAL.id("NavigationConfiguration"); + private static final Scope SETTING_SCOPE = Scope.APPLICATION.id("NavigationConfiguration"); + private static final NavigationConfiguration NULL_VALUE = new NavigationConfiguration(); @Autowired @@ -62,7 +65,7 @@ public NavigationConfiguration getConfiguration(List defaultA public void updateConfiguration(NavigationConfiguration navigationConfiguration) { try { settingService.set(SETTING_GLOBAL_CONTEXT, - SETTING_GLOBAL_SCOPE, + SETTING_SCOPE, SETTING_KEY, SettingValue.create(JsonUtils.toJsonString(navigationConfiguration))); } finally { @@ -70,8 +73,23 @@ public void updateConfiguration(NavigationConfiguration navigationConfiguration) } } + public SidebarMode getSidebarUserMode(String username) { + SettingValue settingValue = settingService.get(Context.USER.id(username), + SETTING_SCOPE, + SETTING_USER_MODE_KEY); + return settingValue == null || settingValue.getValue() == null ? null : + SidebarMode.valueOf(settingValue.getValue().toString()); + } + + public void updateSidebarUserMode(String username, SidebarMode mode) { + settingService.set(Context.USER.id(username), + SETTING_SCOPE, + SETTING_USER_MODE_KEY, + SettingValue.create(mode.name())); + } + private NavigationConfiguration retrieveNavigationConfiguration(List defaultApplications) { - SettingValue settingValue = settingService.get(SETTING_GLOBAL_CONTEXT, SETTING_GLOBAL_SCOPE, SETTING_KEY); + SettingValue settingValue = settingService.get(SETTING_GLOBAL_CONTEXT, SETTING_SCOPE, SETTING_KEY); if (settingValue == null || settingValue.getValue() == null) { return NULL_VALUE; } else { diff --git a/component/service/src/main/java/io/meeds/social/navigation/rest/NavigationConfigurationRest.java b/component/service/src/main/java/io/meeds/social/navigation/rest/NavigationConfigurationRest.java index 7463b1e6b8b..2b5ed28aeab 100644 --- a/component/service/src/main/java/io/meeds/social/navigation/rest/NavigationConfigurationRest.java +++ b/component/service/src/main/java/io/meeds/social/navigation/rest/NavigationConfigurationRest.java @@ -25,14 +25,17 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import io.meeds.social.navigation.constant.SidebarMode; import io.meeds.social.navigation.model.NavigationConfiguration; import io.meeds.social.navigation.model.SidebarConfiguration; import io.meeds.social.navigation.model.TopbarConfiguration; import io.meeds.social.navigation.service.NavigationConfigurationService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; @@ -71,10 +74,7 @@ public TopbarConfiguration getTopbarConfiguration(HttpServletRequest request) { } @GetMapping("/sidebar") - @Secured("users") - @Operation(summary = "Retrieve Sidebar settings", - method = "GET", - description = "This retrieves the configuration of Sidebar switch user roles") + @Operation(summary = "Retrieve Sidebar settings", method = "GET", description = "This retrieves the configuration of Sidebar switch user roles") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Request fulfilled"), }) @@ -82,6 +82,19 @@ public SidebarConfiguration getSidebarConfiguration(HttpServletRequest request) return navigationConfigurationService.getSidebarConfiguration(request.getRemoteUser(), request.getLocale()); } + @PutMapping(path = "/sidebar/mode", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @Secured("users") + @Operation(summary = "Retrieve Sidebar settings", method = "GET", description = "This retrieves the configuration of Sidebar switch user roles") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Request fulfilled"), + }) + public void updateSidebarUserMode(HttpServletRequest request, + @Parameter(description = "User preferred Sidebar Mode") + @RequestParam("mode") + SidebarMode mode) { + navigationConfigurationService.updateSidebarUserMode(request.getRemoteUser(), mode); + } + @PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE) @Secured("administrators") @Operation(summary = "Updates Topbar and Sidebar settings", diff --git a/webapp/src/main/resources/locale/portal/HamburgerMenu_en.properties b/webapp/src/main/resources/locale/portal/HamburgerMenu_en.properties index a28d6966a8c..3c40c8cb33e 100644 --- a/webapp/src/main/resources/locale/portal/HamburgerMenu_en.properties +++ b/webapp/src/main/resources/locale/portal/HamburgerMenu_en.properties @@ -15,6 +15,7 @@ menu.role.navigation.first.level=First Level Navigation menu.role.navigation.second.level=Second Level Navigation menu.expand=Keep the menu opened menu.collapse=Collapse the menu +menu.reduce=Keep icons only menu.createNewSpace=Create a space menu.seeMySpaces=See my spaces menu.spaces.joinOrCreateSpace=Join or create a space diff --git a/webapp/src/main/webapp/WEB-INF/jsp/portlet/hamburgerMenu.jsp b/webapp/src/main/webapp/WEB-INF/jsp/portlet/hamburgerMenu.jsp index e3a9e672c25..4ef1d984b0b 100644 --- a/webapp/src/main/webapp/WEB-INF/jsp/portlet/hamburgerMenu.jsp +++ b/webapp/src/main/webapp/WEB-INF/jsp/portlet/hamburgerMenu.jsp @@ -1,3 +1,5 @@ +<%@page import="io.meeds.social.navigation.constant.SidebarMode"%> +<%@page import="io.meeds.social.navigation.service.NavigationConfigurationService"%> <%@page import="org.exoplatform.social.core.identity.model.Identity"%> <%@page import="io.meeds.social.util.JsonUtils"%> <%@page import="org.exoplatform.social.notification.service.SpaceWebNotificationService"%> @@ -12,44 +14,38 @@ <%@page import="org.exoplatform.commons.api.settings.SettingService"%> <%@page import="org.exoplatform.container.ExoContainerContext"%> <%@page import="io.meeds.social.space.template.service.SpaceTemplateService"%> -<%@ page import="org.exoplatform.social.webui.Utils"%> +<%@page import="org.exoplatform.social.webui.Utils"%> <% - boolean canCreateSpace = ExoContainerContext.getService(SpaceTemplateService.class).canCreateSpace(request.getRemoteUser()); - SettingValue stickySettingValue = ExoContainerContext.getService(SettingService.class).get(Context.USER.id(request.getRemoteUser()), Scope.APPLICATION.id("HamburgerMenu"), "Sticky"); - boolean sticky = stickySettingValue == null ? Boolean.parseBoolean(System.getProperty("io.meeds.userPrefs.HamburgerMenu.sticky", "false")) : Boolean.parseBoolean(stickySettingValue.getValue().toString()); - PortalRequestContext rcontext = (PortalRequestContext) PortalRequestContext.getCurrentInstance(); - PortalHttpServletResponseWrapper responseWrapper = (PortalHttpServletResponseWrapper) rcontext.getResponse(); - if (rcontext.getRequest().getParameter("sticky") != null) { - sticky = StringUtils.equals("true", rcontext.getRequest().getParameter("sticky")); - } UserPortalConfigService portalConfigService = ExoContainerContext.getService(UserPortalConfigService.class); - SpaceWebNotificationService spaceWebNotificationService = ExoContainerContext.getService(SpaceWebNotificationService.class); + + SidebarMode mode = ExoContainerContext.getService(NavigationConfigurationService.class).getSidebarUserMode(request.getRemoteUser()); + Identity viewerIdentity = Utils.getViewerIdentity(); String avatarUrl = viewerIdentity == null ? "" : viewerIdentity.getProfile().getAvatarUrl(); - Map unreadPerSpace = spaceWebNotificationService.countUnreadItemsBySpace(request.getRemoteUser()); + Map unreadPerSpace = ExoContainerContext.getService(SpaceWebNotificationService.class) + .countUnreadItemsBySpace(request.getRemoteUser()); - String defaultHomePath = "/portal/" + rcontext.getPortalOwner(); - String defaultUserPath = defaultHomePath; + String defaultUserPath; if (StringUtils.equals(rcontext.getPortalOwner(), "public")) { defaultUserPath = "/portal/public"; } else { defaultUserPath = portalConfigService.getUserHomePage(request.getRemoteUser()); if (defaultUserPath == null) { defaultUserPath = portalConfigService.computePortalPath(rcontext.getRequest()); - if (defaultUserPath == null) { - defaultUserPath = defaultHomePath; - } } } + if (defaultUserPath == null) { + defaultUserPath = "/portal/" + rcontext.getPortalOwner(); + } - responseWrapper.addHeader("Link", "; rel=preload; as=fetch; crossorigin=use-credentials", false); + ((PortalHttpServletResponseWrapper) rcontext.getResponse()).addHeader("Link", "; rel=preload; as=fetch; crossorigin=use-credentials", false); %>
- <% if (sticky) { %> + <% if (mode != SidebarMode.HIDDEN) { %>
\ No newline at end of file diff --git a/webapp/src/main/webapp/WEB-INF/jsp/portlet/topbarLogo.jsp b/webapp/src/main/webapp/WEB-INF/jsp/portlet/topbarLogo.jsp index bf2097a74c3..0da7198ea9c 100644 --- a/webapp/src/main/webapp/WEB-INF/jsp/portlet/topbarLogo.jsp +++ b/webapp/src/main/webapp/WEB-INF/jsp/portlet/topbarLogo.jsp @@ -99,11 +99,11 @@
<% if (space == null) { %> <% if (logoPath != null) { %> - + <% } %> -