Sat, 22 Aug 2020 16:25:03 +0200
breadcrumb menu is now a sidebar navigation menu
1.1 --- a/pom.xml Sun Jun 21 12:38:15 2020 +0200 1.2 +++ b/pom.xml Sat Aug 22 16:25:03 2020 +0200 1.3 @@ -4,7 +4,7 @@ 1.4 <modelVersion>4.0.0</modelVersion> 1.5 <groupId>de.uapcore</groupId> 1.6 <artifactId>lightpit</artifactId> 1.7 - <version>0.3</version> 1.8 + <version>0.4-SNAPSHOT</version> 1.9 <packaging>war</packaging> 1.10 <properties> 1.11 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2.1 --- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sun Jun 21 12:38:15 2020 +0200 2.2 +++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sat Aug 22 16:25:03 2020 +0200 2.3 @@ -228,14 +228,14 @@ 2.4 } 2.5 2.6 /** 2.7 - * Sets the breadcrumbs menu. 2.8 + * Sets the navigation menu. 2.9 * 2.10 - * @param req the servlet request object 2.11 - * @param breadcrumbs the menu entries for the breadcrumbs menu 2.12 - * @see Constants#REQ_ATTR_BREADCRUMBS 2.13 + * @param req the servlet request object 2.14 + * @param navigationItems the menu entries for the navigation menu 2.15 + * @see Constants#REQ_ATTR_NAVIGATION 2.16 */ 2.17 - protected void setBreadcrumbs(HttpServletRequest req, List<MenuEntry> breadcrumbs) { 2.18 - req.setAttribute(Constants.REQ_ATTR_BREADCRUMBS, breadcrumbs); 2.19 + protected void setNavItems(HttpServletRequest req, List<MenuEntry> navigationItems) { 2.20 + req.setAttribute(Constants.REQ_ATTR_NAVIGATION, navigationItems); 2.21 } 2.22 2.23 /**
3.1 --- a/src/main/java/de/uapcore/lightpit/Constants.java Sun Jun 21 12:38:15 2020 +0200 3.2 +++ b/src/main/java/de/uapcore/lightpit/Constants.java Sat Aug 22 16:25:03 2020 +0200 3.3 @@ -72,9 +72,9 @@ 3.4 public static final String REQ_ATTR_MENU = fqn(AbstractLightPITServlet.class, "mainMenu"); 3.5 3.6 /** 3.7 - * Key for the request attribute containing the breadcrumb menu. 3.8 + * Key for the request attribute containing the navigation menu. 3.9 */ 3.10 - public static final String REQ_ATTR_BREADCRUMBS = fqn(AbstractLightPITServlet.class, "breadcrumbs"); 3.11 + public static final String REQ_ATTR_NAVIGATION = fqn(AbstractLightPITServlet.class, "navMenu"); 3.12 3.13 /** 3.14 * Key for the request attribute containing the base href.
4.1 --- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Sun Jun 21 12:38:15 2020 +0200 4.2 +++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Sat Aug 22 16:25:03 2020 +0200 4.3 @@ -202,27 +202,27 @@ 4.4 } 4.5 4.6 4.7 - private static final int BREADCRUMB_LEVEL_ROOT = 0; 4.8 - private static final int BREADCRUMB_LEVEL_PROJECT = 1; 4.9 - private static final int BREADCRUMB_LEVEL_VERSION = 2; 4.10 - private static final int BREADCRUMB_LEVEL_ISSUE_LIST = 3; 4.11 - private static final int BREADCRUMB_LEVEL_ISSUE = 4; 4.12 + private static final int NAV_LEVEL_ROOT = 0; 4.13 + private static final int NAV_LEVEL_PROJECT = 1; 4.14 + private static final int NAV_LEVEL_VERSION = 2; 4.15 + private static final int NAV_LEVEL_ISSUE_LIST = 3; 4.16 + private static final int NAV_LEVEL_ISSUE = 4; 4.17 4.18 /** 4.19 - * Creates the breadcrumb menu. 4.20 + * Creates the navigation menu. 4.21 * 4.22 - * @param level the current active level (0: root, 1: project, 2: version, 3: issue list, 4: issue) 4.23 + * @param level the current active level (0: root, 1: project, 2: version, 3: issue list, 4: issue) 4.24 * @param selection the currently selected objects 4.25 - * @return a dynamic breadcrumb menu trying to display as many levels as possible 4.26 + * @return a dynamic navigation menu trying to display as many levels as possible 4.27 */ 4.28 - private List<MenuEntry> getBreadcrumbs(int level, SessionSelection selection) { 4.29 + private List<MenuEntry> getNavMenu(int level, SessionSelection selection) { 4.30 MenuEntry entry; 4.31 4.32 - final var breadcrumbs = new ArrayList<MenuEntry>(); 4.33 + final var navigation = new ArrayList<MenuEntry>(); 4.34 entry = new MenuEntry(new ResourceKey("localization.lightpit", "menu.projects"), 4.35 "projects/"); 4.36 - breadcrumbs.add(entry); 4.37 - if (level == BREADCRUMB_LEVEL_ROOT) entry.setActive(true); 4.38 + navigation.add(entry); 4.39 + if (level == NAV_LEVEL_ROOT) entry.setActive(true); 4.40 4.41 if (selection.project != null) { 4.42 if (selection.project.getId() < 0) { 4.43 @@ -232,8 +232,8 @@ 4.44 entry = new MenuEntry(selection.project.getName(), 4.45 "projects/view?pid=" + selection.project.getId()); 4.46 } 4.47 - if (level == BREADCRUMB_LEVEL_PROJECT) entry.setActive(true); 4.48 - breadcrumbs.add(entry); 4.49 + if (level == NAV_LEVEL_PROJECT) entry.setActive(true); 4.50 + navigation.add(entry); 4.51 } 4.52 4.53 if (selection.version != null) { 4.54 @@ -244,19 +244,19 @@ 4.55 entry = new MenuEntry(selection.version.getName(), 4.56 "projects/versions/view?vid=" + selection.version.getId()); 4.57 } 4.58 - if (level == BREADCRUMB_LEVEL_VERSION) entry.setActive(true); 4.59 - breadcrumbs.add(entry); 4.60 + if (level == NAV_LEVEL_VERSION) entry.setActive(true); 4.61 + navigation.add(entry); 4.62 } 4.63 4.64 if (selection.project != null) { 4.65 String path = "projects/issues/?pid=" + selection.project.getId(); 4.66 if (selection.version != null) { 4.67 - path += "&vid="+selection.version.getId(); 4.68 + path += "&vid=" + selection.version.getId(); 4.69 } 4.70 entry = new MenuEntry(new ResourceKey("localization.projects", "menu.issues"), 4.71 path); 4.72 - if (level == BREADCRUMB_LEVEL_ISSUE_LIST) entry.setActive(true); 4.73 - breadcrumbs.add(entry); 4.74 + if (level == NAV_LEVEL_ISSUE_LIST) entry.setActive(true); 4.75 + navigation.add(entry); 4.76 } 4.77 4.78 if (selection.issue != null) { 4.79 @@ -268,11 +268,11 @@ 4.80 // TODO: maybe change link to a view rather than directly opening the editor 4.81 "projects/issues/edit?issue=" + selection.issue.getId()); 4.82 } 4.83 - if (level == BREADCRUMB_LEVEL_ISSUE) entry.setActive(true); 4.84 - breadcrumbs.add(entry); 4.85 + if (level == NAV_LEVEL_ISSUE) entry.setActive(true); 4.86 + navigation.add(entry); 4.87 } 4.88 4.89 - return breadcrumbs; 4.90 + return navigation; 4.91 } 4.92 4.93 @RequestMapping(method = HttpMethod.GET) 4.94 @@ -297,7 +297,7 @@ 4.95 setContentPage(req, "projects"); 4.96 setStylesheet(req, "projects"); 4.97 4.98 - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_ROOT, sessionSelection)); 4.99 + setNavItems(req, getNavMenu(NAV_LEVEL_ROOT, sessionSelection)); 4.100 4.101 return ResponseType.HTML; 4.102 } 4.103 @@ -308,7 +308,7 @@ 4.104 viewModel.setUsers(dao.getUserDao().list()); 4.105 setViewModel(req, viewModel); 4.106 setContentPage(req, "project-form"); 4.107 - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_PROJECT, selection)); 4.108 + setNavItems(req, getNavMenu(NAV_LEVEL_PROJECT, selection)); 4.109 return viewModel; 4.110 } 4.111 4.112 @@ -377,7 +377,7 @@ 4.113 viewModel.updateVersionInfo(); 4.114 setViewModel(req, viewModel); 4.115 4.116 - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_PROJECT, selection)); 4.117 + setNavItems(req, getNavMenu(NAV_LEVEL_PROJECT, selection)); 4.118 setContentPage(req, "project-details"); 4.119 setStylesheet(req, "projects"); 4.120 4.121 @@ -400,7 +400,7 @@ 4.122 viewModel.setIssues(issues); 4.123 setViewModel(req, viewModel); 4.124 4.125 - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_VERSION, selection)); 4.126 + setNavItems(req, getNavMenu(NAV_LEVEL_VERSION, selection)); 4.127 setContentPage(req, "version"); 4.128 setStylesheet(req, "projects"); 4.129 4.130 @@ -414,7 +414,7 @@ 4.131 } 4.132 setViewModel(req, viewModel); 4.133 setContentPage(req, "version-form"); 4.134 - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_VERSION, selection)); 4.135 + setNavItems(req, getNavMenu(NAV_LEVEL_VERSION, selection)); 4.136 return viewModel; 4.137 } 4.138 4.139 @@ -445,7 +445,7 @@ 4.140 dao.getVersionDao().saveOrUpdate(version); 4.141 4.142 // specifying the pid parameter will purposely reset the session selected version! 4.143 - setRedirectLocation(req, "./projects/view?pid="+version.getProject().getId()); 4.144 + setRedirectLocation(req, "./projects/view?pid=" + version.getProject().getId()); 4.145 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 4.146 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 4.147 LOG.warn("Form validation failure: {}", ex.getMessage()); 4.148 @@ -471,7 +471,7 @@ 4.149 setViewModel(req, viewModel); 4.150 4.151 setContentPage(req, "issue-form"); 4.152 - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_ISSUE, selection)); 4.153 + setNavItems(req, getNavMenu(NAV_LEVEL_ISSUE, selection)); 4.154 return viewModel; 4.155 } 4.156 4.157 @@ -494,7 +494,7 @@ 4.158 } 4.159 setViewModel(req, viewModel); 4.160 4.161 - setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_ISSUE_LIST, selection)); 4.162 + setNavItems(req, getNavMenu(NAV_LEVEL_ISSUE_LIST, selection)); 4.163 setContentPage(req, "issues"); 4.164 setStylesheet(req, "projects"); 4.165 4.166 @@ -534,7 +534,7 @@ 4.167 getParameter(req, Integer[].class, "affected") 4.168 .map(Stream::of) 4.169 .map(stream -> 4.170 - stream.map(Version::new).collect(Collectors.toList()) 4.171 + stream.map(Version::new).collect(Collectors.toList()) 4.172 ).ifPresent(issue::setAffectedVersions); 4.173 getParameter(req, Integer[].class, "resolved") 4.174 .map(Stream::of) 4.175 @@ -544,8 +544,8 @@ 4.176 4.177 dao.getIssueDao().saveOrUpdate(issue); 4.178 4.179 - // specifying the issue parameter keeps the edited issue as breadcrumb 4.180 - setRedirectLocation(req, "./projects/issues/?issue="+issue.getId()); 4.181 + // specifying the issue parameter keeps the edited issue as menu item 4.182 + setRedirectLocation(req, "./projects/issues/?issue=" + issue.getId()); 4.183 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 4.184 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 4.185 // TODO: set request attribute with error text
5.1 --- a/src/main/webapp/WEB-INF/jsp/site.jsp Sun Jun 21 12:38:15 2020 +0200 5.2 +++ b/src/main/webapp/WEB-INF/jsp/site.jsp Sat Aug 22 16:25:03 2020 +0200 5.3 @@ -40,7 +40,7 @@ 5.4 <c:set scope="page" var="mainMenu" value="${requestScope[Constants.REQ_ATTR_MENU]}"/> 5.5 5.6 <%-- Define an alias for the main menu --%> 5.7 -<c:set scope="page" var="breadcrumbs" value="${requestScope[Constants.REQ_ATTR_BREADCRUMBS]}"/> 5.8 +<c:set scope="page" var="navMenu" value="${requestScope[Constants.REQ_ATTR_NAVIGATION]}"/> 5.9 5.10 <%-- Define an alias for the content page name --%> 5.11 <c:set scope="page" var="contentPage" value="${requestScope[Constants.REQ_ATTR_CONTENT_PAGE]}"/> 5.12 @@ -83,17 +83,19 @@ 5.13 <%@include file="../jspf/menu-entry.jsp" %> 5.14 </c:forEach> 5.15 </div> 5.16 -<c:if test="${not empty breadcrumbs}"> 5.17 - <div id="breadcrumbs"> 5.18 - <c:forEach var="menu" items="${breadcrumbs}"> 5.19 - <%@include file="../jspf/menu-entry.jsp" %> 5.20 - </c:forEach> 5.21 +<div> 5.22 + <c:if test="${not empty navMenu}"> 5.23 + <div id="sideMenu"> 5.24 + <c:forEach var="menu" items="${navMenu}"> 5.25 + <%@include file="../jspf/menu-entry.jsp" %> 5.26 + </c:forEach> 5.27 + </div> 5.28 + </c:if> 5.29 + <div id="content-area" <c:if test="${not empty navMenu}">class="sidebar-spacing"</c:if>> 5.30 + <c:if test="${not empty contentPage}"> 5.31 + <c:import url="${contentPage}"/> 5.32 + </c:if> 5.33 </div> 5.34 -</c:if> 5.35 -<div id="content-area"> 5.36 - <c:if test="${not empty contentPage}"> 5.37 - <c:import url="${contentPage}"/> 5.38 - </c:if> 5.39 </div> 5.40 </body> 5.41 </html>
6.1 --- a/src/main/webapp/lightpit.css Sun Jun 21 12:38:15 2020 +0200 6.2 +++ b/src/main/webapp/lightpit.css Sat Aug 22 16:25:03 2020 +0200 6.3 @@ -47,7 +47,7 @@ 6.4 text-decoration: none; 6.5 } 6.6 6.7 -#mainMenu, #breadcrumbs { 6.8 +#mainMenu { 6.9 width: 100%; 6.10 display: flex; 6.11 flex-flow: row wrap; 6.12 @@ -56,17 +56,32 @@ 6.13 border-bottom-style: solid; 6.14 border-bottom-width: 1pt; 6.15 } 6.16 +#sideMenu { 6.17 + display: flex; 6.18 + flex-flow: column; 6.19 + position: fixed; 6.20 + height: 100%; 6.21 + width: 20ch; 6.22 + border-image-source: linear-gradient(to bottom, #606060, rgba(60, 60, 60, .25)); 6.23 + border-image-slice: 1; 6.24 + border-right-style: solid; 6.25 + border-right-width: 1pt; 6.26 +} 6.27 + 6.28 +#content-area.sidebar-spacing { 6.29 + margin-left: 20ch; 6.30 +} 6.31 6.32 #mainMenu { 6.33 font-size: large; 6.34 background: #e0e0e5; 6.35 } 6.36 6.37 -#breadcrumbs { 6.38 +#sideMenu { 6.39 background: #f7f7ff; 6.40 } 6.41 6.42 -.menuEntry { 6.43 +#mainMenu .menuEntry { 6.44 padding: .25em 1em .25em 1em; 6.45 border-right-style: solid; 6.46 border-right-width: 1pt; 6.47 @@ -77,7 +92,7 @@ 6.48 background: #d0d0d5; 6.49 } 6.50 6.51 -#breadcrumbs .menuEntry[data-active] { 6.52 +#sideMenu .menuEntry[data-active] { 6.53 background: #e7e7ef 6.54 } 6.55