|
|
@ -1,151 +1,106 @@ |
|
|
|
package com.example.application.views.results; |
|
|
|
|
|
|
|
import com.example.application.data.bean.MatchForMatchdayView; |
|
|
|
import com.example.application.data.entity.Matchday; |
|
|
|
import com.example.application.data.bean.CalculatedMatch; |
|
|
|
import com.example.application.data.entity.Player; |
|
|
|
import com.example.application.data.entity.Season; |
|
|
|
import com.example.application.data.service.MatchService; |
|
|
|
import com.example.application.data.service.MatchdayService; |
|
|
|
import com.example.application.data.service.SeasonService; |
|
|
|
import com.example.application.views.abstractnavigation.SeasonAndMatchdayNavigationView; |
|
|
|
import com.example.application.views.main.MainView; |
|
|
|
import com.vaadin.flow.component.*; |
|
|
|
import com.vaadin.flow.component.button.Button; |
|
|
|
import com.vaadin.flow.component.dependency.CssImport; |
|
|
|
import com.vaadin.flow.component.grid.ColumnTextAlign; |
|
|
|
import com.vaadin.flow.component.grid.Grid; |
|
|
|
import com.vaadin.flow.component.html.Div; |
|
|
|
import com.vaadin.flow.component.html.Label; |
|
|
|
import com.vaadin.flow.component.icon.Icon; |
|
|
|
import com.vaadin.flow.component.icon.VaadinIcon; |
|
|
|
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.component.select.Select; |
|
|
|
import com.vaadin.flow.function.ValueProvider; |
|
|
|
import com.vaadin.flow.router.*; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.lang.NonNull; |
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.List; |
|
|
|
import javax.swing.text.NumberFormatter; |
|
|
|
|
|
|
|
@CssImport("./views/results/results-view.css") |
|
|
|
@Route(value = "results", layout = MainView.class) |
|
|
|
@RouteAlias(value = "", layout = MainView.class) |
|
|
|
@PageTitle("Results") |
|
|
|
public class ResultsView extends Div implements HasUrlParameter<String> { |
|
|
|
public class ResultsView extends SeasonAndMatchdayNavigationView { |
|
|
|
|
|
|
|
private final SeasonService seasonService; |
|
|
|
private final MatchdayService matchdayService; |
|
|
|
private final MatchService matchService; |
|
|
|
|
|
|
|
private String seasonParam; |
|
|
|
private String matchdayParam; |
|
|
|
private VerticalLayout matchdayLayout; |
|
|
|
private Label matchdayHeader; |
|
|
|
private Grid<CalculatedMatch> grid; |
|
|
|
|
|
|
|
private final Label invalidUrlLabel = new Label(); |
|
|
|
private final Label matchdayViewHeader = new Label(); |
|
|
|
|
|
|
|
private final VerticalLayout outer = new VerticalLayout(); |
|
|
|
private final HorizontalLayout selectionLayout = new HorizontalLayout(); |
|
|
|
private final HorizontalLayout outerMatchdaylayout = new HorizontalLayout(); |
|
|
|
private final VerticalLayout innerMatchdayLayout = new VerticalLayout(); |
|
|
|
|
|
|
|
private final List<Season> seasonList = new ArrayList<>(); |
|
|
|
private final Select<Season> seasonSelect = new Select<>(); |
|
|
|
|
|
|
|
private final List<Matchday> matchdayList = new ArrayList<>(); |
|
|
|
private final Select<Matchday> matchdaySelect = new Select<>(); |
|
|
|
|
|
|
|
private final Button prevButton = new Button(new Icon(VaadinIcon.ARROW_LEFT)); |
|
|
|
private final Button nextButton = new Button(new Icon(VaadinIcon.ARROW_RIGHT)); |
|
|
|
|
|
|
|
private final Grid<MatchForMatchdayView> grid = new Grid<>(); |
|
|
|
private Button prevButton; |
|
|
|
private Button nextButton; |
|
|
|
|
|
|
|
public ResultsView(@Autowired SeasonService seasonService, @Autowired MatchdayService matchdayService, @Autowired MatchService matchService) { |
|
|
|
this.seasonService = seasonService; |
|
|
|
this.matchdayService = matchdayService; |
|
|
|
super(seasonService, matchdayService); |
|
|
|
this.matchService = matchService; |
|
|
|
|
|
|
|
addClassName("results-view"); |
|
|
|
|
|
|
|
configureOuterLayout(); |
|
|
|
configureSelectionLayout(); |
|
|
|
configureMatchdayViewLayout(); |
|
|
|
} |
|
|
|
|
|
|
|
private void configureOuterLayout() { |
|
|
|
add(outer); |
|
|
|
outer.setAlignItems(FlexComponent.Alignment.CENTER); |
|
|
|
@Override |
|
|
|
protected String route() { |
|
|
|
return "results"; |
|
|
|
} |
|
|
|
|
|
|
|
private void configureSelectionLayout() { |
|
|
|
// pretty looks |
|
|
|
selectionLayout.setWidthFull(); |
|
|
|
selectionLayout.setAlignItems(FlexComponent.Alignment.CENTER); |
|
|
|
selectionLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.END); |
|
|
|
selectionLayout.add(new Label("Season:"), seasonSelect, new Label("Matchday:"), matchdaySelect); |
|
|
|
|
|
|
|
seasonSelect.addValueChangeListener(seasonSelectValueChangeListener()); |
|
|
|
matchdaySelect.addValueChangeListener(matchdaySelectValueChangeListener()); |
|
|
|
//////////// |
|
|
|
// LAYOUT // |
|
|
|
//////////// |
|
|
|
|
|
|
|
// provide data |
|
|
|
fillSeasonSelectWithData(); |
|
|
|
private VerticalLayout getMatchdayLayout() { |
|
|
|
if (matchdayLayout == null) { |
|
|
|
matchdayLayout = new VerticalLayout(); |
|
|
|
} |
|
|
|
return matchdayLayout; |
|
|
|
} |
|
|
|
|
|
|
|
private HasValue.ValueChangeListener<? super AbstractField.ComponentValueChangeEvent<Select<Matchday>, Matchday>> matchdaySelectValueChangeListener() { |
|
|
|
return matchdayChangeEvent -> getUI().ifPresent(ui -> { |
|
|
|
Season season = seasonSelect.getValue(); |
|
|
|
Matchday matchday = matchdayChangeEvent.getValue(); |
|
|
|
if (season != null && matchday != null) { |
|
|
|
String seasonParam = season.toString(); |
|
|
|
String matchdayParam = matchday.toString(); |
|
|
|
navigate(ui, seasonParam, matchdayParam); |
|
|
|
} |
|
|
|
}); |
|
|
|
private Label getMatchdayHeader() { |
|
|
|
if (matchdayHeader == null) { |
|
|
|
matchdayHeader = new Label(); |
|
|
|
} |
|
|
|
return matchdayHeader; |
|
|
|
} |
|
|
|
|
|
|
|
private HasValue.ValueChangeListener<? super AbstractField.ComponentValueChangeEvent<Select<Season>, Season>> seasonSelectValueChangeListener() { |
|
|
|
return seasonChangeEvent -> getUI().ifPresent(ui -> { |
|
|
|
Season newSeason = seasonChangeEvent.getValue(); |
|
|
|
if (newSeason != null) { |
|
|
|
String seasonParam = newSeason.toString(); |
|
|
|
String matchdayParam = null; |
|
|
|
|
|
|
|
Matchday matchdayInNewSeason = null; |
|
|
|
Matchday matchdayInOldSeason = matchdaySelect.getValue(); |
|
|
|
if (matchdayInOldSeason != null) { |
|
|
|
matchdayParam = matchdayInOldSeason.toString(); |
|
|
|
matchdayInNewSeason = getMatchdayFromParam(matchdayParam, newSeason); |
|
|
|
} |
|
|
|
matchdayParam = matchdayInNewSeason == null ? "1" : matchdayParam; |
|
|
|
|
|
|
|
navigate(ui, seasonParam, matchdayParam); |
|
|
|
} |
|
|
|
}); |
|
|
|
private Grid<CalculatedMatch> getGrid() { |
|
|
|
if (grid == null) { |
|
|
|
grid = new Grid<>(); |
|
|
|
} |
|
|
|
return grid; |
|
|
|
} |
|
|
|
|
|
|
|
private void fillSeasonSelectWithData() { |
|
|
|
seasonList.clear(); |
|
|
|
seasonList.addAll(seasonService.getAllSeasonsSorted()); |
|
|
|
seasonSelect.setItems(seasonList); |
|
|
|
private Button getPrevButton() { |
|
|
|
if (prevButton == null) { |
|
|
|
prevButton = new Button(new Icon(VaadinIcon.ARROW_LEFT)); |
|
|
|
} |
|
|
|
return prevButton; |
|
|
|
} |
|
|
|
|
|
|
|
private void fillMatchdaySelectWithData() { |
|
|
|
matchdayList.clear(); |
|
|
|
matchdayList.addAll(matchdayService.getMatchdaysForSeason(seasonSelect.getValue())); |
|
|
|
matchdaySelect.setItems(matchdayList); |
|
|
|
private Button getNextButton() { |
|
|
|
if (nextButton == null) { |
|
|
|
nextButton = new Button(new Icon(VaadinIcon.ARROW_RIGHT)); |
|
|
|
} |
|
|
|
return nextButton; |
|
|
|
} |
|
|
|
|
|
|
|
private void configureMatchdayViewLayout() { |
|
|
|
outerMatchdaylayout.add(prevButton, innerMatchdayLayout, nextButton); |
|
|
|
@Override |
|
|
|
protected void configureContentLayout() { |
|
|
|
contentLayout = new HorizontalLayout(getPrevButton(), getMatchdayLayout(), getNextButton()); |
|
|
|
configureMatchdayLayout(); |
|
|
|
} |
|
|
|
|
|
|
|
matchdayViewHeader.addClassName("big_header"); |
|
|
|
private void configureMatchdayLayout() { |
|
|
|
getMatchdayHeader().addClassName("big_header"); |
|
|
|
|
|
|
|
innerMatchdayLayout.setPadding(false); |
|
|
|
innerMatchdayLayout.add(matchdayViewHeader, grid); |
|
|
|
innerMatchdayLayout.setAlignItems(FlexComponent.Alignment.CENTER); |
|
|
|
innerMatchdayLayout.addClassName("inner_matchday_layout"); |
|
|
|
getMatchdayLayout().setPadding(false); |
|
|
|
getMatchdayLayout().add(getMatchdayHeader(), getGrid()); |
|
|
|
getMatchdayLayout().setAlignItems(FlexComponent.Alignment.CENTER); |
|
|
|
getMatchdayLayout().addClassName("inner_matchday_layout"); |
|
|
|
|
|
|
|
Label headerPlayer1 = new Label("Player 1"); |
|
|
|
headerPlayer1.addClassName("column_header"); |
|
|
@ -154,129 +109,64 @@ public class ResultsView extends Div implements HasUrlParameter<String> { |
|
|
|
Label headerResult = new Label("Result"); |
|
|
|
headerResult.addClassName("column_header"); |
|
|
|
|
|
|
|
grid.addColumn((ValueProvider<MatchForMatchdayView, Player>) MatchForMatchdayView::getPlayer1) |
|
|
|
getGrid().addColumn((ValueProvider<CalculatedMatch, Player>) CalculatedMatch::getPlayer1) |
|
|
|
.setHeader(headerPlayer1) |
|
|
|
.setTextAlign(ColumnTextAlign.CENTER) |
|
|
|
.setWidth("13em"); |
|
|
|
grid.addColumn((ValueProvider<MatchForMatchdayView, String>) match -> "vs.") |
|
|
|
getGrid().addColumn((ValueProvider<CalculatedMatch, String>) match -> "vs.") |
|
|
|
.setHeader("vs.") |
|
|
|
.setTextAlign(ColumnTextAlign.CENTER) |
|
|
|
.setWidth("3em"); |
|
|
|
grid.addColumn((ValueProvider<MatchForMatchdayView, Player>) MatchForMatchdayView::getPlayer2) |
|
|
|
getGrid().addColumn((ValueProvider<CalculatedMatch, Player>) CalculatedMatch::getPlayer2) |
|
|
|
.setHeader(headerPlayer2) |
|
|
|
.setTextAlign(ColumnTextAlign.CENTER) |
|
|
|
.setWidth("13em"); |
|
|
|
grid.addColumn((ValueProvider<MatchForMatchdayView, String>) match -> { |
|
|
|
String result = match.getScore1().toString() + " : " + match.getScore2().toString(); |
|
|
|
getGrid().addColumn((ValueProvider<CalculatedMatch, String>) match -> { |
|
|
|
|
|
|
|
String result = match.getScore1().toString().replace(".0", "") |
|
|
|
+ " : " |
|
|
|
+ match.getScore2().toString().replace(".0", ""); |
|
|
|
return result.equals("0 : 0") ? "" : result; |
|
|
|
}) |
|
|
|
.setHeader(headerResult) |
|
|
|
.setTextAlign(ColumnTextAlign.CENTER) |
|
|
|
.setWidth("6em"); |
|
|
|
|
|
|
|
grid.setWidth("36em"); |
|
|
|
grid.setHeightByRows(true); |
|
|
|
getGrid().setWidth("36em"); |
|
|
|
getGrid().setHeightByRows(true); |
|
|
|
|
|
|
|
grid.addClassName("matchday_grid"); |
|
|
|
getGrid().addClassName("my_grid"); |
|
|
|
} |
|
|
|
|
|
|
|
private String getPrevMatchdayParam() { |
|
|
|
return String.valueOf(Integer.parseInt(matchdayParam) - 1); |
|
|
|
} |
|
|
|
|
|
|
|
private String getNextMatchdayParam() { |
|
|
|
return String.valueOf(Integer.parseInt(matchdayParam) + 1); |
|
|
|
} |
|
|
|
|
|
|
|
private boolean isMatchDayParamValid(@NonNull String matchdayParam) { |
|
|
|
return matchdayList.stream().anyMatch(matchday -> matchdayParam.equals(matchday.toString())); |
|
|
|
} |
|
|
|
|
|
|
|
private ComponentEventListener<ClickEvent<Button>> getButtonClickListener(Button button, String matchdayParam) { |
|
|
|
return buttonClickEvent -> getUI().ifPresent(ui -> navigate(ui, seasonParam, matchdayParam)); |
|
|
|
} |
|
|
|
|
|
|
|
private void navigate(UI ui, String seasonParam, String matchdayParam) { |
|
|
|
ui.navigate(String.format("results/%s/%s/", seasonParam, matchdayParam)); |
|
|
|
} |
|
|
|
|
|
|
|
private void configureMatchdayView() { |
|
|
|
matchdayViewHeader.setText(String.format("Matchday %s", matchdaySelect.getValue().toString())); |
|
|
|
grid.setItems(matchService.getMatchesForMatchdayView(matchdaySelect.getValue())); |
|
|
|
} |
|
|
|
///////////// |
|
|
|
// CONTENT // |
|
|
|
///////////// |
|
|
|
|
|
|
|
@Override |
|
|
|
public void setParameter(BeforeEvent beforeEvent, @WildcardParameter String param) { |
|
|
|
outer.removeAll(); |
|
|
|
|
|
|
|
if (!param.matches("^[0-9]*/[0-9]*/?$")) { |
|
|
|
invalidUrlLabel.setText("Invalid URL! Please provide params in the form season/matchday/"); |
|
|
|
outer.add(invalidUrlLabel); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
String[] params = param.split("/"); |
|
|
|
seasonParam = params[0]; |
|
|
|
matchdayParam = params[1]; |
|
|
|
|
|
|
|
Season season = getSeasonFromParam(seasonParam); |
|
|
|
if (season == null) { |
|
|
|
invalidUrlLabel.setText(String.format("Invalid URL! Season \"%s\" does not exist in the database!", seasonParam)); |
|
|
|
outer.add(invalidUrlLabel); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
seasonSelect.setValue(season); |
|
|
|
fillMatchdaySelectWithData(); |
|
|
|
|
|
|
|
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)); |
|
|
|
outer.add(invalidUrlLabel); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
matchdaySelect.setValue(matchday); |
|
|
|
configureMatchdayView(); |
|
|
|
|
|
|
|
outer.add(selectionLayout); |
|
|
|
outer.add(outerMatchdaylayout); |
|
|
|
|
|
|
|
protected void configureContent() { |
|
|
|
getMatchdayHeader().setText(String.format("Matchday %s", matchdaySelect.getValue().toString())); |
|
|
|
getGrid().setItems(matchService.getCalculatedMatches(matchdaySelect.getValue())); |
|
|
|
configureButtons(); |
|
|
|
} |
|
|
|
|
|
|
|
private void configureButtons() { |
|
|
|
prevButton.setEnabled(isMatchDayParamValid(getPrevMatchdayParam())); |
|
|
|
prevButton.addClickListener(getButtonClickListener(prevButton, getPrevMatchdayParam())); |
|
|
|
getPrevButton().setEnabled(isMatchDayParamValid(getPrevMatchdayParam())); |
|
|
|
getPrevButton().addClickListener(getButtonClickListener(getPrevMatchdayParam())); |
|
|
|
|
|
|
|
nextButton.setEnabled(isMatchDayParamValid(getNextMatchdayParam())); |
|
|
|
nextButton.addClickListener(getButtonClickListener(nextButton, getNextMatchdayParam())); |
|
|
|
getNextButton().setEnabled(isMatchDayParamValid(getNextMatchdayParam())); |
|
|
|
getNextButton().addClickListener(getButtonClickListener(getNextMatchdayParam())); |
|
|
|
} |
|
|
|
|
|
|
|
@Nullable |
|
|
|
private Season getSeasonFromParam(@NonNull String seasonParam) { |
|
|
|
for (Season season : seasonList) { |
|
|
|
if (seasonParam.equals(season.toString())) { |
|
|
|
return season; |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
private ComponentEventListener<ClickEvent<Button>> getButtonClickListener(String matchdayParam) { |
|
|
|
return buttonClickEvent -> getUI().ifPresent(ui -> navigate(ui, seasonParam, matchdayParam)); |
|
|
|
} |
|
|
|
|
|
|
|
@Nullable |
|
|
|
private Matchday getMatchdayFromParam(@NonNull String matchdayParam) { |
|
|
|
return getMatchdayFromParam(matchdayParam, null); |
|
|
|
private String getPrevMatchdayParam() { |
|
|
|
return String.valueOf(Integer.parseInt(matchdayParam) - 1); |
|
|
|
} |
|
|
|
|
|
|
|
@Nullable |
|
|
|
private Matchday getMatchdayFromParam(@NonNull String matchdayParam, @Nullable Season season) { |
|
|
|
List<Matchday> matchdayList = season == null ? this.matchdayList : matchdayService.getMatchdaysForSeason(season); |
|
|
|
for (Matchday matchday : matchdayList) { |
|
|
|
if (matchdayParam.equals(matchday.toString())) { |
|
|
|
return matchday; |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
private String getNextMatchdayParam() { |
|
|
|
return String.valueOf(Integer.parseInt(matchdayParam) + 1); |
|
|
|
} |
|
|
|
|
|
|
|
} |