199 @Override |
204 @Override |
200 protected String getResourceBundleName() { |
205 protected String getResourceBundleName() { |
201 return "localization.projects"; |
206 return "localization.projects"; |
202 } |
207 } |
203 |
208 |
204 |
209 private String queryParams(Project p, Version v, Issue i) { |
205 private static final int NAV_LEVEL_ROOT = 0; |
210 return String.format("pid=%d&vid=%d&issue=%d", |
206 private static final int NAV_LEVEL_PROJECT = 1; |
211 p == null ? -1 : p.getId(), |
207 private static final int NAV_LEVEL_VERSION = 2; |
212 v == null ? -1 : v.getId(), |
208 private static final int NAV_LEVEL_ISSUE_LIST = 3; |
213 i == null ? -1 : i.getId() |
209 private static final int NAV_LEVEL_ISSUE = 4; |
214 ); |
|
215 } |
210 |
216 |
211 /** |
217 /** |
212 * Creates the navigation menu. |
218 * Creates the navigation menu. |
213 * |
219 * |
214 * @param level the current active level (0: root, 1: project, 2: version, 3: issue list, 4: issue) |
220 * @param projects the list of projects |
215 * @param selection the currently selected objects |
221 * @param selection the currently selected objects |
|
222 * @param projInfo info about the currently selected project or null |
216 * @return a dynamic navigation menu trying to display as many levels as possible |
223 * @return a dynamic navigation menu trying to display as many levels as possible |
217 */ |
224 */ |
218 private List<MenuEntry> getNavMenu(int level, SessionSelection selection) { |
225 private List<MenuEntry> getNavMenu(List<Project> projects, SessionSelection selection, ProjectInfo projInfo) { |
219 MenuEntry entry; |
|
220 |
|
221 final var navigation = new ArrayList<MenuEntry>(); |
226 final var navigation = new ArrayList<MenuEntry>(); |
222 entry = new MenuEntry(new ResourceKey("localization.lightpit", "menu.projects"), |
227 |
223 "projects/"); |
228 for (Project proj : projects) { |
224 navigation.add(entry); |
229 final var projEntry = new MenuEntry( |
225 if (level == NAV_LEVEL_ROOT) entry.setActive(true); |
230 proj.getName(), |
226 |
231 "projects/view?pid=" + proj.getId() |
227 if (selection.project != null) { |
232 ); |
228 if (selection.project.getId() < 0) { |
233 navigation.add(projEntry); |
229 entry = new MenuEntry(new ResourceKey("localization.projects", "button.create"), |
234 if (proj.equals(selection.project)) { |
230 "projects/edit"); |
235 projEntry.setActive(true); |
231 } else { |
236 |
232 entry = new MenuEntry(selection.project.getName(), |
237 // **************** |
233 "projects/view?pid=" + selection.project.getId()); |
238 // Versions Section |
234 } |
239 // **************** |
235 if (level == NAV_LEVEL_PROJECT) entry.setActive(true); |
240 { |
236 navigation.add(entry); |
241 final var entry = new MenuEntry(1, |
237 } |
242 new ResourceKey("localization.projects", "menu.versions"), |
238 |
243 "projects/view?" + queryParams(proj, null, null) |
239 if (selection.version != null) { |
244 ); |
240 if (selection.version.getId() < 0) { |
245 navigation.add(entry); |
241 entry = new MenuEntry(new ResourceKey("localization.projects", "button.version.create"), |
246 } |
242 "projects/versions/edit"); |
247 |
243 } else { |
248 final var level2 = new ArrayList<MenuEntry>(); |
244 entry = new MenuEntry(selection.version.getName(), |
249 { |
245 "projects/versions/view?vid=" + selection.version.getId()); |
250 final var entry = new MenuEntry( |
246 } |
251 new ResourceKey("localization.projects", "filter.all"), |
247 if (level == NAV_LEVEL_VERSION) entry.setActive(true); |
252 "projects/view?" + queryParams(proj, null, null) |
248 navigation.add(entry); |
253 ); |
249 } |
254 if (selection.version == null) entry.setActive(true); |
250 |
255 level2.add(entry); |
251 if (selection.project != null) { |
256 } |
252 String path = "projects/issues/?pid=" + selection.project.getId(); |
257 |
253 if (selection.version != null) { |
258 for (Version version : projInfo.getVersions()) { |
254 path += "&vid=" + selection.version.getId(); |
259 final var entry = new MenuEntry( |
255 } |
260 version.getName(), |
256 entry = new MenuEntry(new ResourceKey("localization.projects", "menu.issues"), |
261 "projects/versions/view?" + queryParams(proj, version, null) |
257 path); |
262 ); |
258 if (level == NAV_LEVEL_ISSUE_LIST) entry.setActive(true); |
263 if (version.equals(selection.version)) entry.setActive(true); |
259 navigation.add(entry); |
264 level2.add(entry); |
260 } |
265 } |
261 |
266 |
262 if (selection.issue != null) { |
267 level2.forEach(e -> e.setLevel(2)); |
263 if (selection.issue.getId() < 0) { |
268 navigation.addAll(level2); |
264 entry = new MenuEntry(new ResourceKey("localization.projects", "button.issue.create"), |
269 } |
265 "projects/issues/edit"); |
|
266 } else { |
|
267 entry = new MenuEntry("#" + selection.issue.getId(), |
|
268 // TODO: maybe change link to a view rather than directly opening the editor |
|
269 "projects/issues/edit?issue=" + selection.issue.getId()); |
|
270 } |
|
271 if (level == NAV_LEVEL_ISSUE) entry.setActive(true); |
|
272 navigation.add(entry); |
|
273 } |
270 } |
274 |
271 |
275 return navigation; |
272 return navigation; |
276 } |
273 } |
277 |
274 |
295 |
292 |
296 setViewModel(req, viewModel); |
293 setViewModel(req, viewModel); |
297 setContentPage(req, "projects"); |
294 setContentPage(req, "projects"); |
298 setStylesheet(req, "projects"); |
295 setStylesheet(req, "projects"); |
299 |
296 |
300 setNavItems(req, getNavMenu(NAV_LEVEL_ROOT, sessionSelection)); |
297 setNavigationMenu(req, getNavMenu(projectList, sessionSelection, currentProjectInfo(dao, sessionSelection.project))); |
301 |
298 |
302 return ResponseType.HTML; |
299 return ResponseType.HTML; |
|
300 } |
|
301 |
|
302 private ProjectInfo currentProjectInfo(DataAccessObjects dao, Project project) throws SQLException { |
|
303 if (project == null) return null; |
|
304 final var projectDao = dao.getProjectDao(); |
|
305 final var versionDao = dao.getVersionDao(); |
|
306 |
|
307 final var info = new ProjectInfo(project); |
|
308 info.setVersions(versionDao.list(project)); |
|
309 info.setIssueSummary(projectDao.getIssueSummary(project)); |
|
310 return info; |
303 } |
311 } |
304 |
312 |
305 private ProjectEditView configureEditForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { |
313 private ProjectEditView configureEditForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { |
306 final var viewModel = new ProjectEditView(); |
314 final var viewModel = new ProjectEditView(); |
307 viewModel.setProject(selection.project); |
315 viewModel.setProject(selection.project); |
308 viewModel.setUsers(dao.getUserDao().list()); |
316 viewModel.setUsers(dao.getUserDao().list()); |
|
317 setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project))); |
309 setViewModel(req, viewModel); |
318 setViewModel(req, viewModel); |
310 setContentPage(req, "project-form"); |
319 setContentPage(req, "project-form"); |
311 setNavItems(req, getNavMenu(NAV_LEVEL_PROJECT, selection)); |
|
312 return viewModel; |
320 return viewModel; |
313 } |
321 } |
314 |
322 |
315 @RequestMapping(requestPath = "edit", method = HttpMethod.GET) |
323 @RequestMapping(requestPath = "edit", method = HttpMethod.GET) |
316 public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
324 public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
364 if (selection.project == null) { |
372 if (selection.project == null) { |
365 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); |
373 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); |
366 return ResponseType.NONE; |
374 return ResponseType.NONE; |
367 } |
375 } |
368 |
376 |
|
377 final var projectDao = dao.getProjectDao(); |
369 final var versionDao = dao.getVersionDao(); |
378 final var versionDao = dao.getVersionDao(); |
370 final var issueDao = dao.getIssueDao(); |
379 final var issueDao = dao.getIssueDao(); |
371 |
380 |
372 final var viewModel = new ProjectView(selection.project); |
381 final var viewModel = new ProjectView(selection.project); |
373 final var issues = issueDao.list(selection.project); |
382 final var issues = issueDao.list(selection.project); |
374 for (var issue : issues) issueDao.joinVersionInformation(issue); |
383 for (var issue : issues) issueDao.joinVersionInformation(issue); |
375 viewModel.setIssues(issues); |
384 viewModel.setIssues(issues); |
|
385 // TODO: fix duplicated selection of versions (projectInfo also contains these infos) |
376 viewModel.setVersions(versionDao.list(selection.project)); |
386 viewModel.setVersions(versionDao.list(selection.project)); |
377 viewModel.updateVersionInfo(); |
387 viewModel.updateVersionInfo(); |
378 setViewModel(req, viewModel); |
388 setViewModel(req, viewModel); |
379 |
389 |
380 setNavItems(req, getNavMenu(NAV_LEVEL_PROJECT, selection)); |
390 setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project))); |
381 setContentPage(req, "project-details"); |
391 setContentPage(req, "project-details"); |
382 setStylesheet(req, "projects"); |
392 setStylesheet(req, "projects"); |
383 |
393 |
384 return ResponseType.HTML; |
394 return ResponseType.HTML; |
385 } |
395 } |
391 if (selection.version == null) { |
401 if (selection.version == null) { |
392 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
402 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
393 return ResponseType.NONE; |
403 return ResponseType.NONE; |
394 } |
404 } |
395 |
405 |
|
406 final var projectDao = dao.getProjectDao(); |
396 final var issueDao = dao.getIssueDao(); |
407 final var issueDao = dao.getIssueDao(); |
|
408 |
397 final var viewModel = new VersionView(selection.version); |
409 final var viewModel = new VersionView(selection.version); |
398 final var issues = issueDao.list(selection.version); |
410 final var issues = issueDao.list(selection.version); |
399 for (var issue : issues) issueDao.joinVersionInformation(issue); |
411 for (var issue : issues) issueDao.joinVersionInformation(issue); |
400 viewModel.setIssues(issues); |
412 viewModel.setIssues(issues); |
401 setViewModel(req, viewModel); |
413 setViewModel(req, viewModel); |
402 |
414 |
403 setNavItems(req, getNavMenu(NAV_LEVEL_VERSION, selection)); |
415 setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project))); |
404 setContentPage(req, "version"); |
416 setContentPage(req, "version"); |
405 setStylesheet(req, "projects"); |
417 setStylesheet(req, "projects"); |
406 |
418 |
407 return ResponseType.HTML; |
419 return ResponseType.HTML; |
408 } |
420 } |
412 if (selection.version.getProject() == null) { |
424 if (selection.version.getProject() == null) { |
413 viewModel.setProjects(dao.getProjectDao().list()); |
425 viewModel.setProjects(dao.getProjectDao().list()); |
414 } |
426 } |
415 setViewModel(req, viewModel); |
427 setViewModel(req, viewModel); |
416 setContentPage(req, "version-form"); |
428 setContentPage(req, "version-form"); |
417 setNavItems(req, getNavMenu(NAV_LEVEL_VERSION, selection)); |
429 setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project))); |
418 return viewModel; |
430 return viewModel; |
419 } |
431 } |
420 |
432 |
421 @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET) |
433 @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET) |
422 public ResponseType editVersion(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
434 public ResponseType editVersion(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
469 } |
481 } |
470 viewModel.setUsers(dao.getUserDao().list()); |
482 viewModel.setUsers(dao.getUserDao().list()); |
471 setViewModel(req, viewModel); |
483 setViewModel(req, viewModel); |
472 |
484 |
473 setContentPage(req, "issue-form"); |
485 setContentPage(req, "issue-form"); |
474 setNavItems(req, getNavMenu(NAV_LEVEL_ISSUE, selection)); |
486 setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project))); |
475 return viewModel; |
487 return viewModel; |
476 } |
488 } |
477 |
489 |
478 @RequestMapping(requestPath = "issues/", method = HttpMethod.GET) |
490 @RequestMapping(requestPath = "issues/", method = HttpMethod.GET) |
479 public ResponseType issues(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { |
491 public ResponseType issues(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { |
482 if (selection.project == null) { |
494 if (selection.project == null) { |
483 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); |
495 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); |
484 return ResponseType.NONE; |
496 return ResponseType.NONE; |
485 } |
497 } |
486 |
498 |
|
499 final var projectDao = dao.getProjectDao(); |
|
500 final var issueDao = dao.getIssueDao(); |
|
501 |
487 final var viewModel = new IssuesView(); |
502 final var viewModel = new IssuesView(); |
488 viewModel.setProject(selection.project); |
503 viewModel.setProject(selection.project); |
489 if (selection.version == null) { |
504 if (selection.version == null) { |
490 viewModel.setIssues(dao.getIssueDao().list(selection.project)); |
505 viewModel.setIssues(issueDao.list(selection.project)); |
491 } else { |
506 } else { |
492 viewModel.setVersion(selection.version); |
507 viewModel.setVersion(selection.version); |
493 viewModel.setIssues(dao.getIssueDao().list(selection.version)); |
508 viewModel.setIssues(issueDao.list(selection.version)); |
494 } |
509 } |
495 setViewModel(req, viewModel); |
510 setViewModel(req, viewModel); |
496 |
511 |
497 setNavItems(req, getNavMenu(NAV_LEVEL_ISSUE_LIST, selection)); |
512 setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project))); |
498 setContentPage(req, "issues"); |
513 setContentPage(req, "issues"); |
499 setStylesheet(req, "projects"); |
514 setStylesheet(req, "projects"); |
500 |
515 |
501 return ResponseType.HTML; |
516 return ResponseType.HTML; |
502 } |
517 } |