Sat, 22 Aug 2020 16:25:03 +0200
breadcrumb menu is now a sidebar navigation menu
--- a/pom.xml Sun Jun 21 12:38:15 2020 +0200 +++ b/pom.xml Sat Aug 22 16:25:03 2020 +0200 @@ -4,7 +4,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>de.uapcore</groupId> <artifactId>lightpit</artifactId> - <version>0.3</version> + <version>0.4-SNAPSHOT</version> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
--- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sun Jun 21 12:38:15 2020 +0200 +++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sat Aug 22 16:25:03 2020 +0200 @@ -228,14 +228,14 @@ } /** - * Sets the breadcrumbs menu. + * Sets the navigation menu. * - * @param req the servlet request object - * @param breadcrumbs the menu entries for the breadcrumbs menu - * @see Constants#REQ_ATTR_BREADCRUMBS + * @param req the servlet request object + * @param navigationItems the menu entries for the navigation menu + * @see Constants#REQ_ATTR_NAVIGATION */ - protected void setBreadcrumbs(HttpServletRequest req, List<MenuEntry> breadcrumbs) { - req.setAttribute(Constants.REQ_ATTR_BREADCRUMBS, breadcrumbs); + protected void setNavItems(HttpServletRequest req, List<MenuEntry> navigationItems) { + req.setAttribute(Constants.REQ_ATTR_NAVIGATION, navigationItems); } /**
--- a/src/main/java/de/uapcore/lightpit/Constants.java Sun Jun 21 12:38:15 2020 +0200 +++ b/src/main/java/de/uapcore/lightpit/Constants.java Sat Aug 22 16:25:03 2020 +0200 @@ -72,9 +72,9 @@ public static final String REQ_ATTR_MENU = fqn(AbstractLightPITServlet.class, "mainMenu"); /** - * Key for the request attribute containing the breadcrumb menu. + * Key for the request attribute containing the navigation menu. */ - public static final String REQ_ATTR_BREADCRUMBS = fqn(AbstractLightPITServlet.class, "breadcrumbs"); + public static final String REQ_ATTR_NAVIGATION = fqn(AbstractLightPITServlet.class, "navMenu"); /** * Key for the request attribute containing the base href.
--- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Sun Jun 21 12:38:15 2020 +0200 +++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Sat Aug 22 16:25:03 2020 +0200 @@ -202,27 +202,27 @@ } - private static final int BREADCRUMB_LEVEL_ROOT = 0; - private static final int BREADCRUMB_LEVEL_PROJECT = 1; - private static final int BREADCRUMB_LEVEL_VERSION = 2; - private static final int BREADCRUMB_LEVEL_ISSUE_LIST = 3; - private static final int BREADCRUMB_LEVEL_ISSUE = 4; + private static final int NAV_LEVEL_ROOT = 0; + private static final int NAV_LEVEL_PROJECT = 1; + private static final int NAV_LEVEL_VERSION = 2; + private static final int NAV_LEVEL_ISSUE_LIST = 3; + private static final int NAV_LEVEL_ISSUE = 4; /** - * Creates the breadcrumb menu. + * Creates the navigation menu. * - * @param level the current active level (0: root, 1: project, 2: version, 3: issue list, 4: issue) + * @param level the current active level (0: root, 1: project, 2: version, 3: issue list, 4: issue) * @param selection the currently selected objects - * @return a dynamic breadcrumb menu trying to display as many levels as possible + * @return a dynamic navigation menu trying to display as many levels as possible */ - private List<MenuEntry> getBreadcrumbs(int level, SessionSelection selection) { + private List<MenuEntry> getNavMenu(int level, SessionSelection selection) { MenuEntry entry; - final var breadcrumbs = new ArrayList<MenuEntry>(); + final var navigation = new ArrayList<MenuEntry>(); entry = new MenuEntry(new ResourceKey("localization.lightpit", "menu.projects"), "projects/"); - breadcrumbs.add(entry); - if (level == BREADCRUMB_LEVEL_ROOT) entry.setActive(true); + navigation.add(entry); + if (level == NAV_LEVEL_ROOT) entry.setActive(true); if (selection.project != null) { if (selection.project.getId() < 0) { @@ -232,8 +232,8 @@ entry = new MenuEntry(selection.project.getName(), "projects/view?pid=" + selection.project.getId()); } - if (level == BREADCRUMB_LEVEL_PROJECT) entry.setActive(true); - breadcrumbs.add(entry); + if (level == NAV_LEVEL_PROJECT) entry.setActive(true); + navigation.add(entry); } if (selection.version != null) { @@ -244,19 +244,19 @@ entry = new MenuEntry(selection.version.getName(), "projects/versions/view?vid=" + selection.version.getId()); } - if (level == BREADCRUMB_LEVEL_VERSION) entry.setActive(true); - breadcrumbs.add(entry); + if (level == NAV_LEVEL_VERSION) entry.setActive(true); + navigation.add(entry); } if (selection.project != null) { String path = "projects/issues/?pid=" + selection.project.getId(); if (selection.version != null) { - path += "&vid="+selection.version.getId(); + path += "&vid=" + selection.version.getId(); } entry = new MenuEntry(new ResourceKey("localization.projects", "menu.issues"), path); - if (level == BREADCRUMB_LEVEL_ISSUE_LIST) entry.setActive(true); - breadcrumbs.add(entry); + if (level == NAV_LEVEL_ISSUE_LIST) entry.setActive(true); + navigation.add(entry); } if (selection.issue != null) { @@ -268,11 +268,11 @@ // TODO: maybe change link to a view rather than directly opening the editor "projects/issues/edit?issue=" + selection.issue.getId()); } - if (level == BREADCRUMB_LEVEL_ISSUE) entry.setActive(true); - breadcrumbs.add(entry); + if (level == NAV_LEVEL_ISSUE) entry.setActive(true); + navigation.add(entry); } - return breadcrumbs; + return navigation; } @RequestMapping(method = HttpMethod.GET) @@ -297,7 +297,7 @@ setContentPage(req, "projects"); setStylesheet(req, "projects"); - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_ROOT, sessionSelection)); + setNavItems(req, getNavMenu(NAV_LEVEL_ROOT, sessionSelection)); return ResponseType.HTML; } @@ -308,7 +308,7 @@ viewModel.setUsers(dao.getUserDao().list()); setViewModel(req, viewModel); setContentPage(req, "project-form"); - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_PROJECT, selection)); + setNavItems(req, getNavMenu(NAV_LEVEL_PROJECT, selection)); return viewModel; } @@ -377,7 +377,7 @@ viewModel.updateVersionInfo(); setViewModel(req, viewModel); - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_PROJECT, selection)); + setNavItems(req, getNavMenu(NAV_LEVEL_PROJECT, selection)); setContentPage(req, "project-details"); setStylesheet(req, "projects"); @@ -400,7 +400,7 @@ viewModel.setIssues(issues); setViewModel(req, viewModel); - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_VERSION, selection)); + setNavItems(req, getNavMenu(NAV_LEVEL_VERSION, selection)); setContentPage(req, "version"); setStylesheet(req, "projects"); @@ -414,7 +414,7 @@ } setViewModel(req, viewModel); setContentPage(req, "version-form"); - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_VERSION, selection)); + setNavItems(req, getNavMenu(NAV_LEVEL_VERSION, selection)); return viewModel; } @@ -445,7 +445,7 @@ dao.getVersionDao().saveOrUpdate(version); // specifying the pid parameter will purposely reset the session selected version! - setRedirectLocation(req, "./projects/view?pid="+version.getProject().getId()); + setRedirectLocation(req, "./projects/view?pid=" + version.getProject().getId()); setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { LOG.warn("Form validation failure: {}", ex.getMessage()); @@ -471,7 +471,7 @@ setViewModel(req, viewModel); setContentPage(req, "issue-form"); - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_ISSUE, selection)); + setNavItems(req, getNavMenu(NAV_LEVEL_ISSUE, selection)); return viewModel; } @@ -494,7 +494,7 @@ } setViewModel(req, viewModel); - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_ISSUE_LIST, selection)); + setNavItems(req, getNavMenu(NAV_LEVEL_ISSUE_LIST, selection)); setContentPage(req, "issues"); setStylesheet(req, "projects"); @@ -534,7 +534,7 @@ getParameter(req, Integer[].class, "affected") .map(Stream::of) .map(stream -> - stream.map(Version::new).collect(Collectors.toList()) + stream.map(Version::new).collect(Collectors.toList()) ).ifPresent(issue::setAffectedVersions); getParameter(req, Integer[].class, "resolved") .map(Stream::of) @@ -544,8 +544,8 @@ dao.getIssueDao().saveOrUpdate(issue); - // specifying the issue parameter keeps the edited issue as breadcrumb - setRedirectLocation(req, "./projects/issues/?issue="+issue.getId()); + // specifying the issue parameter keeps the edited issue as menu item + setRedirectLocation(req, "./projects/issues/?issue=" + issue.getId()); setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { // TODO: set request attribute with error text
--- a/src/main/webapp/WEB-INF/jsp/site.jsp Sun Jun 21 12:38:15 2020 +0200 +++ b/src/main/webapp/WEB-INF/jsp/site.jsp Sat Aug 22 16:25:03 2020 +0200 @@ -40,7 +40,7 @@ <c:set scope="page" var="mainMenu" value="${requestScope[Constants.REQ_ATTR_MENU]}"/> <%-- Define an alias for the main menu --%> -<c:set scope="page" var="breadcrumbs" value="${requestScope[Constants.REQ_ATTR_BREADCRUMBS]}"/> +<c:set scope="page" var="navMenu" value="${requestScope[Constants.REQ_ATTR_NAVIGATION]}"/> <%-- Define an alias for the content page name --%> <c:set scope="page" var="contentPage" value="${requestScope[Constants.REQ_ATTR_CONTENT_PAGE]}"/> @@ -83,17 +83,19 @@ <%@include file="../jspf/menu-entry.jsp" %> </c:forEach> </div> -<c:if test="${not empty breadcrumbs}"> - <div id="breadcrumbs"> - <c:forEach var="menu" items="${breadcrumbs}"> - <%@include file="../jspf/menu-entry.jsp" %> - </c:forEach> +<div> + <c:if test="${not empty navMenu}"> + <div id="sideMenu"> + <c:forEach var="menu" items="${navMenu}"> + <%@include file="../jspf/menu-entry.jsp" %> + </c:forEach> + </div> + </c:if> + <div id="content-area" <c:if test="${not empty navMenu}">class="sidebar-spacing"</c:if>> + <c:if test="${not empty contentPage}"> + <c:import url="${contentPage}"/> + </c:if> </div> -</c:if> -<div id="content-area"> - <c:if test="${not empty contentPage}"> - <c:import url="${contentPage}"/> - </c:if> </div> </body> </html>
--- a/src/main/webapp/lightpit.css Sun Jun 21 12:38:15 2020 +0200 +++ b/src/main/webapp/lightpit.css Sat Aug 22 16:25:03 2020 +0200 @@ -47,7 +47,7 @@ text-decoration: none; } -#mainMenu, #breadcrumbs { +#mainMenu { width: 100%; display: flex; flex-flow: row wrap; @@ -56,17 +56,32 @@ border-bottom-style: solid; border-bottom-width: 1pt; } +#sideMenu { + display: flex; + flex-flow: column; + position: fixed; + height: 100%; + width: 20ch; + border-image-source: linear-gradient(to bottom, #606060, rgba(60, 60, 60, .25)); + border-image-slice: 1; + border-right-style: solid; + border-right-width: 1pt; +} + +#content-area.sidebar-spacing { + margin-left: 20ch; +} #mainMenu { font-size: large; background: #e0e0e5; } -#breadcrumbs { +#sideMenu { background: #f7f7ff; } -.menuEntry { +#mainMenu .menuEntry { padding: .25em 1em .25em 1em; border-right-style: solid; border-right-width: 1pt; @@ -77,7 +92,7 @@ background: #d0d0d5; } -#breadcrumbs .menuEntry[data-active] { +#sideMenu .menuEntry[data-active] { background: #e7e7ef }