diff --git a/README.md b/README.md index df5c5dd..bdc87a0 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ breakpoints in code for debugging purposes, by clicking next to a line number in ## Project structure -- `MainView.java` in `src/main/java` contains the app.regularNavigation setup. It +- `MainView.java` in `src/main/java` contains the app.matchNavigation setup. It uses [App Layout](https://vaadin.com/components/vaadin-app-layout). - `app.views` package in `src/main/java` contains the server-side Java app.views of your application. - `app.views` folder in `frontend/` contains the client-side JavaScript app.views of your application. diff --git a/src/main/java/app/data/entity/Match.java b/src/main/java/app/data/entity/Match.java index ef8bb11..c99e29b 100644 --- a/src/main/java/app/data/entity/Match.java +++ b/src/main/java/app/data/entity/Match.java @@ -1,5 +1,6 @@ package app.data.entity; +import app.navigation.Navigable; import lombok.Getter; import lombok.Setter; @@ -12,7 +13,7 @@ import java.util.Collection; @Table(name = "match", schema = "public", catalog = "chessleague") -public class Match extends AbstractEntity { +public class Match extends AbstractEntity implements Navigable { @ManyToOne(cascade = CascadeType.DETACH) @JoinColumn(name = "matchday", diff --git a/src/main/java/app/data/entity/Matchday.java b/src/main/java/app/data/entity/Matchday.java index d18bb5f..162fe66 100644 --- a/src/main/java/app/data/entity/Matchday.java +++ b/src/main/java/app/data/entity/Matchday.java @@ -1,5 +1,6 @@ package app.data.entity; +import app.navigation.Navigable; import lombok.Getter; import lombok.Setter; @@ -12,7 +13,7 @@ import java.util.Collection; @Table(name = "matchday", schema = "public", catalog = "chessleague") -public class Matchday extends AbstractEntity { +public class Matchday extends AbstractEntity implements Navigable { @ManyToOne(cascade = CascadeType.DETACH) @JoinColumn(name = "season", diff --git a/src/main/java/app/data/entity/Season.java b/src/main/java/app/data/entity/Season.java index af9817d..2b56cc0 100644 --- a/src/main/java/app/data/entity/Season.java +++ b/src/main/java/app/data/entity/Season.java @@ -1,5 +1,6 @@ package app.data.entity; +import app.navigation.Navigable; import lombok.Getter; import lombok.Setter; @@ -12,7 +13,7 @@ import java.util.Collection; @Table(name = "season", schema = "public", catalog = "chessleague") -public class Season extends AbstractEntity { +public class Season extends AbstractEntity implements Navigable { @Basic @Column(name = "year_start", diff --git a/src/main/java/app/data/service/MatchService.java b/src/main/java/app/data/service/MatchService.java index dec5155..13a9213 100644 --- a/src/main/java/app/data/service/MatchService.java +++ b/src/main/java/app/data/service/MatchService.java @@ -5,6 +5,7 @@ import app.data.entity.Game; import app.data.entity.Match; import app.data.entity.Matchday; import app.data.repository.MatchRepository; +import app.navigation.NavigableService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; @@ -14,7 +15,7 @@ import java.util.Optional; import java.util.stream.Collectors; @Service -public class MatchService extends CrudService { +public class MatchService extends CrudService implements NavigableService { private final MatchRepository repository; @@ -66,4 +67,9 @@ public class MatchService extends CrudService { } return score; } + + @Override + public Class getNavigableClass() { + return Match.class; + } } diff --git a/src/main/java/app/data/service/MatchdayService.java b/src/main/java/app/data/service/MatchdayService.java index 4448e61..dfb46c2 100644 --- a/src/main/java/app/data/service/MatchdayService.java +++ b/src/main/java/app/data/service/MatchdayService.java @@ -1,8 +1,10 @@ package app.data.service; +import app.data.bean.CalculatedMatch; import app.data.entity.Matchday; import app.data.entity.Season; import app.data.repository.MatchdayRepository; +import app.navigation.NavigableService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; @@ -14,12 +16,15 @@ import java.util.Optional; import java.util.stream.Collectors; @Service -public class MatchdayService extends CrudService { +public class MatchdayService extends CrudService implements NavigableService { private final MatchdayRepository repository; - public MatchdayService(@Autowired MatchdayRepository repository) { + private final MatchService matchService; + + public MatchdayService(@Autowired MatchdayRepository repository, MatchService matchService) { this.repository = repository; + this.matchService = matchService; } @Override @@ -60,4 +65,13 @@ public class MatchdayService extends CrudService { public boolean hasActivity(@NonNull Matchday matchday) { return matchday.getMatches().stream().mapToInt(match -> match.getGames().size()).sum() != 0; } + + @Override + public Class getNavigableClass() { + return Matchday.class; + } + + public List getCalculatedMatches(Matchday matchday) { + return matchService.getCalculatedMatches(matchday); + } } diff --git a/src/main/java/app/data/service/SeasonService.java b/src/main/java/app/data/service/SeasonService.java index 08061fd..5856b88 100644 --- a/src/main/java/app/data/service/SeasonService.java +++ b/src/main/java/app/data/service/SeasonService.java @@ -3,6 +3,7 @@ package app.data.service; import app.data.entity.Player; import app.data.entity.Season; import app.data.repository.SeasonRepository; +import app.navigation.NavigableService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; @@ -13,7 +14,7 @@ import java.util.Optional; import java.util.stream.Collectors; @Service -public class SeasonService extends CrudService { +public class SeasonService extends CrudService implements NavigableService { private final SeasonRepository repository; @@ -54,4 +55,9 @@ public class SeasonService extends CrudService { .anyMatch(match -> match.getPlayer1().equals(player) || match.getPlayer2().equals(player)))) .collect(Collectors.toList()); } + + @Override + public Class getNavigableClass() { + return Season.class; + } } diff --git a/src/main/java/app/navigation/Navigable.java b/src/main/java/app/navigation/Navigable.java new file mode 100644 index 0000000..17b5713 --- /dev/null +++ b/src/main/java/app/navigation/Navigable.java @@ -0,0 +1,4 @@ +package app.navigation; + +public interface Navigable { +} diff --git a/src/main/java/app/navigation/NavigableService.java b/src/main/java/app/navigation/NavigableService.java new file mode 100644 index 0000000..3347ed2 --- /dev/null +++ b/src/main/java/app/navigation/NavigableService.java @@ -0,0 +1,5 @@ +package app.navigation; + +public interface NavigableService { + Class getNavigableClass(); +} diff --git a/src/main/java/app/navigation/Navigation.java b/src/main/java/app/navigation/Navigation.java index 74b249f..aae24a1 100644 --- a/src/main/java/app/navigation/Navigation.java +++ b/src/main/java/app/navigation/Navigation.java @@ -1,20 +1,64 @@ package app.navigation; import app.components.label.ValidationLabel; +import app.utils.EntityStringUtils; +import com.vaadin.flow.component.AbstractField; +import com.vaadin.flow.component.HasValue; +import com.vaadin.flow.component.UI; +import com.vaadin.flow.component.select.Select; +import com.vaadin.flow.router.BeforeEvent; import com.vaadin.flow.router.HasUrlParameter; +import com.vaadin.flow.router.WildcardParameter; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; -import java.util.ArrayList; -import java.util.List; +import java.util.*; + +import static app.navigation.NavigationUtils.EDIT; public abstract class Navigation implements HasUrlParameter { protected String route; + protected final List> navigableClasses = new ArrayList<>(); + + protected final Map, NavigableService> serviceMap = new HashMap<>(); + + protected final Map, List> listMap = new HashMap<>(); + + protected final Map, Select> selectMap = new HashMap<>(); + protected final List runnablesToBeRunAfterSelection = new ArrayList<>(); protected final ValidationLabel validationLabel = new ValidationLabel(); protected boolean editFlag = false; + @SafeVarargs + public Navigation(NavigableService... services) { + for (NavigableService service : services) { + initNavigable(service); + } + + if (!navigableClasses.isEmpty()) { + fillChildrenSelectWithData(null, navigableClasses.get(0)); + } + } + + private void initNavigable(NavigableService service) { + Class clazz = service.getNavigableClass(); + + navigableClasses.add(clazz); + + serviceMap.put(clazz, service); + + listMap.put(clazz, new ArrayList<>()); + + Select select = new Select<>(); + select.addValueChangeListener(selectValueChangeListener(clazz)); + select.setItemLabelGenerator(EntityStringUtils::getObjectString); + selectMap.put(clazz, select); + } + public final void setRoute(String route) { this.route = route; } @@ -23,8 +67,6 @@ public abstract class Navigation implements HasUrlParameter { return validationLabel; } - public abstract String getWildcardParam(); - protected final String getRoute() { if (route != null) return route; throw new IllegalStateException("Route must be set!"); @@ -36,7 +78,22 @@ public abstract class Navigation implements HasUrlParameter { runnablesToBeRunAfterSelection.forEach(Runnable::run); } - protected abstract void updateUrl(); + protected abstract List getChildren(@Nullable PARENT parent, @NonNull Class childClass); + + protected abstract T getDefaultValue(Class clazz); + + protected void updateUrl() { + String[] params = new String[navigableClasses.size()]; + for (int i = 0; i < navigableClasses.size(); i++) { + Select select = selectMap.get(navigableClasses.get(i)); + if (select.getOptionalValue().isPresent()) { + params[i] = EntityStringUtils.getObjectStringForURL(select.getValue()); + } + } + + String wildcardParam = NavigationUtils.getWildcardParam(editFlag, params); + UI.getCurrent().getPage().getHistory().pushState(null, String.format("%s/%s", getRoute(), wildcardParam)); + } public boolean editFlag() { return editFlag; @@ -50,4 +107,82 @@ public abstract class Navigation implements HasUrlParameter { } } + public void addRunnableToBeRunAfterSelection(Runnable runnable) { + runnablesToBeRunAfterSelection.add(runnable); + } + + protected HasValue.ValueChangeListener, T>> selectValueChangeListener(Class clazz) { + return event -> { + if (!isLastClass(clazz)) { + Class childClass = getChildClass(clazz); + fillChildrenSelectWithData(event.getValue(), childClass); + autoselect(childClass); + return; + } + doPostSelectionStuff(); + }; + } + + private boolean isLastClass(@NonNull Class clazz) { + return navigableClasses.indexOf(clazz) == navigableClasses.size() - 1; + } + + @Nullable + private Class getChildClass(@NonNull Class clazz) { + if (!navigableClasses.contains(clazz) || isLastClass(clazz)) return null; + return navigableClasses.get(navigableClasses.indexOf(clazz) + 1); + } + + @SuppressWarnings("unchecked") + protected void fillChildrenSelectWithData(PARENT parent, Class childClass) { + List children = getChildren(parent, childClass); + listMap.put(childClass, children); + Select childSelect = (Select) selectMap.get(childClass); + childSelect.setItems(children); + } + + @SuppressWarnings("unchecked") + protected void autoselect(Class clazz) { + if (listMap.get(clazz).isEmpty()) { + validationLabel.setText(String.format("No %ss in List!", clazz.getSimpleName())); + validationLabel.setValid(false); + return; + } + Select childSelect = (Select) selectMap.get(clazz); + childSelect.setValue(getDefaultValue(clazz)); + } + + @Override + public void setParameter(BeforeEvent event, @WildcardParameter String param) { + String[] params = param.split("/"); + editFlag = params[params.length - 1].equals(EDIT); + + for (int i = 0; i < Math.min(params.length, navigableClasses.size()); i++) { + navigateClass(navigableClasses.get(i), params[i]); + } + } + + @SuppressWarnings("unchecked") + private void navigateClass(Class clazz, String param) { + List list = (List) listMap.get(clazz); + Select select = (Select) selectMap.get(clazz); + Optional navigable = NavigationUtils.getObjectFromParam(list, param); + if (navigable.isPresent()) + select.setValue(navigable.get()); + else autoselect(clazz); + } + + public String getWildcardParam() { + String[] params = new String[navigableClasses.size()]; + for (int i = 0; i < navigableClasses.size(); i++) { + params[i] = getParam(navigableClasses.get(i)).orElse(null); + } + return NavigationUtils.getWildcardParam(editFlag, params); + } + + @SuppressWarnings("unchecked") + private Optional getParam(Class clazz) { + Select select = (Select) selectMap.get(clazz); + return select.getOptionalValue().map(EntityStringUtils::getObjectStringForURL); + } } \ No newline at end of file diff --git a/src/main/java/app/navigation/NavigationService.java b/src/main/java/app/navigation/NavigationService.java index 31befbd..fee474f 100644 --- a/src/main/java/app/navigation/NavigationService.java +++ b/src/main/java/app/navigation/NavigationService.java @@ -2,4 +2,5 @@ package app.navigation; public interface NavigationService { T getNewNavigation(); + AbstractNavigationHeader getNewNavigationHeader(T navigation); } diff --git a/src/main/java/app/navigation/NavigationUtils.java b/src/main/java/app/navigation/NavigationUtils.java index b63117a..525ff5a 100644 --- a/src/main/java/app/navigation/NavigationUtils.java +++ b/src/main/java/app/navigation/NavigationUtils.java @@ -7,18 +7,12 @@ import org.springframework.lang.NonNull; import java.util.List; import java.util.Optional; -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") public class NavigationUtils { public static final String EDIT = "edit"; private NavigationUtils() { } - public static boolean editFlag(@WildcardParameter String param) { - String[] params = param.split("/"); - return params[params.length - 1].equals(EDIT); - } - @NonNull public static String getWildcardParam(boolean editFlag, String... params) { StringBuilder stringBuilder = new StringBuilder(); @@ -32,12 +26,9 @@ public class NavigationUtils { return stringBuilder.toString(); } - public static Optional getObjectFromParam(List objectList, Optional param) { - if (param.isEmpty()) { - return Optional.empty(); - } + public static Optional getObjectFromParam(List objectList, String param) { return objectList.stream() - .filter(object -> EntityStringUtils.getObjectStringForURL(object).equals(param.get())) + .filter(object -> EntityStringUtils.getObjectStringForURL(object).equals(param)) .findFirst(); } } diff --git a/src/main/java/app/navigation/match/MatchNavigation.java b/src/main/java/app/navigation/match/MatchNavigation.java new file mode 100644 index 0000000..19056b4 --- /dev/null +++ b/src/main/java/app/navigation/match/MatchNavigation.java @@ -0,0 +1,127 @@ +package app.navigation.match; + +import app.data.entity.Match; +import app.data.entity.Matchday; +import app.data.entity.Season; +import app.data.service.MatchService; +import app.data.service.MatchdayService; +import app.data.service.SeasonService; +import app.navigation.Navigable; +import app.navigation.Navigation; +import com.vaadin.flow.component.select.Select; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; + +import java.util.List; +import java.util.Optional; + +public class MatchNavigation extends Navigation { + + private boolean onlyMatchdaysWithActivity; + + public MatchNavigation(@Autowired SeasonService seasonService, + @Autowired MatchdayService matchdayService, + @Autowired MatchService matchService) { + super(seasonService, matchdayService, matchService); + } + + public void setOnlyMatchdaysWithActivity(boolean onlyMatchdaysWithActivity) { + this.onlyMatchdaysWithActivity = onlyMatchdaysWithActivity; + } + + @Override + @SuppressWarnings("unchecked") + protected List getChildren(@Nullable PARENT parent, @NonNull Class childClass) { + if (childClass.equals(Season.class)) { + return (List) getSeasonService().getAllSeasonsSorted(); + } + if (childClass.equals(Matchday.class)) { + assert parent != null; + if (onlyMatchdaysWithActivity) + return (List) getMatchdayService().getMatchdaysWithActivitySortedOrElseListWithOnlyFirstMatchday((Season) parent); + return (List) getMatchdayService().getMatchdaysSorted((Season) parent); + } + if (childClass.equals(Match.class)) { + assert parent != null; + return (List) getMatchService().getMatches((Matchday) parent); + } + throw new UnsupportedOperationException(String.format("This method is not supported for childClass %s", childClass.getSimpleName())); + } + + @Override + @SuppressWarnings("unchecked") + protected T getDefaultValue(Class clazz) { + if (clazz.equals(Season.class)) { + assert !getSeasonList().isEmpty(); + return (T) getSeasonList().get(getSeasonList().size() - 1); + } + if (clazz.equals(Matchday.class)) { + assert !getMatchdayList().isEmpty(); + Matchday matchdayToSelect = getMatchdayList().get(0); + for (Matchday matchday : getMatchdayList()) + if (getMatchdayService().hasActivity(matchday)) matchdayToSelect = matchday; + return (T) matchdayToSelect; + } + if (clazz.equals(Match.class)) { + assert !getMatchList().isEmpty(); + return (T) getMatchList().get(0); + } + throw new UnsupportedOperationException(String.format("This method is not supported for clazz %s", clazz.getSimpleName())); + } + + public SeasonService getSeasonService() { + return (SeasonService) serviceMap.get(Season.class); + } + + public MatchdayService getMatchdayService() { + return (MatchdayService) serviceMap.get(Matchday.class); + } + + public MatchService getMatchService() { + return (MatchService) serviceMap.get(Match.class); + } + + @SuppressWarnings("unchecked") + public List getSeasonList() { + return (List) listMap.get(Season.class); + } + + @SuppressWarnings("unchecked") + public List getMatchdayList() { + return (List) listMap.get(Matchday.class); + } + + @SuppressWarnings("unchecked") + public List getMatchList() { + return (List) listMap.get(Match.class); + } + + @SuppressWarnings("unchecked") + public Select getSeasonSelect() { + return (Select) selectMap.get(Season.class); + } + + @SuppressWarnings("unchecked") + public Select getMatchdaySelect() { + return (Select) selectMap.get(Matchday.class); + } + + @SuppressWarnings("unchecked") + public Select getMatchSelect() { + return (Select) selectMap.get(Match.class); + } + + public Optional getSelectedMatchday() { + return getMatchdaySelect().getOptionalValue(); + } + + public Optional getSelectedSeason() { + return getSeasonSelect().getOptionalValue(); + } + + public Optional getSelectedMatch() { + return getMatchSelect().getOptionalValue(); + } + +} diff --git a/src/main/java/app/navigation/match/MatchNavigationService.java b/src/main/java/app/navigation/match/MatchNavigationService.java new file mode 100644 index 0000000..97fe213 --- /dev/null +++ b/src/main/java/app/navigation/match/MatchNavigationService.java @@ -0,0 +1,37 @@ +package app.navigation.match; + +import app.data.service.MatchService; +import app.data.service.MatchdayService; +import app.data.service.SeasonService; +import app.navigation.AbstractNavigationHeader; +import app.navigation.NavigationService; +import app.navigation.match.components.MatchNavigationHeader; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class MatchNavigationService implements NavigationService { + + private final SeasonService seasonService; + private final MatchdayService matchdayService; + private final MatchService matchService; + + public MatchNavigationService(@Autowired SeasonService seasonService, + @Autowired MatchdayService matchdayService, + @Autowired MatchService matchService) { + this.seasonService = seasonService; + this.matchdayService = matchdayService; + this.matchService = matchService; + } + + @Override + public MatchNavigation getNewNavigation() { + return new MatchNavigation(seasonService, matchdayService, matchService); + } + + @Override + public AbstractNavigationHeader getNewNavigationHeader(MatchNavigation navigation) { + return new MatchNavigationHeader(navigation); + } + +} diff --git a/src/main/java/app/navigation/match/components/MatchNavigationHeader.java b/src/main/java/app/navigation/match/components/MatchNavigationHeader.java new file mode 100644 index 0000000..98cbe83 --- /dev/null +++ b/src/main/java/app/navigation/match/components/MatchNavigationHeader.java @@ -0,0 +1,20 @@ +package app.navigation.match.components; + +import app.navigation.AbstractNavigationHeader; +import app.navigation.match.MatchNavigation; +import com.vaadin.flow.component.html.Label; + +public class MatchNavigationHeader extends AbstractNavigationHeader { + + public MatchNavigationHeader(MatchNavigation navigation) { + super(navigation); + } + + @Override + protected void defineChildren() { + removeAll(); + add(new Label("Season:"), navigation.getSeasonSelect()); + add(new Label("Matchday:"), navigation.getMatchdaySelect()); + add(new Label("Match:"), navigation.getMatchSelect()); + } +} diff --git a/src/main/java/app/navigation/matchday/MatchdayNavigation.java b/src/main/java/app/navigation/matchday/MatchdayNavigation.java new file mode 100644 index 0000000..a52cbd4 --- /dev/null +++ b/src/main/java/app/navigation/matchday/MatchdayNavigation.java @@ -0,0 +1,99 @@ +package app.navigation.matchday; + +import app.data.entity.Match; +import app.data.entity.Matchday; +import app.data.entity.Season; +import app.data.service.MatchService; +import app.data.service.MatchdayService; +import app.data.service.SeasonService; +import app.navigation.Navigable; +import app.navigation.Navigation; +import com.vaadin.flow.component.select.Select; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; + +import java.util.List; +import java.util.Optional; + +public class MatchdayNavigation extends Navigation { + + private boolean onlyMatchdaysWithActivity; + + MatchdayNavigation(@Autowired SeasonService seasonService, + @Autowired MatchdayService matchdayService) { + super(seasonService, matchdayService); + } + + public void setOnlyMatchdaysWithActivity(boolean onlyMatchdaysWithActivity) { + this.onlyMatchdaysWithActivity = onlyMatchdaysWithActivity; + } + + @Override + @SuppressWarnings({"unchecked", "DuplicatedCode"}) + protected List getChildren(@Nullable PARENT parent, @NonNull Class childClass) { + if (childClass.equals(Season.class)) { + return (List) getSeasonService().getAllSeasonsSorted(); + } + if (childClass.equals(Matchday.class)) { + assert parent != null; + if (onlyMatchdaysWithActivity) + return (List) getMatchdayService().getMatchdaysWithActivitySortedOrElseListWithOnlyFirstMatchday((Season) parent); + return (List) getMatchdayService().getMatchdaysSorted((Season) parent); + } + throw new UnsupportedOperationException(String.format("This method is not supported for childClass %s", childClass.getSimpleName())); + } + + @Override + @SuppressWarnings({"unchecked", "DuplicatedCode"}) + protected T getDefaultValue(Class clazz) { + if (clazz.equals(Season.class)) { + assert !getSeasonList().isEmpty(); + return (T) getSeasonList().get(getSeasonList().size() - 1); + } + if (clazz.equals(Matchday.class)) { + assert !getMatchdayList().isEmpty(); + Matchday matchdayToSelect = getMatchdayList().get(0); + for (Matchday matchday : getMatchdayList()) + if (getMatchdayService().hasActivity(matchday)) matchdayToSelect = matchday; + return (T) matchdayToSelect; + } + throw new UnsupportedOperationException(String.format("This method is not supported for clazz %s", clazz.getSimpleName())); + } + + public SeasonService getSeasonService() { + return (SeasonService) serviceMap.get(Season.class); + } + + public MatchdayService getMatchdayService() { + return (MatchdayService) serviceMap.get(Matchday.class); + } + + @SuppressWarnings("unchecked") + public List getSeasonList() { + return (List) listMap.get(Season.class); + } + + @SuppressWarnings("unchecked") + public List getMatchdayList() { + return (List) listMap.get(Matchday.class); + } + + @SuppressWarnings("unchecked") + public Select getSeasonSelect() { + return (Select) selectMap.get(Season.class); + } + + @SuppressWarnings("unchecked") + public Select getMatchdaySelect() { + return (Select) selectMap.get(Matchday.class); + } + + public Optional getSelectedMatchday() { + return getMatchdaySelect().getOptionalValue(); + } + + public Optional getSelectedSeason() { + return getSeasonSelect().getOptionalValue(); + } +} diff --git a/src/main/java/app/navigation/matchday/MatchdayNavigationService.java b/src/main/java/app/navigation/matchday/MatchdayNavigationService.java new file mode 100644 index 0000000..4b11ed9 --- /dev/null +++ b/src/main/java/app/navigation/matchday/MatchdayNavigationService.java @@ -0,0 +1,33 @@ +package app.navigation.matchday; + +import app.data.service.MatchService; +import app.data.service.MatchdayService; +import app.data.service.SeasonService; +import app.navigation.AbstractNavigationHeader; +import app.navigation.NavigationService; +import app.navigation.matchday.components.MatchdayNavigationHeader; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class MatchdayNavigationService implements NavigationService { + + private final SeasonService seasonService; + private final MatchdayService matchdayService; + + public MatchdayNavigationService(@Autowired SeasonService seasonService, + @Autowired MatchdayService matchdayService) { + this.seasonService = seasonService; + this.matchdayService = matchdayService; + } + + @Override + public MatchdayNavigation getNewNavigation() { + return new MatchdayNavigation(seasonService, matchdayService); + } + + @Override + public AbstractNavigationHeader getNewNavigationHeader(MatchdayNavigation navigation) { + return new MatchdayNavigationHeader(navigation); + } +} diff --git a/src/main/java/app/navigation/matchday/components/MatchdayNavigationHeader.java b/src/main/java/app/navigation/matchday/components/MatchdayNavigationHeader.java new file mode 100644 index 0000000..b628647 --- /dev/null +++ b/src/main/java/app/navigation/matchday/components/MatchdayNavigationHeader.java @@ -0,0 +1,19 @@ +package app.navigation.matchday.components; + +import app.navigation.AbstractNavigationHeader; +import app.navigation.matchday.MatchdayNavigation; +import com.vaadin.flow.component.html.Label; + +public class MatchdayNavigationHeader extends AbstractNavigationHeader { + + public MatchdayNavigationHeader(MatchdayNavigation navigation) { + super(navigation); + } + + @Override + protected void defineChildren() { + removeAll(); + add(new Label("Season:"), navigation.getSeasonSelect()); + add(new Label("Matchday:"), navigation.getMatchdaySelect()); + } +} diff --git a/src/main/java/app/navigation/matchday/components/button/MatchdayButtonUtils.java b/src/main/java/app/navigation/matchday/components/button/MatchdayButtonUtils.java new file mode 100644 index 0000000..1894102 --- /dev/null +++ b/src/main/java/app/navigation/matchday/components/button/MatchdayButtonUtils.java @@ -0,0 +1,14 @@ +package app.navigation.matchday.components.button; + +import app.navigation.matchday.MatchdayNavigation; + +import java.util.concurrent.atomic.AtomicInteger; + +class MatchdayButtonUtils { + + static int getMatchdayIndex(MatchdayNavigation matchdayNavigation) { + AtomicInteger index = new AtomicInteger(-1); + matchdayNavigation.getSelectedMatchday().ifPresent(matchday -> index.set(matchdayNavigation.getMatchdayList().indexOf(matchday))); + return index.get(); + } +} diff --git a/src/main/java/app/navigation/matchday/components/button/NextMatchdayButton.java b/src/main/java/app/navigation/matchday/components/button/NextMatchdayButton.java new file mode 100644 index 0000000..1ae222e --- /dev/null +++ b/src/main/java/app/navigation/matchday/components/button/NextMatchdayButton.java @@ -0,0 +1,35 @@ +package app.navigation.matchday.components.button; + +import app.data.entity.Matchday; +import app.navigation.match.MatchNavigation; +import app.navigation.matchday.MatchdayNavigation; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.icon.VaadinIcon; + +import java.util.Optional; + +public class NextMatchdayButton extends Button { + + private final MatchdayNavigation matchdayNavigation; + + public NextMatchdayButton(MatchdayNavigation matchdayNavigation) { + this.matchdayNavigation = matchdayNavigation; + + setIcon(VaadinIcon.ARROW_RIGHT.create()); + + matchdayNavigation.addRunnableToBeRunAfterSelection(this::configure); + } + + private void configure() { + Optional nextMatchday = getNextMatchday(); + setEnabled(nextMatchday.isPresent()); + addClickListener(event -> nextMatchday.ifPresent(matchday -> matchdayNavigation.getMatchdaySelect().setValue(matchday))); + } + + private Optional getNextMatchday() { + int index = MatchdayButtonUtils.getMatchdayIndex(matchdayNavigation); + if (index >= 0 && index < matchdayNavigation.getMatchdayList().size() - 1) + return Optional.ofNullable(matchdayNavigation.getMatchdayList().get(index + 1)); + return Optional.empty(); + } +} diff --git a/src/main/java/app/navigation/matchday/components/button/PrevMatchdayButton.java b/src/main/java/app/navigation/matchday/components/button/PrevMatchdayButton.java new file mode 100644 index 0000000..456d432 --- /dev/null +++ b/src/main/java/app/navigation/matchday/components/button/PrevMatchdayButton.java @@ -0,0 +1,34 @@ +package app.navigation.matchday.components.button; + +import app.data.entity.Matchday; +import app.navigation.match.MatchNavigation; +import app.navigation.matchday.MatchdayNavigation; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.icon.VaadinIcon; + +import java.util.Optional; + +public class PrevMatchdayButton extends Button { + + private final MatchdayNavigation matchdayNavigation; + + public PrevMatchdayButton(MatchdayNavigation matchdayNavigation) { + this.matchdayNavigation = matchdayNavigation; + + setIcon(VaadinIcon.ARROW_LEFT.create()); + + matchdayNavigation.addRunnableToBeRunAfterSelection(this::configure); + } + + private void configure() { + Optional prevMatchday = getPrevMatchday(); + setEnabled(prevMatchday.isPresent()); + addClickListener(event -> prevMatchday.ifPresent(matchday -> matchdayNavigation.getMatchdaySelect().setValue(matchday))); + } + + private Optional getPrevMatchday() { + int index = MatchdayButtonUtils.getMatchdayIndex(matchdayNavigation); + if (index > 0) return Optional.ofNullable(matchdayNavigation.getMatchdayList().get(index - 1)); + return Optional.empty(); + } +} diff --git a/src/main/java/app/navigation/player/PlayerNavigation.java b/src/main/java/app/navigation/player/PlayerNavigation.java deleted file mode 100644 index 452d675..0000000 --- a/src/main/java/app/navigation/player/PlayerNavigation.java +++ /dev/null @@ -1,172 +0,0 @@ -package app.navigation.player; - -import app.components.label.ValidationLabel; -import app.data.entity.Player; -import app.data.entity.Season; -import app.data.service.PlayerService; -import app.data.service.SeasonService; -import app.navigation.Navigation; -import app.navigation.NavigationUtils; -import app.utils.EntityStringUtils; -import com.vaadin.flow.component.AbstractField.ComponentValueChangeEvent; -import com.vaadin.flow.component.HasValue.ValueChangeListener; -import com.vaadin.flow.component.UI; -import com.vaadin.flow.component.select.Select; -import com.vaadin.flow.router.BeforeEvent; -import com.vaadin.flow.router.WildcardParameter; -import org.springframework.beans.factory.annotation.Autowired; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") -public class PlayerNavigation extends Navigation { - - - private final PlayerService playerService; - private final SeasonService seasonService; - - private final List playerList = new ArrayList<>(); - private final List seasonList = new ArrayList<>(); - - private final Select playerSelect = new Select<>(); - private final Select seasonSelect = new Select<>(); - - - public PlayerNavigation(@Autowired PlayerService playerService, - @Autowired SeasonService seasonService) { - this.playerService = playerService; - this.seasonService = seasonService; - - fillPlayerSelectWithData(); - - playerSelect.addValueChangeListener(playerSelectValueChangeListener()); - seasonSelect.addValueChangeListener(seasonSelectValueChangeListener()); - - playerSelect.setItemLabelGenerator(EntityStringUtils::getPlayerString); - seasonSelect.setItemLabelGenerator(EntityStringUtils::getSeasonString); - } - - public void addRunnableToBeRunAfterSelection(Runnable runnable) { - runnablesToBeRunAfterSelection.add(runnable); - } - - protected void updateUrl() { - String playerParam = null; - String seasonParam = null; - if (playerSelect.getOptionalValue().isPresent()) - playerParam = EntityStringUtils.getPlayerStringForURL(playerSelect.getValue()); - if (seasonSelect.getOptionalValue().isPresent()) - seasonParam = EntityStringUtils.getSeasonStringForURL(seasonSelect.getValue()); - - String params = NavigationUtils.getWildcardParam(false, playerParam, seasonParam); - UI.getCurrent().getPage().getHistory().pushState(null, String.format("%s/%s", getRoute(), params)); - } - - private ValueChangeListener, Player>> playerSelectValueChangeListener() { - return event -> { - fillSeasonSelectWithData(event.getValue()); - autoselectSeason(); - }; - } - - private ValueChangeListener, Season>> seasonSelectValueChangeListener() { - return event -> doPostSelectionStuff(); - } - - private void autoselectPlayer() { - if (playerList.isEmpty()) { - validationLabel.setText("No Players in List!"); - validationLabel.setValid(false); - return; - } - playerSelect.setValue(playerList.get(0)); - } - - private void autoselectSeason() { - if (seasonList.isEmpty()) { - validationLabel.setText("No Season in List!"); - validationLabel.setValid(false); - return; - } - seasonSelect.setValue(seasonList.get(seasonList.size() - 1)); - } - - private void fillPlayerSelectWithData() { - playerList.clear(); - playerList.addAll(playerService.getAllPlayersSorted()); - playerSelect.setItems(playerList); - } - - private void fillSeasonSelectWithData(Player player) { - seasonList.clear(); - seasonList.addAll(seasonService.getAllSeasonsForPlayerSorted(player)); - seasonSelect.setItems(seasonList); - } - - @Override - public void setParameter(BeforeEvent event, @WildcardParameter String param) { - Map> map = PlayerNavigationUtils.getParameterMap(param); - navigate(map.get(PlayerNavigationLevel.PLAYER), map.get(PlayerNavigationLevel.SEASON)); - } - - private void navigate(Optional playerParam, Optional seasonParam) { - Optional player = NavigationUtils.getObjectFromParam(playerList, playerParam); - if (player.isPresent()) playerSelect.setValue(player.get()); - else autoselectPlayer(); - - Optional season = NavigationUtils.getObjectFromParam(seasonList, seasonParam); - if (season.isPresent()) seasonSelect.setValue(season.get()); - else autoselectSeason(); - } - - public List getPlayerList() { - return playerList; - } - - public List getSeasonList() { - return seasonList; - } - - public Select getPlayerSelect() { - return playerSelect; - } - - public Select getSeasonSelect() { - return seasonSelect; - } - - public Optional getSelectedPlayer() { - return playerSelect.getOptionalValue(); - } - - public Optional getSelectedSeason() { - return seasonSelect.getOptionalValue(); - } - - public PlayerService getPlayerService() { - return playerService; - } - - public SeasonService getSeasonService() { - return seasonService; - } - - @Override - public String getWildcardParam() { - return NavigationUtils.getWildcardParam( - false, - getPlayerParam().orElse(null), - getSeasonParam().orElse(null)); - } - - public Optional getPlayerParam() { - return getSelectedPlayer().map(EntityStringUtils::getPlayerStringForURL); - } - - public Optional getSeasonParam() { - return getSelectedSeason().map(EntityStringUtils::getSeasonStringForURL); - } -} diff --git a/src/main/java/app/navigation/player/PlayerNavigationLevel.java b/src/main/java/app/navigation/player/PlayerNavigationLevel.java deleted file mode 100644 index ed4c2d2..0000000 --- a/src/main/java/app/navigation/player/PlayerNavigationLevel.java +++ /dev/null @@ -1,7 +0,0 @@ -package app.navigation.player; - -public enum PlayerNavigationLevel { - NONE, - PLAYER, - SEASON, -} diff --git a/src/main/java/app/navigation/player/PlayerNavigationService.java b/src/main/java/app/navigation/player/PlayerNavigationService.java deleted file mode 100644 index a9dd599..0000000 --- a/src/main/java/app/navigation/player/PlayerNavigationService.java +++ /dev/null @@ -1,24 +0,0 @@ -package app.navigation.player; - -import app.data.service.PlayerService; -import app.data.service.SeasonService; -import app.navigation.NavigationService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class PlayerNavigationService implements NavigationService { - - private final SeasonService seasonService; - private final PlayerService playerService; - - public PlayerNavigationService(@Autowired PlayerService playerService, - @Autowired SeasonService seasonService) { - this.playerService = playerService; - this.seasonService = seasonService; - } - - public PlayerNavigation getNewNavigation() { - return new PlayerNavigation(playerService, seasonService); - } -} diff --git a/src/main/java/app/navigation/player/PlayerNavigationUtils.java b/src/main/java/app/navigation/player/PlayerNavigationUtils.java deleted file mode 100644 index 07c3fe5..0000000 --- a/src/main/java/app/navigation/player/PlayerNavigationUtils.java +++ /dev/null @@ -1,25 +0,0 @@ -package app.navigation.player; - -import com.vaadin.flow.router.WildcardParameter; -import org.springframework.lang.NonNull; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -class PlayerNavigationUtils { - private PlayerNavigationUtils() { - } - - @NonNull - static Map> getParameterMap(@WildcardParameter String param) { - Map> map = new HashMap<>(); - String[] params = param.split("/"); - if (params.length >= 1) map.put(PlayerNavigationLevel.PLAYER, Optional.of(params[0])); - if (params.length >= 2) map.put(PlayerNavigationLevel.SEASON, Optional.of(params[1])); - - map.putIfAbsent(PlayerNavigationLevel.PLAYER, Optional.empty()); - map.putIfAbsent(PlayerNavigationLevel.SEASON, Optional.empty()); - return map; - } -} diff --git a/src/main/java/app/navigation/player/components/PlayerNavigationHeader.java b/src/main/java/app/navigation/player/components/PlayerNavigationHeader.java deleted file mode 100644 index 22aa025..0000000 --- a/src/main/java/app/navigation/player/components/PlayerNavigationHeader.java +++ /dev/null @@ -1,31 +0,0 @@ -package app.navigation.player.components; - -import app.navigation.player.PlayerNavigation; -import com.vaadin.flow.component.html.Label; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; - -public class PlayerNavigationHeader extends HorizontalLayout { - - private final PlayerNavigation playerNavigation; - - private final Label seasonLabel = new Label("Season:"); - private final Label playerLabel = new Label("Player:"); - - public PlayerNavigationHeader(PlayerNavigation playerNavigation) { - this.playerNavigation = playerNavigation; - defineLayout(); - configureChildren(); - } - - private void defineLayout() { - setWidthFull(); - setAlignItems(Alignment.CENTER); - setJustifyContentMode(JustifyContentMode.END); - } - - private void configureChildren() { - removeAll(); - add(playerLabel, playerNavigation.getPlayerSelect()); - add(seasonLabel, playerNavigation.getSeasonSelect()); - } -} diff --git a/src/main/java/app/navigation/player/components/button/NextPlayerButton.java b/src/main/java/app/navigation/player/components/button/NextPlayerButton.java deleted file mode 100644 index ada31c8..0000000 --- a/src/main/java/app/navigation/player/components/button/NextPlayerButton.java +++ /dev/null @@ -1,37 +0,0 @@ -package app.navigation.player.components.button; - -import app.data.entity.Player; -import app.navigation.player.PlayerNavigation; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.icon.VaadinIcon; - -import java.util.List; -import java.util.Optional; - -public class NextPlayerButton extends Button { - - private final PlayerNavigation playerNavigation; - - public NextPlayerButton(PlayerNavigation playerNavigation) { - this.playerNavigation = playerNavigation; - - setIcon(VaadinIcon.ARROW_RIGHT.create()); - - playerNavigation.addRunnableToBeRunAfterSelection(this::configure); - } - - private void configure() { - Optional nextPlayer = getNextPlayer(); - setEnabled(nextPlayer.isPresent()); - addClickListener(event -> nextPlayer.ifPresent(player -> playerNavigation.getPlayerSelect().setValue(player))); - } - - private Optional getNextPlayer() { - int index = PlayerButtonUtils.getPlayerIndex(playerNavigation); - - if (index < 0) return Optional.empty(); - - List playerList = playerNavigation.getPlayerList(); - return Optional.ofNullable(playerList.get((index + 1) % playerList.size())); - } -} diff --git a/src/main/java/app/navigation/player/components/button/PlayerButtonUtils.java b/src/main/java/app/navigation/player/components/button/PlayerButtonUtils.java deleted file mode 100644 index 1a5620e..0000000 --- a/src/main/java/app/navigation/player/components/button/PlayerButtonUtils.java +++ /dev/null @@ -1,14 +0,0 @@ -package app.navigation.player.components.button; - -import app.navigation.player.PlayerNavigation; - -import java.util.concurrent.atomic.AtomicInteger; - -class PlayerButtonUtils { - - static int getPlayerIndex(PlayerNavigation playerNavigation) { - AtomicInteger index = new AtomicInteger(-1); - playerNavigation.getSelectedPlayer().ifPresent(player -> index.set(playerNavigation.getPlayerList().indexOf(player))); - return index.get(); - } -} diff --git a/src/main/java/app/navigation/player/components/button/PrevPlayerButton.java b/src/main/java/app/navigation/player/components/button/PrevPlayerButton.java deleted file mode 100644 index b359976..0000000 --- a/src/main/java/app/navigation/player/components/button/PrevPlayerButton.java +++ /dev/null @@ -1,37 +0,0 @@ -package app.navigation.player.components.button; - -import app.data.entity.Player; -import app.navigation.player.PlayerNavigation; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.icon.VaadinIcon; - -import java.util.List; -import java.util.Optional; - -public class PrevPlayerButton extends Button { - - private final PlayerNavigation playerNavigation; - - public PrevPlayerButton(PlayerNavigation playerNavigation) { - this.playerNavigation = playerNavigation; - - setIcon(VaadinIcon.ARROW_LEFT.create()); - - playerNavigation.addRunnableToBeRunAfterSelection(this::configure); - } - - private void configure() { - Optional prevPlayer = getPrevPlayer(); - setEnabled(prevPlayer.isPresent()); - addClickListener(event -> prevPlayer.ifPresent(player -> playerNavigation.getPlayerSelect().setValue(player))); - } - - private Optional getPrevPlayer() { - int index = PlayerButtonUtils.getPlayerIndex(playerNavigation); - - if (index < 0) return Optional.empty(); - - List playerList = playerNavigation.getPlayerList(); - return Optional.ofNullable(playerList.get((index - 1) % playerList.size())); - } -} diff --git a/src/main/java/app/navigation/regular/RegularNavigation.java b/src/main/java/app/navigation/regular/RegularNavigation.java deleted file mode 100644 index 5b1b562..0000000 --- a/src/main/java/app/navigation/regular/RegularNavigation.java +++ /dev/null @@ -1,280 +0,0 @@ -package app.navigation.regular; - -import app.data.entity.Match; -import app.data.entity.Matchday; -import app.data.entity.Season; -import app.data.service.MatchService; -import app.data.service.MatchdayService; -import app.data.service.SeasonService; -import app.navigation.Navigation; -import app.navigation.NavigationUtils; -import app.utils.EntityStringUtils; -import com.vaadin.flow.component.AbstractField.ComponentValueChangeEvent; -import com.vaadin.flow.component.HasValue.ValueChangeListener; -import com.vaadin.flow.component.UI; -import com.vaadin.flow.component.select.Select; -import com.vaadin.flow.router.BeforeEvent; -import com.vaadin.flow.router.WildcardParameter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.lang.NonNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") -public class RegularNavigation extends Navigation { - - private boolean onlyMatchdaysWithActivity; - - private final SeasonService seasonService; - private final MatchdayService matchdayService; - private final MatchService matchService; - - private final List seasonList = new ArrayList<>(); - private final List matchdayList = new ArrayList<>(); - private final List matchList = new ArrayList<>(); - - private final Select seasonSelect = new Select<>(); - private final Select matchdaySelect = new Select<>(); - private final Select matchSelect = new Select<>(); - - private RegularNavigationLevel regularNavigationLevel = RegularNavigationLevel.SEASON; - - public RegularNavigation(@Autowired SeasonService seasonService, - @Autowired MatchdayService matchdayService, - @Autowired MatchService matchService) { - this.seasonService = seasonService; - this.matchdayService = matchdayService; - this.matchService = matchService; - - fillSeasonSelectWithData(); - - seasonSelect.addValueChangeListener(seasonSelectValueChangeListener()); - matchdaySelect.addValueChangeListener(matchdaySelectValueChangeListener()); - matchSelect.addValueChangeListener(matchSelectValueChangeListener()); - - seasonSelect.setItemLabelGenerator(EntityStringUtils::getSeasonString); - matchdaySelect.setItemLabelGenerator(EntityStringUtils::getMatchdayString); - matchSelect.setItemLabelGenerator(EntityStringUtils::getMatchString); - } - - public void setOnlyMatchdaysWithActivity(boolean onlyMatchdaysWithActivity) { - this.onlyMatchdaysWithActivity = onlyMatchdaysWithActivity; - } - - public void setNavigationLevel(@NonNull RegularNavigationLevel regularNavigationLevel) { - this.regularNavigationLevel = regularNavigationLevel; - } - - public void addRunnableToBeRunAfterSelection(Runnable runnable) { - runnablesToBeRunAfterSelection.add(runnable); - } - - public boolean seasonEnabled() { - return this.regularNavigationLevel.compareTo(RegularNavigationLevel.SEASON) >= 0; - } - - public boolean matchdayEnabled() { - return this.regularNavigationLevel.compareTo(RegularNavigationLevel.MATCHDAY) >= 0; - } - - public boolean matchEnabled() { - return this.regularNavigationLevel.compareTo(RegularNavigationLevel.MATCH) >= 0; - } - - protected void updateUrl() { - String seasonParam = null; - String matchdayParam = null; - String matchParam = null; - if (seasonEnabled() && seasonSelect.getOptionalValue().isPresent()) - seasonParam = EntityStringUtils.getSeasonStringForURL(seasonSelect.getValue()); - if (matchdayEnabled() && matchdaySelect.getOptionalValue().isPresent()) - matchdayParam = EntityStringUtils.getMatchdayStringForURL(matchdaySelect.getValue()); - if (matchEnabled() && matchSelect.getOptionalValue().isPresent()) - matchParam = EntityStringUtils.getMatchStringForURL(matchSelect.getValue()); - - String params = NavigationUtils.getWildcardParam(editFlag, seasonParam, matchdayParam, matchParam); - UI.getCurrent().getPage().getHistory().pushState(null, String.format("%s/%s", getRoute(), params)); - } - - private ValueChangeListener, Season>> seasonSelectValueChangeListener() { - return event -> { - if (!seasonEnabled()) throw new IllegalStateException("Cannot select season when it is not enabled!"); - if (matchdayEnabled()) { - fillMatchdaySelectWithData(event.getValue()); - autoselectMatchday(); - return; - } - doPostSelectionStuff(); - }; - } - - private ValueChangeListener, Matchday>> matchdaySelectValueChangeListener() { - return event -> { - if (!matchdayEnabled()) throw new IllegalStateException("Cannot select matchday when it is not enabled!"); - if (matchEnabled()) { - fillMatchSelectWithData(event.getValue()); - autoselectMatch(); - return; - } - doPostSelectionStuff(); - }; - } - - private ValueChangeListener, Match>> matchSelectValueChangeListener() { - return event -> { - if (!matchEnabled()) throw new IllegalStateException("Cannot select match when it is not enabled!"); - doPostSelectionStuff(); - }; - } - - private void autoselectSeason() { - if (!seasonEnabled()) - throw new IllegalStateException("This method should not be called when season is not enabled!"); - if (seasonList.isEmpty()) { - validationLabel.setText("No Seasons in List!"); - validationLabel.setValid(false); - return; - } - seasonSelect.setValue(seasonList.get(seasonList.size() - 1)); - } - - private void autoselectMatchday() { - if (!matchdayEnabled()) - throw new IllegalStateException("This method should not be called when matchday is not enabled!"); - if (matchdayList.isEmpty()) { - validationLabel.setText("No Matchdays in List!"); - validationLabel.setValid(false); - return; - } - Matchday matchdayToSelect = matchdayList.get(0); - for (Matchday matchday : matchdayList) if (matchdayService.hasActivity(matchday)) matchdayToSelect = matchday; - matchdaySelect.setValue(matchdayToSelect); - } - - private void autoselectMatch() { - if (!matchEnabled()) - throw new IllegalStateException("This method should not be called when match is not enabled!"); - if (matchList.isEmpty()) { - validationLabel.setText("No Matches in List!"); - validationLabel.setValid(false); - return; - } - matchSelect.setValue(matchList.get(0)); - } - - private void fillSeasonSelectWithData() { - seasonList.clear(); - seasonList.addAll(seasonService.getAllSeasonsSorted()); - seasonSelect.setItems(seasonList); - } - - private void fillMatchdaySelectWithData(Season season) { - matchdayList.clear(); - List matchdaysToAdd = onlyMatchdaysWithActivity ? - matchdayService.getMatchdaysWithActivitySortedOrElseListWithOnlyFirstMatchday(season) : matchdayService.getMatchdaysSorted(season); - matchdayList.addAll(matchdaysToAdd); - matchdaySelect.setItems(matchdayList); - } - - private void fillMatchSelectWithData(Matchday matchday) { - matchList.clear(); - matchList.addAll(matchService.getMatches(matchday)); - matchSelect.setItems(matchList); - } - - @Override - public void setParameter(BeforeEvent event, @WildcardParameter String param) { - Map> map = RegularNavigationUtils.getParameterMap(param); - editFlag = NavigationUtils.editFlag(param); - navigate(map.get(RegularNavigationLevel.SEASON), map.get(RegularNavigationLevel.MATCHDAY), map.get(RegularNavigationLevel.MATCH)); - } - - private void navigate(Optional seasonParam, Optional matchdayParam, Optional matchParam) { - if (!seasonEnabled()) return; - Optional season = NavigationUtils.getObjectFromParam(seasonList, seasonParam); - if (season.isPresent()) seasonSelect.setValue(season.get()); - else autoselectSeason(); - - if (!matchdayEnabled()) return; - Optional matchday = NavigationUtils.getObjectFromParam(matchdayList, matchdayParam); - if (matchday.isPresent()) matchdaySelect.setValue(matchday.get()); - else autoselectMatchday(); - - if (!matchEnabled()) return; - Optional match = NavigationUtils.getObjectFromParam(matchList, matchParam); - if (match.isPresent()) matchSelect.setValue(match.get()); - else autoselectMatch(); - } - - public List getSeasonList() { - return seasonList; - } - - public List getMatchdayList() { - return matchdayList; - } - - public List getMatchList() { - return matchList; - } - - public Select getSeasonSelect() { - return seasonSelect; - } - - public Select getMatchdaySelect() { - return matchdaySelect; - } - - public Select getMatchSelect() { - return matchSelect; - } - - public Optional getSelectedMatchday() { - return matchdaySelect.getOptionalValue(); - } - - public Optional getSelectedSeason() { - return seasonSelect.getOptionalValue(); - } - - public Optional getSelectedMatch() { - return matchSelect.getOptionalValue(); - } - - public SeasonService getSeasonService() { - return seasonService; - } - - public MatchdayService getMatchdayService() { - return matchdayService; - } - - public MatchService getMatchService() { - return matchService; - } - - @Override - public String getWildcardParam() { - return NavigationUtils.getWildcardParam( - editFlag, - getSeasonParam().orElse(null), - getMatchdayParam().orElse(null), - getMatchParam().orElse(null)); - } - - public Optional getSeasonParam() { - return getSelectedSeason().map(EntityStringUtils::getSeasonStringForURL); - } - - public Optional getMatchdayParam() { - return getSelectedMatchday().map(EntityStringUtils::getMatchdayStringForURL); - } - - public Optional getMatchParam() { - return getSelectedMatch().map(EntityStringUtils::getMatchStringForURL); - } -} diff --git a/src/main/java/app/navigation/regular/RegularNavigationLevel.java b/src/main/java/app/navigation/regular/RegularNavigationLevel.java deleted file mode 100644 index d3d47fb..0000000 --- a/src/main/java/app/navigation/regular/RegularNavigationLevel.java +++ /dev/null @@ -1,8 +0,0 @@ -package app.navigation.regular; - -public enum RegularNavigationLevel { - NONE, - SEASON, - MATCHDAY, - MATCH -} diff --git a/src/main/java/app/navigation/regular/RegularNavigationService.java b/src/main/java/app/navigation/regular/RegularNavigationService.java deleted file mode 100644 index 225c37e..0000000 --- a/src/main/java/app/navigation/regular/RegularNavigationService.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.navigation.regular; - -import app.data.service.MatchService; -import app.data.service.MatchdayService; -import app.data.service.SeasonService; -import app.navigation.NavigationService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class RegularNavigationService implements NavigationService { - - private final SeasonService seasonService; - private final MatchdayService matchdayService; - private final MatchService matchService; - - public RegularNavigationService(@Autowired SeasonService seasonService, - @Autowired MatchdayService matchdayService, - @Autowired MatchService matchService) { - this.seasonService = seasonService; - this.matchdayService = matchdayService; - this.matchService = matchService; - } - - @Override - public RegularNavigation getNewNavigation() { - return new RegularNavigation(seasonService, matchdayService, matchService); - } -} diff --git a/src/main/java/app/navigation/regular/RegularNavigationUtils.java b/src/main/java/app/navigation/regular/RegularNavigationUtils.java deleted file mode 100644 index 9c0c4f2..0000000 --- a/src/main/java/app/navigation/regular/RegularNavigationUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -package app.navigation.regular; - -import app.navigation.NavigationUtils; -import com.vaadin.flow.router.WildcardParameter; -import org.springframework.lang.NonNull; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -class RegularNavigationUtils { - private RegularNavigationUtils() { - } - - @NonNull - static Map> getParameterMap(@WildcardParameter String param) { - Map> map = new HashMap<>(); - String[] params = param.split("/"); - if (params.length >= 1 && !params[0].equals(NavigationUtils.EDIT)) - map.put(RegularNavigationLevel.SEASON, Optional.of(params[0])); - if (params.length >= 2 && !params[1].equals(NavigationUtils.EDIT)) - map.put(RegularNavigationLevel.MATCHDAY, Optional.of(params[1])); - if (params.length >= 3 && !params[2].equals(NavigationUtils.EDIT)) - map.put(RegularNavigationLevel.MATCH, Optional.of(params[2])); - - map.putIfAbsent(RegularNavigationLevel.MATCH, Optional.empty()); - map.putIfAbsent(RegularNavigationLevel.MATCHDAY, Optional.empty()); - map.putIfAbsent(RegularNavigationLevel.SEASON, Optional.empty()); - return map; - } -} diff --git a/src/main/java/app/navigation/regular/components/RegularNavigationHeader.java b/src/main/java/app/navigation/regular/components/RegularNavigationHeader.java deleted file mode 100644 index ea8c364..0000000 --- a/src/main/java/app/navigation/regular/components/RegularNavigationHeader.java +++ /dev/null @@ -1,38 +0,0 @@ -package app.navigation.regular.components; - -import app.navigation.AbstractNavigationHeader; -import app.navigation.Navigation; -import app.navigation.regular.RegularNavigation; -import com.vaadin.flow.component.html.Label; -import com.vaadin.flow.component.orderedlayout.FlexComponent; - -public class RegularNavigationHeader extends AbstractNavigationHeader { - - private final Label seasonLabel = new Label("Season:"); - private final Label matchdayLabel = new Label("Matchday:"); - private final Label matchLabel = new Label("Match:"); - - public RegularNavigationHeader(Navigation navigation) { - super(navigation); - } - - private void defineLayout() { - setWidthFull(); - setAlignItems(FlexComponent.Alignment.CENTER); - setJustifyContentMode(FlexComponent.JustifyContentMode.END); - } - - @Override - protected void defineChildren() { - removeAll(); - if (navigation.seasonEnabled()) { - add(seasonLabel, navigation.getSeasonSelect()); - } - if (navigation.matchdayEnabled()) { - add(matchdayLabel, navigation.getMatchdaySelect()); - } - if (navigation.matchEnabled()) { - add(matchLabel, navigation.getMatchSelect()); - } - } -} diff --git a/src/main/java/app/navigation/regular/components/button/MatchdayButtonUtils.java b/src/main/java/app/navigation/regular/components/button/MatchdayButtonUtils.java deleted file mode 100644 index b88fbeb..0000000 --- a/src/main/java/app/navigation/regular/components/button/MatchdayButtonUtils.java +++ /dev/null @@ -1,14 +0,0 @@ -package app.navigation.regular.components.button; - -import app.navigation.regular.RegularNavigation; - -import java.util.concurrent.atomic.AtomicInteger; - -class MatchdayButtonUtils { - - static int getMatchdayIndex(RegularNavigation regularNavigation) { - AtomicInteger index = new AtomicInteger(-1); - regularNavigation.getSelectedMatchday().ifPresent(matchday -> index.set(regularNavigation.getMatchdayList().indexOf(matchday))); - return index.get(); - } -} diff --git a/src/main/java/app/navigation/regular/components/button/NextMatchdayButton.java b/src/main/java/app/navigation/regular/components/button/NextMatchdayButton.java deleted file mode 100644 index 44fc46e..0000000 --- a/src/main/java/app/navigation/regular/components/button/NextMatchdayButton.java +++ /dev/null @@ -1,37 +0,0 @@ -package app.navigation.regular.components.button; - -import app.data.entity.Matchday; -import app.navigation.regular.RegularNavigation; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.icon.VaadinIcon; - -import java.util.Optional; - -public class NextMatchdayButton extends Button { - - private final RegularNavigation regularNavigation; - - public NextMatchdayButton(RegularNavigation regularNavigation) { - this.regularNavigation = regularNavigation; - - if (!regularNavigation.matchdayEnabled()) - throw new IllegalStateException("Cannot instantiate NextMatchdayButton when Matchdays are not enabled!"); - - setIcon(VaadinIcon.ARROW_RIGHT.create()); - - regularNavigation.addRunnableToBeRunAfterSelection(this::configure); - } - - private void configure() { - Optional nextMatchday = getNextMatchday(); - setEnabled(nextMatchday.isPresent()); - addClickListener(event -> nextMatchday.ifPresent(matchday -> regularNavigation.getMatchdaySelect().setValue(matchday))); - } - - private Optional getNextMatchday() { - int index = MatchdayButtonUtils.getMatchdayIndex(regularNavigation); - if (index >= 0 && index < regularNavigation.getMatchdayList().size() - 1) - return Optional.ofNullable(regularNavigation.getMatchdayList().get(index + 1)); - return Optional.empty(); - } -} diff --git a/src/main/java/app/navigation/regular/components/button/PrevMatchdayButton.java b/src/main/java/app/navigation/regular/components/button/PrevMatchdayButton.java deleted file mode 100644 index e1325a5..0000000 --- a/src/main/java/app/navigation/regular/components/button/PrevMatchdayButton.java +++ /dev/null @@ -1,36 +0,0 @@ -package app.navigation.regular.components.button; - -import app.data.entity.Matchday; -import app.navigation.regular.RegularNavigation; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.icon.VaadinIcon; - -import java.util.Optional; - -public class PrevMatchdayButton extends Button { - - private final RegularNavigation regularNavigation; - - public PrevMatchdayButton(RegularNavigation regularNavigation) { - this.regularNavigation = regularNavigation; - - if (!regularNavigation.matchdayEnabled()) - throw new IllegalStateException("Cannot instantiate PrevMatchdayButton when Matchdays are not enabled!"); - - setIcon(VaadinIcon.ARROW_LEFT.create()); - - regularNavigation.addRunnableToBeRunAfterSelection(this::configure); - } - - private void configure() { - Optional prevMatchday = getPrevMatchday(); - setEnabled(prevMatchday.isPresent()); - addClickListener(event -> prevMatchday.ifPresent(matchday -> regularNavigation.getMatchdaySelect().setValue(matchday))); - } - - private Optional getPrevMatchday() { - int index = MatchdayButtonUtils.getMatchdayIndex(regularNavigation); - if (index > 0) return Optional.ofNullable(regularNavigation.getMatchdayList().get(index - 1)); - return Optional.empty(); - } -} diff --git a/src/main/java/app/utils/EntityStringUtils.java b/src/main/java/app/utils/EntityStringUtils.java index 51f2a0d..9cb3f94 100644 --- a/src/main/java/app/utils/EntityStringUtils.java +++ b/src/main/java/app/utils/EntityStringUtils.java @@ -26,12 +26,20 @@ public class EntityStringUtils { return string; } + public static String getObjectString(Object object) { + if (object instanceof Player) return getPlayerString((Player) object); + if (object instanceof Season) return getSeasonString((Season) object); + if (object instanceof Matchday) return getMatchdayString((Matchday) object); + if (object instanceof Match) return getMatchString((Match) object); + throw new UnsupportedOperationException(String.format("Cannot get Object String for Type %s!", object.getClass().getSimpleName())); + } + public static String getObjectStringForURL(Object object) { if (object instanceof Player) return getPlayerStringForURL((Player) object); if (object instanceof Season) return getSeasonStringForURL((Season) object); if (object instanceof Matchday) return getMatchdayStringForURL((Matchday) object); if (object instanceof Match) return getMatchStringForURL((Match) object); - throw new IllegalStateException(String.format("Cannot get Object String for URL for Type %s!", object.getClass().getSimpleName())); + throw new UnsupportedOperationException(String.format("Cannot get Object String for URL for Type %s!", object.getClass().getSimpleName())); } public static String getSeasonStringForURL(Season season) { diff --git a/src/main/java/app/views/match/MatchView.java b/src/main/java/app/views/match/MatchView.java index 53b2a4d..3423451 100644 --- a/src/main/java/app/views/match/MatchView.java +++ b/src/main/java/app/views/match/MatchView.java @@ -4,8 +4,8 @@ import app.data.service.ChessComService; import app.data.service.GameInfoService; import app.data.service.GameService; import app.gameimage.GameImageService; -import app.navigation.regular.RegularNavigationLevel; -import app.navigation.regular.RegularNavigationService; +import app.navigation.match.MatchNavigation; +import app.navigation.match.MatchNavigationService; import app.views.main.MainView; import app.views.match.components.MatchComponent; import app.views.navigation.NavigationViewBase; @@ -17,20 +17,16 @@ import org.springframework.beans.factory.annotation.Autowired; @CssImport("app/views/match/match-view.css") @Route(value = "match", layout = MainView.class) @PageTitle("Schachliga DACH - Results - Matches") -public class MatchView extends NavigationViewBase { +public class MatchView extends NavigationViewBase { private final ChessComService chessComService; - private final GameService gameService; - private final GameInfoService gameInfoService; private final GameImageService gameImageService; private MatchComponent matchComponent; - public MatchView(@Autowired RegularNavigationService regularNavigationService, - @Autowired ChessComService chessComService, @Autowired GameService gameService, GameInfoService gameInfoService, GameImageService gameImageService) { - super(regularNavigationService, "match", RegularNavigationLevel.MATCH); + public MatchView(@Autowired MatchNavigationService matchNavigationService, + @Autowired ChessComService chessComService, GameImageService gameImageService) { + super(matchNavigationService, "match"); this.chessComService = chessComService; - this.gameService = gameService; - this.gameInfoService = gameInfoService; this.gameImageService = gameImageService; addClassName("match-view"); @@ -43,7 +39,7 @@ public class MatchView extends NavigationViewBase { //////////// private void configureLayout() { - matchComponent = new MatchComponent(navigation, chessComService, gameImageService); + matchComponent = new MatchComponent((MatchNavigation) navigation, chessComService, gameImageService); add(matchComponent); } diff --git a/src/main/java/app/views/match/components/EditMatchCard.java b/src/main/java/app/views/match/components/EditMatchCard.java index 661a4ff..940204b 100644 --- a/src/main/java/app/views/match/components/EditMatchCard.java +++ b/src/main/java/app/views/match/components/EditMatchCard.java @@ -5,7 +5,7 @@ import app.data.entity.Match; import app.data.service.ChessComService; import app.data.service.MatchService; import app.gameimage.GameImageService; -import app.navigation.regular.RegularNavigation; +import app.navigation.match.MatchNavigation; import app.utils.ChessComUtils; import app.utils.ComponentUtils; import app.utils.MatchUtils; @@ -28,7 +28,7 @@ import static com.vaadin.flow.component.button.ButtonVariant.LUMO_PRIMARY; public class EditMatchCard extends VerticalLayout { - private final RegularNavigation regularNavigation; + private final MatchNavigation matchNavigation; private final MatchService matchService; private final ChessComService chessComService; private final GameImageService gameImageService; @@ -48,10 +48,10 @@ public class EditMatchCard extends VerticalLayout { private Match match; - public EditMatchCard(RegularNavigation regularNavigation, ChessComService chessComService, GameImageService gameImageService) { - this.regularNavigation = regularNavigation; + public EditMatchCard(MatchNavigation matchNavigation, ChessComService chessComService, GameImageService gameImageService) { + this.matchNavigation = matchNavigation; this.chessComService = chessComService; - this.matchService = regularNavigation.getMatchService(); + this.matchService = matchNavigation.getMatchService(); this.gameImageService = gameImageService; defineLayout(); @@ -167,7 +167,7 @@ public class EditMatchCard extends VerticalLayout { matchService.update(match); match.getGames().forEach(gameImageService::createImageIfNotPresent); - regularNavigation.setEditFlag(false); + matchNavigation.setEditFlag(false); }; } @@ -192,6 +192,6 @@ public class EditMatchCard extends VerticalLayout { } private ComponentEventListener> createEditCancelButtonListener() { - return event -> UI.getCurrent().navigate(String.format("matchday/%s", regularNavigation.getWildcardParam().replace("edit/", ""))); + return event -> UI.getCurrent().navigate(String.format("matchday/%s", matchNavigation.getWildcardParam().replace("edit/", ""))); } } diff --git a/src/main/java/app/views/match/components/MatchComponent.java b/src/main/java/app/views/match/components/MatchComponent.java index 58d4a63..2de3f17 100644 --- a/src/main/java/app/views/match/components/MatchComponent.java +++ b/src/main/java/app/views/match/components/MatchComponent.java @@ -6,7 +6,7 @@ import app.data.entity.Match; import app.data.service.ChessComService; import app.data.service.MatchService; import app.gameimage.GameImageService; -import app.navigation.regular.RegularNavigation; +import app.navigation.match.MatchNavigation; import app.utils.ComponentUtils; import app.utils.StringUtils; import app.views.navigation.interfaces.ContentConfigurable; @@ -26,7 +26,7 @@ import java.util.NoSuchElementException; public class MatchComponent extends Div implements ContentConfigurable { - private final RegularNavigation regularNavigation; + private final MatchNavigation matchNavigation; private final MatchService matchService; private final GameImageService gameImageService; @@ -43,14 +43,14 @@ public class MatchComponent extends Div implements ContentConfigurable { private Match match; private CalculatedMatch calculatedMatch; - public MatchComponent(RegularNavigation regularNavigation, + public MatchComponent(MatchNavigation matchNavigation, @Autowired ChessComService chessComService, @Autowired GameImageService gameImageService) { - this.regularNavigation = regularNavigation; - this.matchService = regularNavigation.getMatchService(); + this.matchNavigation = matchNavigation; + this.matchService = matchNavigation.getMatchService(); this.gameImageService = gameImageService; - this.editMatchCard = new EditMatchCard(regularNavigation, chessComService, gameImageService); + this.editMatchCard = new EditMatchCard(matchNavigation, chessComService, gameImageService); defineLayout(); } @@ -95,7 +95,7 @@ public class MatchComponent extends Div implements ContentConfigurable { Button button = new Button("Add games", new Icon(VaadinIcon.PLUS)); button.addThemeVariants(ButtonVariant.LUMO_PRIMARY); button.addClickListener(event -> { - regularNavigation.setEditFlag(true); + matchNavigation.setEditFlag(true); remove(noGamesLayout); }); return button; @@ -113,13 +113,13 @@ public class MatchComponent extends Div implements ContentConfigurable { @Override public void configureContent() { try { - match = regularNavigation.getSelectedMatch().orElseThrow(); + match = matchNavigation.getSelectedMatch().orElseThrow(); calculatedMatch = matchService.getCalculatedMatch(match); configureHeaderContent(); configureMainContent(); } catch (NoSuchElementException e) { gamesLayout.removeAll(); - add(regularNavigation.getValidationLabel()); + add(matchNavigation.getValidationLabel()); } } @@ -138,7 +138,7 @@ public class MatchComponent extends Div implements ContentConfigurable { } private void configureHeaderResultLabel() { - if (match.getGames().isEmpty() || regularNavigation.editFlag()) { + if (match.getGames().isEmpty() || matchNavigation.editFlag()) { headerLayout.remove(headerResultLabel); } else { headerLayout.add(headerResultLabel); @@ -148,7 +148,7 @@ public class MatchComponent extends Div implements ContentConfigurable { } private void configureMainContent() { - if (regularNavigation.editFlag()) { + if (matchNavigation.editFlag()) { remove(gamesLayout); add(editLayout); editMatchCard.configureContent(match); diff --git a/src/main/java/app/views/matchday/MatchdayView.java b/src/main/java/app/views/matchday/MatchdayView.java index c4517f3..274eea4 100644 --- a/src/main/java/app/views/matchday/MatchdayView.java +++ b/src/main/java/app/views/matchday/MatchdayView.java @@ -1,7 +1,8 @@ package app.views.matchday; -import app.navigation.regular.RegularNavigationLevel; -import app.navigation.regular.RegularNavigationService; +import app.navigation.match.MatchNavigation; +import app.navigation.matchday.MatchdayNavigation; +import app.navigation.matchday.MatchdayNavigationService; import app.views.main.MainView; import app.views.matchday.components.MatchdayCard; import app.views.navigation.NavigationViewBase; @@ -13,24 +14,24 @@ import org.springframework.beans.factory.annotation.Autowired; @CssImport("app/views/matchday/matchday-view.css") @Route(value = "matchday", layout = MainView.class) @PageTitle("Schachliga DACH - Results - Matchdays") -public class MatchdayView extends NavigationViewBase { +public class MatchdayView extends NavigationViewBase { private MatchdayCard matchdayCard; - public MatchdayView(@Autowired RegularNavigationService regularNavigationService) { - super(regularNavigationService, "matchday", RegularNavigationLevel.MATCHDAY); + public MatchdayView(@Autowired MatchdayNavigationService matchNavigationService) { + super(matchNavigationService, "matchday"); addClassName("matchday-view"); - configureLayout(); + defineLayout(); } //////////// // LAYOUT // //////////// - private void configureLayout() { - matchdayCard = new MatchdayCard(navigation); + private void defineLayout() { + matchdayCard = new MatchdayCard((MatchdayNavigation) navigation); add(matchdayCard); } diff --git a/src/main/java/app/views/matchday/components/MatchdayCard.java b/src/main/java/app/views/matchday/components/MatchdayCard.java index b25bfc6..55cf202 100644 --- a/src/main/java/app/views/matchday/components/MatchdayCard.java +++ b/src/main/java/app/views/matchday/components/MatchdayCard.java @@ -2,9 +2,10 @@ package app.views.matchday.components; import app.data.bean.CalculatedMatch; import app.data.entity.Matchday; -import app.navigation.regular.RegularNavigation; -import app.navigation.regular.components.button.NextMatchdayButton; -import app.navigation.regular.components.button.PrevMatchdayButton; +import app.navigation.match.MatchNavigation; +import app.navigation.matchday.MatchdayNavigation; +import app.navigation.matchday.components.button.NextMatchdayButton; +import app.navigation.matchday.components.button.PrevMatchdayButton; import app.utils.ComponentUtils; import app.utils.EntityStringUtils; import app.utils.StringUtils; @@ -28,7 +29,7 @@ import java.util.NoSuchElementException; public class MatchdayCard extends Div implements ContentConfigurable { - private final RegularNavigation regularNavigation; + private final MatchdayNavigation matchdayNavigation; private final Calendar calendar = Calendar.getInstance(); SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM."); @@ -38,8 +39,8 @@ public class MatchdayCard extends Div implements ContentConfigurable { private final Grid grid = new Grid<>(); - public MatchdayCard(RegularNavigation regularNavigation) { - this.regularNavigation = regularNavigation; + public MatchdayCard(MatchdayNavigation matchdayNavigation) { + this.matchdayNavigation = matchdayNavigation; addClassName("card"); add(new VerticalLayout(header, grid)); @@ -55,7 +56,7 @@ public class MatchdayCard extends Div implements ContentConfigurable { } private void defineHeader() { - header.add(new PrevMatchdayButton(this.regularNavigation), headerLabelLayout, new NextMatchdayButton(this.regularNavigation)); + header.add(new PrevMatchdayButton(this.matchdayNavigation), headerLabelLayout, new NextMatchdayButton(this.matchdayNavigation)); header.setWidthFull(); headerLabelLayout.addClassName("matchday-header-label-layout"); @@ -107,7 +108,7 @@ public class MatchdayCard extends Div implements ContentConfigurable { Button button = new Button(); button.addThemeVariants(ButtonVariant.LUMO_TERTIARY_INLINE); - String seasonAndMatchdayParam = regularNavigation.getWildcardParam(); + String seasonAndMatchdayParam = matchdayNavigation.getWildcardParam(); String matchParam = EntityStringUtils.getMatchStringForURL(match.getMatch()); String targetWildcardParam = String.format("match/%s%s/", seasonAndMatchdayParam, matchParam); @@ -129,12 +130,12 @@ public class MatchdayCard extends Div implements ContentConfigurable { @Override public void configureContent() { try { - Matchday matchday = regularNavigation.getSelectedMatchday().orElseThrow(); + Matchday matchday = matchdayNavigation.getSelectedMatchday().orElseThrow(); configureHeaderLabels(matchday); - grid.setItems(regularNavigation.getMatchService().getCalculatedMatches(matchday)); + grid.setItems(matchdayNavigation.getMatchdayService().getCalculatedMatches(matchday)); } catch (NoSuchElementException e) { removeAll(); - add(regularNavigation.getValidationLabel()); + add(matchdayNavigation.getValidationLabel()); } } diff --git a/src/main/java/app/views/navigation/NavigationViewBase.java b/src/main/java/app/views/navigation/NavigationViewBase.java index eabe86b..6c07c5a 100644 --- a/src/main/java/app/views/navigation/NavigationViewBase.java +++ b/src/main/java/app/views/navigation/NavigationViewBase.java @@ -3,12 +3,7 @@ package app.views.navigation; import app.navigation.AbstractNavigationHeader; import app.navigation.Navigation; import app.navigation.NavigationService; -import app.navigation.regular.RegularNavigation; -import app.navigation.regular.RegularNavigationLevel; -import app.navigation.regular.RegularNavigationService; -import app.navigation.regular.components.RegularNavigationHeader; import com.vaadin.flow.component.orderedlayout.FlexComponent; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.router.BeforeEvent; import com.vaadin.flow.router.HasUrlParameter; @@ -20,25 +15,15 @@ public abstract class NavigationViewBase extends VerticalL protected final Navigation navigation; protected final AbstractNavigationHeader navigationHeader; - protected NavigationViewBase(@Autowired NavigationService navigationService, - String route, - RegularNavigationLevel regularNavigationLevel) { + @SuppressWarnings("unchecked") + protected NavigationViewBase(@Autowired NavigationService navigationService, String route) { this.navigation = navigationService.getNewNavigation(); navigation.setRoute(route); - if (navigation instanceof RegularNavigation) { - ((RegularNavigation) navigation).setNavigationLevel(regularNavigationLevel); - } - - this.navigationHeader = new RegularNavigationHeader(navigation); + this.navigationHeader = navigationService.getNewNavigationHeader((T) navigation); define(); } - protected NavigationViewBase(@Autowired RegularNavigationService regularNavigationService, - String route) { - this(regularNavigationService, route, null); - } - private void define() { add(navigationHeader); addClassName("content"); diff --git a/src/main/java/app/views/table/TableView.java b/src/main/java/app/views/table/TableView.java index 0fc2f9b..954e990 100644 --- a/src/main/java/app/views/table/TableView.java +++ b/src/main/java/app/views/table/TableView.java @@ -1,8 +1,9 @@ package app.views.table; import app.data.service.PlayerService; -import app.navigation.regular.RegularNavigationLevel; -import app.navigation.regular.RegularNavigationService; +import app.navigation.match.MatchNavigationService; +import app.navigation.matchday.MatchdayNavigation; +import app.navigation.matchday.MatchdayNavigationService; import app.views.main.MainView; import app.views.navigation.NavigationViewBase; import app.views.table.components.TableCard; @@ -16,18 +17,18 @@ import org.springframework.beans.factory.annotation.Autowired; @Route(value = "table", layout = MainView.class) @RouteAlias(value = "", layout = MainView.class) @PageTitle("Schachliga DACH - Table") -public class TableView extends NavigationViewBase { +public class TableView extends NavigationViewBase { private final PlayerService playerService; private TableCard tableCard; - public TableView(@Autowired RegularNavigationService regularNavigationService, + public TableView(@Autowired MatchdayNavigationService matchdayNavigationService, @Autowired PlayerService playerService) { - super(regularNavigationService, "table", RegularNavigationLevel.MATCHDAY); + super(matchdayNavigationService, "table"); this.playerService = playerService; - this.navigation.setOnlyMatchdaysWithActivity(true); + ((MatchdayNavigation) this.navigation).setOnlyMatchdaysWithActivity(true); addClassName("table-view"); @@ -39,7 +40,7 @@ public class TableView extends NavigationViewBase { //////////// private void defineLayout() { - tableCard = new TableCard(navigation, playerService); + tableCard = new TableCard((MatchdayNavigation) navigation, playerService); add(tableCard); } diff --git a/src/main/java/app/views/table/components/TableCard.java b/src/main/java/app/views/table/components/TableCard.java index 4245cc6..1d3e3dc 100644 --- a/src/main/java/app/views/table/components/TableCard.java +++ b/src/main/java/app/views/table/components/TableCard.java @@ -3,9 +3,10 @@ package app.views.table.components; import app.data.bean.PlayerForTable; import app.data.entity.Matchday; import app.data.service.PlayerService; -import app.navigation.regular.RegularNavigation; -import app.navigation.regular.components.button.NextMatchdayButton; -import app.navigation.regular.components.button.PrevMatchdayButton; +import app.navigation.match.MatchNavigation; +import app.navigation.matchday.MatchdayNavigation; +import app.navigation.matchday.components.button.NextMatchdayButton; +import app.navigation.matchday.components.button.PrevMatchdayButton; import app.utils.ComponentUtils; import app.utils.EntityStringUtils; import app.utils.StringUtils; @@ -27,7 +28,7 @@ import java.util.NoSuchElementException; public class TableCard extends Div implements ContentConfigurable { - private final RegularNavigation regularNavigation; + private final MatchdayNavigation matchdayNavigation; private final PlayerService playerService; @@ -35,8 +36,8 @@ public class TableCard extends Div implements ContentConfigurable { private final HorizontalLayout headerLabelLayout = new HorizontalLayout(); private final Grid grid = new Grid<>(); - public TableCard(RegularNavigation regularNavigation, @Autowired PlayerService playerService) { - this.regularNavigation = regularNavigation; + public TableCard(MatchdayNavigation matchdayNavigation, @Autowired PlayerService playerService) { + this.matchdayNavigation = matchdayNavigation; this.playerService = playerService; addClassName("card"); @@ -47,7 +48,7 @@ public class TableCard extends Div implements ContentConfigurable { } private void defineHeader() { - header.add(new PrevMatchdayButton(this.regularNavigation), headerLabelLayout, new NextMatchdayButton(this.regularNavigation)); + header.add(new PrevMatchdayButton(this.matchdayNavigation), headerLabelLayout, new NextMatchdayButton(this.matchdayNavigation)); header.setWidthFull(); headerLabelLayout.addClassName("table-header-label-layout"); @@ -161,7 +162,7 @@ public class TableCard extends Div implements ContentConfigurable { @Override public void configureContent() { try { - Matchday matchday = regularNavigation.getSelectedMatchday().orElseThrow(); + Matchday matchday = matchdayNavigation.getSelectedMatchday().orElseThrow(); String mainText = "Table"; String matchdayText = String.format("Matchday %s", EntityStringUtils.getMatchdayString(matchday)); @@ -169,7 +170,7 @@ public class TableCard extends Div implements ContentConfigurable { grid.setItems(playerService.getPlayersForTable(matchday)); } catch (NoSuchElementException e) { removeAll(); - add(regularNavigation.getValidationLabel()); + add(matchdayNavigation.getValidationLabel()); } } }