Browse Source

Dates for Matchdays, Table-Formatting

master
GAM 4 years ago
parent
commit
ca14661ae9
15 changed files with 146 additions and 58 deletions
  1. +9
    -8
      db/db_increment_001.sql
  2. +5
    -0
      db/db_increment_002.sql
  3. +1
    -1
      frontend/app/views/main/main-view.css
  4. +4
    -4
      frontend/app/views/matchday/matchday-view.css
  5. +7
    -1
      frontend/app/views/table/table-view.css
  6. +20
    -0
      src/main/java/app/data/entity/Season.java
  7. +3
    -6
      src/main/java/app/data/service/MatchdayService.java
  8. +1
    -1
      src/main/java/app/navigation/Navigation.java
  9. +30
    -0
      src/main/java/app/utils/ComponentUtils.java
  10. +0
    -18
      src/main/java/app/utils/EntityComponentUtils.java
  11. +4
    -5
      src/main/java/app/views/match/components/EditMatchCard.java
  12. +3
    -3
      src/main/java/app/views/match/components/MatchComponent.java
  13. +2
    -2
      src/main/java/app/views/match/components/utils/GameCardUtils.java
  14. +36
    -7
      src/main/java/app/views/matchday/components/MatchdayCard.java
  15. +21
    -2
      src/main/java/app/views/table/components/TableCard.java

+ 9
- 8
db/db_increment_001.sql View File

@ -1,8 +1,9 @@
ALTER TABLE "game_info" ADD COLUMN "pgn" varchar;
ALTER TABLE "game_info" ADD COLUMN "rated" boolean;
ALTER TABLE "game_info" ADD COLUMN "time_class" varchar;
ALTER TABLE "game_info" ADD COLUMN "rules" varchar;
ALTER TABLE "game_info" ADD COLUMN "white_rating" int;
ALTER TABLE "game_info" ADD COLUMN "black_rating" int;
ALTER TABLE "game_info" ADD COLUMN "white_result" varchar;
ALTER TABLE "game_info" ADD COLUMN "black_result" varchar;
ALTER TABLE "game_info"
ADD COLUMN "pgn" varchar,
ADD COLUMN "rated" boolean,
ADD COLUMN "time_class" varchar,
ADD COLUMN "rules" varchar,
ADD COLUMN "white_rating" int,
ADD COLUMN "black_rating" int,
ADD COLUMN "white_result" varchar,
ADD COLUMN "black_result" varchar;

+ 5
- 0
db/db_increment_002.sql View File

@ -0,0 +1,5 @@
ALTER TABLE "season"
ADD COLUMN "week_of_first_matchday" int not null default 9 CHECK ( week_of_first_matchday > 0 AND week_of_first_matchday <= 53 ),
ADD COLUMN "first_weekday_of_matchday" int not null default 2 CHECK ( first_weekday_of_matchday > 0 AND first_weekday_of_matchday <= 7 ),
ADD COLUMN "last_weekday_of_matchday" int not null default 1 CHECK ( last_weekday_of_matchday > 0 AND last_weekday_of_matchday <= 7 ),
ADD COLUMN "weekday_of_view_change" int not null default 4 CHECK ( weekday_of_view_change > 0 AND weekday_of_view_change <= 7 );

+ 1
- 1
frontend/app/views/main/main-view.css View File

@ -25,7 +25,7 @@
font-weight: bold; font-weight: bold;
} }
.nickname-label {
.parentheses-label {
margin-left: var(--lumo-space-xs); margin-left: var(--lumo-space-xs);
} }


+ 4
- 4
frontend/app/views/matchday/matchday-view.css View File

@ -3,9 +3,9 @@
font-size: large; font-size: large;
} }
.matchday-view .matchday-header-label {
.matchday-view .matchday-header-label-layout {
width: 100%; width: 100%;
font-weight: bolder;
justify-content: center;
font-size: x-large; font-size: x-large;
text-align: center;
}
}

+ 7
- 1
frontend/app/views/table/table-view.css View File

@ -1,4 +1,10 @@
.table-view .important-table-column-header { .table-view .important-table-column-header {
font-weight: bold; font-weight: bold;
font-size: large; font-size: large;
}
}
.table-view .table-header-label-layout {
width: 100%;
justify-content: center;
font-size: x-large;
}

+ 20
- 0
src/main/java/app/data/entity/Season.java View File

@ -24,6 +24,26 @@ public class Season extends AbstractEntity {
nullable = false) nullable = false)
private Integer yearEnd; private Integer yearEnd;
@Basic
@Column(name = "week_of_first_matchday",
nullable = false)
private Integer weekOfFirstMatchday;
@Basic
@Column(name = "first_weekday_of_matchday",
nullable = false)
private Integer firstWeekdayOfMatchday;
@Basic
@Column(name = "last_weekday_of_matchday",
nullable = false)
private Integer lastWeekdayOfMatchday;
@Basic
@Column(name = "weekday_of_view_change",
nullable = false)
private Integer weekdayOfViewChange;
@OneToMany(mappedBy = "season", @OneToMany(mappedBy = "season",
cascade = CascadeType.ALL, cascade = CascadeType.ALL,
orphanRemoval = true) orphanRemoval = true)


+ 3
- 6
src/main/java/app/data/service/MatchdayService.java View File

@ -52,12 +52,9 @@ public class MatchdayService extends CrudService<Matchday, Integer> {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public Optional<Matchday> getLastMatchdayWithActivityOrElseFirstMatchday(@NonNull Season season) {
List<Matchday> matchdaysWithActivity = getMatchdaysWithActivitySorted(season);
if (matchdaysWithActivity.isEmpty()) {
return getFirstMatchday(season);
}
return Optional.of(matchdaysWithActivity.get(matchdaysWithActivity.size() - 1));
public List<Matchday> getMatchdaysWithActivitySortedOrElseListWithOnlyFirstMatchday(@NonNull Season season) {
List<Matchday> matchdaysWithActivitySorted = getMatchdaysWithActivitySorted(season);
return matchdaysWithActivitySorted.isEmpty() ? List.of(getFirstMatchday(season).orElseThrow()) : matchdaysWithActivitySorted;
} }
public boolean hasActivity(@NonNull Matchday matchday) { public boolean hasActivity(@NonNull Matchday matchday) {


+ 1
- 1
src/main/java/app/navigation/Navigation.java View File

@ -196,7 +196,7 @@ public class Navigation implements HasUrlParameter<String> {
private void fillMatchdaySelectWithData(Season season) { private void fillMatchdaySelectWithData(Season season) {
matchdayList.clear(); matchdayList.clear();
List<Matchday> matchdaysToAdd = onlyMatchdaysWithActivity ? List<Matchday> matchdaysToAdd = onlyMatchdaysWithActivity ?
matchdayService.getMatchdaysWithActivitySorted(season) : matchdayService.getMatchdaysSorted(season);
matchdayService.getMatchdaysWithActivitySortedOrElseListWithOnlyFirstMatchday(season) : matchdayService.getMatchdaysSorted(season);
matchdayList.addAll(matchdaysToAdd); matchdayList.addAll(matchdaysToAdd);
matchdaySelect.setItems(matchdayList); matchdaySelect.setItems(matchdayList);
} }


+ 30
- 0
src/main/java/app/utils/ComponentUtils.java View File

@ -0,0 +1,30 @@
package app.utils;
import app.data.entity.Player;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
public class ComponentUtils {
private ComponentUtils() {
}
public static HorizontalLayout getPlayerLabel(Player player) {
return getFormattedLabelWithParentheses(player.getName(), player.getNickname());
}
public static HorizontalLayout getFormattedLabelWithParentheses(String mainText, String textInParentheses) {
HorizontalLayout horizontalLayout = new HorizontalLayout();
configureFormattedLabelWithParentheses(horizontalLayout, mainText, textInParentheses);
return horizontalLayout;
}
public static void configureFormattedLabelWithParentheses(HorizontalLayout horizontalLayout, String mainText, String textInParentheses) {
Label mainLabel = new Label(mainText);
mainLabel.addClassName("bold-label");
Label parenthesesLabel = new Label(String.format("(%s)", textInParentheses));
parenthesesLabel.addClassName("parentheses-label");
horizontalLayout.removeAll();
horizontalLayout.add(mainLabel, parenthesesLabel);
}
}

+ 0
- 18
src/main/java/app/utils/EntityComponentUtils.java View File

@ -1,18 +0,0 @@
package app.utils;
import app.data.entity.Player;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
public class EntityComponentUtils {
private EntityComponentUtils() {
}
public static HorizontalLayout getPlayerLabel(Player player) {
Label name = new Label(player.getName());
name.addClassName("bold-label");
Label nickname = new Label(String.format("(%s)", player.getNickname()));
nickname.addClassName("nickname-label");
return new HorizontalLayout(name, nickname);
}
}

+ 4
- 5
src/main/java/app/views/match/components/EditMatchCard.java View File

@ -7,6 +7,7 @@ import app.data.service.MatchService;
import app.gameimage.GameImageService; import app.gameimage.GameImageService;
import app.navigation.Navigation; import app.navigation.Navigation;
import app.utils.ChessComUtils; import app.utils.ChessComUtils;
import app.utils.ComponentUtils;
import app.utils.MatchUtils; import app.utils.MatchUtils;
import app.utils.TimeControl; import app.utils.TimeControl;
import com.vaadin.flow.component.ClickEvent; import com.vaadin.flow.component.ClickEvent;
@ -85,11 +86,9 @@ public class EditMatchCard extends VerticalLayout {
TextField textField = new TextField(); TextField textField = new TextField();
textField.setWidth("23em"); textField.setWidth("23em");
textField.setPlaceholder("Please enter URL"); textField.setPlaceholder("Please enter URL");
Label gameLabel = new Label(String.format("Game %d", startGameNumber + i));
gameLabel.addClassName("bold-label");
Label timeControlLabel = new Label(String.format("(%s):", timeControl.toPresentationString()));
timeControlLabel.addClassName("nickname-label");
HorizontalLayout labelLayout = new HorizontalLayout(gameLabel, timeControlLabel);
String gameString = String.format("Game %d", startGameNumber + i);
String timeControlString = timeControl.toPresentationString();
HorizontalLayout labelLayout = ComponentUtils.getFormattedLabelWithParentheses(gameString, timeControlString);
labelLayout.setSpacing(false); labelLayout.setSpacing(false);
labelLayout.setAlignItems(Alignment.CENTER); labelLayout.setAlignItems(Alignment.CENTER);
labelLayout.setJustifyContentMode(JustifyContentMode.START); labelLayout.setJustifyContentMode(JustifyContentMode.START);


+ 3
- 3
src/main/java/app/views/match/components/MatchComponent.java View File

@ -7,7 +7,7 @@ import app.data.service.ChessComService;
import app.data.service.MatchService; import app.data.service.MatchService;
import app.gameimage.GameImageService; import app.gameimage.GameImageService;
import app.navigation.Navigation; import app.navigation.Navigation;
import app.utils.EntityComponentUtils;
import app.utils.ComponentUtils;
import app.utils.StringUtils; import app.utils.StringUtils;
import app.views.navigation.interfaces.ContentConfigurable; import app.views.navigation.interfaces.ContentConfigurable;
import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.Button;
@ -129,8 +129,8 @@ public class MatchComponent extends Div implements ContentConfigurable {
} }
private void configureHeaderPlayersLayout() { private void configureHeaderPlayersLayout() {
HorizontalLayout player1 = EntityComponentUtils.getPlayerLabel(calculatedMatch.getPlayer1());
HorizontalLayout player2 = EntityComponentUtils.getPlayerLabel(calculatedMatch.getPlayer2());
HorizontalLayout player1 = ComponentUtils.getPlayerLabel(calculatedMatch.getPlayer1());
HorizontalLayout player2 = ComponentUtils.getPlayerLabel(calculatedMatch.getPlayer2());
Label vs = new Label("vs."); Label vs = new Label("vs.");
headerPlayersLayout.removeAll(); headerPlayersLayout.removeAll();


+ 2
- 2
src/main/java/app/views/match/components/utils/GameCardUtils.java View File

@ -3,7 +3,7 @@ package app.views.match.components.utils;
import app.data.entity.Game; import app.data.entity.Game;
import app.data.entity.Player; import app.data.entity.Player;
import app.utils.ChessComUtils; import app.utils.ChessComUtils;
import app.utils.EntityComponentUtils;
import app.utils.ComponentUtils;
import app.utils.TimeControl; import app.utils.TimeControl;
import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.button.ButtonVariant;
@ -44,7 +44,7 @@ public class GameCardUtils {
div.addClassName("player"); div.addClassName("player");
div.addClassName(white ? "white-player" : "black-player"); div.addClassName(white ? "white-player" : "black-player");
HorizontalLayout playerLabel = EntityComponentUtils.getPlayerLabel(player);
HorizontalLayout playerLabel = ComponentUtils.getPlayerLabel(player);
playerLabel.setWidthFull(); playerLabel.setWidthFull();
playerLabel.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); playerLabel.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);


+ 36
- 7
src/main/java/app/views/matchday/components/MatchdayCard.java View File

@ -5,6 +5,7 @@ import app.data.entity.Matchday;
import app.navigation.Navigation; import app.navigation.Navigation;
import app.navigation.components.button.NextMatchdayButton; import app.navigation.components.button.NextMatchdayButton;
import app.navigation.components.button.PrevMatchdayButton; import app.navigation.components.button.PrevMatchdayButton;
import app.utils.ComponentUtils;
import app.utils.EntityStringUtils; import app.utils.EntityStringUtils;
import app.utils.StringUtils; import app.utils.StringUtils;
import app.utils.VaadinUtils; import app.utils.VaadinUtils;
@ -21,33 +22,43 @@ import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
public class MatchdayCard extends Div implements ContentConfigurable { public class MatchdayCard extends Div implements ContentConfigurable {
private final Navigation navigation; private final Navigation navigation;
private final Calendar calendar = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.");
private final HorizontalLayout header = new HorizontalLayout(); private final HorizontalLayout header = new HorizontalLayout();
private final Label headerLabel = new Label();
private final HorizontalLayout headerLabelLayout = new HorizontalLayout();
private final Grid<CalculatedMatch> grid = new Grid<>(); private final Grid<CalculatedMatch> grid = new Grid<>();
public MatchdayCard(Navigation navigation) { public MatchdayCard(Navigation navigation) {
this.navigation = navigation; this.navigation = navigation;
addClassName("card"); addClassName("card");
VerticalLayout inner = new VerticalLayout();
add(inner);
inner.add(header, grid);
add(new VerticalLayout(header, grid));
defineCalendar();
defineHeader(); defineHeader();
defineGrid(); defineGrid();
} }
private void defineCalendar() {
calendar.setFirstDayOfWeek(Calendar.MONDAY);
}
private void defineHeader() { private void defineHeader() {
header.add(new PrevMatchdayButton(this.navigation), headerLabel, new NextMatchdayButton(this.navigation));
header.add(new PrevMatchdayButton(this.navigation), headerLabelLayout, new NextMatchdayButton(this.navigation));
header.setWidthFull(); header.setWidthFull();
headerLabel.addClassName("matchday-header-label");
headerLabelLayout.addClassName("matchday-header-label-layout");
} }
@ -119,11 +130,29 @@ public class MatchdayCard extends Div implements ContentConfigurable {
public void configureContent() { public void configureContent() {
try { try {
Matchday matchday = navigation.getSelectedMatchday().orElseThrow(); Matchday matchday = navigation.getSelectedMatchday().orElseThrow();
headerLabel.setText(String.format("Matchday %s", EntityStringUtils.getMatchdayString(matchday))); // TODO: add dates
configureHeaderLabels(matchday);
grid.setItems(navigation.getMatchService().getCalculatedMatches(matchday)); grid.setItems(navigation.getMatchService().getCalculatedMatches(matchday));
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
removeAll(); removeAll();
add(navigation.getValidationLabel()); add(navigation.getValidationLabel());
} }
} }
private void configureHeaderLabels(Matchday matchday) {
int week = matchday.getSeason().getWeekOfFirstMatchday() + matchday.getNumber() - 1;
int firstDay = matchday.getSeason().getFirstWeekdayOfMatchday();
int lastDay = matchday.getSeason().getLastWeekdayOfMatchday();
calendar.set(Calendar.WEEK_OF_YEAR, week);
calendar.set(Calendar.DAY_OF_WEEK, firstDay);
String startDate = dateFormat.format(calendar.getTime());
calendar.set(Calendar.DAY_OF_WEEK, lastDay);
String endDate = dateFormat.format(calendar.getTime());
String mainText = String.format("Matchday %s", EntityStringUtils.getMatchdayString(matchday));
String dateText = String.format("%s - %s", startDate, endDate);
ComponentUtils.configureFormattedLabelWithParentheses(headerLabelLayout, mainText, dateText);
}
} }

+ 21
- 2
src/main/java/app/views/table/components/TableCard.java View File

@ -4,6 +4,10 @@ import app.data.bean.PlayerForTable;
import app.data.entity.Matchday; import app.data.entity.Matchday;
import app.data.service.PlayerService; import app.data.service.PlayerService;
import app.navigation.Navigation; import app.navigation.Navigation;
import app.navigation.components.button.NextMatchdayButton;
import app.navigation.components.button.PrevMatchdayButton;
import app.utils.ComponentUtils;
import app.utils.EntityStringUtils;
import app.utils.StringUtils; import app.utils.StringUtils;
import app.utils.VaadinUtils; import app.utils.VaadinUtils;
import app.views.navigation.interfaces.ContentConfigurable; import app.views.navigation.interfaces.ContentConfigurable;
@ -16,6 +20,7 @@ import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.FlexComponent; import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
@ -26,18 +31,28 @@ public class TableCard extends Div implements ContentConfigurable {
private final PlayerService playerService; private final PlayerService playerService;
private final HorizontalLayout header = new HorizontalLayout();
private final HorizontalLayout headerLabelLayout = new HorizontalLayout();
private final Grid<PlayerForTable> grid = new Grid<>(); private final Grid<PlayerForTable> grid = new Grid<>();
public TableCard(Navigation navigation, @Autowired PlayerService playerService) { public TableCard(Navigation navigation, @Autowired PlayerService playerService) {
this.navigation = navigation; this.navigation = navigation;
this.playerService = playerService; this.playerService = playerService;
addClassName("grid-card");
add(grid);
addClassName("card");
add(new VerticalLayout(header, grid));
defineHeader();
defineGrid(); defineGrid();
} }
private void defineHeader() {
header.add(new PrevMatchdayButton(this.navigation), headerLabelLayout, new NextMatchdayButton(this.navigation));
header.setWidthFull();
headerLabelLayout.addClassName("table-header-label-layout");
}
private void defineGrid() { private void defineGrid() {
// TODO: rounded corners for rows? // TODO: rounded corners for rows?
@ -147,6 +162,10 @@ public class TableCard extends Div implements ContentConfigurable {
public void configureContent() { public void configureContent() {
try { try {
Matchday matchday = navigation.getSelectedMatchday().orElseThrow(); Matchday matchday = navigation.getSelectedMatchday().orElseThrow();
String mainText = "Table";
String matchdayText = String.format("Matchday %s", EntityStringUtils.getMatchdayString(matchday));
ComponentUtils.configureFormattedLabelWithParentheses(headerLabelLayout, mainText, matchdayText);
grid.setItems(playerService.getPlayersForTable(matchday)); grid.setItems(playerService.getPlayersForTable(matchday));
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
removeAll(); removeAll();


Loading…
Cancel
Save