@ -1,18 +0,0 @@ | |||
package app.components.leafletmap; | |||
import com.vaadin.flow.component.Component; | |||
import com.vaadin.flow.component.HasSize; | |||
import com.vaadin.flow.component.Tag; | |||
import com.vaadin.flow.component.dependency.CssImport; | |||
import com.vaadin.flow.component.dependency.JsModule; | |||
@CssImport("leaflet/dist/leaflet.css") | |||
@JsModule("app/components/leafletmap/leaflet-map.js") | |||
@Tag("leaflet-map") | |||
public class LeafletMap extends Component implements HasSize { | |||
public void setView(double latitude, double longitude, int zoomLevel) { | |||
getElement().callJsFunction("setView", latitude, longitude, zoomLevel); | |||
} | |||
} |
@ -1,11 +1,11 @@ | |||
package app.data; | |||
package app.data.entity; | |||
import javax.persistence.GeneratedValue; | |||
import javax.persistence.Id; | |||
import javax.persistence.MappedSuperclass; | |||
@MappedSuperclass | |||
public abstract class AbstractEntity { | |||
public abstract class AbstractEntity { // TODO: Use this in your own entities (adapt annotations and equals()) | |||
@Id | |||
@GeneratedValue |
@ -1,6 +1,6 @@ | |||
package app.data.entity; | |||
package app.data.entity.example; | |||
import app.data.AbstractEntity; | |||
import app.data.entity.AbstractEntity; | |||
import javax.persistence.Entity; | |||
@ -1,6 +1,6 @@ | |||
package app.data.entity; | |||
package app.data.entity.example; | |||
import app.data.AbstractEntity; | |||
import app.data.entity.AbstractEntity; | |||
import javax.persistence.Entity; | |||
import java.time.LocalDate; |
@ -1,40 +0,0 @@ | |||
package app.data.generator; | |||
import app.data.service.SamplePersonRepository; | |||
import com.vaadin.flow.spring.annotation.SpringComponent; | |||
import org.springframework.boot.CommandLineRunner; | |||
import org.springframework.context.annotation.Bean; | |||
@SpringComponent | |||
public class DataGenerator { | |||
@Bean | |||
public CommandLineRunner loadData(SamplePersonRepository samplePersonRepository) { | |||
return args -> { | |||
// Logger logger = LoggerFactory.getLogger(getClass()); | |||
// if (samplePersonRepository.count() != 0L) { | |||
// logger.info("Using existing database"); | |||
// return; | |||
// } | |||
// int seed = 123; | |||
// | |||
// logger.info("Generating demo data"); | |||
// | |||
// logger.info("... generating 100 Sample Person entities..."); | |||
// ExampleDataGenerator<SamplePerson> samplePersonRepositoryGenerator = new ExampleDataGenerator<>( | |||
// SamplePerson.class, LocalDateTime.of(2021, 2, 26, 0, 0, 0)); | |||
// samplePersonRepositoryGenerator.setData(SamplePerson::setId, DataType.ID); | |||
// samplePersonRepositoryGenerator.setData(SamplePerson::setFirstName, DataType.FIRST_NAME); | |||
// samplePersonRepositoryGenerator.setData(SamplePerson::setLastName, DataType.LAST_NAME); | |||
// samplePersonRepositoryGenerator.setData(SamplePerson::setEmail, DataType.EMAIL); | |||
// samplePersonRepositoryGenerator.setData(SamplePerson::setPhone, DataType.PHONE_NUMBER); | |||
// samplePersonRepositoryGenerator.setData(SamplePerson::setDateOfBirth, DataType.DATE_OF_BIRTH); | |||
// samplePersonRepositoryGenerator.setData(SamplePerson::setOccupation, DataType.OCCUPATION); | |||
// samplePersonRepositoryGenerator.setData(SamplePerson::setImportant, DataType.BOOLEAN_10_90); | |||
// samplePersonRepository.saveAll(samplePersonRepositoryGenerator.create(100, seed)); | |||
// | |||
// logger.info("Generated demo data"); | |||
}; | |||
} | |||
} |
@ -1,4 +1,4 @@ | |||
package app.data.service; | |||
package app.data.repository; | |||
import app.data.entity.GameInfo; | |||
import org.springframework.data.jpa.repository.JpaRepository; |
@ -1,4 +1,4 @@ | |||
package app.data.service; | |||
package app.data.repository; | |||
import app.data.entity.Game; | |||
import org.springframework.data.jpa.repository.JpaRepository; |
@ -1,4 +1,4 @@ | |||
package app.data.service; | |||
package app.data.repository; | |||
import app.data.entity.Match; | |||
import org.springframework.data.jpa.repository.JpaRepository; |
@ -1,4 +1,4 @@ | |||
package app.data.service; | |||
package app.data.repository; | |||
import app.data.entity.Matchday; | |||
import org.springframework.data.jpa.repository.JpaRepository; |
@ -1,4 +1,4 @@ | |||
package app.data.service; | |||
package app.data.repository; | |||
import app.data.entity.PlayerInfo; | |||
import org.springframework.data.jpa.repository.JpaRepository; |
@ -1,4 +1,4 @@ | |||
package app.data.service; | |||
package app.data.repository; | |||
import app.data.entity.Player; | |||
import org.springframework.data.jpa.repository.JpaRepository; |
@ -1,4 +1,4 @@ | |||
package app.data.service; | |||
package app.data.repository; | |||
import app.data.entity.Season; | |||
import org.springframework.data.jpa.repository.JpaRepository; |
@ -1,6 +1,6 @@ | |||
package app.data.service; | |||
package app.data.repository.example; | |||
import app.data.entity.SampleAddress; | |||
import app.data.entity.example.SampleAddress; | |||
import org.springframework.data.jpa.repository.JpaRepository; | |||
public interface SampleAddressRepository extends JpaRepository<SampleAddress, Integer> { |
@ -1,6 +1,6 @@ | |||
package app.data.service; | |||
package app.data.repository.example; | |||
import app.data.entity.SamplePerson; | |||
import app.data.entity.example.SamplePerson; | |||
import org.springframework.data.jpa.repository.JpaRepository; | |||
public interface SamplePersonRepository extends JpaRepository<SamplePerson, Integer> { |
@ -1,6 +1,7 @@ | |||
package app.data.service; | |||
package app.data.service.example; | |||
import app.data.entity.SampleAddress; | |||
import app.data.entity.example.SampleAddress; | |||
import app.data.repository.example.SampleAddressRepository; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
import org.vaadin.artur.helpers.CrudService; |
@ -1,6 +1,7 @@ | |||
package app.data.service; | |||
package app.data.service.example; | |||
import app.data.entity.SamplePerson; | |||
import app.data.entity.example.SamplePerson; | |||
import app.data.repository.example.SamplePersonRepository; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
import org.vaadin.artur.helpers.CrudService; |
@ -1,17 +1,17 @@ | |||
package app.image; | |||
package app.gameimage; | |||
import javax.imageio.ImageIO; | |||
import java.awt.image.BufferedImage; | |||
import java.io.File; | |||
import java.io.IOException; | |||
public class ImageUtils { | |||
public class GameImageUtils { | |||
public static final String IMAGE_SOURCE_PATH = "src/main/resources/META-INF/resources/images/chess-sources/"; | |||
public static final String IMAGE_DEST_PATH = "src/main/resources/META-INF/resources/images/games/"; | |||
public static final String EXTENSION = ".png"; | |||
private static final String EXTENSION_WITHOUT_DOT = "png"; | |||
private ImageUtils() {} | |||
private GameImageUtils() {} | |||
public static BufferedImage readImage(String fileNameWithoutExtension) { | |||
BufferedImage img = null; |
@ -1,4 +1,4 @@ | |||
package app.components.navigation; | |||
package app.navigation.components; | |||
import app.navigation.Navigation; | |||
import com.vaadin.flow.component.html.Label; |
@ -1,4 +1,4 @@ | |||
package app.components.navigation.button; | |||
package app.navigation.components.button; | |||
import app.navigation.Navigation; | |||
@ -1,4 +1,4 @@ | |||
package app.components.navigation.button; | |||
package app.navigation.components.button; | |||
import app.data.entity.Matchday; | |||
import app.navigation.Navigation; |
@ -1,4 +1,4 @@ | |||
package app.components.navigation.button; | |||
package app.navigation.components.button; | |||
import app.data.entity.Matchday; | |||
import app.navigation.Navigation; |
@ -0,0 +1,28 @@ | |||
package app.navigation.service; | |||
import app.data.service.MatchService; | |||
import app.data.service.MatchdayService; | |||
import app.data.service.SeasonService; | |||
import app.navigation.Navigation; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
@Service | |||
public class NavigationService { | |||
private final SeasonService seasonService; | |||
private final MatchdayService matchdayService; | |||
private final MatchService matchService; | |||
public NavigationService(@Autowired SeasonService seasonService, | |||
@Autowired MatchdayService matchdayService, | |||
@Autowired MatchService matchService) { | |||
this.seasonService = seasonService; | |||
this.matchdayService = matchdayService; | |||
this.matchService = matchService; | |||
} | |||
public Navigation getNewNavigation() { | |||
return new Navigation(seasonService, matchdayService, matchService); | |||
} | |||
} |
@ -1,22 +0,0 @@ | |||
package app.views.example.map; | |||
import app.components.leafletmap.LeafletMap; | |||
import app.views.main.MainView; | |||
import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||
import com.vaadin.flow.router.PageTitle; | |||
import com.vaadin.flow.router.Route; | |||
@Route(value = "map", layout = MainView.class) | |||
@PageTitle("Map") | |||
public class MapView extends VerticalLayout { | |||
private LeafletMap map = new LeafletMap(); | |||
public MapView() { | |||
setSizeFull(); | |||
setPadding(false); | |||
map.setSizeFull(); | |||
map.setView(55.0, 10.0, 4); | |||
add(map); | |||
} | |||
} |
@ -1,58 +1,54 @@ | |||
package app.views.match; | |||
import app.data.entity.Game; | |||
import app.data.entity.Match; | |||
import app.data.service.MatchService; | |||
import app.data.service.MatchdayService; | |||
import app.data.service.SeasonService; | |||
import app.image.ImageService; | |||
import app.navigation.Navigation; | |||
import app.navigation.service.NavigationService; | |||
import app.views.main.MainView; | |||
import app.views.navigation.NavigationViewBase; | |||
import com.vaadin.flow.component.dependency.CssImport; | |||
import com.vaadin.flow.component.html.Image; | |||
import com.vaadin.flow.router.PageTitle; | |||
import com.vaadin.flow.router.Route; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
@CssImport("app/views/match/match-view.css") | |||
@Route(value = "match", layout = MainView.class) | |||
@PageTitle("Schachliga DACH - Results - Matches") | |||
public class MatchView extends NavigationViewBase { | |||
private final List<Image> images = new ArrayList<>(); | |||
private final MatchService matchService; | |||
private final ImageService imageService; | |||
public MatchView(@Autowired NavigationService navigationService, | |||
@Autowired MatchService matchService) { | |||
super(navigationService, true, true, true); | |||
this.matchService = matchService; | |||
public MatchView(@Autowired SeasonService seasonService, | |||
@Autowired MatchdayService matchdayService, | |||
@Autowired MatchService matchService, | |||
@Autowired ImageService imageService) { | |||
super(seasonService, matchdayService, matchService, true, true, true); | |||
this.imageService = imageService; | |||
addClassName("match-view"); | |||
this.navigation.setSeasonEnabled(true); | |||
this.navigation.setMatchdayEnabled(true); | |||
this.navigation.setMatchEnabled(true); | |||
configureLayout(); | |||
} | |||
/////////// | |||
// ROUTE // | |||
/////////// | |||
@Override | |||
public String getRoute() { | |||
return "match"; | |||
} | |||
//////////// | |||
// LAYOUT // | |||
//////////// | |||
private void configureLayout() { | |||
} | |||
///////////// | |||
// CONTENT // | |||
///////////// | |||
@Override | |||
protected void configureContent() { | |||
Match match = navigation.getSelectedMatch().orElseThrow(); | |||
removeAll(); | |||
for (Game game : match.getGames()) { | |||
Image image = new Image(imageService.getVaadinImagePath(game).orElse(""), "image"); | |||
image.setWidth("30%"); | |||
add(image); | |||
} | |||
} | |||
} |
@ -0,0 +1,96 @@ | |||
package app.views.matchday.components; | |||
import app.data.bean.CalculatedMatch; | |||
import app.data.entity.Matchday; | |||
import app.navigation.Navigation; | |||
import app.navigation.components.button.NextMatchdayButton; | |||
import app.navigation.components.button.PrevMatchdayButton; | |||
import app.utils.StringUtils; | |||
import app.utils.VaadinUtils; | |||
import app.views.navigation.interfaces.ContentConfigurable; | |||
import com.vaadin.flow.component.grid.ColumnTextAlign; | |||
import com.vaadin.flow.component.grid.Grid; | |||
import com.vaadin.flow.component.grid.GridVariant; | |||
import com.vaadin.flow.component.html.Div; | |||
import com.vaadin.flow.component.html.Label; | |||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout; | |||
import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||
import com.vaadin.flow.function.ValueProvider; | |||
import java.util.NoSuchElementException; | |||
public class MatchdayComponent extends Div implements ContentConfigurable { | |||
private final Navigation navigation; | |||
private final VerticalLayout inner = new VerticalLayout(); | |||
private final HorizontalLayout header = new HorizontalLayout(); | |||
private final Label headerLabel = new Label(); | |||
private final Grid<CalculatedMatch> grid = new Grid<>(); | |||
public MatchdayComponent(Navigation navigation) { | |||
this.navigation = navigation; | |||
addClassName("wrapper"); | |||
add(inner); | |||
inner.add(header, grid); | |||
configureHeader(); | |||
configureGrid(); | |||
} | |||
private void configureHeader() { | |||
header.add(new PrevMatchdayButton(this.navigation), headerLabel, new NextMatchdayButton(this.navigation)); | |||
header.setWidthFull(); | |||
headerLabel.addClassName("matchday-header-label"); | |||
} | |||
private void configureGrid() { | |||
Label headerPlayer1 = new Label("Player 1"); | |||
headerPlayer1.addClassName("column_header"); | |||
Label headerPlayer2 = new Label("Player 2"); | |||
headerPlayer2.addClassName("column_header"); | |||
grid.addColumn(VaadinUtils.getPlayerRenderer(CalculatedMatch::getPlayer1)) | |||
.setHeader(headerPlayer1) | |||
.setTextAlign(ColumnTextAlign.END) | |||
.setWidth("13em") | |||
.setFlexGrow(1); | |||
grid.addColumn((ValueProvider<CalculatedMatch, String>) this::getResultString) | |||
.setHeader("vs.") | |||
.setTextAlign(ColumnTextAlign.CENTER) | |||
.setWidth("6em"); | |||
grid.addColumn(VaadinUtils.getPlayerRenderer(CalculatedMatch::getPlayer2)) | |||
.setHeader(headerPlayer2) | |||
.setTextAlign(ColumnTextAlign.START) | |||
.setWidth("13em") | |||
.setFlexGrow(1); | |||
grid.setWidth("32em"); // TODO: find a way to set this dynamically based on column widths | |||
grid.setHeightByRows(true); | |||
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER, | |||
GridVariant.LUMO_NO_ROW_BORDERS, GridVariant.LUMO_ROW_STRIPES); | |||
} | |||
private String getResultString(CalculatedMatch match) { | |||
return StringUtils.getResultString(match.getScore1(), match.getScore2()); | |||
} | |||
@Override | |||
public void configureContent() { | |||
try { | |||
Matchday matchday = navigation.getSelectedMatchday().orElseThrow(); | |||
headerLabel.setText(String.format("Matchday %s", matchday.toString())); // TODO: add dates | |||
grid.setItems(navigation.getMatchService().getCalculatedMatches(matchday)); | |||
} catch (NoSuchElementException e) { | |||
removeAll(); | |||
add(navigation.getValidationLabel()); | |||
} | |||
} | |||
} |
@ -0,0 +1,5 @@ | |||
package app.views.navigation.interfaces; | |||
public interface ContentConfigurable { | |||
void configureContent(); | |||
} |
@ -0,0 +1,129 @@ | |||
package app.views.table.components; | |||
import app.data.bean.PlayerForTable; | |||
import app.data.entity.Matchday; | |||
import app.data.service.PlayerService; | |||
import app.navigation.Navigation; | |||
import app.utils.StringUtils; | |||
import app.utils.VaadinUtils; | |||
import app.views.navigation.interfaces.ContentConfigurable; | |||
import com.vaadin.flow.component.grid.ColumnTextAlign; | |||
import com.vaadin.flow.component.grid.Grid; | |||
import com.vaadin.flow.component.grid.GridVariant; | |||
import com.vaadin.flow.component.html.Div; | |||
import com.vaadin.flow.component.html.Label; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import java.util.NoSuchElementException; | |||
public class TableComponent extends Div implements ContentConfigurable { | |||
private final Navigation navigation; | |||
private final PlayerService playerService; | |||
private final Grid<PlayerForTable> grid = new Grid<>(); | |||
public TableComponent(Navigation navigation, @Autowired PlayerService playerService) { | |||
this.navigation = navigation; | |||
this.playerService = playerService; | |||
addClassName("grid-wrapper"); | |||
add(grid); | |||
configureGrid(); | |||
} | |||
private void configureGrid() { | |||
// TODO: add diff to last matchday | |||
// TODO: rounded corners for rows? | |||
Label headerPlace = new Label("Place"); | |||
headerPlace.addClassName("important-table-column-header"); | |||
Label headerPlayer = new Label("Player"); | |||
headerPlayer.addClassName("important-table-column-header"); | |||
Label headerMatchesPlayed = new Label("Played"); | |||
Label headerMatchPoints = new Label("Points"); | |||
headerMatchPoints.addClassName("important-table-column-header"); | |||
Label headerWon = new Label("W"); | |||
Label headerDrawn = new Label("D"); | |||
Label headerLost = new Label("L"); | |||
Label headerGames = new Label("Games"); | |||
Label headerDiff = new Label("Diff"); | |||
grid.addColumn(VaadinUtils.getBoldStringRenderer(PlayerForTable::getPlaceString)) | |||
.setHeader(headerPlace) | |||
.setTextAlign(ColumnTextAlign.CENTER) | |||
// .setClassNameGenerator(playerForTable -> "leftmost-column-cell") | |||
.setWidth("5em"); | |||
grid.addColumn(VaadinUtils.getPlayerRenderer(PlayerForTable::getPlayer)) | |||
.setHeader(headerPlayer) | |||
.setTextAlign(ColumnTextAlign.START) | |||
.setWidth("13em"); | |||
grid.addColumn(PlayerForTable::getAmountOfMatches) | |||
.setHeader(headerMatchesPlayed) | |||
.setTextAlign(ColumnTextAlign.CENTER) | |||
.setWidth("5em"); | |||
grid.addColumn(VaadinUtils.getBoldStringRenderer(player -> String.valueOf(player.getMatchPoints()))) | |||
.setHeader(headerMatchPoints) | |||
.setTextAlign(ColumnTextAlign.CENTER) | |||
.setWidth("6em"); | |||
grid.addColumn(PlayerForTable::getAmountOfMatchesWon) | |||
.setHeader(headerWon) | |||
.setTextAlign(ColumnTextAlign.CENTER) | |||
.setWidth("3em"); | |||
grid.addColumn(PlayerForTable::getAmountOfMatchesDrawn) | |||
.setHeader(headerDrawn) | |||
.setTextAlign(ColumnTextAlign.CENTER) | |||
.setWidth("3em"); | |||
grid.addColumn(PlayerForTable::getAmountOfMatchesLost) | |||
.setHeader(headerLost) | |||
.setTextAlign(ColumnTextAlign.CENTER) | |||
.setWidth("3em"); | |||
grid.addColumn(this::getResultString) | |||
.setHeader(headerGames) | |||
.setTextAlign(ColumnTextAlign.CENTER) | |||
.setWidth("6em"); | |||
grid.addColumn(player -> StringUtils.getSignedString(player.getGamePointDiff())) | |||
.setHeader(headerDiff) | |||
.setTextAlign(ColumnTextAlign.CENTER) | |||
.setWidth("5em"); | |||
grid.setWidth("51em"); | |||
grid.setHeightByRows(true); | |||
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER, | |||
GridVariant.LUMO_NO_ROW_BORDERS, GridVariant.LUMO_ROW_STRIPES); | |||
} | |||
private String getResultString(PlayerForTable player) { | |||
return StringUtils.getResultString(player.getGamePointsForSelf(), player.getGamePointsForOpponents()); | |||
} | |||
@Override | |||
public void configureContent() { | |||
try { | |||
Matchday matchday = navigation.getSelectedMatchday().orElseThrow(); | |||
grid.setItems(playerService.getPlayersForTable(matchday)); | |||
} catch (NoSuchElementException e) { | |||
removeAll(); | |||
add(navigation.getValidationLabel()); | |||
} | |||
} | |||
} |