make details for Comic, Artist and Issue clickable, add CustomField to select Comic and Issue

This commit is contained in:
Thomas Peetz
2025-06-05 17:58:27 +02:00
parent ea9f596abe
commit b4a0c2d7a5
11 changed files with 160 additions and 28 deletions
@@ -70,6 +70,18 @@ public class Issue extends AbstractEntity {
return null;
}
public String getFullTitle() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(this.getComic().getTitle());
stringBuilder.append(" #");
stringBuilder.append(this.getIssueNumber());
if (this.title !=null && !this.title.isEmpty()) {
stringBuilder.append(": ");
stringBuilder.append(this.title);
}
return stringBuilder.toString();
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
@@ -16,7 +16,10 @@ import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.Binder;
import de.thpeetz.kontor.comics.data.*;
import de.thpeetz.kontor.comics.data.Comic;
import de.thpeetz.kontor.comics.data.Issue;
import de.thpeetz.kontor.comics.data.IssueWork;
import de.thpeetz.kontor.comics.data.Volume;
import de.thpeetz.kontor.common.views.YearMonthField;
import lombok.extern.slf4j.Slf4j;
@@ -14,12 +14,13 @@ import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.Binder;
import de.thpeetz.kontor.comics.data.Artist;
import de.thpeetz.kontor.comics.data.Issue;
import de.thpeetz.kontor.comics.data.Comic;
import de.thpeetz.kontor.comics.data.IssueWork;
import de.thpeetz.kontor.comics.data.Worktype;
import de.thpeetz.kontor.common.views.ComicIssueField;
public class IssueWorkForm extends FormLayout {
ComboBox<Issue> issue = new ComboBox<>("Issue");
ComicIssueField issue = new ComicIssueField("Issue");
ComboBox<Artist> artist = new ComboBox<>("Artist");
ComboBox<Worktype> workType = new ComboBox<>("Worktype");
@@ -29,12 +30,13 @@ public class IssueWorkForm extends FormLayout {
Binder<IssueWork> binder = new BeanValidationBinder<>(IssueWork.class);
public IssueWorkForm(List<Issue> issues, List<Artist> artists, List<Worktype> workTypes) {
public IssueWorkForm(List<Comic> comics, List<Artist> artists, List<Worktype> workTypes) {
addClassName("issuework-form");
binder.bindInstanceFields(this);
issue.setItems(issues);
issue.setItemLabelGenerator(Issue::getIssueNumber);
issue.setComics(comics);
//issue.setItems(issues);
//issue.setItemLabelGenerator(Issue::getIssueNumber);
artist.setItems(artists);
artist.setItemLabelGenerator(Artist::getName);
workType.setItems(workTypes);
@@ -1,6 +1,8 @@
package de.thpeetz.kontor.comics.views;
import de.thpeetz.kontor.comics.data.Issue;
import de.thpeetz.kontor.comics.data.IssueWork;
import lombok.Getter;
import org.springframework.context.annotation.Scope;
import com.vaadin.flow.component.Component;
@@ -24,7 +26,9 @@ import jakarta.annotation.security.PermitAll;
@PageTitle("IssueWork | Comics | Kontor")
public class IssueWorkView extends VerticalLayout {
@Getter
Grid<IssueWork> grid = new Grid<>(IssueWork.class);
@Getter
IssueWorkForm form;
ComicService service;
@@ -39,24 +43,16 @@ public class IssueWorkView extends VerticalLayout {
updateList();
}
public Grid<IssueWork> getGrid() {
return grid;
}
private void configureGrid() {
grid.addClassName("issue-grid");
grid.setSizeFull();
grid.setColumns("issue.title", "artist.name", "workType.name");
grid.setColumns("issue.fullTitle", "artist.name", "workType.name");
grid.getColumns().forEach(col -> col.setAutoWidth(true));
grid.asSingleSelect().addValueChangeListener(event -> editIssueWork(event.getValue()));
}
public IssueWorkForm getForm() {
return form;
}
private void configureForm() {
form = new IssueWorkForm(service.findAllIssues(), service.findAllArtists(null),
form = new IssueWorkForm(service.findAllComics(null), service.findAllArtists(null),
service.findAllWorktypes(null));
form.setWidth("25em");
form.setVisible(false);
@@ -0,0 +1,63 @@
package de.thpeetz.kontor.common.views;
import com.vaadin.flow.component.Unit;
import com.vaadin.flow.component.customfield.CustomField;
import com.vaadin.flow.component.select.Select;
import lombok.extern.slf4j.Slf4j;
import de.thpeetz.kontor.comics.data.Comic;
import de.thpeetz.kontor.comics.data.Issue;
import java.util.List;
@Slf4j
public class ComicIssueField extends CustomField<Issue> {
public final Select<Comic> comic = new Select<>();
public final Select<Issue> issue = new Select<>();
public ComicIssueField(String caption) {
comic.setEnabled(false);
comic.setWidth(9, Unit.EM);
comic.setItemLabelGenerator(Comic::getTitle);
comic.addValueChangeListener(e -> {
updateIssues();
});
issue.setEnabled(false);
issue.setWidth(9, Unit.EM);
issue.setItemLabelGenerator(Issue::getIssueNumber);
add(comic, issue);
}
@Override
protected Issue generateModelValue() {
log.info("ComicIssueField.generateModelValue: {}", issue.getValue());
return issue.getValue();
}
@Override
protected void setPresentationValue(Issue newPresentationValue) {
log.info("ComicIssueField.setPresentationValue({})", newPresentationValue);
if (newPresentationValue == null) return;
comic.setValue(newPresentationValue.getComic());
log.info("setPresentationValue: set Comic select = {}", comic.getValue());
issue.setValue(newPresentationValue);
}
public void setComics(List<Comic> comics) {
log.info("ComicIssueField.setComics");
comic.setItems(comics);
comic.setEnabled(true);
}
private void updateIssues() {
log.info("ComicIssueField.updateIssues");
if (comic.getValue() == null) {
issue.setValue(null);
issue.setEnabled(false);
return;
}
issue.setItems(comic.getValue().getIssues());
issue.setEnabled(true);
}
}