diff --git a/src/main/java/org/kickerelo/kickerelo/MainView.java b/src/main/java/org/kickerelo/kickerelo/MainView.java
deleted file mode 100644
index 0e030f1..0000000
--- a/src/main/java/org/kickerelo/kickerelo/MainView.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.kickerelo.kickerelo;
-
-import com.vaadin.flow.component.button.Button;
-import com.vaadin.flow.component.button.ButtonVariant;
-import com.vaadin.flow.component.combobox.ComboBox;
-import com.vaadin.flow.component.notification.Notification;
-import com.vaadin.flow.component.notification.NotificationVariant;
-import com.vaadin.flow.component.orderedlayout.VerticalLayout;
-import com.vaadin.flow.component.textfield.IntegerField;
-import com.vaadin.flow.component.textfield.TextField;
-import com.vaadin.flow.router.Route;
-import org.kickerelo.kickerelo.exception.NoSuchPlayerException;
-import org.kickerelo.kickerelo.service.KickerEloService;
-
-/**
- * A sample Vaadin view class.
- *
- * To implement a Vaadin view just extend any Vaadin component and use @Route
- * annotation to announce it in a URL as a Spring managed bean.
- *
- * A new instance of this class is created for every new user and every browser
- * tab/window.
- *
- * The main view contains a text field for getting the user name and a button
- * that shows a greeting message in a notification.
- */
-@Route
-public class MainView extends VerticalLayout {
-
- /**
- * Construct a new Vaadin view.
- */
-
- public MainView(KickerEloService eloService) {
-
-
- TextField spielername = new TextField("Spielername");
- spielername.addClassName("bordered");
-
- // Button click listeners can be defined as lambda expressions
- Button button = new Button("Spieler hinzufügen", e -> {
- eloService.addSpieler(spielername.getValue());
- Notification.show("Spieler gespeichert").addThemeVariants(NotificationVariant.LUMO_SUCCESS);
- });
-
- button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
-
- ComboBox winnerSelect = new ComboBox<>("Gewinner");
- winnerSelect.setItems(eloService.getSpielerNamen());
- winnerSelect.setPlaceholder("Spieler auswählen");
-
- ComboBox loserSelect = new ComboBox<>("Verlierer");
- loserSelect.setItems(eloService.getSpielerNamen());
- loserSelect.setPlaceholder("Spieler auswählen");
-
- IntegerField loserGoals = new IntegerField("Tore des Verlierers");
- loserGoals.setMin(0);
- loserGoals.setMax(9);
- loserGoals.setValue(0);
- loserGoals.setStepButtonsVisible(true);
-
- Button saveButton = new Button("Speichern", e -> {
- try {
- eloService.enterResult1vs1(winnerSelect.getValue(), loserSelect.getValue(), loserGoals.getValue().shortValue());
- Notification.show("Gespeichert").addThemeVariants(NotificationVariant.LUMO_SUCCESS);
- } catch (NoSuchPlayerException err) {
- Notification.show("Konnte nicht gespeichert werden").addThemeVariants(NotificationVariant.LUMO_ERROR);
- }
- });
-
-
-
- // Use custom CSS classes to apply styling. This is defined in
- // styles.css.
- addClassName("centered-content");
-
- add(spielername, button, winnerSelect, loserSelect, loserGoals, saveButton);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/kickerelo/kickerelo/layout/KickerAppLayout.java b/src/main/java/org/kickerelo/kickerelo/layout/KickerAppLayout.java
index 675edad..8751077 100644
--- a/src/main/java/org/kickerelo/kickerelo/layout/KickerAppLayout.java
+++ b/src/main/java/org/kickerelo/kickerelo/layout/KickerAppLayout.java
@@ -4,14 +4,10 @@ import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.applayout.DrawerToggle;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.html.H1;
-import com.vaadin.flow.component.orderedlayout.Scroller;
-import com.vaadin.flow.component.sidenav.SideNav;
import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.router.Layout;
-import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouterLink;
-import com.vaadin.flow.theme.lumo.LumoUtility;
import org.kickerelo.kickerelo.views.*;
@Layout
@@ -33,9 +29,7 @@ public class KickerAppLayout extends AppLayout {
RouterLink graph2vs2 = new RouterLink("Graph 2 vs 2", Graph2vs2View.class);
RouterLink admin = new RouterLink("Verwaltung", AdminView.class);
-
-
- Tabs tabs = new Tabs(new Tab(enter1vs1), new Tab(enter2vs2), new Tab(playerList), new Tab(graph1vs1), new Tab(graph2vs2), new Tab(admin));
+ Tabs tabs = new Tabs(new Tab(playerList), new Tab(enter1vs1), new Tab(enter2vs2), new Tab(graph1vs1), new Tab(graph2vs2), new Tab(admin));
tabs.setOrientation(Tabs.Orientation.VERTICAL);
addToDrawer(tabs);
}
diff --git a/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis1vs1Repository.java b/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis1vs1Repository.java
index ecbaea3..6332e2d 100644
--- a/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis1vs1Repository.java
+++ b/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis1vs1Repository.java
@@ -1,8 +1,5 @@
package org.kickerelo.kickerelo.repository;
-import java.util.List;
-import java.util.stream.Stream;
-
import org.kickerelo.kickerelo.data.Ergebnis1vs1;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
diff --git a/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis2vs2Repository.java b/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis2vs2Repository.java
index 9f2e0f7..3e9c3f9 100644
--- a/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis2vs2Repository.java
+++ b/src/main/java/org/kickerelo/kickerelo/repository/Ergebnis2vs2Repository.java
@@ -4,8 +4,6 @@ import org.kickerelo.kickerelo.data.Ergebnis2vs2;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
-import java.util.stream.Stream;
-
@Repository
public interface Ergebnis2vs2Repository extends JpaRepository {
}
diff --git a/src/main/java/org/kickerelo/kickerelo/repository/SpielerRepository.java b/src/main/java/org/kickerelo/kickerelo/repository/SpielerRepository.java
index 44e340a..833de58 100644
--- a/src/main/java/org/kickerelo/kickerelo/repository/SpielerRepository.java
+++ b/src/main/java/org/kickerelo/kickerelo/repository/SpielerRepository.java
@@ -4,7 +4,6 @@ import org.kickerelo.kickerelo.data.Spieler;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
-import java.util.List;
import java.util.Optional;
@Repository
diff --git a/src/main/java/org/kickerelo/kickerelo/service/EloCalculationService.java b/src/main/java/org/kickerelo/kickerelo/service/EloCalculationService.java
index 3a5c1ed..4e201a7 100644
--- a/src/main/java/org/kickerelo/kickerelo/service/EloCalculationService.java
+++ b/src/main/java/org/kickerelo/kickerelo/service/EloCalculationService.java
@@ -4,17 +4,34 @@ import org.kickerelo.kickerelo.data.Spieler;
import org.springframework.stereotype.Service;
-
+/**
+ * This contains the math for calculating ELO only.
+ */
@Service
public class EloCalculationService {
+ // Default ELOs for a player with 0 games
final float initialElo1vs1 = 1500;
final float initialElo2vs2 = 1500;
+ /**
+ * Updates the 1 vs 1 ELOs of the players according to the result of the game.
+ * @param gewinner The entity representing the winning player
+ * @param verlierer The entity representing the losing player
+ * @param toreVerlierer The number of goals of the losing player
+ */
public void updateElo1vs1(Spieler gewinner, Spieler verlierer, short toreVerlierer) {
gewinner.setElo1vs1(gewinner.getElo1vs1() + 10 - toreVerlierer);
verlierer.setElo1vs1(verlierer.getElo1vs1() - 10 + toreVerlierer);
}
+ /**
+ * Updates the 2 vs 2 ELOs of the players according to the result of the game
+ * @param gewinnerVorn The winning offensive player
+ * @param gewinnerHinten The winning defensive player
+ * @param verliererVorn The losing offensive player
+ * @param verliererHinten The losing defensive player
+ * @param toreVerlierer The number of goals of the losing teams
+ */
public void updateElo2vs2(Spieler gewinnerVorn, Spieler gewinnerHinten, Spieler verliererVorn, Spieler verliererHinten, short toreVerlierer) {
gewinnerVorn.setElo2vs2(gewinnerVorn.getElo2vs2() + 10 - toreVerlierer);
gewinnerHinten.setElo2vs2(gewinnerHinten.getElo2vs2() + 10 - toreVerlierer);
diff --git a/src/main/java/org/kickerelo/kickerelo/service/KickerEloService.java b/src/main/java/org/kickerelo/kickerelo/service/KickerEloService.java
index 9cdc2da..b6308e7 100644
--- a/src/main/java/org/kickerelo/kickerelo/service/KickerEloService.java
+++ b/src/main/java/org/kickerelo/kickerelo/service/KickerEloService.java
@@ -20,6 +20,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.stream.Stream;
+/**
+ * Provides all functions for the application
+ */
@Service
public class KickerEloService {
@Autowired
@@ -31,16 +34,29 @@ public class KickerEloService {
@Autowired
private EloCalculationService eloCalculationService;
+ /**
+ * @return List of all player names sorted alphabetically
+ */
public List getSpielerNamen() {
return spielerRepository.findAll().stream().map(Spieler::getName).sorted().toList();
}
+ /**
+ * @return List of all player entities sorted by 1 vs 1 ELO
+ */
public List getSpielerEntities() {
return spielerRepository.findAll().stream().sorted(new Spieler1vs1EloComparator()).toList();
}
+ /**
+ * Enter a result of a 1 vs 1 game
+ * @param gewinnerName The name of the winning player
+ * @param verliererName The name of the losing player
+ * @param toreVerlierer The number of goals of the loser
+ */
public void enterResult1vs1(String gewinnerName, String verliererName,
short toreVerlierer) {
+ // Check if the inputs are valid
if (gewinnerName == null || verliererName == null) {
throw new PlayerNameNotSetException("Alle Namen müssen gesetzt sein");
}
@@ -60,7 +76,6 @@ public class KickerEloService {
Ergebnis1vs1 ergebnis = new Ergebnis1vs1(gewinner, verlierer, toreVerlierer);
-
ergebnis1vs1Repository.save(ergebnis);
eloCalculationService.updateElo1vs1(gewinner, verlierer, toreVerlierer);
@@ -69,10 +84,18 @@ public class KickerEloService {
}
+ /**
+ * Enter the result of a 2 vs 2 game
+ * @param gewinnerNameVorn Name of the winning offensive player
+ * @param gewinnerNameHinten Name of the winning defensive player
+ * @param verliererNameVorn Name of the losing offensive player
+ * @param verliererNameHinten Name of the losing defensive player
+ * @param toreVerlierer Number of goals of the losing team
+ */
public void enterResult2vs2(String gewinnerNameVorn, String gewinnerNameHinten,
String verliererNameVorn, String verliererNameHinten,
short toreVerlierer) {
-
+ // Check if the inputs are valid
if (gewinnerNameVorn == null || gewinnerNameHinten == null
|| verliererNameVorn == null || verliererNameHinten == null) {
throw new PlayerNameNotSetException("Alle Namen müssen gesetzt sein");
@@ -104,7 +127,6 @@ public class KickerEloService {
.orElseThrow(() -> new NoSuchPlayerException(verliererNameHinten));
Ergebnis2vs2 ergebnis = new Ergebnis2vs2(gewinnerVorn, gewinnerHinten, verliererVorn, verliererHinten, toreVerlierer);
-
ergebnis2vs2Repository.save(ergebnis);
eloCalculationService.updateElo2vs2(gewinnerVorn, gewinnerHinten, verliererVorn, verliererHinten, toreVerlierer);
@@ -114,13 +136,21 @@ public class KickerEloService {
spielerRepository.save(verliererHinten);
}
+ /**
+ * Add a new player to the system
+ * @param name Name of the new player
+ */
public void addSpieler(String name) {
+ // Check if the player name is valid
if (name == null || name.isBlank()) {
throw new PlayerNameNotSetException("Leerer Name");
}
if (getSpielerNamen().contains(name)) {
throw new DuplicatePlayerException("players must not be identical");
}
+ if (name.length() > 30) {
+ throw new InvalidDataException("Zu lang");
+ }
Spieler spieler = new Spieler();
spieler.setName(name);
spieler.setElo1vs1(eloCalculationService.getInitialElo1vs1());
@@ -128,6 +158,9 @@ public class KickerEloService {
spielerRepository.save(spieler);
}
+ /**
+ * Recalculate and overwrite all 1 vs 1 ELOs.
+ */
public void recalculateAll1vs1() {
HashMap players = new HashMap<>();
for (Spieler spieler : spielerRepository.findAll()) {
@@ -143,6 +176,9 @@ public class KickerEloService {
spielerRepository.saveAll(players.values());
}
+ /**
+ * Recalculate and overwrite all 2 vs 2 ELOs.
+ */
public void recalculateAll2vs2() {
HashMap players = new HashMap<>();
for (Spieler spieler : spielerRepository.findAll()) {
diff --git a/src/main/java/org/kickerelo/kickerelo/views/AdminView.java b/src/main/java/org/kickerelo/kickerelo/views/AdminView.java
index 421beb2..5098cbb 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/AdminView.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/AdminView.java
@@ -8,6 +8,7 @@ import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.router.Route;
import org.kickerelo.kickerelo.exception.DuplicatePlayerException;
+import org.kickerelo.kickerelo.exception.InvalidDataException;
import org.kickerelo.kickerelo.exception.PlayerNameNotSetException;
import org.kickerelo.kickerelo.service.KickerEloService;
@@ -26,10 +27,11 @@ public class AdminView extends VerticalLayout {
} catch (PlayerNameNotSetException err) {
Notification.show("Spielername darf nicht leer sein").addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
- }
- catch (DuplicatePlayerException err) {
+ } catch (DuplicatePlayerException err) {
Notification.show("Spieler existiert bereits").addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
+ } catch (InvalidDataException err) {
+ Notification.show("Name zu lang").addThemeVariants(NotificationVariant.LUMO_ERROR);
}
Notification.show("Spieler gespeichert").addThemeVariants(NotificationVariant.LUMO_SUCCESS);
});
diff --git a/src/main/java/org/kickerelo/kickerelo/views/Chart1vs1.java b/src/main/java/org/kickerelo/kickerelo/views/Chart1vs1.java
index d2b772b..48e7df3 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/Chart1vs1.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/Chart1vs1.java
@@ -1,16 +1,23 @@
package org.kickerelo.kickerelo.views;
import com.github.appreciated.apexcharts.ApexChartsBuilder;
+import com.github.appreciated.apexcharts.config.Theme;
import com.github.appreciated.apexcharts.config.builder.ChartBuilder;
import com.github.appreciated.apexcharts.config.builder.XAxisBuilder;
import com.github.appreciated.apexcharts.config.builder.YAxisBuilder;
import com.github.appreciated.apexcharts.config.chart.Type;
import com.github.appreciated.apexcharts.config.chart.builder.ZoomBuilder;
import com.github.appreciated.apexcharts.config.chart.zoom.ZoomType;
+import com.github.appreciated.apexcharts.config.theme.Mode;
+import com.github.appreciated.apexcharts.config.theme.Monochrome;
import com.github.appreciated.apexcharts.config.xaxis.Labels;
import com.github.appreciated.apexcharts.config.xaxis.labels.Style;
import com.github.appreciated.apexcharts.config.yaxis.Title;
import com.github.appreciated.apexcharts.helper.Series;
+import com.vaadin.flow.component.UI;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.server.VaadinService;
+import com.vaadin.flow.theme.lumo.Lumo;
import org.kickerelo.kickerelo.data.Spieler;
import org.kickerelo.kickerelo.util.Spieler1vs1EloComparator;
@@ -19,13 +26,17 @@ import java.util.List;
public class Chart1vs1 extends ApexChartsBuilder {
public Chart1vs1(List l) {
- Style style = new Style();
- style.setColors(List.of("#80C3FC"));
+ Theme theme = new Theme();
+ Monochrome monochrome = new Monochrome();
+ monochrome.setEnabled(true);
+ theme.setMode(Mode.DARK);
+ theme.setMonochrome(monochrome);
Labels labels = new Labels();
labels.setRotate(270d);
labels.setShow(true);
labels.setRotateAlways(false);
- labels.setStyle(style);
+
+
withChart(ChartBuilder.get().withType(Type.SCATTER)
.withZoom(ZoomBuilder.get().withEnabled(true).withType(ZoomType.XY).build()).build())
.withSeries(new Series<>("ELO",
@@ -33,6 +44,7 @@ public class Chart1vs1 extends ApexChartsBuilder {
))
.withXaxis(XAxisBuilder.get().withCategories(l.stream().sorted(new Spieler1vs1EloComparator())
.map(Spieler::getName).toList()).withLabels(labels).build())
- .withYaxis(YAxisBuilder.get().build());
+ .withYaxis(YAxisBuilder.get().build())
+ .withTheme(theme);
}
}
diff --git a/src/main/java/org/kickerelo/kickerelo/views/Chart2vs2.java b/src/main/java/org/kickerelo/kickerelo/views/Chart2vs2.java
index 8de13b8..696e0cd 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/Chart2vs2.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/Chart2vs2.java
@@ -1,12 +1,16 @@
package org.kickerelo.kickerelo.views;
import com.github.appreciated.apexcharts.ApexChartsBuilder;
+import com.github.appreciated.apexcharts.config.Theme;
import com.github.appreciated.apexcharts.config.builder.ChartBuilder;
import com.github.appreciated.apexcharts.config.builder.XAxisBuilder;
import com.github.appreciated.apexcharts.config.builder.YAxisBuilder;
import com.github.appreciated.apexcharts.config.chart.Type;
import com.github.appreciated.apexcharts.config.chart.builder.ZoomBuilder;
import com.github.appreciated.apexcharts.config.chart.zoom.ZoomType;
+import com.github.appreciated.apexcharts.config.theme.Mode;
+import com.github.appreciated.apexcharts.config.theme.Monochrome;
+import com.github.appreciated.apexcharts.config.xaxis.Labels;
import com.github.appreciated.apexcharts.helper.Series;
import org.kickerelo.kickerelo.data.Spieler;
import org.kickerelo.kickerelo.util.Spieler2vs2EloComparator;
@@ -15,12 +19,23 @@ import java.util.List;
public class Chart2vs2 extends ApexChartsBuilder {
public Chart2vs2(List l) {
+ Theme theme = new Theme();
+ Monochrome monochrome = new Monochrome();
+ monochrome.setEnabled(true);
+ theme.setMode(Mode.DARK);
+ theme.setMonochrome(monochrome);
+ Labels labels = new Labels();
+ labels.setRotate(270d);
+ labels.setShow(true);
+ labels.setRotateAlways(false);
+
withChart(ChartBuilder.get().withType(Type.SCATTER)
.withZoom(ZoomBuilder.get().withEnabled(true).withType(ZoomType.XY).build()).build())
.withSeries(new Series<>("ELO",
l.stream().sorted(new Spieler2vs2EloComparator()).map(Spieler::getElo2vs2).toArray()
))
- .withXaxis(XAxisBuilder.get().withCategories(l.stream().sorted(new Spieler2vs2EloComparator()).map(Spieler::getName).toList()).build())
- .withYaxis(YAxisBuilder.get().build());
+ .withXaxis(XAxisBuilder.get().withCategories(l.stream().sorted(new Spieler2vs2EloComparator()).map(Spieler::getName).toList()).withLabels(labels).build())
+ .withYaxis(YAxisBuilder.get().build())
+ .withTheme(theme);
}
}
diff --git a/src/main/java/org/kickerelo/kickerelo/views/PlayerListView.java b/src/main/java/org/kickerelo/kickerelo/views/PlayerListView.java
index 1fd8d79..4be1c89 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/PlayerListView.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/PlayerListView.java
@@ -11,9 +11,10 @@ import org.kickerelo.kickerelo.service.KickerEloService;
import java.util.List;
-@Route("playerlist")
+@Route("")
public class PlayerListView extends VerticalLayout {
public PlayerListView(KickerEloService eloService) {
+ setSizeFull();
H2 subheading = new H2("Spielerliste");
List players = eloService.getSpielerEntities();
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 743bb0a..902fa33 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -6,10 +6,9 @@ spring.mustache.check-template-location = false
vaadin.launch-browser=true
spring.datasource.url=jdbc:mariadb://localhost:3306/kickerelo
-spring.datasource.username=
-spring.datasource.password=
+spring.datasource.username=root
+spring.datasource.password=root
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.hibernate.ddl-auto=validate
-spring.jpa.show-sql=true
-spring.jpa.format-sql=true
+spring.jpa.show-sql=false
spring.jpa.open-in-view=false
\ No newline at end of file