From 4b8822e5ad7cef7930699a226c165b4471d0bf8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Henke?= Date: Wed, 13 Sep 2023 09:18:04 +0200 Subject: [PATCH] theme persistence --- build.gradle | 4 +- .../timetrack/component/OAuth2Provider.java | 24 ++++++++ .../config/InitialConfiguration.java | 1 - .../timetrack/modules/IndexController.java | 11 +++- .../modules/calendar/CalendarController.java | 10 ++++ .../modules/contact/ContactController.java | 10 ++++ .../modules/done/DoneController.java | 38 +++++++----- .../modules/done/job/JobController.java | 19 ++++-- .../modules/done/module/ModuleController.java | 24 +++++--- .../done/project/ProjectController.java | 19 ++++-- .../modules/note/NoteController.java | 19 +++++- .../modules/profile/ProfileController.java | 31 ++++++++++ .../modules/profile/ProfileRepository.java | 58 +++++++++++++++++++ .../modules/profile/ProfileService.java | 24 ++++++++ src/main/resources/static/css/style.css | 19 ++++++ src/main/resources/static/js/helper.js | 7 +++ src/main/resources/templates/layout/main.html | 43 ++++++++------ 17 files changed, 303 insertions(+), 58 deletions(-) create mode 100644 src/main/java/de/jottyfan/timetrack/component/OAuth2Provider.java create mode 100644 src/main/java/de/jottyfan/timetrack/modules/profile/ProfileController.java create mode 100644 src/main/java/de/jottyfan/timetrack/modules/profile/ProfileRepository.java create mode 100644 src/main/java/de/jottyfan/timetrack/modules/profile/ProfileService.java diff --git a/build.gradle b/build.gradle index f138e13..d461334 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { apply plugin: 'io.spring.dependency-management' group = 'de.jottyfan' -version = '1.3.2' +version = '1.3.3' description = """timetrack""" @@ -47,7 +47,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' - implementation 'de.jottyfan:timetrackjooq:0.1.1' + implementation 'de.jottyfan:timetrackjooq:0.1.2' implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.2.1' diff --git a/src/main/java/de/jottyfan/timetrack/component/OAuth2Provider.java b/src/main/java/de/jottyfan/timetrack/component/OAuth2Provider.java new file mode 100644 index 0000000..8247796 --- /dev/null +++ b/src/main/java/de/jottyfan/timetrack/component/OAuth2Provider.java @@ -0,0 +1,24 @@ +package de.jottyfan.timetrack.component; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; + +/** + * + * @author jotty + * + */ +@Component +public class OAuth2Provider { + + /** + * get the name of the authenticated user or null if not logged in + * + * @return the name or null + */ + public String getName() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + return authentication == null ? null : authentication.getName(); + } +} diff --git a/src/main/java/de/jottyfan/timetrack/config/InitialConfiguration.java b/src/main/java/de/jottyfan/timetrack/config/InitialConfiguration.java index f1b60a2..8c865f9 100644 --- a/src/main/java/de/jottyfan/timetrack/config/InitialConfiguration.java +++ b/src/main/java/de/jottyfan/timetrack/config/InitialConfiguration.java @@ -47,7 +47,6 @@ public class InitialConfiguration { DefaultConfiguration jooqConfiguration = new DefaultConfiguration(); jooqConfiguration.set(connectionProvider()); jooqConfiguration.set(SQLDialect.POSTGRES); -// jooqConfiguration.set(new DefaultExecuteListenerProvider(exceptionTransformer())); return jooqConfiguration; } } diff --git a/src/main/java/de/jottyfan/timetrack/modules/IndexController.java b/src/main/java/de/jottyfan/timetrack/modules/IndexController.java index 97af106..9df1b39 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/IndexController.java +++ b/src/main/java/de/jottyfan/timetrack/modules/IndexController.java @@ -14,10 +14,12 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; +import de.jottyfan.timetrack.component.OAuth2Provider; import de.jottyfan.timetrack.modules.done.DoneBean; import de.jottyfan.timetrack.modules.done.DoneModel; import de.jottyfan.timetrack.modules.done.DoneService; import de.jottyfan.timetrack.modules.done.SummaryBean; +import de.jottyfan.timetrack.modules.profile.ProfileService; import jakarta.annotation.security.RolesAllowed; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -33,7 +35,13 @@ public class IndexController { @Autowired private DoneService doneService; + + @Autowired + private OAuth2Provider provider; + @Autowired + private ProfileService profileService; + @GetMapping("/logout") public String getLogout(HttpServletRequest request) throws ServletException { request.logout(); @@ -43,11 +51,12 @@ public class IndexController { @RolesAllowed("timetrack_user") @RequestMapping("/") public String getIndex(@ModelAttribute DoneModel doneModel, Model model, OAuth2AuthenticationToken token) { - String username = doneService.getCurrentUser(token); + String username = provider.getName(); Duration maxWorkTime = Duration.ofHours(8); // TODO: to the configuration file LocalDate day = LocalDate.now(); List list = doneService.getList(day, username); model.addAttribute("sum", new SummaryBean(list, day, maxWorkTime)); + model.addAttribute("theme", profileService.getTheme(username)); LOGGER.debug("sum = {}", model.getAttribute("sum")); return "public/index"; } diff --git a/src/main/java/de/jottyfan/timetrack/modules/calendar/CalendarController.java b/src/main/java/de/jottyfan/timetrack/modules/calendar/CalendarController.java index 89189b7..73370f0 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/calendar/CalendarController.java +++ b/src/main/java/de/jottyfan/timetrack/modules/calendar/CalendarController.java @@ -5,6 +5,9 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; +import de.jottyfan.timetrack.component.OAuth2Provider; +import de.jottyfan.timetrack.modules.profile.ProfileService; + /** * * @author jotty @@ -12,6 +15,12 @@ import org.springframework.web.bind.annotation.GetMapping; */ @Controller public class CalendarController { + + @Autowired + private OAuth2Provider provider; + + @Autowired + private ProfileService profileService; @Autowired private CalendarService service; @@ -19,6 +28,7 @@ public class CalendarController { @GetMapping("/calendar") public String getCalendar(Model model) { model.addAttribute("events", service.getJsonEvents()); + model.addAttribute("theme", profileService.getTheme(provider.getName())); return "/calendar/calendar"; } } diff --git a/src/main/java/de/jottyfan/timetrack/modules/contact/ContactController.java b/src/main/java/de/jottyfan/timetrack/modules/contact/ContactController.java index 9674cd1..b5c6c63 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/contact/ContactController.java +++ b/src/main/java/de/jottyfan/timetrack/modules/contact/ContactController.java @@ -14,7 +14,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; +import de.jottyfan.timetrack.component.OAuth2Provider; import de.jottyfan.timetrack.db.contact.enums.EnumContacttype; +import de.jottyfan.timetrack.modules.profile.ProfileService; import jakarta.annotation.security.RolesAllowed; /** @@ -25,6 +27,12 @@ import jakarta.annotation.security.RolesAllowed; @Controller public class ContactController { + @Autowired + private OAuth2Provider provider; + + @Autowired + private ProfileService profileService; + @Autowired private ContactService contactService; @@ -39,6 +47,7 @@ public class ContactController { public String getList(Model model) { List list = contactService.getList(); model.addAttribute("contactList", list); + model.addAttribute("theme", profileService.getTheme(provider.getName())); return "contact/list"; } @@ -57,6 +66,7 @@ public class ContactController { } model.addAttribute("contactBean", bean); model.addAttribute("types", Arrays.asList(EnumContacttype.values())); + model.addAttribute("theme", profileService.getTheme(provider.getName())); return "contact/item"; } diff --git a/src/main/java/de/jottyfan/timetrack/modules/done/DoneController.java b/src/main/java/de/jottyfan/timetrack/modules/done/DoneController.java index e348d07..2624b37 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/done/DoneController.java +++ b/src/main/java/de/jottyfan/timetrack/modules/done/DoneController.java @@ -6,7 +6,6 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -15,6 +14,8 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import de.jottyfan.timetrack.component.OAuth2Provider; +import de.jottyfan.timetrack.modules.profile.ProfileService; import jakarta.annotation.security.RolesAllowed; /** @@ -25,13 +26,19 @@ import jakarta.annotation.security.RolesAllowed; @Controller public class DoneController { + @Autowired + private OAuth2Provider provider; + + @Autowired + private ProfileService profileService; + @Autowired private DoneService doneService; @RolesAllowed("timetrack_user") @RequestMapping(value = "/done/list") - public String getList(@ModelAttribute DoneModel doneModel, Model model, OAuth2AuthenticationToken token) { - String username = doneService.getCurrentUser(token); + public String getList(@ModelAttribute DoneModel doneModel, Model model) { + String username = provider.getName(); Duration maxWorkTime = Duration.ofHours(8); // TODO: to the configuration file LocalDate day = doneModel.getDay(); List list = doneService.getList(day, username); @@ -46,15 +53,16 @@ public class DoneController { model.addAttribute("moduleList", doneService.getModules(false)); model.addAttribute("jobList", doneService.getJobs(false)); model.addAttribute("billingList", doneService.getBillings(false)); + model.addAttribute("theme", profileService.getTheme(username)); return "done/list"; } - + @RolesAllowed("timetrack_user") @GetMapping("/done/abort/{day}") - public String abort(@PathVariable String day, Model model, OAuth2AuthenticationToken token) { + public String abort(@PathVariable String day, Model model) { DoneModel doneModel = new DoneModel(); doneModel.setDayString(day); - return getList(doneModel, model, token); + return getList(doneModel, model); } @RolesAllowed("timetrack_user") @@ -66,6 +74,7 @@ public class DoneController { } private String toItem(DoneBean bean, Model model) { + String username = provider.getName(); DoneModel doneModel = new DoneModel(); doneModel.setDay(bean.getLocalDate()); model.addAttribute("doneBean", bean); @@ -74,11 +83,12 @@ public class DoneController { model.addAttribute("moduleList", doneService.getModules(true)); model.addAttribute("jobList", doneService.getJobs(true)); model.addAttribute("billingList", doneService.getBillings(true)); + model.addAttribute("theme", profileService.getTheme(username)); return "done/item"; } - + @RolesAllowed("timetrack_user") - @GetMapping("/done/edit/{id}") + @GetMapping("/done/edit/{id}") public String toItem(@PathVariable Integer id, Model model) { DoneBean bean = doneService.getBean(id); if (bean == null) { @@ -86,24 +96,24 @@ public class DoneController { } return toItem(bean, model); } - + @RolesAllowed("timetrack_user") @RequestMapping(value = "/done/upsert", method = RequestMethod.POST) - public String doUpsert(Model model, @ModelAttribute DoneBean bean, OAuth2AuthenticationToken token) { - String username = doneService.getCurrentUser(token); + public String doUpsert(Model model, @ModelAttribute DoneBean bean) { + String username = provider.getName(); Integer amount = doneService.doUpsert(bean, username); DoneModel doneModel = new DoneModel(); doneModel.setDay(bean.getLocalDate()); - return amount.equals(1) ? getList(doneModel, model, token) : toItem(bean.getPk(), model); + return amount.equals(1) ? getList(doneModel, model) : toItem(bean.getPk(), model); } @RolesAllowed("timetrack_user") @GetMapping(value = "/done/delete/{id}") - public String doDelete(@PathVariable Integer id, Model model, OAuth2AuthenticationToken token) { + public String doDelete(@PathVariable Integer id, Model model) { DoneBean bean = doneService.getBean(id); Integer amount = doneService.doDelete(id); DoneModel doneModel = new DoneModel(); doneModel.setDay(bean.getLocalDate()); - return amount.equals(1) ? getList(doneModel, model, token) : toItem(id, model); + return amount.equals(1) ? getList(doneModel, model) : toItem(id, model); } } diff --git a/src/main/java/de/jottyfan/timetrack/modules/done/job/JobController.java b/src/main/java/de/jottyfan/timetrack/modules/done/job/JobController.java index 4b67c12..7b08c78 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/done/job/JobController.java +++ b/src/main/java/de/jottyfan/timetrack/modules/done/job/JobController.java @@ -1,7 +1,6 @@ package de.jottyfan.timetrack.modules.done.job; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -10,9 +9,11 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import de.jottyfan.timetrack.component.OAuth2Provider; import de.jottyfan.timetrack.db.done.tables.records.TJobRecord; import de.jottyfan.timetrack.modules.done.DoneController; import de.jottyfan.timetrack.modules.done.DoneModel; +import de.jottyfan.timetrack.modules.profile.ProfileService; import jakarta.annotation.security.RolesAllowed; /** @@ -28,19 +29,27 @@ public class JobController { @Autowired private DoneController doneController; + @Autowired + private OAuth2Provider provider; + + @Autowired + private ProfileService profileService; + @RolesAllowed("timetrack_user") @GetMapping("/done/edit/job/{id}") public String toJob(@PathVariable Integer id, Model model) { + String username = provider.getName(); TJobRecord job = jobService.get(id); model.addAttribute("jobBean", job); + model.addAttribute("theme", profileService.getTheme(username)); return "done/job"; } @RolesAllowed("timetrack_user") @RequestMapping(value = "/done/upsert/job", method = RequestMethod.POST) - public String doUpsert(Model model, @ModelAttribute TJobRecord bean, OAuth2AuthenticationToken token) { + public String doUpsert(Model model, @ModelAttribute TJobRecord bean) { Integer amount = jobService.doUpsert(bean); - return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toJob(bean.getPk(), model); + return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toJob(bean.getPk(), model); } @RolesAllowed("timetrack_user") @@ -51,8 +60,8 @@ public class JobController { @RolesAllowed("timetrack_user") @GetMapping(value = "/done/delete/job/{id}") - public String doDeleteJob(@PathVariable Integer id, Model model, OAuth2AuthenticationToken token) { + public String doDeleteJob(@PathVariable Integer id, Model model) { Integer amount = jobService.doDelete(id); - return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toJob(id, model); + return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toJob(id, model); } } diff --git a/src/main/java/de/jottyfan/timetrack/modules/done/module/ModuleController.java b/src/main/java/de/jottyfan/timetrack/modules/done/module/ModuleController.java index 4ea8778..937da12 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/done/module/ModuleController.java +++ b/src/main/java/de/jottyfan/timetrack/modules/done/module/ModuleController.java @@ -1,11 +1,6 @@ package de.jottyfan.timetrack.modules.done.module; -import jakarta.annotation.security.RolesAllowed; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -14,9 +9,12 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import de.jottyfan.timetrack.component.OAuth2Provider; import de.jottyfan.timetrack.db.done.tables.records.TModuleRecord; import de.jottyfan.timetrack.modules.done.DoneController; import de.jottyfan.timetrack.modules.done.DoneModel; +import de.jottyfan.timetrack.modules.profile.ProfileService; +import jakarta.annotation.security.RolesAllowed; /** * @@ -32,19 +30,27 @@ public class ModuleController { @Autowired private DoneController doneController; + @Autowired + private OAuth2Provider provider; + + @Autowired + private ProfileService profileService; + @RolesAllowed("timetrack_user") @GetMapping("/done/edit/module/{id}") public String toModule(@PathVariable Integer id, Model model) { + String username = provider.getName(); TModuleRecord module = moduleService.get(id); model.addAttribute("moduleBean", module); + model.addAttribute("theme", profileService.getTheme(username)); return "done/module"; } @RolesAllowed("timetrack_user") @RequestMapping(value = "/done/upsert/module", method = RequestMethod.POST) - public String doUpsert(Model model, @ModelAttribute TModuleRecord bean, OAuth2AuthenticationToken token) { + public String doUpsert(Model model, @ModelAttribute TModuleRecord bean) { Integer amount = moduleService.doUpsert(bean); - return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toModule(bean.getPk(), model); + return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toModule(bean.getPk(), model); } @RolesAllowed("timetrack_user") @@ -55,8 +61,8 @@ public class ModuleController { @RolesAllowed("timetrack_user") @GetMapping(value = "/done/delete/module/{id}") - public String doDeleteModule(@PathVariable Integer id, Model model, OAuth2AuthenticationToken token) { + public String doDeleteModule(@PathVariable Integer id, Model model) { Integer amount = moduleService.doDelete(id); - return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toModule(id, model); + return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toModule(id, model); } } diff --git a/src/main/java/de/jottyfan/timetrack/modules/done/project/ProjectController.java b/src/main/java/de/jottyfan/timetrack/modules/done/project/ProjectController.java index cfe6929..0c434b3 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/done/project/ProjectController.java +++ b/src/main/java/de/jottyfan/timetrack/modules/done/project/ProjectController.java @@ -1,7 +1,6 @@ package de.jottyfan.timetrack.modules.done.project; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -10,9 +9,11 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import de.jottyfan.timetrack.component.OAuth2Provider; import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord; import de.jottyfan.timetrack.modules.done.DoneController; import de.jottyfan.timetrack.modules.done.DoneModel; +import de.jottyfan.timetrack.modules.profile.ProfileService; import jakarta.annotation.security.RolesAllowed; /** @@ -27,20 +28,28 @@ public class ProjectController { @Autowired private DoneController doneController; + + @Autowired + private OAuth2Provider provider; + @Autowired + private ProfileService profileService; + @RolesAllowed("timetrack_user") @GetMapping("/done/edit/project/{id}") public String toProject(@PathVariable Integer id, Model model) { + String username = provider.getName(); TProjectRecord project = projectService.get(id); model.addAttribute("projectBean", project); + model.addAttribute("theme", profileService.getTheme(username)); return "done/project"; } @RolesAllowed("timetrack_user") @RequestMapping(value = "/done/upsert/project", method = RequestMethod.POST) - public String doUpsert(Model model, @ModelAttribute TProjectRecord bean, OAuth2AuthenticationToken token) { + public String doUpsert(Model model, @ModelAttribute TProjectRecord bean) { Integer amount = projectService.doUpsert(bean); - return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toProject(bean.getPk(), model); + return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toProject(bean.getPk(), model); } @RolesAllowed("timetrack_user") @@ -51,8 +60,8 @@ public class ProjectController { @RolesAllowed("timetrack_user") @GetMapping(value = "/done/delete/project/{id}") - public String doDeleteProject(@PathVariable Integer id, Model model, OAuth2AuthenticationToken token) { + public String doDeleteProject(@PathVariable Integer id, Model model) { Integer amount = projectService.doDelete(id); - return amount.equals(1) ? doneController.getList(new DoneModel(), model, token) : toProject(id, model); + return amount.equals(1) ? doneController.getList(new DoneModel(), model) : toProject(id, model); } } diff --git a/src/main/java/de/jottyfan/timetrack/modules/note/NoteController.java b/src/main/java/de/jottyfan/timetrack/modules/note/NoteController.java index 3e71296..ef1b158 100644 --- a/src/main/java/de/jottyfan/timetrack/modules/note/NoteController.java +++ b/src/main/java/de/jottyfan/timetrack/modules/note/NoteController.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -12,8 +13,10 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import de.jottyfan.timetrack.component.OAuth2Provider; import de.jottyfan.timetrack.db.note.enums.EnumCategory; import de.jottyfan.timetrack.db.note.enums.EnumNotetype; +import de.jottyfan.timetrack.modules.profile.ProfileService; import jakarta.annotation.security.RolesAllowed; /** @@ -24,26 +27,35 @@ import jakarta.annotation.security.RolesAllowed; @Controller public class NoteController { + @Autowired + private OAuth2Provider provider; + + @Autowired + private ProfileService profileService; + @Autowired private NoteService noteService; @RolesAllowed("timetrack_user") @RequestMapping(value = "/note/list") public String getList(Model model) { + String username = provider.getName(); List list = noteService.getList(); model.addAttribute("noteList", list); + model.addAttribute("theme", profileService.getTheme(username)); return "note/list"; } @RolesAllowed("timetrack_user") @RequestMapping(value = "/note/add", method = RequestMethod.GET) - public String toAdd(Model model) { + public String toAdd(Model model, OAuth2AuthenticationToken token) { return toItem(null, model); } @RolesAllowed("timetrack_user") @GetMapping("/note/edit/{id}") public String toItem(@PathVariable Integer id, Model model) { + String username = provider.getName(); NoteBean bean = noteService.getBean(id); if (bean == null) { bean = new NoteBean(); // the add case @@ -51,19 +63,20 @@ public class NoteController { model.addAttribute("noteBean", bean); model.addAttribute("types", Arrays.asList(EnumNotetype.values())); model.addAttribute("categories", Arrays.asList(EnumCategory.values())); + model.addAttribute("theme", profileService.getTheme(username)); return "note/item"; } @RolesAllowed("timetrack_user") @RequestMapping(value = "/note/upsert", method = RequestMethod.POST) - public String doUpsert(Model model, @ModelAttribute NoteBean bean) { + public String doUpsert(Model model, @ModelAttribute NoteBean bean, OAuth2AuthenticationToken token) { Integer amount = noteService.doUpsert(bean); return amount.equals(1) ? getList(model) : toItem(bean.getPk(), model); } @RolesAllowed("timetrack_user") @GetMapping(value = "/note/delete/{id}") - public String doDelete(@PathVariable Integer id, Model model) { + public String doDelete(@PathVariable Integer id, Model model, OAuth2AuthenticationToken token) { Integer amount = noteService.doDelete(id); return amount.equals(1) ? getList(model) : toItem(id, model); } diff --git a/src/main/java/de/jottyfan/timetrack/modules/profile/ProfileController.java b/src/main/java/de/jottyfan/timetrack/modules/profile/ProfileController.java new file mode 100644 index 0000000..8ab3c18 --- /dev/null +++ b/src/main/java/de/jottyfan/timetrack/modules/profile/ProfileController.java @@ -0,0 +1,31 @@ +package de.jottyfan.timetrack.modules.profile; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import de.jottyfan.timetrack.component.OAuth2Provider; + +/** + * + * @author jotty + * + */ +@Controller +public class ProfileController { + + @Autowired + private OAuth2Provider provider; + + @Autowired + private ProfileService service; + + @RequestMapping(value = "/profile/{theme}", method = RequestMethod.POST) + public String setTheme(@PathVariable String theme) { + String username = provider.getName(); + service.setTheme(username, theme); + return "redirect:/"; + } +} diff --git a/src/main/java/de/jottyfan/timetrack/modules/profile/ProfileRepository.java b/src/main/java/de/jottyfan/timetrack/modules/profile/ProfileRepository.java new file mode 100644 index 0000000..525c659 --- /dev/null +++ b/src/main/java/de/jottyfan/timetrack/modules/profile/ProfileRepository.java @@ -0,0 +1,58 @@ +package de.jottyfan.timetrack.modules.profile; + +import static de.jottyfan.timetrack.db.profile.Tables.T_PROFILE; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jooq.DSLContext; +import org.jooq.InsertOnDuplicateSetMoreStep; +import org.jooq.Record1; +import org.jooq.SelectConditionStep; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import de.jottyfan.timetrack.db.profile.tables.records.TProfileRecord; + +/** + * + * @author jotty + * + */ +@Repository +public class ProfileRepository { + private static final Logger LOGGER = LogManager.getLogger(ProfileRepository.class); + + @Autowired + private DSLContext jooq; + + public void setTheme(String username, String theme) { + InsertOnDuplicateSetMoreStep sql = jooq + // @formatter:off + .insertInto(T_PROFILE, + T_PROFILE.USERNAME, + T_PROFILE.THEME) + .values(username, theme) + .onConflict(T_PROFILE.USERNAME) + .doUpdate() + .set(T_PROFILE.THEME, theme); + // @formatter:on + LOGGER.trace(sql.toString()); + sql.execute(); + } + + public String getTheme(String username) { + SelectConditionStep> sql = jooq + // @formatter:off + .select(T_PROFILE.THEME) + .from(T_PROFILE) + .where(T_PROFILE.USERNAME.eq(username)); + // @formatter:on + LOGGER.trace(sql.toString()); + Record1 res = sql.fetchOne(); + if (res == null) { + return "light"; // default + } else { + return res.get(T_PROFILE.THEME); + } + } +} diff --git a/src/main/java/de/jottyfan/timetrack/modules/profile/ProfileService.java b/src/main/java/de/jottyfan/timetrack/modules/profile/ProfileService.java new file mode 100644 index 0000000..8380211 --- /dev/null +++ b/src/main/java/de/jottyfan/timetrack/modules/profile/ProfileService.java @@ -0,0 +1,24 @@ +package de.jottyfan.timetrack.modules.profile; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * @author jotty + * + */ +@Service +public class ProfileService { + + @Autowired + private ProfileRepository repository; + + public void setTheme(String username, String theme) { + repository.setTheme(username, theme); + } + + public String getTheme(String username) { + return username == null ? "light" : repository.getTheme(username); + } +} diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index a752a1a..a6abf0b 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -172,18 +172,37 @@ body { background: radial-gradient(#ffff00, #ffe169) !important; } +[data-bs-theme="dark"] .WP2 { + color: black !important; +} + .WP4 { + color: black; background: radial-gradient(#00ffff, #69c3ff) !important; } +[data-bs-theme="dark"] .WP4 { + color: black !important; +} + .WP5 { + color: black; background: radial-gradient(#ff0000, #e396ff) !important; } +[data-bs-theme="dark"] .WP5 { + color: black !important; +} + .TA3 { + color: black; background: radial-gradient(#99ff99, #ccffcc) !important; } +[data-bs-theme="dark"] .TA3 { + color: black !important; +} + .left { text-align: left; } diff --git a/src/main/resources/static/js/helper.js b/src/main/resources/static/js/helper.js index 74b8502..ee7ba27 100644 --- a/src/main/resources/static/js/helper.js +++ b/src/main/resources/static/js/helper.js @@ -2,6 +2,13 @@ toggleTheme = function() { var oldValue = $("html").attr("data-bs-theme"); var newValue = oldValue == "dark" ? "light" : "dark"; $("html").attr("data-bs-theme", newValue); + var url = "profile/" + newValue; + $.ajax({ + url: url, + dataType: 'json', + type: "POST", + contentType: 'application/json' + }); } resetValue = function(selector, value) { diff --git a/src/main/resources/templates/layout/main.html b/src/main/resources/templates/layout/main.html index ce20792..a21613c 100644 --- a/src/main/resources/templates/layout/main.html +++ b/src/main/resources/templates/layout/main.html @@ -52,24 +52,31 @@