diff --git a/db/db_init.sql b/db/db_init.sql index 4591475..b85cbd8 100644 --- a/db/db_init.sql +++ b/db/db_init.sql @@ -452,6 +452,44 @@ INSERT INTO "game_info" (format, url) VALUES (3, 'https://www.chess.com/live/gam INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8854002505')); +INSERT INTO "game_info" (format, url) VALUES (10, 'https://www.chess.com/live/game/8858219835'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8858219835')); + +INSERT INTO "game_info" (format, url) VALUES (10, 'https://www.chess.com/live/game/8859375675'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8859375675')); + +INSERT INTO "game_info" (format, url) VALUES (5, 'https://www.chess.com/live/game/8859976305'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8859976305')); + +INSERT INTO "game_info" (format, url) VALUES (5, 'https://www.chess.com/live/game/8860591347'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8860591347')); + +INSERT INTO "game_info" (format, url) VALUES (3, 'https://www.chess.com/live/game/8860675419'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8860675419')); + +INSERT INTO "game_info" (format, url) VALUES (3, 'https://www.chess.com/live/game/8861228997'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8861228997')); + + +INSERT INTO "game_info" (format, url) VALUES (10, 'https://www.chess.com/live/game/8877523129'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8877523129')); + +INSERT INTO "game_info" (format, url) VALUES (10, 'https://www.chess.com/live/game/8878652939'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8878652939')); + +INSERT INTO "game_info" (format, url) VALUES (5, 'https://www.chess.com/live/game/8879853665'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8879853665')); + +INSERT INTO "game_info" (format, url) VALUES (5, 'https://www.chess.com/live/game/8880469509'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8880469509')); + +INSERT INTO "game_info" (format, url) VALUES (3, 'https://www.chess.com/live/game/8881562307'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8881562307')); + +INSERT INTO "game_info" (format, url) VALUES (3, 'https://www.chess.com/live/game/8881610243'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8881610243')); + + diff --git a/src/main/java/com/example/application/data/entity/Matchday.java b/src/main/java/com/example/application/data/entity/Matchday.java index 3d9acd7..f940dcb 100644 --- a/src/main/java/com/example/application/data/entity/Matchday.java +++ b/src/main/java/com/example/application/data/entity/Matchday.java @@ -46,7 +46,7 @@ public class Matchday { return Objects.hash(id, number); } - @OneToMany(mappedBy = "matchday") + @OneToMany(mappedBy = "matchday", fetch = FetchType.EAGER) public Collection getMatches() { return matches; } diff --git a/src/main/java/com/example/application/data/service/MatchdayService.java b/src/main/java/com/example/application/data/service/MatchdayService.java index 60393f2..ce5b70b 100644 --- a/src/main/java/com/example/application/data/service/MatchdayService.java +++ b/src/main/java/com/example/application/data/service/MatchdayService.java @@ -3,9 +3,12 @@ package com.example.application.data.service; import com.example.application.data.entity.Matchday; import com.example.application.data.entity.Season; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -23,9 +26,33 @@ public class MatchdayService extends CrudService { return repository; } - public List getMatchdaysForSeason(Season season) { + @NonNull + public List getMatchdaysForSeasonSorted(@NonNull Season season) { return repository.findAll().stream() .filter(matchday -> matchday.getSeason().equals(season)) + .sorted(Comparator.comparingInt(Matchday::getNumber)) .collect(Collectors.toList()); } + + @NonNull + public List getMatchdaysWithActivityForSeasonSorted(@NonNull Season season) { + return repository.findAll().stream() + .filter(matchday -> matchday.getSeason().equals(season)) + .filter(this::hasActivity) + .sorted(Comparator.comparingInt(Matchday::getNumber)) + .collect(Collectors.toList()); + } + + @Nullable + public Matchday getLastMatchdayWithActivityForSeason(@NonNull Season season) { + List matchdaysWithActivity = getMatchdaysWithActivityForSeasonSorted(season); + if (matchdaysWithActivity.isEmpty()) { + return null; + } + return matchdaysWithActivity.get(matchdaysWithActivity.size()-1); + } + + public boolean hasActivity(@NonNull Matchday matchday) { + return matchday.getMatches().stream().mapToInt(match -> match.getGames().size()).sum() != 0; + } } diff --git a/src/main/java/com/example/application/data/service/PlayerService.java b/src/main/java/com/example/application/data/service/PlayerService.java index a0cc0ee..982df5a 100644 --- a/src/main/java/com/example/application/data/service/PlayerService.java +++ b/src/main/java/com/example/application/data/service/PlayerService.java @@ -42,7 +42,7 @@ public class PlayerService extends CrudService { List players = repository.findAll(); public PlayerForTableProvider(Matchday matchday) { - matchdays.addAll(matchdayService.getMatchdaysForSeason(matchday.getSeason()).stream() + matchdays.addAll(matchdayService.getMatchdaysForSeasonSorted(matchday.getSeason()).stream() .filter(matchdayToFilter -> matchdayToFilter.getNumber() <= matchday.getNumber()) .collect(Collectors.toList())); diff --git a/src/main/java/com/example/application/data/service/SeasonService.java b/src/main/java/com/example/application/data/service/SeasonService.java index 9365512..574ee20 100644 --- a/src/main/java/com/example/application/data/service/SeasonService.java +++ b/src/main/java/com/example/application/data/service/SeasonService.java @@ -2,6 +2,7 @@ package com.example.application.data.service; import com.example.application.data.entity.Season; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; @@ -30,4 +31,13 @@ public class SeasonService extends CrudService { .collect(Collectors.toList()); } + @Nullable + public Season getLatestSeason() { + List allSeasonsSorted = getAllSeasonsSorted(); + if (allSeasonsSorted.isEmpty()) { + return null; + } + return allSeasonsSorted.get(allSeasonsSorted.size() - 1); + } + } diff --git a/src/main/java/com/example/application/views/abstractnavigation/SeasonAndMatchdayNavigationView.java b/src/main/java/com/example/application/views/abstractnavigation/SeasonAndMatchdayNavigationView.java index 4b6f442..50feb9b 100644 --- a/src/main/java/com/example/application/views/abstractnavigation/SeasonAndMatchdayNavigationView.java +++ b/src/main/java/com/example/application/views/abstractnavigation/SeasonAndMatchdayNavigationView.java @@ -62,6 +62,8 @@ public abstract class SeasonAndMatchdayNavigationView extends Div implements Has protected abstract void configureContent(); + protected abstract boolean showOnlyMatchdaysWithActivity(); + private void configureOuterLayout() { add(outer); outer.setAlignItems(FlexComponent.Alignment.CENTER); @@ -120,7 +122,9 @@ public abstract class SeasonAndMatchdayNavigationView extends Div implements Has private void fillMatchdaySelectWithData() { matchdayList.clear(); - matchdayList.addAll(matchdayService.getMatchdaysForSeason(seasonSelect.getValue())); + List matchdaysToAdd = showOnlyMatchdaysWithActivity() ? + matchdayService.getMatchdaysWithActivityForSeasonSorted(seasonSelect.getValue()) : matchdayService.getMatchdaysForSeasonSorted(seasonSelect.getValue()); + matchdayList.addAll(matchdaysToAdd); matchdaySelect.setItems(matchdayList); } @@ -136,10 +140,18 @@ public abstract class SeasonAndMatchdayNavigationView extends Div implements Has public void setParameter(BeforeEvent beforeEvent, @WildcardParameter String param) { outer.removeAll(); - // TODO: replace this with something more sensible + // TODO: handle corner case where first matchday has no active games yet: still show first matchday if (param.equals("")) { - navigate(UI.getCurrent(), "2020", "1"); - setParameter(beforeEvent, "2020/1/"); + Season latestSeason = seasonService.getLatestSeason(); + if (latestSeason != null) { + Matchday latestMatchday = matchdayService.getLastMatchdayWithActivityForSeason(latestSeason); + if (latestMatchday != null) { + String seasonParam = latestSeason.toString(); + String matchdayParam = latestMatchday.toString(); + navigate(UI.getCurrent(), seasonParam, matchdayParam); + setParameter(beforeEvent, String.format("%s/%s/", seasonParam, matchdayParam)); // TODO: check why this line seems to be necessary + } + } return; } @@ -165,7 +177,8 @@ public abstract class SeasonAndMatchdayNavigationView extends Div implements Has Matchday matchday = getMatchdayFromParam(matchdayParam); if (matchday == null) { - invalidUrlLabel.setText(String.format("Invalid URL! Matchday \"%s\" in Season \"%s\" does not exist in the database!", matchdayParam, seasonParam)); + String messageExtra = showOnlyMatchdaysWithActivity() ? " or has no games played yet" : ""; + invalidUrlLabel.setText(String.format("Invalid URL! Matchday \"%s\" in Season \"%s\" does not exist in the database%s!", matchdayParam, seasonParam, messageExtra)); outer.add(invalidUrlLabel); return; } @@ -195,7 +208,7 @@ public abstract class SeasonAndMatchdayNavigationView extends Div implements Has @Nullable private Matchday getMatchdayFromParam(@NonNull String matchdayParam, @Nullable Season season) { - List matchdayList = season == null ? this.matchdayList : matchdayService.getMatchdaysForSeason(season); + List matchdayList = season == null ? this.matchdayList : matchdayService.getMatchdaysForSeasonSorted(season); for (Matchday matchday : matchdayList) { if (matchdayParam.equals(matchday.toString())) { return matchday; diff --git a/src/main/java/com/example/application/views/main/MainView.java b/src/main/java/com/example/application/views/main/MainView.java index ccd479c..e4a2c0e 100644 --- a/src/main/java/com/example/application/views/main/MainView.java +++ b/src/main/java/com/example/application/views/main/MainView.java @@ -37,6 +37,7 @@ import java.util.Optional; @Theme(value = Lumo.class, variant = Lumo.DARK) public class MainView extends AppLayout { // TODO: Add Localization + // TODO: Handle database connection with environment variables private final Tabs menu; private H1 viewTitle; diff --git a/src/main/java/com/example/application/views/results/ResultsView.java b/src/main/java/com/example/application/views/results/ResultsView.java index 62dd94e..35d8acc 100644 --- a/src/main/java/com/example/application/views/results/ResultsView.java +++ b/src/main/java/com/example/application/views/results/ResultsView.java @@ -49,6 +49,11 @@ public class ResultsView extends SeasonAndMatchdayNavigationView { return "results"; } + @Override + protected boolean showOnlyMatchdaysWithActivity() { + return false; + } + //////////// // LAYOUT // //////////// diff --git a/src/main/java/com/example/application/views/table/TableView.java b/src/main/java/com/example/application/views/table/TableView.java index 2bf28aa..d058f26 100644 --- a/src/main/java/com/example/application/views/table/TableView.java +++ b/src/main/java/com/example/application/views/table/TableView.java @@ -39,6 +39,11 @@ public class TableView extends SeasonAndMatchdayNavigationView { return "table"; } + @Override + protected boolean showOnlyMatchdaysWithActivity() { + return true; + } + //////////// // LAYOUT // ////////////