200 protected String getResourceBundleName() { |
200 protected String getResourceBundleName() { |
201 return "localization.projects"; |
201 return "localization.projects"; |
202 } |
202 } |
203 |
203 |
204 |
204 |
205 private static final int BREADCRUMB_LEVEL_ROOT = 0; |
205 private static final int NAV_LEVEL_ROOT = 0; |
206 private static final int BREADCRUMB_LEVEL_PROJECT = 1; |
206 private static final int NAV_LEVEL_PROJECT = 1; |
207 private static final int BREADCRUMB_LEVEL_VERSION = 2; |
207 private static final int NAV_LEVEL_VERSION = 2; |
208 private static final int BREADCRUMB_LEVEL_ISSUE_LIST = 3; |
208 private static final int NAV_LEVEL_ISSUE_LIST = 3; |
209 private static final int BREADCRUMB_LEVEL_ISSUE = 4; |
209 private static final int NAV_LEVEL_ISSUE = 4; |
210 |
210 |
211 /** |
211 /** |
212 * Creates the breadcrumb menu. |
212 * Creates the navigation menu. |
213 * |
213 * |
214 * @param level the current active level (0: root, 1: project, 2: version, 3: issue list, 4: issue) |
214 * @param level the current active level (0: root, 1: project, 2: version, 3: issue list, 4: issue) |
215 * @param selection the currently selected objects |
215 * @param selection the currently selected objects |
216 * @return a dynamic breadcrumb menu trying to display as many levels as possible |
216 * @return a dynamic navigation menu trying to display as many levels as possible |
217 */ |
217 */ |
218 private List<MenuEntry> getBreadcrumbs(int level, SessionSelection selection) { |
218 private List<MenuEntry> getNavMenu(int level, SessionSelection selection) { |
219 MenuEntry entry; |
219 MenuEntry entry; |
220 |
220 |
221 final var breadcrumbs = new ArrayList<MenuEntry>(); |
221 final var navigation = new ArrayList<MenuEntry>(); |
222 entry = new MenuEntry(new ResourceKey("localization.lightpit", "menu.projects"), |
222 entry = new MenuEntry(new ResourceKey("localization.lightpit", "menu.projects"), |
223 "projects/"); |
223 "projects/"); |
224 breadcrumbs.add(entry); |
224 navigation.add(entry); |
225 if (level == BREADCRUMB_LEVEL_ROOT) entry.setActive(true); |
225 if (level == NAV_LEVEL_ROOT) entry.setActive(true); |
226 |
226 |
227 if (selection.project != null) { |
227 if (selection.project != null) { |
228 if (selection.project.getId() < 0) { |
228 if (selection.project.getId() < 0) { |
229 entry = new MenuEntry(new ResourceKey("localization.projects", "button.create"), |
229 entry = new MenuEntry(new ResourceKey("localization.projects", "button.create"), |
230 "projects/edit"); |
230 "projects/edit"); |
231 } else { |
231 } else { |
232 entry = new MenuEntry(selection.project.getName(), |
232 entry = new MenuEntry(selection.project.getName(), |
233 "projects/view?pid=" + selection.project.getId()); |
233 "projects/view?pid=" + selection.project.getId()); |
234 } |
234 } |
235 if (level == BREADCRUMB_LEVEL_PROJECT) entry.setActive(true); |
235 if (level == NAV_LEVEL_PROJECT) entry.setActive(true); |
236 breadcrumbs.add(entry); |
236 navigation.add(entry); |
237 } |
237 } |
238 |
238 |
239 if (selection.version != null) { |
239 if (selection.version != null) { |
240 if (selection.version.getId() < 0) { |
240 if (selection.version.getId() < 0) { |
241 entry = new MenuEntry(new ResourceKey("localization.projects", "button.version.create"), |
241 entry = new MenuEntry(new ResourceKey("localization.projects", "button.version.create"), |
242 "projects/versions/edit"); |
242 "projects/versions/edit"); |
243 } else { |
243 } else { |
244 entry = new MenuEntry(selection.version.getName(), |
244 entry = new MenuEntry(selection.version.getName(), |
245 "projects/versions/view?vid=" + selection.version.getId()); |
245 "projects/versions/view?vid=" + selection.version.getId()); |
246 } |
246 } |
247 if (level == BREADCRUMB_LEVEL_VERSION) entry.setActive(true); |
247 if (level == NAV_LEVEL_VERSION) entry.setActive(true); |
248 breadcrumbs.add(entry); |
248 navigation.add(entry); |
249 } |
249 } |
250 |
250 |
251 if (selection.project != null) { |
251 if (selection.project != null) { |
252 String path = "projects/issues/?pid=" + selection.project.getId(); |
252 String path = "projects/issues/?pid=" + selection.project.getId(); |
253 if (selection.version != null) { |
253 if (selection.version != null) { |
254 path += "&vid="+selection.version.getId(); |
254 path += "&vid=" + selection.version.getId(); |
255 } |
255 } |
256 entry = new MenuEntry(new ResourceKey("localization.projects", "menu.issues"), |
256 entry = new MenuEntry(new ResourceKey("localization.projects", "menu.issues"), |
257 path); |
257 path); |
258 if (level == BREADCRUMB_LEVEL_ISSUE_LIST) entry.setActive(true); |
258 if (level == NAV_LEVEL_ISSUE_LIST) entry.setActive(true); |
259 breadcrumbs.add(entry); |
259 navigation.add(entry); |
260 } |
260 } |
261 |
261 |
262 if (selection.issue != null) { |
262 if (selection.issue != null) { |
263 if (selection.issue.getId() < 0) { |
263 if (selection.issue.getId() < 0) { |
264 entry = new MenuEntry(new ResourceKey("localization.projects", "button.issue.create"), |
264 entry = new MenuEntry(new ResourceKey("localization.projects", "button.issue.create"), |
295 |
295 |
296 setViewModel(req, viewModel); |
296 setViewModel(req, viewModel); |
297 setContentPage(req, "projects"); |
297 setContentPage(req, "projects"); |
298 setStylesheet(req, "projects"); |
298 setStylesheet(req, "projects"); |
299 |
299 |
300 setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_ROOT, sessionSelection)); |
300 setNavItems(req, getNavMenu(NAV_LEVEL_ROOT, sessionSelection)); |
301 |
301 |
302 return ResponseType.HTML; |
302 return ResponseType.HTML; |
303 } |
303 } |
304 |
304 |
305 private ProjectEditView configureEditForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { |
305 private ProjectEditView configureEditForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { |
306 final var viewModel = new ProjectEditView(); |
306 final var viewModel = new ProjectEditView(); |
307 viewModel.setProject(selection.project); |
307 viewModel.setProject(selection.project); |
308 viewModel.setUsers(dao.getUserDao().list()); |
308 viewModel.setUsers(dao.getUserDao().list()); |
309 setViewModel(req, viewModel); |
309 setViewModel(req, viewModel); |
310 setContentPage(req, "project-form"); |
310 setContentPage(req, "project-form"); |
311 setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_PROJECT, selection)); |
311 setNavItems(req, getNavMenu(NAV_LEVEL_PROJECT, selection)); |
312 return viewModel; |
312 return viewModel; |
313 } |
313 } |
314 |
314 |
315 @RequestMapping(requestPath = "edit", method = HttpMethod.GET) |
315 @RequestMapping(requestPath = "edit", method = HttpMethod.GET) |
316 public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
316 public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
398 final var issues = issueDao.list(selection.version); |
398 final var issues = issueDao.list(selection.version); |
399 for (var issue : issues) issueDao.joinVersionInformation(issue); |
399 for (var issue : issues) issueDao.joinVersionInformation(issue); |
400 viewModel.setIssues(issues); |
400 viewModel.setIssues(issues); |
401 setViewModel(req, viewModel); |
401 setViewModel(req, viewModel); |
402 |
402 |
403 setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_VERSION, selection)); |
403 setNavItems(req, getNavMenu(NAV_LEVEL_VERSION, selection)); |
404 setContentPage(req, "version"); |
404 setContentPage(req, "version"); |
405 setStylesheet(req, "projects"); |
405 setStylesheet(req, "projects"); |
406 |
406 |
407 return ResponseType.HTML; |
407 return ResponseType.HTML; |
408 } |
408 } |
412 if (selection.version.getProject() == null) { |
412 if (selection.version.getProject() == null) { |
413 viewModel.setProjects(dao.getProjectDao().list()); |
413 viewModel.setProjects(dao.getProjectDao().list()); |
414 } |
414 } |
415 setViewModel(req, viewModel); |
415 setViewModel(req, viewModel); |
416 setContentPage(req, "version-form"); |
416 setContentPage(req, "version-form"); |
417 setBreadcrumbs(req, getBreadcrumbs(BREADCRUMB_LEVEL_VERSION, selection)); |
417 setNavItems(req, getNavMenu(NAV_LEVEL_VERSION, selection)); |
418 return viewModel; |
418 return viewModel; |
419 } |
419 } |
420 |
420 |
421 @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET) |
421 @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET) |
422 public ResponseType editVersion(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
422 public ResponseType editVersion(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
443 getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal); |
443 getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal); |
444 version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow())); |
444 version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow())); |
445 dao.getVersionDao().saveOrUpdate(version); |
445 dao.getVersionDao().saveOrUpdate(version); |
446 |
446 |
447 // specifying the pid parameter will purposely reset the session selected version! |
447 // specifying the pid parameter will purposely reset the session selected version! |
448 setRedirectLocation(req, "./projects/view?pid="+version.getProject().getId()); |
448 setRedirectLocation(req, "./projects/view?pid=" + version.getProject().getId()); |
449 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
449 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
450 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { |
450 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { |
451 LOG.warn("Form validation failure: {}", ex.getMessage()); |
451 LOG.warn("Form validation failure: {}", ex.getMessage()); |
452 LOG.debug("Details:", ex); |
452 LOG.debug("Details:", ex); |
453 final var selection = new SessionSelection(req, dao); |
453 final var selection = new SessionSelection(req, dao); |
532 getParameter(req, Date.class, "eta").ifPresent(issue::setEta); |
532 getParameter(req, Date.class, "eta").ifPresent(issue::setEta); |
533 |
533 |
534 getParameter(req, Integer[].class, "affected") |
534 getParameter(req, Integer[].class, "affected") |
535 .map(Stream::of) |
535 .map(Stream::of) |
536 .map(stream -> |
536 .map(stream -> |
537 stream.map(Version::new).collect(Collectors.toList()) |
537 stream.map(Version::new).collect(Collectors.toList()) |
538 ).ifPresent(issue::setAffectedVersions); |
538 ).ifPresent(issue::setAffectedVersions); |
539 getParameter(req, Integer[].class, "resolved") |
539 getParameter(req, Integer[].class, "resolved") |
540 .map(Stream::of) |
540 .map(Stream::of) |
541 .map(stream -> |
541 .map(stream -> |
542 stream.map(Version::new).collect(Collectors.toList()) |
542 stream.map(Version::new).collect(Collectors.toList()) |
543 ).ifPresent(issue::setResolvedVersions); |
543 ).ifPresent(issue::setResolvedVersions); |
544 |
544 |
545 dao.getIssueDao().saveOrUpdate(issue); |
545 dao.getIssueDao().saveOrUpdate(issue); |
546 |
546 |
547 // specifying the issue parameter keeps the edited issue as breadcrumb |
547 // specifying the issue parameter keeps the edited issue as menu item |
548 setRedirectLocation(req, "./projects/issues/?issue="+issue.getId()); |
548 setRedirectLocation(req, "./projects/issues/?issue=" + issue.getId()); |
549 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
549 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
550 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { |
550 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { |
551 // TODO: set request attribute with error text |
551 // TODO: set request attribute with error text |
552 LOG.warn("Form validation failure: {}", ex.getMessage()); |
552 LOG.warn("Form validation failure: {}", ex.getMessage()); |
553 LOG.debug("Details:", ex); |
553 LOG.debug("Details:", ex); |