diff --git a/src/main/java/com/primefactorsolutions/model/AppUser.java b/src/main/java/com/primefactorsolutions/model/AppUser.java index 73dc753..83707de 100644 --- a/src/main/java/com/primefactorsolutions/model/AppUser.java +++ b/src/main/java/com/primefactorsolutions/model/AppUser.java @@ -1,8 +1,6 @@ package com.primefactorsolutions.model; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.OneToMany; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -16,6 +14,7 @@ import java.util.List; @NoArgsConstructor @EqualsAndHashCode(callSuper = true) public class AppUser extends BaseEntity { + @Column(unique = true) private String email; @OneToMany(fetch = FetchType.EAGER, mappedBy = "appUser") diff --git a/src/main/java/com/primefactorsolutions/model/Question.java b/src/main/java/com/primefactorsolutions/model/Question.java index 4523e3c..0b08d5c 100644 --- a/src/main/java/com/primefactorsolutions/model/Question.java +++ b/src/main/java/com/primefactorsolutions/model/Question.java @@ -1,5 +1,6 @@ package com.primefactorsolutions.model; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Lob; import lombok.AllArgsConstructor; @@ -13,6 +14,7 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @EqualsAndHashCode(callSuper = true) public class Question extends BaseEntity{ + @Column(unique = true) private String title; @Lob private String description; diff --git a/src/main/java/com/primefactorsolutions/service/QuestionService.java b/src/main/java/com/primefactorsolutions/service/QuestionService.java index 3b09775..cdd2151 100644 --- a/src/main/java/com/primefactorsolutions/service/QuestionService.java +++ b/src/main/java/com/primefactorsolutions/service/QuestionService.java @@ -21,7 +21,7 @@ public class QuestionService { return questionRepository.findAll(); } - public void createOrUpdate(Question question) { - questionRepository.save(question); + public Question createOrUpdate(Question question) { + return questionRepository.save(question); } } diff --git a/src/main/java/com/primefactorsolutions/views/AssessmentView.java b/src/main/java/com/primefactorsolutions/views/AssessmentView.java index 1b17dcd..00800ac 100644 --- a/src/main/java/com/primefactorsolutions/views/AssessmentView.java +++ b/src/main/java/com/primefactorsolutions/views/AssessmentView.java @@ -50,13 +50,16 @@ public class AssessmentView extends BeanValidationForm implements Ha questions.setReadOnly(false); questions.setAvailableOptions(questionService.getQuestions()); - setSavedHandler((SavedHandler) this.assessmentService::saveAssessment); + setSavedHandler((SavedHandler) assessment -> { + final var saved = this.assessmentService.saveAssessment(assessment); + setEntityWithEnabledSave(saved); + }); } @Override public void setParameter(final BeforeEvent beforeEvent, final String s) { if (StringUtils.isNotBlank(s) && !"new".equals(s)) { - var assessment = assessmentService.getAssessment(UUID.fromString(s)); + final var assessment = assessmentService.getAssessment(UUID.fromString(s)); setEntityWithEnabledSave(assessment); } else { diff --git a/src/main/java/com/primefactorsolutions/views/AssessmentsListView.java b/src/main/java/com/primefactorsolutions/views/AssessmentsListView.java index 6246bb7..2130fc6 100644 --- a/src/main/java/com/primefactorsolutions/views/AssessmentsListView.java +++ b/src/main/java/com/primefactorsolutions/views/AssessmentsListView.java @@ -2,12 +2,15 @@ package com.primefactorsolutions.views; import com.primefactorsolutions.model.Assessment; import com.primefactorsolutions.service.AssessmentService; +import com.vaadin.flow.component.ClickEvent; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.ComponentEventListener; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.confirmdialog.ConfirmDialog; +import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.html.Main; import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.data.provider.DataProvider; import com.vaadin.flow.data.provider.DataProviderListener; import com.vaadin.flow.data.provider.Query; @@ -31,8 +34,21 @@ import java.util.stream.Stream; public class AssessmentsListView extends Main { public AssessmentsListView(final AssessmentService assessmentService) { + final HorizontalLayout hl = new HorizontalLayout(); + final Button addAssessment = new Button("Add Assessment"); + addAssessment.addClickListener((ComponentEventListener>) buttonClickEvent -> { + this.getUI().get().navigate(AssessmentView.class, "new"); + }); + hl.add(addAssessment); + final VGrid grid = new VGrid<>(Assessment.class); grid.setColumns("id", "appUser.email"); + final Grid.Column statusColumn = grid.addColumn((ValueProvider) assessment -> + assessment.getAssessmentEvents().isEmpty() + ? "N/A" + : assessment.getAssessmentEvents().getLast().getStatus().name()); + statusColumn.setHeader("Status"); + grid.addComponentColumn((ValueProvider) assessment -> new Button("Copy Link", event -> ClientsideClipboard.writeToClipboard( String.format("email: %s link: https://careers.primefactorsolutions.com/evaluation/%s", @@ -91,8 +107,9 @@ public class AssessmentsListView extends Main { return null; } }); + grid.setAllRowsVisible(true); - add(grid); + add(hl, grid); } } diff --git a/src/main/java/com/primefactorsolutions/views/EvaluationView.java b/src/main/java/com/primefactorsolutions/views/EvaluationView.java index 219a893..f549cb6 100644 --- a/src/main/java/com/primefactorsolutions/views/EvaluationView.java +++ b/src/main/java/com/primefactorsolutions/views/EvaluationView.java @@ -434,6 +434,10 @@ public class EvaluationView extends Main implements HasUrlParameter { public void setParameter(BeforeEvent beforeEvent, String s) { this.assessment = this.assessmentService.getAssessment(UUID.fromString(s)); + if (this.assessment == null) { + throw new NotFoundException(); + } + if (this.assessment.isCompleted()) { goToCompleted(); } diff --git a/src/main/java/com/primefactorsolutions/views/QuestionView.java b/src/main/java/com/primefactorsolutions/views/QuestionView.java index 4f085d6..e2a41dd 100644 --- a/src/main/java/com/primefactorsolutions/views/QuestionView.java +++ b/src/main/java/com/primefactorsolutions/views/QuestionView.java @@ -6,10 +6,7 @@ import com.vaadin.flow.component.Component; import com.vaadin.flow.component.textfield.IntegerField; import com.vaadin.flow.component.textfield.TextArea; import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.router.BeforeEvent; -import com.vaadin.flow.router.HasUrlParameter; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; +import com.vaadin.flow.router.*; import com.vaadin.flow.spring.annotation.SpringComponent; import jakarta.annotation.security.PermitAll; import org.apache.commons.lang3.StringUtils; @@ -36,28 +33,35 @@ public class QuestionView extends BeanValidationForm implements HasUrl super(Question.class); this.questionService = questionService; title = new TextField(); + title.setWidthFull(); title.setLabel("Title"); description = new TextArea(); + description.setWidthFull(); description.setLabel("Description"); - content = new TextArea(); - content.setLabel("Content"); - timeMinutes = new IntegerField(); timeMinutes.setLabel("TimeMinutes"); - setSavedHandler((SavedHandler) questionService::createOrUpdate); - } + content = new TextArea(); + content.setWidthFull(); + content.setLabel("Content"); + setSavedHandler((SavedHandler) question -> { + final Question saved = questionService.createOrUpdate(question); + setEntityWithEnabledSave(saved); + }); + } @Override public void setParameter(final BeforeEvent beforeEvent, final String s) { if (StringUtils.isNotBlank(s) && !"new".equals(s)) { var user = questionService.getQuestion(UUID.fromString(s)); setEntityWithEnabledSave(user); - } else { + } else if ("new".equals(s)) { setEntityWithEnabledSave(new Question()); + } else { + throw new NotFoundException(); } } diff --git a/src/main/java/com/primefactorsolutions/views/QuestionsListView.java b/src/main/java/com/primefactorsolutions/views/QuestionsListView.java index 4f4775a..69f0991 100644 --- a/src/main/java/com/primefactorsolutions/views/QuestionsListView.java +++ b/src/main/java/com/primefactorsolutions/views/QuestionsListView.java @@ -1,13 +1,17 @@ package com.primefactorsolutions.views; -import com.primefactorsolutions.model.AppUser; import com.primefactorsolutions.model.Question; import com.primefactorsolutions.service.QuestionService; -import com.primefactorsolutions.service.UserService; +import com.vaadin.flow.component.ClickEvent; +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.html.Main; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.data.provider.DataProvider; import com.vaadin.flow.data.provider.DataProviderListener; import com.vaadin.flow.data.provider.Query; +import com.vaadin.flow.function.ValueProvider; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import com.vaadin.flow.shared.Registration; @@ -28,9 +32,22 @@ public class QuestionsListView extends Main { public QuestionsListView(final QuestionService questionService) { this.questionService = questionService; + + final HorizontalLayout hl = new HorizontalLayout(); + final Button addQuestion = new Button("Add Question"); + addQuestion.addClickListener((ComponentEventListener>) buttonClickEvent -> { + this.getUI().get().navigate(QuestionView.class, "new"); + }); + hl.add(addQuestion); + final VGrid grid = new VGrid<>(Question.class); grid.setColumns("id", "title"); - + grid.addComponentColumn((ValueProvider) question -> { + final Button edit = new Button("Edit"); + edit.addClickListener((ComponentEventListener>) buttonClickEvent -> + this.getUI().get().navigate(QuestionView.class, question.getId().toString())); + return edit; + }); grid.setDataProvider(new DataProvider<>() { @Override public boolean isInMemory() { @@ -65,7 +82,8 @@ public class QuestionsListView extends Main { return null; } }); + grid.setAllRowsVisible(true); - add(grid); + add(hl, grid); } } diff --git a/src/main/java/com/primefactorsolutions/views/UserView.java b/src/main/java/com/primefactorsolutions/views/UserView.java index 4f2c3ee..fdd6898 100644 --- a/src/main/java/com/primefactorsolutions/views/UserView.java +++ b/src/main/java/com/primefactorsolutions/views/UserView.java @@ -3,7 +3,7 @@ package com.primefactorsolutions.views; import com.primefactorsolutions.model.AppUser; import com.primefactorsolutions.service.UserService; import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.component.textfield.EmailField; import com.vaadin.flow.router.BeforeEvent; import com.vaadin.flow.router.HasUrlParameter; import com.vaadin.flow.router.PageTitle; @@ -25,18 +25,21 @@ import java.util.UUID; public class UserView extends BeanValidationForm implements HasUrlParameter { private final UserService userService; - private TextField email = null; + private EmailField email = null; public UserView(final UserService userService) { super(AppUser.class); this.userService = userService; - email = new TextField(); + email = new EmailField(); + email.setWidthFull(); email.setLabel("Email"); - setSavedHandler((SavedHandler) userService::createOrUpdate); + setSavedHandler((SavedHandler) appUser -> { + final AppUser saved = userService.createOrUpdate(appUser); + setEntityWithEnabledSave(saved); + }); } - @Override public void setParameter(final BeforeEvent beforeEvent, final String s) { if (StringUtils.isNotBlank(s) && !"new".equals(s)) { diff --git a/src/main/java/com/primefactorsolutions/views/UsersListView.java b/src/main/java/com/primefactorsolutions/views/UsersListView.java index f102344..98f586a 100644 --- a/src/main/java/com/primefactorsolutions/views/UsersListView.java +++ b/src/main/java/com/primefactorsolutions/views/UsersListView.java @@ -2,10 +2,16 @@ package com.primefactorsolutions.views; import com.primefactorsolutions.model.AppUser; import com.primefactorsolutions.service.UserService; +import com.vaadin.flow.component.ClickEvent; +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.html.Main; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.data.provider.DataProvider; import com.vaadin.flow.data.provider.DataProviderListener; import com.vaadin.flow.data.provider.Query; +import com.vaadin.flow.function.ValueProvider; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import com.vaadin.flow.shared.Registration; @@ -14,7 +20,6 @@ import jakarta.annotation.security.PermitAll; import org.springframework.context.annotation.Scope; import org.vaadin.firitin.components.grid.VGrid; -import java.util.List; import java.util.stream.Stream; @SpringComponent @@ -27,8 +32,23 @@ public class UsersListView extends Main { public UsersListView(final UserService userService) { this.userService = userService; + + final HorizontalLayout hl = new HorizontalLayout(); + final Button addUser = new Button("Add User"); + addUser.addClickListener((ComponentEventListener>) buttonClickEvent -> { + this.getUI().get().navigate(UserView.class, "new"); + }); + hl.add(addUser); + final VGrid grid = new VGrid<>(AppUser.class); grid.setColumns("id", "email"); + grid.setAllRowsVisible(true); + grid.addComponentColumn((ValueProvider) appUser -> { + final Button edit = new Button("Edit"); + edit.addClickListener((ComponentEventListener>) buttonClickEvent -> + this.getUI().get().navigate(UserView.class, appUser.getId().toString())); + return edit; + }); grid.setDataProvider(new DataProvider<>() { @Override @@ -65,6 +85,6 @@ public class UsersListView extends Main { } }); - add(grid); + add(hl, grid); } }