Vorbereitung Release 0.2.0 #83

Merged
tpeetz merged 178 commits from develop/0.2.0 into main 2026-01-29 22:50:42 +00:00
7 changed files with 76 additions and 23 deletions
Showing only changes of commit 41d513e402 - Show all commits
+6 -1
View File
@@ -68,6 +68,7 @@ class Volume(Base, BaseMixin):
name = Column(String, nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="volumes")
story_arcs = relationship("StoryArc")
issues = relationship("Issue")
@@ -85,6 +86,9 @@ class StoryArc(Base, BaseMixin):
name = Column(String, nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="story_arcs")
volume_id = Column(String, ForeignKey("volume.id"), nullable=True)
volume = relationship("Volume", back_populates="story_arcs")
issues = relationship("Issue")
class Issue(Base, BaseMixin):
@@ -96,7 +100,8 @@ class Issue(Base, BaseMixin):
comic = relationship("Comic", back_populates="issues")
volume_id = Column(String, ForeignKey("volume.id"), nullable=True)
volume = relationship("Volume", back_populates="issues")
story_arc_id = Column(String, ForeignKey("story_arc.id"), nullable=True)
story_arc = relationship("StoryArc", back_populates="issues")
class Artist(Base, BaseMixin):
__tablename__ = "artist"
@@ -46,6 +46,28 @@
{% endfor %}
</td>
</tr>
{% if comic.volumes|length > 0 %}
<tr>
<th scope="row">Volumes</th>
<td colspan="2">
<ul>
{% for volume in comic.volumes %}
<li><a href="/comic/volumes/{{volume.id}}">{{volume.name}}</a></li>
{% endfor %}
</ul>
</td>
</tr>
{% endif %}
<tr>
<th scope="row">Issues</th>
<td colspan="2">
<ul>
{% for issue in comic.sorted_issues() %}
<li><a href="/comic/issues/{{issue.id}}">{{issue.issue_number}}</a></li>
{% endfor %}
</ul>
</td>
</tr>
<tr>
<th scope="row">Data Created</th>
<td colspan="2">{{comic.created_date}}</td>
@@ -58,16 +80,6 @@
<th scope="row">Data Version</th>
<td colspan="2">{{comic.version}}</td>
</tr>
<tr>
<th scope="row">Issues</th>
<td colspan="2">
<ul>
{% for issue in comic.sorted_issues() %}
<li><a href="/comic/issues/{{issue.id}}">{{issue.issue_number}}</a></li>
{% endfor %}
</ul>
</td>
</tr>
</tbody>
</table>
</div>
@@ -33,6 +33,12 @@ public class Issue extends AbstractEntity {
@Nullable
private Volume volume;
@ManyToOne
@JoinColumn(name = "storyArc_id")
@JsonIgnoreProperties({ "issues" })
@Nullable
private StoryArc storyArc;
@NotEmpty
private String issueNumber;
@@ -43,4 +49,11 @@ public class Issue extends AbstractEntity {
public String getComicTitle() {
return comic.getTitle();
}
public String getVolumeName() {
if (volume != null) {
return volume.getName();
}
return null;
}
}
@@ -1,11 +1,14 @@
package de.thpeetz.kontor.comics.data;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.annotation.Nullable;
import de.thpeetz.kontor.common.data.AbstractEntity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.EqualsAndHashCode;
@@ -13,6 +16,8 @@ import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.*;
@Getter
@Setter
@ToString
@@ -28,4 +33,14 @@ public class StoryArc extends AbstractEntity {
@NotNull
@JsonIgnoreProperties({ "storyArcs" })
private Comic comic;
@ManyToOne
@JoinColumn(name = "volume_id")
@JsonIgnoreProperties({ "storyArcs" })
@Nullable
private Volume volume;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "storyArc", cascade = CascadeType.REMOVE, orphanRemoval = true)
@Nullable
private List<Issue> issues = new LinkedList<>();
}
@@ -6,7 +6,7 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import de.thpeetz.kontor.common.data.AbstractEntity;
import io.micrometer.common.lang.Nullable;
import jakarta.annotation.*;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
@@ -36,6 +36,10 @@ public class Volume extends AbstractEntity {
@JsonIgnoreProperties({ "volumes" })
private Comic comic;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true)
@Nullable
private List<StoryArc> storyArcs = new LinkedList<>();
@OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true)
@Nullable
private List<Issue> issues = new LinkedList<>();
@@ -15,14 +15,14 @@ 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.Comic;
import de.thpeetz.kontor.comics.data.Issue;
import de.thpeetz.kontor.comics.data.*;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class IssueForm extends FormLayout {
ComboBox<Comic> comic = new ComboBox<>("Comic");
ComboBox<Volume> volume = new ComboBox<>("Volume");
TextField issueNumber = new TextField("Issue number");
Checkbox isRead = new Checkbox("Read");
Checkbox inStock = new Checkbox("In stock");
@@ -39,7 +39,7 @@ public class IssueForm extends FormLayout {
comic.setItems(comics);
comic.setItemLabelGenerator(Comic::getTitle);
add(comic, issueNumber, isRead, inStock, createButtonsLayout());
add(comic, volume, issueNumber, isRead, inStock, createButtonsLayout());
}
private HorizontalLayout createButtonsLayout() {
@@ -66,19 +66,20 @@ public class IssueForm extends FormLayout {
public void setIssue(Issue issue) {
binder.setBean(issue);
if (issue != null) {
volume.setItems(issue.getComic().getVolumes());
volume.setItemLabelGenerator(Volume::getName);
}
}
public abstract static class IssueFormEvent extends ComponentEvent<IssueForm> {
private Issue issue;
@lombok.Getter
private final Issue issue;
protected IssueFormEvent(IssueForm source, Issue issue) {
super(source, false);
this.issue = issue;
}
public Issue getIssue() {
return issue;
}
}
public static class SaveEvent extends IssueFormEvent {
@@ -49,6 +49,8 @@ public class IssueView extends VerticalLayout {
.setHeader("Version").setResizable(true).setSortable(true);
Grid.Column<Issue> titleColumn = grid.addColumn(Issue::getComicTitle)
.setHeader("Comic").setResizable(true).setSortable(true);
Grid.Column<Issue> volumeColumn = grid.addColumn(Issue::getVolumeName)
.setHeader("Volume").setResizable(true).setSortable(true);
Grid.Column<Issue> issueNumberColumn = grid.addColumn(Issue::getIssueNumber)
.setHeader("Heft Nummer").setResizable(true).setSortable(true);
Grid.Column<Issue> isReadColumn = grid.addComponentColumn(issueColumn -> StatusIcon.create(issueColumn.getIsRead()))
@@ -118,10 +120,11 @@ public class IssueView extends VerticalLayout {
menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
ColumnToggleContextMenu<Issue> columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton);
columnToggleContextMenu.addColumnToggleItem(idColumn);
columnToggleContextMenu.addColumnToggleItem(createdColumn);
columnToggleContextMenu.addColumnToggleItem(createdColumn);
columnToggleContextMenu.addColumnToggleItem(modifiedColumn);
columnToggleContextMenu.addColumnToggleItem(versionColumn);
columnToggleContextMenu.addColumnToggleItem(titleColumn);
columnToggleContextMenu.addColumnToggleItem(volumeColumn);
columnToggleContextMenu.addColumnToggleItem(issueNumberColumn);
columnToggleContextMenu.addColumnToggleItem(isReadColumn);
columnToggleContextMenu.addColumnToggleItem(inStockColumn);