From d4864af6f0237ea81841b216c86fd2c72c991786 Mon Sep 17 00:00:00 2001 From: GAM Date: Sat, 20 Mar 2021 07:44:25 +0100 Subject: [PATCH] smaller MatchComponent: added EditMatchCard --- .../views/match/components/EditMatchCard.java | 164 ++++++++++++++++++ .../{GameComponent.java => GameCard.java} | 8 +- .../match/components/MatchComponent.java | 159 +++-------------- src/main/java/app/views/table/TableView.java | 4 +- 4 files changed, 198 insertions(+), 137 deletions(-) create mode 100644 src/main/java/app/views/match/components/EditMatchCard.java rename src/main/java/app/views/match/components/{GameComponent.java => GameCard.java} (92%) diff --git a/src/main/java/app/views/match/components/EditMatchCard.java b/src/main/java/app/views/match/components/EditMatchCard.java new file mode 100644 index 0000000..1b9aed4 --- /dev/null +++ b/src/main/java/app/views/match/components/EditMatchCard.java @@ -0,0 +1,164 @@ +package app.views.match.components; + +import app.data.entity.Game; +import app.data.entity.Match; +import app.data.service.ChessComService; +import app.data.service.MatchService; +import app.gameimage.GameImageService; +import app.navigation.Navigation; +import app.utils.ChessComUtils; +import com.vaadin.flow.component.ClickEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.UI; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +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.textfield.TextField; +import com.vaadin.flow.shared.Registration; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class EditMatchCard extends VerticalLayout { + + private final Navigation navigation; + private final MatchService matchService; + private final ChessComService chessComService; + private final GameImageService gameImageService; + + private final ArrayList textFields = new ArrayList<>(); + // TODO: autocorrect "/live/game" to "/game/live/" + private final Button submitButton = new Button("Submit", new Icon(VaadinIcon.CHECK)); + // TODO: disable when no 6 values in form, and make sure you don't freeze forever when there are wrong entries + // TODO: use overlapping progress here + private Registration editSubmitButtonRegistration; + private final Button editCancelButton = new Button("Cancel", new Icon(VaadinIcon.CLOSE)); + private Registration editCancelButtonRegistration; + private final Button chessComButton = new Button("Autofill with the latest 6 games between the players", new Icon(VaadinIcon.MAGIC)); + private Registration chessComButtonButtonRegistration; + + private Match match; + + public EditMatchCard(Navigation navigation, ChessComService chessComService, GameImageService gameImageService) { + this.navigation = navigation; + this.chessComService = chessComService; + this.matchService = navigation.getMatchService(); + this.gameImageService = gameImageService; + + defineLayout(); + } + + //////////// + // LAYOUT // + //////////// + + private void defineLayout() { + setAlignItems(FlexComponent.Alignment.CENTER); + setWidth(""); + addClassName("wrapper"); + add(chessComButton); + + defineTextFields(); + defineSubmitButton(); + addSubmitAndCancelButtons(); + } + + private void defineTextFields() { + for (int i = 0; i < 6; i++) { + TextField textField = new TextField(); + textField.setWidth("23em"); + HorizontalLayout horizontalLayout = new HorizontalLayout(new Label(String.format("Game %d:", i + 1)), textField); + horizontalLayout.setAlignItems(FlexComponent.Alignment.CENTER); + horizontalLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); + add(horizontalLayout); + textFields.add(textField); + } + } + + private void defineSubmitButton() { + submitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + } + + private void addSubmitAndCancelButtons() { + HorizontalLayout buttonLayout = new HorizontalLayout(); + buttonLayout.setAlignItems(FlexComponent.Alignment.CENTER); + buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); + buttonLayout.add(submitButton, editCancelButton); + add(buttonLayout); + } + + ///////////// + // CONTENT // + ///////////// + + void configureContent(Match match) { + this.match = match; + List games = new ArrayList<>(match.getGames()); + + clearTextFields(); + fillTextFieldsWithURLs(games); + + configureChessComButton(); + configureEditSubmitButton(); + configureEditCancelButton(); + } + + private void clearTextFields() { + textFields.forEach(textField -> textField.setValue("")); + } + + private void fillTextFieldsWithURLs(List games) { + for (int i = 0; i < Math.min(games.size(), 6); i++) + textFields.get(i).setValue(ChessComUtils.getGameURL(games.get(i))); + } + + private void configureChessComButton() { + if (chessComButtonButtonRegistration != null) chessComButtonButtonRegistration.remove(); + chessComButtonButtonRegistration = chessComButton.addClickListener(createChessComButtonClickListener()); + } + + private ComponentEventListener> createChessComButtonClickListener() { + return event -> { + List gamesBetweenPlayers = chessComService.getLatestGamesBetweenPlayers(match, 6, 2); + fillTextFieldsWithURLs(gamesBetweenPlayers); + }; + } + + private void configureEditSubmitButton() { + if (editSubmitButtonRegistration != null) editSubmitButtonRegistration.remove(); + editSubmitButtonRegistration = submitButton.addClickListener(createEditSubmitButtonClickListener()); + } + + private ComponentEventListener> createEditSubmitButtonClickListener() { + return event -> { + match.getGames().clear(); + addGamesToMatchFromFieldValues(); + matchService.update(match); + match.getGames().forEach(gameImageService::createImageIfNotPresent); + + navigation.setEditFlag(false); + }; + } + + private void addGamesToMatchFromFieldValues() { + for (TextField textField : textFields) { + Optional game = chessComService.getGame(textField.getValue(), match); // TODO: handle this when Optional is empty! + game.ifPresent(value -> match.getGames().add(value)); + } + } + + private void configureEditCancelButton() { + if (editCancelButtonRegistration != null) editCancelButtonRegistration.remove(); + editCancelButtonRegistration = editCancelButton.addClickListener(createEditCancelButtonListener()); + } + + private ComponentEventListener> createEditCancelButtonListener() { + return event -> UI.getCurrent().navigate(String.format("matchday/%s", navigation.getWildcardParam().replace("edit/", ""))); + } +} diff --git a/src/main/java/app/views/match/components/GameComponent.java b/src/main/java/app/views/match/components/GameCard.java similarity index 92% rename from src/main/java/app/views/match/components/GameComponent.java rename to src/main/java/app/views/match/components/GameCard.java index 46cf601..64caf52 100644 --- a/src/main/java/app/views/match/components/GameComponent.java +++ b/src/main/java/app/views/match/components/GameCard.java @@ -12,7 +12,7 @@ import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import org.springframework.beans.factory.annotation.Autowired; -public class GameComponent extends Div { +public class GameCard extends Div { private final GameImageService gameImageService; @@ -23,7 +23,7 @@ public class GameComponent extends Div { private final VerticalLayout left = new VerticalLayout(); private final Div right = new Div(); - public GameComponent(Game game, @Autowired GameImageService gameImageService) { + public GameCard(Game game, @Autowired GameImageService gameImageService) { this.gameImageService = gameImageService; this.game = game; @@ -33,6 +33,10 @@ public class GameComponent extends Div { defineInner(); } + //////////// + // LAYOUT // + //////////// + private void defineInner() { add(inner); inner.add(left, right); diff --git a/src/main/java/app/views/match/components/MatchComponent.java b/src/main/java/app/views/match/components/MatchComponent.java index c1714f3..9f6e581 100644 --- a/src/main/java/app/views/match/components/MatchComponent.java +++ b/src/main/java/app/views/match/components/MatchComponent.java @@ -7,13 +7,9 @@ import app.data.service.ChessComService; import app.data.service.MatchService; import app.gameimage.GameImageService; import app.navigation.Navigation; -import app.utils.ChessComUtils; import app.utils.EntityComponentUtils; import app.utils.StringUtils; import app.views.navigation.interfaces.ContentConfigurable; -import com.vaadin.flow.component.ClickEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.UI; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.html.Div; @@ -24,20 +20,13 @@ import com.vaadin.flow.component.orderedlayout.FlexComponent; import com.vaadin.flow.component.orderedlayout.FlexLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.progressbar.ProgressBar; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.shared.Registration; import org.springframework.beans.factory.annotation.Autowired; -import java.util.ArrayList; -import java.util.List; import java.util.NoSuchElementException; -import java.util.Optional; public class MatchComponent extends Div implements ContentConfigurable { private final Navigation navigation; - private final ChessComService chessComService; private final MatchService matchService; private final GameImageService gameImageService; @@ -48,18 +37,9 @@ public class MatchComponent extends Div implements ContentConfigurable { private final FlexLayout gamesLayout = new FlexLayout(); private final VerticalLayout noGamesLayout = new VerticalLayout(); - private final FlexLayout editLayoutWrapper = new FlexLayout(); - private final VerticalLayout editLayout = new VerticalLayout(); - private final ArrayList editTextFields = new ArrayList<>(); - // TODO: autocorrect "/live/game" to "/game/live/" - private final Button editSubmitButton = new Button("Submit", new Icon(VaadinIcon.CHECK)); - // TODO: disable when no 6 values in form, and make sure you don't freeze forever when there are wrong entries - // TODO: use overlapping progress here - private Registration editSubmitButtonRegistration; - private final Button editCancelButton = new Button("Cancel", new Icon(VaadinIcon.CLOSE)); - private Registration editCancelButtonRegistration; - private final Button chessComButton = new Button("Autofill with the latest 6 games between the players", new Icon(VaadinIcon.MAGIC)); - private Registration chessComButtonButtonRegistration; + private final FlexLayout editMatchLayout = new FlexLayout(); + + private final EditMatchCard editMatchCard; private Match match; private CalculatedMatch calculatedMatch; @@ -68,18 +48,33 @@ public class MatchComponent extends Div implements ContentConfigurable { @Autowired ChessComService chessComService, @Autowired GameImageService gameImageService) { this.navigation = navigation; - this.chessComService = chessComService; this.matchService = navigation.getMatchService(); this.gameImageService = gameImageService; + this.editMatchCard = new EditMatchCard(navigation, chessComService, gameImageService); + + defineLayout(); + } + + //////////// + // LAYOUT // + //////////// + + private void defineLayout() { add(headerLayout); + defineEditMatchLayout(); defineHeaderLayout(); defineGamesLayout(); defineNoGamesLayout(); defineEditLayout(); } + private void defineEditMatchLayout() { + editMatchLayout.add(editMatchCard); + editMatchLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); + } + private void defineNoGamesLayout() { noGamesLayout.add(createNoGamesLabel(), createAddGamesButton()); noGamesLayout.setAlignItems(FlexComponent.Alignment.CENTER); @@ -114,49 +109,11 @@ public class MatchComponent extends Div implements ContentConfigurable { } private void defineEditLayout() { - defineEditLayoutWrapper(); - defineEditLayoutItself(); - defineEditLayoutTextFields(); - defineEditSubmitButton(); - addButtonsToEditLayout(); - } - - private void defineEditLayoutWrapper() { - editLayoutWrapper.add(editLayout); - editLayoutWrapper.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); } - private void defineEditLayoutItself() { - editLayout.setAlignItems(FlexComponent.Alignment.CENTER); - editLayout.setWidth(""); - - editLayout.addClassName("wrapper"); - - editLayout.add(chessComButton); - } - - private void defineEditLayoutTextFields() { - for (int i = 0; i < 6; i++) { - TextField textField = new TextField(); - textField.setWidth("23em"); - HorizontalLayout horizontalLayout = new HorizontalLayout(new Label(String.format("Game %d:", i + 1)), textField); - horizontalLayout.setAlignItems(FlexComponent.Alignment.CENTER); - horizontalLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); - editLayout.add(horizontalLayout); - editTextFields.add(textField); - } - } - - private void defineEditSubmitButton() { - editSubmitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - } - private void addButtonsToEditLayout() { - HorizontalLayout buttonLayout = new HorizontalLayout(); - buttonLayout.setAlignItems(FlexComponent.Alignment.CENTER); - buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); - buttonLayout.add(editSubmitButton, editCancelButton); - editLayout.add(buttonLayout); - } + ///////////// + // CONTENT // + ///////////// @Override public void configureContent() { @@ -198,78 +155,14 @@ public class MatchComponent extends Div implements ContentConfigurable { private void configureMainContent() { if (navigation.editFlag()) { remove(gamesLayout); - add(editLayoutWrapper); - configureEditContent(); + add(editMatchCard); + editMatchCard.configureContent(match); return; } - remove(editLayoutWrapper); + remove(editMatchCard); configureGamesContent(); } - private void configureEditContent() { - List games = new ArrayList<>(match.getGames()); - - clearTextFields(); - fillTextFieldsWithURLs(games); - - configureChessComButton(); - configureEditSubmitButton(); - configureEditCancelButton(); - } - - private void clearTextFields() { - editTextFields.forEach(textField -> textField.setValue("")); - } - - private void fillTextFieldsWithURLs(List games) { - for (int i = 0; i < Math.min(games.size(), 6); i++) - editTextFields.get(i).setValue(ChessComUtils.getGameURL(games.get(i))); - } - - private void configureChessComButton() { - if (chessComButtonButtonRegistration != null) chessComButtonButtonRegistration.remove(); - chessComButtonButtonRegistration = chessComButton.addClickListener(createChessComButtonClickListener()); - } - - private ComponentEventListener> createChessComButtonClickListener() { - return event -> { - List gamesBetweenPlayers = chessComService.getLatestGamesBetweenPlayers(match, 6, 2); - fillTextFieldsWithURLs(gamesBetweenPlayers); - }; - } - - private void configureEditSubmitButton() { - if (editSubmitButtonRegistration != null) editSubmitButtonRegistration.remove(); - editSubmitButtonRegistration = editSubmitButton.addClickListener(createEditSubmitButtonClickListener()); - } - - private ComponentEventListener> createEditSubmitButtonClickListener() { - return event -> { - match.getGames().clear(); - addGamesToMatchFromFieldValues(); - matchService.update(match); - match.getGames().forEach(gameImageService::createImageIfNotPresent); - - navigation.setEditFlag(false); - }; - } - - private void addGamesToMatchFromFieldValues() { - for (TextField textField : editTextFields) { - Optional game = chessComService.getGame(textField.getValue(), match); // TODO: handle this when Optional is empty! - game.ifPresent(value -> match.getGames().add(value)); - } - } - - private void configureEditCancelButton() { - if (editCancelButtonRegistration != null) editCancelButtonRegistration.remove(); - editCancelButtonRegistration = editCancelButton.addClickListener(createEditCancelButtonListener()); - } - - private ComponentEventListener> createEditCancelButtonListener() { - return event -> UI.getCurrent().navigate(String.format("matchday/%s", navigation.getWildcardParam().replace("edit/", ""))); - } - private void configureGamesContent() { if (match.getGames().isEmpty()) { remove(gamesLayout); @@ -282,7 +175,7 @@ public class MatchComponent extends Div implements ContentConfigurable { gamesLayout.removeAll(); for (Game game : match.getGames()) { - gamesLayout.add(new GameComponent(game, gameImageService)); + gamesLayout.add(new GameCard(game, gameImageService)); } } } diff --git a/src/main/java/app/views/table/TableView.java b/src/main/java/app/views/table/TableView.java index 4af2419..6d53945 100644 --- a/src/main/java/app/views/table/TableView.java +++ b/src/main/java/app/views/table/TableView.java @@ -31,14 +31,14 @@ public class TableView extends NavigationViewBase { addClassName("table-view"); - configureLayout(); + defineLayout(); } //////////// // LAYOUT // //////////// - private void configureLayout() { + private void defineLayout() { tableComponent = new TableComponent(navigation, playerService); add(tableComponent); }