Skip to content

Commit 8bfc199

Browse files
committed
🏆 Add achievements dialog
1 parent da1bcdb commit 8bfc199

File tree

14 files changed

+278
-115
lines changed

14 files changed

+278
-115
lines changed

src/main/java/org/cleancode/journal/component/AddSpeedDial.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import org.cleancode.journal.domain.LogEntry;
44
import org.cleancode.journal.domain.Profile;
5+
import org.cleancode.journal.service.IAchievementService;
56
import org.cleancode.journal.service.IGradeService;
7+
import org.cleancode.journal.view.AchievementDialog;
68
import org.cleancode.journal.view.LogDialog;
79

810
import java.io.Serializable;
@@ -14,11 +16,13 @@ public class AddSpeedDial extends SpeedDial {
1416

1517
private final Profile profile;
1618
private final IGradeService gradeService;
19+
private final IAchievementService achievementService;
1720
private NewLogEntryListener entryListener;
1821

19-
public AddSpeedDial(Profile profile, IGradeService gradeService) {
22+
public AddSpeedDial(Profile profile, IGradeService gradeService, IAchievementService achievementService) {
2023
this.profile = profile;
2124
this.gradeService = gradeService;
25+
this.achievementService = achievementService;
2226
setBackdrop(false);
2327
addMenuItem(getTranslation("app.action.add.log-achievement"), TROPHY.create(), e -> activateAchievement());
2428
addMenuItem(getTranslation("app.action.add.log-block"), NOTEBOOK.create(), e -> createNote());
@@ -30,8 +34,8 @@ public void createNote() {
3034
}
3135

3236
public void activateAchievement() {
33-
LogDialog logDialog = new LogDialog(gradeService, profile, entryListener);
34-
logDialog.open();
37+
AchievementDialog achievementDialog = new AchievementDialog(achievementService, profile, null);
38+
achievementDialog.open();
3539
}
3640

3741
public void add(NewLogEntryListener entryListener) {

src/main/java/org/cleancode/journal/domain/Achievement.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package org.cleancode.journal.domain;
22

3+
import java.io.Serializable;
34
import java.util.Objects;
45

5-
public class Achievement {
6+
public class Achievement implements Serializable {
67

78

89
private Group group;
@@ -112,6 +113,6 @@ public int hashCode() {
112113
}
113114

114115
public enum Group {
115-
Grade, Log, CleanCode, Social, Dev, Health, Knowledge;
116+
Grade, Log, CleanCode, Social, Dev, Health, Knowledge
116117
}
117118
}

src/main/java/org/cleancode/journal/service/AchievementService.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.cleancode.journal.domain.Achievement;
55
import org.springframework.stereotype.Service;
66

7+
import javax.annotation.PostConstruct;
78
import java.io.InputStreamReader;
89
import java.util.List;
910
import java.util.Map;
@@ -12,16 +13,27 @@
1213
@Service
1314
public class AchievementService implements IAchievementService {
1415

15-
@Override
16-
public List<Achievement> loadAllAchievements() {
16+
private List<Achievement> achievements;
17+
18+
@PostConstruct
19+
private void loadAchievementsFromFile() {
1720
Gson gson = new Gson();
1821
String gradeFilePath = "/achievements.json";
19-
Achievement[] achievements = gson.fromJson(new InputStreamReader(getClass().getResourceAsStream(gradeFilePath)), Achievement[].class);
20-
return List.of(achievements);
22+
achievements = List.of(gson.fromJson(new InputStreamReader(getClass().getResourceAsStream(gradeFilePath)), Achievement[].class));
23+
}
24+
25+
@Override
26+
public List<Achievement> loadAllAchievements() {
27+
return achievements;
2128
}
2229

2330
@Override
2431
public Map<Achievement.Group, List<Achievement>> loadAllAchievementsInGroups() {
2532
return loadAllAchievements().stream().collect(Collectors.groupingBy(Achievement::getGroup));
2633
}
34+
35+
@Override
36+
public List<Achievement> loadAllAchievementsByGroup(Achievement.Group group) {
37+
return loadAllAchievementsInGroups().get(group);
38+
}
2739
}

src/main/java/org/cleancode/journal/service/IAchievementService.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
import org.cleancode.journal.domain.Achievement;
44
import org.springframework.stereotype.Service;
55

6+
import java.io.Serializable;
67
import java.util.List;
78
import java.util.Map;
89

910
@Service
10-
public interface IAchievementService {
11+
public interface IAchievementService extends Serializable {
1112
List<Achievement> loadAllAchievements();
1213

1314
Map<Achievement.Group, List<Achievement>> loadAllAchievementsInGroups();
15+
16+
List<Achievement> loadAllAchievementsByGroup(Achievement.Group group);
1417
}

src/main/java/org/cleancode/journal/view/AboutView.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
import com.vaadin.flow.router.Route;
66
import org.cleancode.journal.component.AddSpeedDial;
77
import org.cleancode.journal.domain.Profile;
8+
import org.cleancode.journal.service.IAchievementService;
89
import org.cleancode.journal.service.IGradeService;
910

1011
@Route(layout = MainView.class)
1112
public class AboutView extends VerticalLayout {
1213

13-
public AboutView(Profile profile, IGradeService gradeService) {
14+
public AboutView(Profile profile, IGradeService gradeService, IAchievementService achievementService) {
1415
add(new Label("Lorem ipsum"));
15-
add(new AddSpeedDial(profile, gradeService));
16+
add(new AddSpeedDial(profile, gradeService, achievementService));
1617
}
1718
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package org.cleancode.journal.view;
2+
3+
import com.vaadin.flow.component.button.Button;
4+
import com.vaadin.flow.component.dialog.Dialog;
5+
import com.vaadin.flow.component.html.H2;
6+
import com.vaadin.flow.component.icon.Icon;
7+
import com.vaadin.flow.component.icon.VaadinIcon;
8+
import com.vaadin.flow.component.notification.Notification;
9+
import com.vaadin.flow.component.orderedlayout.FlexComponent;
10+
import com.vaadin.flow.component.orderedlayout.FlexComponent.JustifyContentMode;
11+
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
12+
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
13+
import com.vaadin.flow.component.select.Select;
14+
import com.vaadin.flow.component.textfield.TextArea;
15+
import org.cleancode.journal.domain.Achievement;
16+
import org.cleancode.journal.domain.Profile;
17+
import org.cleancode.journal.service.IAchievementService;
18+
19+
import java.io.Serializable;
20+
21+
22+
public class AchievementDialog extends Dialog {
23+
24+
25+
private final IAchievementService achievementService;
26+
private final Profile profile;
27+
private final NewAchievementListener entryListener;
28+
private final TextArea comment;
29+
private final Select<Achievement.Group> groupSelect;
30+
private final Select<Achievement> achievementSelect;
31+
32+
public AchievementDialog(IAchievementService achievementService, Profile profile, NewAchievementListener entryListener) {
33+
this.achievementService = achievementService;
34+
this.profile = profile;
35+
this.entryListener = entryListener;
36+
37+
VerticalLayout content = new VerticalLayout();
38+
content.setJustifyContentMode(JustifyContentMode.BETWEEN);
39+
content.setSizeFull();
40+
add(content);
41+
42+
HorizontalLayout title = new HorizontalLayout();
43+
title.setAlignItems(FlexComponent.Alignment.BASELINE);
44+
title.setJustifyContentMode(JustifyContentMode.CENTER);
45+
title.setWidthFull();
46+
title.add(new Icon(VaadinIcon.TROPHY));
47+
title.add(new H2(getTranslation("dialog.achievement.achievement")));
48+
title.setMargin(false);
49+
title.setPadding(false);
50+
content.add(title);
51+
52+
setWidth("360px");
53+
setHeight("600px");
54+
55+
groupSelect = new Select<>();
56+
groupSelect.setLabel(getTranslation("dialog.achievement.category"));
57+
groupSelect.setItems(Achievement.Group.values());
58+
groupSelect.setItemLabelGenerator(this::getTranslation);
59+
groupSelect.setWidthFull();
60+
groupSelect.addValueChangeListener(e -> selectedGroup(e.getValue()));
61+
content.add(groupSelect);
62+
63+
64+
achievementSelect = new Select<>();
65+
achievementSelect.setLabel(getTranslation("dialog.achievement.achievement"));
66+
achievementSelect.setEnabled(false);
67+
achievementSelect.setItemLabelGenerator(this::getTranslation);
68+
achievementSelect.setWidthFull();
69+
content.add(achievementSelect);
70+
71+
72+
comment = new TextArea();
73+
comment.setWidthFull();
74+
comment.setHeightFull();
75+
comment.setLabel(getTranslation("dialog.log.comment"));
76+
comment.setPlaceholder(getTranslation("dialog.log.comment.placeholder"));
77+
content.setFlexGrow(1, comment);
78+
content.add(comment);
79+
80+
setCloseOnOutsideClick(false);
81+
setCloseOnOutsideClick(false);
82+
83+
Button ok = new Button(getTranslation("dialog.achievement.commit"));
84+
ok.addClickListener(e -> submit());
85+
Button cancel = new Button(getTranslation("dialog.achievement.cancel"));
86+
cancel.addClickListener(e -> cancel());
87+
88+
HorizontalLayout actions = new HorizontalLayout(cancel, ok);
89+
actions.setWidthFull();
90+
actions.setJustifyContentMode(JustifyContentMode.END);
91+
92+
content.add(actions);
93+
}
94+
95+
private void selectedGroup(Achievement.Group group) {
96+
achievementSelect.setEnabled(true);
97+
achievementSelect.setItems(achievementService.loadAllAchievementsByGroup(group));
98+
}
99+
100+
101+
private String getTranslation(Achievement.Group group) {
102+
return getTranslation("achievement.group." + group.name().toLowerCase());
103+
}
104+
105+
private String getTranslation(Achievement achievement) {
106+
return getTranslation(achievement.getId());
107+
}
108+
109+
110+
public void cancel() {
111+
close();
112+
}
113+
114+
public void submit() {
115+
if (!achievementSelect.isInvalid() && !groupSelect.isInvalid()) {
116+
Notification.show(getTranslation("dialog.achievement.committed", getTranslation(achievementSelect.getValue())));
117+
}
118+
close();
119+
}
120+
121+
public interface NewAchievementListener extends Serializable {
122+
void newAchievement(Achievement newLogEntry);
123+
}
124+
125+
}

src/main/java/org/cleancode/journal/view/AchievementsView.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public AchievementsView(Profile profile, IGradeService gradeService, IAchievemen
2222

2323
achievements.keySet().stream().sorted().map(achievements::get).forEach(this::addAchievements);
2424

25-
add(new AddSpeedDial(profile, gradeService));
25+
add(new AddSpeedDial(profile, gradeService, achievementService));
2626
}
2727

2828
public void addAchievements(List<Achievement> achievements) {

src/main/java/org/cleancode/journal/view/CompendiumView.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
import org.cleancode.journal.domain.grade.GradeTopic;
1818
import org.cleancode.journal.domain.grade.Practice;
1919
import org.cleancode.journal.domain.grade.Principle;
20-
import org.cleancode.journal.service.GradeService;
20+
import org.cleancode.journal.service.IAchievementService;
2121
import org.cleancode.journal.service.IGradeService;
22-
import org.springframework.beans.factory.annotation.Autowired;
2322

2423
import java.util.Collection;
2524
import java.util.List;
@@ -37,7 +36,7 @@ public class CompendiumView extends VerticalLayout {
3736
private final Grid<GradeTopic> table;
3837
private Accordion tree;
3938

40-
public CompendiumView(Profile profile, IGradeService gradeService) {
39+
public CompendiumView(Profile profile, IGradeService gradeService, IAchievementService achievementService) {
4140
setHeightFull();
4241

4342
HorizontalLayout controls = new HorizontalLayout();
@@ -54,7 +53,7 @@ public CompendiumView(Profile profile, IGradeService gradeService) {
5453

5554
setViewMode(defaultViewMode);
5655

57-
add(new AddSpeedDial(profile, gradeService));
56+
add(new AddSpeedDial(profile, gradeService, achievementService));
5857
}
5958

6059
private TextField createFilter(IGradeService gradeService) {

src/main/java/org/cleancode/journal/view/GradeView.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.cleancode.journal.domain.grade.GradeRating;
1616
import org.cleancode.journal.domain.grade.GradeRating.Rating;
1717
import org.cleancode.journal.domain.grade.GradeTopic;
18+
import org.cleancode.journal.service.IAchievementService;
1819
import org.cleancode.journal.service.IGradeService;
1920

2021
import java.util.Locale;
@@ -30,7 +31,7 @@ public class GradeView extends VerticalLayout implements HasUrlParameter<String>
3031
private final IGradeService gradeService;
3132
private final VerticalLayout ratings;
3233

33-
public GradeView(Profile profile, IGradeService gradeService) {
34+
public GradeView(Profile profile, IGradeService gradeService, IAchievementService achievementService) {
3435
this.gradeService = gradeService;
3536

3637
name = new H2(EMPTY);
@@ -47,7 +48,7 @@ public GradeView(Profile profile, IGradeService gradeService) {
4748
description = new Label();
4849
add(description);
4950

50-
add(new AddSpeedDial(profile, gradeService));
51+
add(new AddSpeedDial(profile, gradeService, achievementService));
5152
}
5253

5354
@Override

src/main/java/org/cleancode/journal/view/JournalView.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.cleancode.journal.domain.grade.GradeColor;
2323
import org.cleancode.journal.domain.grade.GradeTopic;
2424
import org.cleancode.journal.service.GradeService;
25+
import org.cleancode.journal.service.IAchievementService;
2526
import org.cleancode.journal.service.IProgressService;
2627

2728
import javax.annotation.PostConstruct;
@@ -41,7 +42,7 @@ public class JournalView extends VerticalLayout {
4142
private final VerticalLayout log;
4243
private VerticalLayout favorites;
4344

44-
public JournalView(IProgressService progressService, GradeService gradeService, Profile profile) {
45+
public JournalView(IProgressService progressService, GradeService gradeService, Profile profile, IAchievementService achievementService) {
4546
this.progressService = progressService;
4647
this.gradeService = gradeService;
4748
this.profile = profile;
@@ -61,7 +62,7 @@ public JournalView(IProgressService progressService, GradeService gradeService,
6162
bindLogEntries();
6263

6364

64-
AddSpeedDial addSpeedDial = new AddSpeedDial(profile, gradeService);
65+
AddSpeedDial addSpeedDial = new AddSpeedDial(profile, gradeService, achievementService);
6566
//noinspection Convert2Lambda - Using a lamda would break the serialisation
6667
addSpeedDial.add(new AddSpeedDial.NewLogEntryListener() {
6768
@Override

0 commit comments

Comments
 (0)