Merge branch 'develop/0.1.0' into 'feature/8-create-docker-build'

# Conflicts:
#   springboot/Dockerfile
This commit is contained in:
2025-03-31 18:30:11 +02:00
892 changed files with 45701 additions and 582 deletions
+5 -15
View File
@@ -1,15 +1,5 @@
FROM gradle:4.7.0-jdk8-alpine AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build --no-daemon
FROM openjdk:8-jre-slim
EXPOSE 8080
RUN mkdir /app
COPY --from=build /home/gradle/src/build/libs/*.jar /app/spring-boot-application.jar
ENTRYPOINT ["java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-Djava.security.egd=file:/dev/./urandom","-jar","/app/spring-boot-application.jar"]
FROM alpine/java:21-jdk
WORKDIR /
ADD build/libs/kontor-spring-0.1.0-SNAPSHOT.jar app.jar
EXPOSE 8000
CMD java -jar -Dspring.profiles.active=prod -Dvaadin.productionMode=true app.jar
+32
View File
@@ -0,0 +1,32 @@
services:
mariadb:
image: mariadb
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: kontor
MYSQL_USER: kontor
MYSQL_PASSWORD: kontor
MYSQL_DATABASE: kontor
ports:
- 3316:3306
networks:
- database
volumes:
- mariadb-storage:/var/lib/mysql:rw
kontor:
image: kontor
restart: unless-stopped
networks:
- database
- frontend
ports:
- 8000:8000
networks:
database:
frontend:
volumes:
mariadb-storage:
@@ -6,6 +6,8 @@ import com.vaadin.flow.router.RouterLink;
import de.thpeetz.kontor.admin.views.*;
import de.thpeetz.kontor.comics.ComicConstants;
import de.thpeetz.kontor.comics.views.ComicWorkView;
import de.thpeetz.kontor.media.MediaConstants;
import de.thpeetz.kontor.media.views.MediaActorFileView;
public class AdminConstants {
@@ -44,6 +46,7 @@ public class AdminConstants {
administration.addItem(new SideNavItem(ROLE, RoleView.class));
SideNavItem data = new SideNavItem(DATA, AUTHORIZATION_ROUTE, VaadinIcon.DATABASE.create());
data.addItem(new SideNavItem(ComicConstants.COMICWORK, ComicWorkView.class));
data.addItem(new SideNavItem(MediaConstants.MEDIAACTORFILE, MediaActorFileView.class));
data.addItem(new SideNavItem(AUTHORIZATION, AuthorizationView.class));
data.addItem(new SideNavItem("Data Import", ModuleDataView.class));
data.addItem(new SideNavItem("Meta Data", MetaDataView.class));
@@ -1,5 +1,6 @@
package de.thpeetz.kontor.admin;
import com.vaadin.flow.component.page.Meta;
import de.thpeetz.kontor.admin.data.*;
import de.thpeetz.kontor.admin.services.AdminService;
import de.thpeetz.kontor.admin.services.MetaDataService;
@@ -159,6 +160,19 @@ public class SetupModuleAdmin implements ApplicationListener<ContextRefreshedEve
metaDataService.getColumn(mediaFileTable, "file_name", "file_name", "TEXT", null, 9, Boolean.TRUE, "Dateiname", Boolean.FALSE, null);
metaDataService.getColumn(mediaFileTable, "path", "path", "TEXT", null, 10, Boolean.TRUE, "Verzeichnis", Boolean.FALSE, null);
metaDataService.getColumn(mediaFileTable, "cloud_link", "cloud_link", "TEXT", null, 11, Boolean.TRUE, "Cloud Link", Boolean.FALSE, null);
MetaDataTable mediaActorTable = metaDataService.getTable("media_actor");
metaDataService.getColumn(mediaActorTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "ID", Boolean.FALSE, null);
metaDataService.getColumn(mediaActorTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "Created", Boolean.FALSE, null);
metaDataService.getColumn(mediaActorTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "Modified", Boolean.FALSE, null);
metaDataService.getColumn(mediaActorTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "Version", Boolean.FALSE, null);
metaDataService.getColumn(mediaActorTable, "name", "name", "TEXT", "UNIQUE", 5, Boolean.TRUE, "", Boolean.FALSE, null);
MetaDataTable mediaActorFileTable = metaDataService.getTable("media_actor_file");
metaDataService.getColumn(mediaActorFileTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "ID", Boolean.FALSE, null);
metaDataService.getColumn(mediaActorFileTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "Created", Boolean.FALSE, null);
metaDataService.getColumn(mediaActorFileTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "Modified", Boolean.FALSE, null);
metaDataService.getColumn(mediaActorFileTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "Version", Boolean.FALSE, null);
metaDataService.getColumn(mediaActorFileTable, "media_actor_id", "media_actor_id", "TEXT", null, 5, Boolean.TRUE, "Actor", Boolean.FALSE, null, "name");
metaDataService.getColumn(mediaActorFileTable, "media_file_id", "media_file_id", "TEXT", null, 6, Boolean.TRUE, "File", Boolean.FALSE, null, "title");
MetaDataTable artistTable = metaDataService.getTable("artist");
metaDataService.getColumn(artistTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(artistTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
@@ -166,11 +180,11 @@ public class SetupModuleAdmin implements ApplicationListener<ContextRefreshedEve
metaDataService.getColumn(artistTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(artistTable, "name", "name", "TEXT", "UNIQUE", 5, Boolean.FALSE, "", Boolean.FALSE, null);
MetaDataTable publisherTable = metaDataService.getTable("publisher");
metaDataService.getColumn(publisherTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(publisherTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(publisherTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(publisherTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(publisherTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(publisherTable, "name", "name", "TEXT", "UNIQUE", 5, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(publisherTable, "name", "name", "TEXT", "UNIQUE", 5, Boolean.TRUE, "", Boolean.FALSE, null);
MetaDataTable comicTable = metaDataService.getTable("comic");
metaDataService.getColumn(comicTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "ID", Boolean.FALSE, null);
metaDataService.getColumn(comicTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
@@ -179,7 +193,7 @@ public class SetupModuleAdmin implements ApplicationListener<ContextRefreshedEve
metaDataService.getColumn(comicTable, "completed", "completed", "BOOLEAN", null, 5, Boolean.TRUE, "Complete", Boolean.TRUE, "Complete");
metaDataService.getColumn(comicTable, "current_order", "current_order", "BOOLEAN", null, 6, Boolean.TRUE, "Bestellung", Boolean.TRUE, "Bestellung");
metaDataService.getColumn(comicTable, "title", "title", "TEXT", "UNIQUE", 7, Boolean.TRUE, "Title", Boolean.FALSE, null);
metaDataService.getColumn(comicTable, "publisher_id", "publisher_id", "TEXT", null, 8, Boolean.TRUE, "Verlag", Boolean.FALSE, null);
metaDataService.getColumn(comicTable, "publisher_id", "publisher_id", "TEXT", null, 8, Boolean.TRUE, "Verlag", Boolean.FALSE, null, "name");
MetaDataTable issueTable = metaDataService.getTable("issue");
metaDataService.getColumn(issueTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(issueTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
@@ -188,7 +202,7 @@ public class SetupModuleAdmin implements ApplicationListener<ContextRefreshedEve
metaDataService.getColumn(issueTable, "in_stock", "in_stock", "BOOLEAN", null, 5, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(issueTable, "is_read", "is_read", "BOOLEAN", null, 6, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(issueTable, "issue_number", "issue_number", "TEXT", null, 7, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(issueTable, "comic_id", "comic_id", "TEXT", null, 8, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(issueTable, "comic_id", "comic_id", "TEXT", null, 8, Boolean.FALSE, "", Boolean.FALSE, null, "title");
metaDataService.getColumn(issueTable, "volume_id", "volume_id", "TEXT", null, 9, Boolean.FALSE, "", Boolean.FALSE, null);
MetaDataTable volumeTable = metaDataService.getTable("volume");
metaDataService.getColumn(volumeTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.FALSE, "", Boolean.FALSE, null);
@@ -205,7 +219,7 @@ public class SetupModuleAdmin implements ApplicationListener<ContextRefreshedEve
metaDataService.getColumn(tpbTable, "issue_start", "issue_start", "LONG", null, 5, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(tpbTable, "issue_end", "issue_end", "LONG", null, 6, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(tpbTable, "name", "name", "TEXT", null, 7, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(tpbTable, "comic_id", "comic_id", "TEXT", null, 8, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(tpbTable, "comic_id", "comic_id", "TEXT", null, 8, Boolean.FALSE, "", Boolean.FALSE, null, "title");
MetaDataTable storyArcTable = metaDataService.getTable("story_arc");
metaDataService.getColumn(storyArcTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(storyArcTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
@@ -332,5 +346,89 @@ public class SetupModuleAdmin implements ApplicationListener<ContextRefreshedEve
metaDataService.getColumn(cardTable, "card_set_id", "card_set_id", "TEXT", null, 7, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(cardTable, "rooster_id", "rooster_id", "TEXT", null, 8, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(cardTable, "vendor_id", "vendor_id", "TEXT", null, 9, Boolean.FALSE, "", Boolean.FALSE, null);
MetaDataTable userTable = metaDataService.getTable("user");
metaDataService.getColumn(userTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(userTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(userTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(userTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(userTable, "first_name", "first_name", "TEXT", null, 5, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(userTable, "last_name", "last_name", "TEXT", null, 6, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(userTable, "user_name", "user_name", "TEXT", "UNIQUE", 7, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(userTable, "email", "email", "TEXT", null, 8, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(userTable, "password", "password", "TEXT", null, 9, Boolean.FALSE, "Password", Boolean.FALSE, null);
metaDataService.getColumn(userTable, "enabled", "enabled", "BOOLEAN", null, 10, Boolean.TRUE, "", Boolean.TRUE, null);
MetaDataTable tokenTable = metaDataService.getTable("token");
metaDataService.getColumn(tokenTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(tokenTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(tokenTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(tokenTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(tokenTable, "token", "token", "TEXT", null, 5, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(tokenTable, "name", "name", "TEXT", null, 6, Boolean.TRUE, "Name", Boolean.FALSE, null);
metaDataService.getColumn(tokenTable, "last_used_date", "used", "TIMESTAMP", null, 7, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(tokenTable, "enabled", "enabled", "BOOLEAN", null, 8, Boolean.TRUE, "", Boolean.TRUE, "Enabled");
metaDataService.getColumn(tokenTable, "user_id", "user_id", "TEXT", null, 9, Boolean.TRUE, "User", Boolean.FALSE, null, "user_name");
MetaDataTable roleTable = metaDataService.getTable("role");
metaDataService.getColumn(roleTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(roleTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(roleTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(roleTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(roleTable, "name", "name", "TEXT", null, 5, Boolean.TRUE, "", Boolean.FALSE, null);
MetaDataTable authorizationMatrix = metaDataService.getTable("authorization_matrix");
metaDataService.getColumn(authorizationMatrix, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(authorizationMatrix, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(authorizationMatrix, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(authorizationMatrix, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(authorizationMatrix, "user_id", "user_id", "TEXT", null, 5, Boolean.TRUE, "User", Boolean.FALSE, null, "user_name");
metaDataService.getColumn(authorizationMatrix, "role_id", "role_id", "TEXT", null, 6, Boolean.TRUE, "Role", Boolean.FALSE, null, "name");
MetaDataTable moduleDataTable = metaDataService.getTable("module_data");
metaDataService.getColumn(moduleDataTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(moduleDataTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(moduleDataTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(moduleDataTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(moduleDataTable, "module_name", "module_name", "TEXT", "UNIQUE", 5, Boolean.TRUE, "Module", Boolean.FALSE, null);
metaDataService.getColumn(moduleDataTable, "import_data", "import_data", "BOOLEAN", null, 6, Boolean.TRUE, "Import Data?", Boolean.TRUE, "Import Data");
MetaDataTable mailAccountTable = metaDataService.getTable("mail_account");
metaDataService.getColumn(mailAccountTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(mailAccountTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(mailAccountTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(mailAccountTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(mailAccountTable, "host", "host", "TEXT", null, 5, Boolean.TRUE, "Host", Boolean.FALSE, null);
metaDataService.getColumn(mailAccountTable, "port", "port", "LONG", null, 6, Boolean.TRUE, "Port", Boolean.FALSE, null);
metaDataService.getColumn(mailAccountTable, "protocol", "protocol", "TEXT", null, 7, Boolean.TRUE, "Protocol", Boolean.FALSE, null);
metaDataService.getColumn(mailAccountTable, "user_name", "user_name", "TEXT", null, 8, Boolean.TRUE, "Username", Boolean.FALSE, null);
metaDataService.getColumn(mailAccountTable, "password", "password", "TEXT", null, 9, Boolean.FALSE, "Password", Boolean.FALSE, null);
metaDataService.getColumn(mailAccountTable, "start_tls", "start_tls", "BOOLEAN", null, 10, Boolean.TRUE, "StartTLS", Boolean.TRUE, "StartTLS");
MetaDataTable mailTable = metaDataService.getTable("mail");
metaDataService.getColumn(mailTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(mailTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(mailTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(mailTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(mailTable, "folder", "folder", "TEXT", null, 5, Boolean.TRUE, "Folder", Boolean.FALSE, null);
metaDataService.getColumn(mailTable, "subject", "subject", "TEXT", null, 6, Boolean.TRUE, "Subject", Boolean.FALSE, null);
metaDataService.getColumn(mailTable, "body", "body", "TEXT", null, 7, Boolean.FALSE, "Body", Boolean.FALSE, null);
metaDataService.getColumn(mailTable, "sent_date", "created", "TIMESTAMP", null, 8, Boolean.FALSE, "Gesendet", Boolean.FALSE, null);
metaDataService.getColumn(mailTable, "received_date", "created", "TIMESTAMP", null, 9, Boolean.FALSE, "Empfangen", Boolean.FALSE, null);
MetaDataTable metaDataTableTable = metaDataService.getTable("meta_data_table");
metaDataService.getColumn(metaDataTableTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.TRUE, "", Boolean.FALSE, null);
metaDataService.getColumn(metaDataTableTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(metaDataTableTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(metaDataTableTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(metaDataTableTable, "table_name", "table_name", "TEXT", "UNIQUE", 5, Boolean.TRUE, "Table", Boolean.FALSE, null);
MetaDataTable metaDataColumnTable = metaDataService.getTable("meta_data_column");
metaDataService.getColumn(metaDataColumnTable, "id", "identifier", "TEXT", "PRIMARY KEY", 1, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "created_date", "created", "TIMESTAMP", null, 2, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "last_modified_date", "modified", "TIMESTAMP", null, 3, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "version", "version", "LONG", null, 4, Boolean.FALSE, "", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "column_name", "column_name", "TEXT", null, 5, Boolean.TRUE, "Column", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "column_sync_name", "column_sync_name", "TEXT", null, 6, Boolean.TRUE, "SQLite Column", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "column_type", "column_type", "TEXT", null, 7, Boolean.TRUE, "Type", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "column_modifier", "column_modifier", "TEXT", null, 8, Boolean.TRUE, "Modifier", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "column_order", "column_order", "LONG", null, 9, Boolean.TRUE, "Order", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "is_shown", "is_shown", "BOOLEAN", null, 10, Boolean.TRUE, "Is Shown", Boolean.TRUE, "Is Shown");
metaDataService.getColumn(metaDataColumnTable, "column_label", "column_label", "TEXT", null, 11, Boolean.TRUE, "Label", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "show_filter", "show_filter", "BOOLEAN", null, 12, Boolean.TRUE, "Show Filter", Boolean.TRUE, "Show Filter");
metaDataService.getColumn(metaDataColumnTable, "filter_label", "filter_label", "TEXT", null, 13, Boolean.TRUE, "Filter Label", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "ref_column", "ref_column", "TEXT", null, 14, Boolean.TRUE, "Ref Column", Boolean.FALSE, null);
metaDataService.getColumn(metaDataColumnTable, "table_id", "table_id", "TEXT", null, 15, Boolean.TRUE, "Table", Boolean.FALSE, null, "table_name");
}
}
@@ -32,10 +32,12 @@ public class MetaDataColumn extends AbstractEntity {
private String columnLabel;
private Boolean showFilter;
private Boolean showFilter = Boolean.FALSE;
private String filterLabel;
private String refColumn;
@ManyToOne
@JoinColumn(name = "table_id")
@NotNull
@@ -0,0 +1,37 @@
package de.thpeetz.kontor.admin.data;
import de.thpeetz.kontor.common.data.AbstractEntity;
import jakarta.persistence.Entity;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
@Slf4j
@Getter
@Setter
@ToString
@Entity
@Table(indexes = @Index(columnList = "token"), uniqueConstraints = @UniqueConstraint(columnNames = {"token"}))
public class Token extends AbstractEntity {
private String token;
private String name;
private Date lastUsedDate;
private boolean enabled;
@ManyToOne
@JoinColumn(name="user_id")
@NotNull
private User user;
}
@@ -38,14 +38,14 @@ public class User extends AbstractEntity {
private boolean enabled;
private boolean tokenExpired;
private String token;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
@Nullable
private List<AuthorizationMatrix> matrix = new LinkedList<>();
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
@Nullable
private List<Token> tokens = new LinkedList<>();
public String getFullName() {
StringBuilder fullNamBuilder = new StringBuilder();
if (firstName != null) {
@@ -35,6 +35,10 @@ public class MetaDataService {
}
public void getColumn(MetaDataTable table, String columnName, String columnSyncName, String columnType, String columnModifier, Integer columnOrder, Boolean isShown, String columnLabel, Boolean showFilter, String filterLabel) {
this.getColumn(table, columnName, columnSyncName, columnType, columnModifier, columnOrder, isShown, columnLabel, showFilter, filterLabel, null);
}
public void getColumn(MetaDataTable table, String columnName, String columnSyncName, String columnType, String columnModifier, Integer columnOrder, Boolean isShown, String columnLabel, Boolean showFilter, String filterLabel, String refColumn) {
if (table.getTableColumns().stream().anyMatch(column -> column.getColumnName().equals(columnName))) {
log.debug("Column {} with name {} of table {} found, check Values", columnOrder, columnName, table.getTableName());
MetaDataColumn column = table.getTableColumns().get(columnOrder.intValue()-1);
@@ -50,7 +54,7 @@ public class MetaDataService {
log.debug("columnType has to be changed to {}", columnType);
column.setColumnType(columnType);
}
if (columnModifier != null && !column.getColumnModifier().equals(columnModifier)) {
if (columnModifier != null && !columnModifier.equals(column.getColumnModifier())) {
log.debug("columnModifier has to be changed to {}", columnModifier);
column.setColumnModifier(columnModifier);
}
@@ -70,6 +74,10 @@ public class MetaDataService {
log.debug("filterLabel has to be change to {}}", filterLabel);
column.setFilterLabel(filterLabel);
}
if (refColumn != null && !refColumn.equals(column.getRefColumn())) {
log.debug("refColumn has to be change to {}}", filterLabel);
column.setRefColumn(refColumn);
}
metaDataColumnRepository.save(column);
} else {
log.info("Column {} of table {} not found, will create it", columnName, table.getTableName());
@@ -85,6 +93,7 @@ public class MetaDataService {
}
}
public List<MetaDataColumn> findAllMetaDataColumns(String stringFilter) {
if (stringFilter == null || stringFilter.isEmpty()) {
log.debug("Found " + metaDataColumnRepository.count()+ " entries");
@@ -29,6 +29,7 @@ public class MetaDataForm extends FormLayout {
TextField columnLabel = new TextField("Column Label");
Checkbox showFilter = new Checkbox("Show Filter");
TextField filterLabel = new TextField("Filter Label");
TextField refColumn = new TextField("Ref Column");
Button save = new com.vaadin.flow.component.button.Button("Save");
Button delete = new com.vaadin.flow.component.button.Button("Delete");
@@ -47,6 +48,7 @@ public class MetaDataForm extends FormLayout {
isShown.addClickListener(click -> columnLabel.setEnabled(isShown.getValue()));
add(showFilter, filterLabel);
showFilter.addClickListener(click -> filterLabel.setEnabled(showFilter.getValue()));
add(refColumn);
add(createButtonsLayout());
}
@@ -66,6 +66,8 @@ public class MetaDataView extends VerticalLayout {
setHeader("Zeige Filter").setWidth("6rem").setSortable(true);
Grid.Column<MetaDataColumn> filterLabelColumn = grid.addColumn(MetaDataColumn::getFilterLabel)
.setHeader("Filter Name").setResizable(true).setSortable(true);
Grid.Column<MetaDataColumn> refColumnColumn = grid.addColumn(MetaDataColumn::getRefColumn)
.setHeader("Ref Column Name").setResizable(true).setSortable(true);
TextField searchField = new TextField();
@Getter
MetaDataForm form;
@@ -186,7 +188,7 @@ public class MetaDataView extends VerticalLayout {
columnToggleContextMenu.addColumnToggleItem(columnLabelColumn.getHeaderText(), columnLabelColumn);
columnToggleContextMenu.addColumnToggleItem(showFilterColumn.getHeaderText(), showFilterColumn);
columnToggleContextMenu.addColumnToggleItem(filterLabelColumn.getHeaderText(), filterLabelColumn);
columnToggleContextMenu.addColumnToggleItem(refColumnColumn.getHeaderText(), refColumnColumn);
HorizontalLayout toolbar = new HorizontalLayout(searchField, addMetaDataButton, menuButton);
toolbar.addClassName("toolbar");
return toolbar;
@@ -2,7 +2,12 @@ package de.thpeetz.kontor.admin.views;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.contextmenu.ContextMenu;
import com.vaadin.flow.component.contextmenu.MenuItem;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
@@ -14,6 +19,7 @@ import de.thpeetz.kontor.admin.data.ModuleData;
import de.thpeetz.kontor.admin.services.ModuleService;
import de.thpeetz.kontor.common.views.MainLayout;
import jakarta.annotation.security.RolesAllowed;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
@@ -25,11 +31,35 @@ import org.springframework.context.annotation.Scope;
@PageTitle("Module Data | Admin | Kontor")
public class ModuleDataView extends VerticalLayout {
Grid<ModuleData> grid = new Grid<>(ModuleData.class);
Grid<ModuleData> grid = new Grid<>(ModuleData.class, false);
Grid.Column<ModuleData> idColumn = grid.addColumn(ModuleData::getId)
.setHeader("ID").setResizable(true).setSortable(true);
Grid.Column<ModuleData> nameColumn = grid.addColumn(ModuleData::getModuleName)
.setHeader("Name").setResizable(true).setSortable(true);
Grid.Column<ModuleData> importColumn = grid.addComponentColumn(moduleData -> createStatusIcon(moduleData.getImportData()))
.setHeader("Import Data").setWidth("6rem").setSortable(true);
TextField filterText = new TextField();
@Getter
ModuleDataForm form;
ModuleService service;
private static class ColumnToggleContextMenu extends ContextMenu {
public ColumnToggleContextMenu(Component target) {
super(target);
setOpenOnClick(true);
}
void addColumnToggleItem(String label, Grid.Column<ModuleData> column) {
MenuItem menuItem = this.addItem(label, e -> {
column.setVisible(e.getSource().isChecked());
});
menuItem.setCheckable(true);
menuItem.setChecked(column.isVisible());
menuItem.setKeepOpen(true);
}
}
public ModuleDataView(ModuleService service) {
this.service = service;
addClassName("moduleData-view");
@@ -44,7 +74,7 @@ public class ModuleDataView extends VerticalLayout {
private void configureGrid() {
grid.addClassName("moduleData-grid");
grid.setSizeFull();
grid.setColumns("moduleName", "importData");
//grid.setColumns("moduleName", "importData");
grid.getColumns().forEach(col -> col.setAutoWidth(true));
grid.asSingleSelect().addValueChangeListener(event -> editModuleData(event.getValue()));
}
@@ -58,7 +88,20 @@ public class ModuleDataView extends VerticalLayout {
form.addCloseListener(e -> closeEditor());
}
private void saveModuleData(ModuleDataForm.SaveEvent event) {
private Icon createStatusIcon(boolean status) {
Icon icon;
if (status) {
icon = VaadinIcon.CHECK.create();
icon.getElement().getThemeList().add("badge success");
} else {
icon = VaadinIcon.CLOSE_SMALL.create();
icon.getElement().getThemeList().add("badge error");
}
icon.getStyle().set("padding", "var(--lumo-space-xs");
return icon;
}
private void saveModuleData(ModuleDataForm.SaveEvent event) {
ModuleData moduleData = event.getModuleData();
service.saveModuleData(moduleData);
updateList();
@@ -86,7 +129,14 @@ public class ModuleDataView extends VerticalLayout {
filterText.setValueChangeMode(ValueChangeMode.LAZY);
filterText.addValueChangeListener(e -> updateList());
Button addModuleDataButton = new Button("Add module", click -> addModuleData());
HorizontalLayout toolbar = new HorizontalLayout(filterText, addModuleDataButton);
Button menuButton = new Button("Show/Hide Columns");
menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu(menuButton);
columnToggleContextMenu.addColumnToggleItem("ID", idColumn);
columnToggleContextMenu.addColumnToggleItem("Module Name", nameColumn);
columnToggleContextMenu.addColumnToggleItem("Import Data", importColumn);
HorizontalLayout toolbar = new HorizontalLayout(filterText, addModuleDataButton, menuButton);
toolbar.addClassName("toolbar");
return toolbar;
}
@@ -1,5 +1,6 @@
package de.thpeetz.kontor.comics.data;
import java.util.LinkedList;
import java.util.List;
import de.thpeetz.kontor.common.data.AbstractEntity;
@@ -32,7 +33,7 @@ public class Artist extends AbstractEntity {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "artist", cascade = CascadeType.REFRESH, orphanRemoval = true)
@Nullable
List<ComicWork> comicWorks;
List<ComicWork> comicWorks = new LinkedList<>();
@Override
public String toString() {
@@ -1,5 +1,6 @@
package de.thpeetz.kontor.comics.views;
import lombok.Getter;
import org.springframework.context.annotation.Scope;
import com.vaadin.flow.component.Component;
@@ -25,8 +26,10 @@ import jakarta.annotation.security.PermitAll;
@PageTitle("Artist | Comics | Kontor")
public class ArtistView extends VerticalLayout {
@Getter
Grid<Artist> grid = new Grid<>(Artist.class);
TextField filterText = new TextField();
@Getter
ArtistForm form;
ComicService service;
@@ -41,14 +44,6 @@ public class ArtistView extends VerticalLayout {
updateList();
}
public Grid<Artist> getGrid() {
return grid;
}
public ArtistForm getForm() {
return form;
}
private void configureGrid() {
grid.addClassName("artist-grid");
grid.setSizeFull();
@@ -2,6 +2,7 @@ package de.thpeetz.kontor.media;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.sidenav.SideNavItem;
import de.thpeetz.kontor.media.views.MediaActorView;
import de.thpeetz.kontor.media.views.MediaArticleView;
import de.thpeetz.kontor.media.views.MediaFileView;
import de.thpeetz.kontor.media.views.MediaVideoView;
@@ -15,9 +16,13 @@ public class MediaConstants {
public static final String MEDIAVIDEO_ROUTE = "media/mediavideo";
public static final String MEDIAARTICLE_ROUTE = "media/mediaarticle";
public static final String MEDIA_ROLE = "ROLE_MEDIA";
public static final String MEDIAACTOR_ROUTE = "media/mediaactor";
public static final String MEDIAACTORFILE_ROUTE = "media/mediaactorfile";
public static final String MEDIAACTORFILE = "Media Actor Files";
private static final String MEDIAFILE = "Media Files";
private static final String MEDIAVIDEO = "Media Videos";
private static final String MEDIAARTICLE = "Media Article";
private static final String MEDIAACTOR = "Media Actor";
public static SideNavItem getMediaNavigation(ArrayList<String> roles) {
SideNavItem media = new SideNavItem(MEDIA, MEDIAFILE_ROUTE, VaadinIcon.VIMEO.create());
@@ -25,6 +30,7 @@ public class MediaConstants {
media.addItem(new SideNavItem(MEDIAARTICLE, MediaArticleView.class));
if (roles.contains(MEDIA_ROLE)) {
media.addItem(new SideNavItem(MEDIAFILE, MediaFileView.class));
media.addItem(new SideNavItem(MEDIAACTOR, MediaActorView.class));
}
return media;
}
@@ -0,0 +1,29 @@
package de.thpeetz.kontor.media.data;
import de.thpeetz.kontor.common.data.AbstractEntity;
import jakarta.annotation.Nullable;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotEmpty;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.util.LinkedList;
import java.util.List;
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@Slf4j
@Entity
public class MediaActor extends AbstractEntity {
@NotEmpty
@Column(unique = true)
private String name;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "media_actor", cascade = CascadeType.REFRESH, orphanRemoval = true)
@Nullable
List<MediaActorFile> mediaActorFiles = new LinkedList<>();
}
@@ -0,0 +1,34 @@
package de.thpeetz.kontor.media.data;
import de.thpeetz.kontor.comics.data.Artist;
import de.thpeetz.kontor.comics.data.Comic;
import de.thpeetz.kontor.common.data.AbstractEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(indexes = {@Index(columnList = "media_file_id, media_actor_id") },
uniqueConstraints = @UniqueConstraint(columnNames = {"media_file_id", "media_actor_id" })
)
public class MediaActorFile extends AbstractEntity {
@ManyToOne
@JoinColumn(name = "media_file_id")
@NotNull
private MediaFile media_file;
@ManyToOne
@JoinColumn(name = "media_actor_id")
@NotNull
private MediaActor media_actor;
public String getTitle() {
return media_file.getTitle();
}
}
@@ -0,0 +1,6 @@
package de.thpeetz.kontor.media.data;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MediaActorFileRepository extends JpaRepository<MediaActorFile, String> {
}
@@ -0,0 +1,17 @@
package de.thpeetz.kontor.media.data;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface MediaActorRepository extends JpaRepository<MediaActor, String> {
@Query("select m from MediaActor m " +
"where lower(m.name) like lower(concat('%', :searchTerm, '%')) ")
List<MediaActor> search(@Param("searchTerm") String searchTerm);
List<MediaActor> findByNameIgnoreCase(String name);
MediaActor findByName(String name);
}
@@ -2,14 +2,15 @@ package de.thpeetz.kontor.media.data;
import de.thpeetz.kontor.common.data.AbstractEntity;
import jakarta.annotation.Nullable;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.persistence.*;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.util.LinkedList;
import java.util.List;
@Slf4j
@Getter
@Setter
@@ -37,4 +38,7 @@ public class MediaFile extends AbstractEntity {
@Nullable
private String path;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "media_file", cascade = CascadeType.REFRESH, orphanRemoval = true)
@Nullable
List<MediaActorFile> mediaActorFiles = new LinkedList<>();
}
@@ -1,40 +0,0 @@
package de.thpeetz.kontor.media.data;
import de.thpeetz.kontor.common.data.AbstractEntity;
import jakarta.annotation.Nullable;
import jakarta.persistence.Entity;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.NotEmpty;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Getter
@Setter
@Entity
@Table(indexes = @Index(columnList = "url"), uniqueConstraints = @UniqueConstraint(columnNames = {"url"}))
public class MediaLink extends AbstractEntity {
@NotEmpty
private String url;
private String title;
private boolean review;
@OneToOne
@JoinColumn(name = "video_id", referencedColumnName = "id")
@Nullable
private MediaVideo mediaVideo;
@OneToOne
@JoinColumn(name = "article_id", referencedColumnName = "id")
@Nullable
private MediaArticle mediaArticle;
}
@@ -1,7 +1,6 @@
package de.thpeetz.kontor.media.services;
import de.thpeetz.kontor.media.data.MediaFile;
import de.thpeetz.kontor.media.data.MediaFileRepository;
import de.thpeetz.kontor.media.data.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -12,20 +11,24 @@ import java.util.List;
public class MediaFileService {
private final MediaFileRepository mediaFileRepository;
private final MediaActorRepository mediaActorRepository;
private final MediaActorFileRepository mediaActorFileRepository;
public MediaFileService(MediaFileRepository mediaFileRepository) {
public MediaFileService(MediaFileRepository mediaFileRepository, MediaActorRepository mediaActorRepository, MediaActorFileRepository mediaActorFileRepository) {
this.mediaFileRepository = mediaFileRepository;
this.mediaActorRepository = mediaActorRepository;
this.mediaActorFileRepository = mediaActorFileRepository;
}
public List<MediaFile> findAllMediaFiles(String stringFilter) {
List<MediaFile> results;
if (stringFilter == null || stringFilter.isEmpty()) {
log.debug("Found " + mediaFileRepository.count()+ " entries");
return mediaFileRepository.findAll();
results = mediaFileRepository.findAll();
} else {
List<MediaFile> results = mediaFileRepository.search(stringFilter);
log.debug("Found " + results.size() + " entries");
return results;
results = mediaFileRepository.search(stringFilter);
}
log.debug("Found " + results.size() + " entries");
return results;
}
public void saveMediaFile(MediaFile mediaFile) {
@@ -39,4 +42,49 @@ public class MediaFileService {
public void deleteMediaFile(MediaFile mediaFile) {
mediaFileRepository.delete(mediaFile);
}
public List<MediaActor> findAllMediaActors(String stringFilter) {
List<MediaActor> results;
if (stringFilter == null || stringFilter.isEmpty()) {
results = mediaActorRepository.findAll();
} else {
results = mediaActorRepository.search(stringFilter);
}
log.debug("Found " + results.size() + " entries");
return results;
}
public void saveMediaActor(MediaActor mediaActor) {
if (mediaActor == null) {
log.warn("MediaActor is null. Are you sure you have connected your form to the application?");
return;
}
mediaActorRepository.save(mediaActor);
}
public void deleteMediaActor(MediaActor mediaActor) {
mediaActorRepository.delete(mediaActor);
}
public List<MediaActorFile> findAllMediaActorFiles() {
return mediaActorFileRepository.findAll();
}
public void saveMediaActorFile(MediaActorFile mediaActorFile) {
if (mediaActorFile == null){
log.warn("MediaActorFile is null. Are you sure you have connected your form to the application?");
return;
}
mediaActorFileRepository.save(mediaActorFile);
}
public void deleteMediaActorFile(MediaActorFile mediaActorFile) {
MediaFile mediaFile = mediaActorFile.getMedia_file();
mediaFile.getMediaActorFiles().remove(mediaActorFile);
mediaFileRepository.save(mediaFile);
MediaActor mediaActor = mediaActorFile.getMedia_actor();
mediaActor.getMediaActorFiles().remove(mediaActorFile);
mediaActorRepository.save(mediaActor);
mediaActorFileRepository.delete(mediaActorFile);
}
}
@@ -0,0 +1,106 @@
package de.thpeetz.kontor.media.views;
import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.Key;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.Binder;
import de.thpeetz.kontor.media.data.MediaActor;
import de.thpeetz.kontor.media.data.MediaActorFile;
import de.thpeetz.kontor.media.data.MediaFile;
import lombok.Getter;
import java.util.List;
public class MediaActorFileForm extends FormLayout {
ComboBox<MediaFile> mediaFile = new ComboBox<>("Media File");
ComboBox<MediaActor> mediaActor = new ComboBox<>("Actor");
Button save = new Button("Save");
Button delete = new Button("Delete");
Button close = new Button("Cancel");
Binder<MediaActorFile> binder = new BeanValidationBinder<>(MediaActorFile.class);
public MediaActorFileForm(List<MediaFile> mediaFiles, List<MediaActor> actors) {
addClassName("mediaactorfile-form");
binder.bindInstanceFields(this);
mediaFile.setItems(mediaFiles);
mediaFile.setItemLabelGenerator(MediaFile::getTitle);
mediaActor.setItems(actors);
mediaActor.setItemLabelGenerator(MediaActor::getName);
add(mediaFile, mediaActor, createButtonsLayout());
}
private HorizontalLayout createButtonsLayout() {
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
close.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
save.addClickShortcut(Key.ENTER);
close.addClickShortcut(Key.ESCAPE);
save.addClickListener(event -> validateAndSave());
delete.addClickListener(event -> fireEvent(new MediaActorFileForm.DeleteEvent(this, binder.getBean())));
close.addClickListener(event -> fireEvent(new MediaActorFileForm.CloseEvent(this)));
binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid()));
return new HorizontalLayout(save, delete, close);
}
private void validateAndSave() {
if (binder.isValid()) {
fireEvent(new MediaActorFileForm.SaveEvent(this, binder.getBean()));
}
}
public void setMediaActorFile(MediaActorFile mediaActorFile) {
binder.setBean(mediaActorFile);
}
public abstract static class MediaActorFileFormEvent extends ComponentEvent<MediaActorFileForm> {
@Getter
private MediaActorFile mediaActorFile;
protected MediaActorFileFormEvent(MediaActorFileForm source, MediaActorFile mediaActorFile) {
super(source, false);
this.mediaActorFile = mediaActorFile;
}
}
public static class SaveEvent extends MediaActorFileForm.MediaActorFileFormEvent {
SaveEvent(MediaActorFileForm source, MediaActorFile mediaActorFile) {
super(source, mediaActorFile);
}
}
public static class DeleteEvent extends MediaActorFileForm.MediaActorFileFormEvent {
DeleteEvent(MediaActorFileForm source, MediaActorFile mediaActorFile) {
super(source, mediaActorFile);
}
}
public static class CloseEvent extends MediaActorFileForm.MediaActorFileFormEvent {
CloseEvent(MediaActorFileForm source) {
super(source, null);
}
}
public void addDeleteListener(ComponentEventListener<MediaActorFileForm.DeleteEvent> listener) {
addListener(MediaActorFileForm.DeleteEvent.class, listener);
}
public void addSaveListener(ComponentEventListener<MediaActorFileForm.SaveEvent> listener) {
addListener(MediaActorFileForm.SaveEvent.class, listener);
}
public void addCloseListener(ComponentEventListener<MediaActorFileForm.CloseEvent> listener) {
addListener(MediaActorFileForm.CloseEvent.class, listener);
}
}
@@ -0,0 +1,114 @@
package de.thpeetz.kontor.media.views;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent;
import de.thpeetz.kontor.common.views.MainLayout;
import de.thpeetz.kontor.media.MediaConstants;
import de.thpeetz.kontor.media.data.MediaActorFile;
import de.thpeetz.kontor.media.services.MediaFileService;
import jakarta.annotation.security.PermitAll;
import lombok.Getter;
import org.springframework.context.annotation.Scope;
@SpringComponent
@Scope("prototype")
@PermitAll
@Route(value = MediaConstants.MEDIAACTORFILE_ROUTE, layout = MainLayout.class)
@PageTitle("MediaActorFile | Media | Kontor")
public class MediaActorFileView extends VerticalLayout {
@Getter
Grid<MediaActorFile> grid = new Grid<>(MediaActorFile.class);
@Getter
MediaActorFileForm form;
MediaFileService service;
public MediaActorFileView(MediaFileService service) {
this.service = service;
addClassName("mediaactorfile-view");
setSizeFull();
configureGrid();
configureForm();
add(getToolbar(), getContent());
updateList();
}
private void configureGrid() {
grid.addClassName("mediaactorfile-grid");
grid.setSizeFull();
grid.setColumns("id", "media_actor.name", "media_file.title");
grid.getColumns().forEach(col -> col.setAutoWidth(true));
grid.asSingleSelect().addValueChangeListener(event -> editMediaActorFile(event.getValue()));
}
private void configureForm() {
form = new MediaActorFileForm(service.findAllMediaFiles(null), service.findAllMediaActors(null));
form.setWidth("25em");
form.setVisible(false);
form.addSaveListener(this::saveMediaActorFile);
form.addDeleteListener(this::deleteMediaActorFile);
form.addCloseListener(e -> closeEditor());
}
private void saveMediaActorFile(MediaActorFileForm.SaveEvent event) {
service.saveMediaActorFile(event.getMediaActorFile());
updateList();
closeEditor();
}
private void deleteMediaActorFile(MediaActorFileForm.DeleteEvent event) {
service.deleteMediaActorFile(event.getMediaActorFile());
updateList();
closeEditor();
}
private Component getContent() {
HorizontalLayout content = new HorizontalLayout(grid, form);
content.setFlexGrow(2, grid);
content.setFlexGrow(1, form);
content.addClassName("content");
content.setSizeFull();
return content;
}
private HorizontalLayout getToolbar() {
Button addMediaActorFileButton = new Button("Add MediaActorFile");
addMediaActorFileButton.addClickListener(click -> addMediaActorFile());
HorizontalLayout toolbar = new HorizontalLayout(addMediaActorFileButton);
toolbar.addClassName("toolbar");
return toolbar;
}
public void editMediaActorFile(MediaActorFile mediaActorFile) {
if (mediaActorFile == null) {
closeEditor();
} else {
form.setMediaActorFile(mediaActorFile);
form.setVisible(true);
addClassName("editing");
}
}
private void closeEditor() {
form.setMediaActorFile(null);
form.setVisible(false);
removeClassName("editing");
}
private void addMediaActorFile() {
grid.asSingleSelect().clear();
editMediaActorFile(new MediaActorFile());
}
public void updateList() {
grid.setItems(service.findAllMediaActorFiles());
}
}
@@ -0,0 +1,117 @@
package de.thpeetz.kontor.media.views;
import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.Key;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.listbox.MultiSelectListBox;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
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.media.data.MediaActor;
import de.thpeetz.kontor.media.data.MediaActorFile;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
public class MediaActorForm extends FormLayout {
TextField name = new TextField("Name");
Grid<MediaActorFile> mediaActorFiles = new Grid<>(MediaActorFile.class);
Button save = new Button("Save");
Button delete = new Button("Delete");
Button close = new Button("Cancel");
Binder<MediaActor> binder = new BeanValidationBinder<>(MediaActor.class);
public MediaActorForm() {
addClassName("media-actor-form");
binder.bindInstanceFields(this);
mediaActorFiles.setColumns("media_file.title");
mediaActorFiles.getColumnByKey("media_file.title").setHeader("File Title");
add(name, 2);
add(mediaActorFiles, 2);
add(createButtonsLayout());
}
private HorizontalLayout createButtonsLayout() {
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
close.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
save.addClickShortcut(Key.ENTER);
close.addClickShortcut(Key.ESCAPE);
save.addClickListener(event -> validateAndSave());
delete.addClickListener(event -> fireEvent(new MediaActorForm.DeleteEvent(this, binder.getBean())));
close.addClickListener(event -> fireEvent(new MediaActorForm.CloseEvent(this)));
binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid()));
return new HorizontalLayout(save, delete, close);
}
private void validateAndSave() {
if (binder.isValid()) {
fireEvent(new MediaActorForm.SaveEvent(this, binder.getBean()));
}
}
public void setMediaActor(MediaActor mediaActor) {
binder.setBean(mediaActor);
}
public void setMediaActorFiles(List<MediaActorFile> mediaActorFiles) {
log.info("Setting mediaActorFiles: {}", mediaActorFiles);
this.mediaActorFiles.setItems(mediaActorFiles);
}
public abstract static class MediaActorFormEvent extends ComponentEvent<MediaActorForm> {
private MediaActor mediaActor;
protected MediaActorFormEvent(MediaActorForm source, MediaActor mediaActor) {
super(source, false);
this.mediaActor = mediaActor;
}
public MediaActor getMediaActor() {
return mediaActor;
}
}
public static class SaveEvent extends MediaActorForm.MediaActorFormEvent {
SaveEvent(MediaActorForm source, MediaActor mediaActor) {
super(source, mediaActor);
}
}
public static class DeleteEvent extends MediaActorForm.MediaActorFormEvent {
DeleteEvent(MediaActorForm source, MediaActor mediaActor) {
super(source, mediaActor);
}
}
public static class CloseEvent extends MediaActorForm.MediaActorFormEvent {
CloseEvent(MediaActorForm source) {
super(source, null);
}
}
public void addDeleteListener(ComponentEventListener<MediaActorForm.DeleteEvent> listener) {
addListener(MediaActorForm.DeleteEvent.class, listener);
}
public void addSaveListener(ComponentEventListener<MediaActorForm.SaveEvent> listener) {
addListener(MediaActorForm.SaveEvent.class, listener);
}
public void addCloseListener(ComponentEventListener<MediaActorForm.CloseEvent> listener) {
addListener(MediaActorForm.CloseEvent.class, listener);
}
}
@@ -0,0 +1,123 @@
package de.thpeetz.kontor.media.views;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.grid.Grid;
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.data.value.ValueChangeMode;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent;
import de.thpeetz.kontor.common.views.MainLayout;
import de.thpeetz.kontor.media.MediaConstants;
import de.thpeetz.kontor.media.data.MediaActor;
import de.thpeetz.kontor.media.services.MediaFileService;
import jakarta.annotation.security.PermitAll;
import lombok.Getter;
import org.springframework.context.annotation.Scope;
@SpringComponent
@Scope("prototype")
@PermitAll
@Route(value = MediaConstants.MEDIAACTOR_ROUTE, layout = MainLayout.class)
@PageTitle("Actor | Media | Kontor")
public class MediaActorView extends VerticalLayout {
@Getter
Grid<MediaActor> grid = new Grid<>(MediaActor.class);
TextField filterText = new TextField();
@Getter
MediaActorForm form;
MediaFileService service;
public MediaActorView(MediaFileService service) {
this.service = service;
addClassName("media-actor-view");
setSizeFull();
configureGrid();
configureForm();
add(getToolbar(), getContent());
updateList();
}
private void configureGrid() {
grid.addClassName("media-actor-grid");
grid.setSizeFull();
grid.setColumns("name");
grid.getColumns().forEach(col -> col.setAutoWidth(true));
grid.asSingleSelect().addValueChangeListener(event -> editMediaActor(event.getValue()));
}
private void configureForm() {
form = new MediaActorForm();
form.setWidth("75em");
form.setVisible(false);
form.addSaveListener(this::saveMediaActor);
form.addDeleteListener(this::deleteMediaActor);
form.addCloseListener(e -> closeEditor());
}
private void saveMediaActor(MediaActorForm.SaveEvent event) {
service.saveMediaActor(event.getMediaActor());
updateList();
closeEditor();
}
private void deleteMediaActor(MediaActorForm.DeleteEvent event) {
service.deleteMediaActor(event.getMediaActor());
updateList();
closeEditor();
}
private Component getContent() {
HorizontalLayout content = new HorizontalLayout(grid, form);
content.setFlexGrow(2, grid);
content.setFlexGrow(1, form);
content.addClassName("content");
content.setSizeFull();
return content;
}
private HorizontalLayout getToolbar() {
filterText.setPlaceholder("Filter by name...");
filterText.setClearButtonVisible(true);
filterText.setValueChangeMode(ValueChangeMode.LAZY);
filterText.addValueChangeListener(e -> updateList());
Button addMediaActorButton = new Button("Add actor");
addMediaActorButton.addClickListener(click -> addMediaActor());
HorizontalLayout toolbar = new HorizontalLayout(filterText, addMediaActorButton);
toolbar.addClassName("toolbar");
return toolbar;
}
public void editMediaActor(MediaActor mediaActor) {
if (mediaActor == null) {
closeEditor();
} else {
form.setMediaActor(mediaActor);
form.setMediaActorFiles(mediaActor.getMediaActorFiles());
form.setVisible(true);
addClassName("editing");
}
}
private void closeEditor() {
form.setMediaActor(null);
form.setVisible(false);
removeClassName("editing");
}
private void addMediaActor() {
grid.asSingleSelect().clear();
editMediaActor(new MediaActor());
}
public void updateList() {
grid.setItems(service.findAllMediaActors(filterText.getValue()));
}
}
@@ -7,14 +7,18 @@ import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
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.media.data.MediaActorFile;
import de.thpeetz.kontor.media.data.MediaFile;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
public class MediaFileForm extends FormLayout {
@@ -25,6 +29,7 @@ public class MediaFileForm extends FormLayout {
TextField cloudLink = new TextField("Cloud Link");
Checkbox review = new Checkbox("Review");
Checkbox shouldDownload = new Checkbox("Download");
Grid<MediaActorFile> mediaActorFiles = new Grid<>(MediaActorFile.class);
Button save = new Button("Save");
Button delete = new Button("Delete");
@@ -36,12 +41,18 @@ public class MediaFileForm extends FormLayout {
addClassName("mediafile-form");
binder.bindInstanceFields(this);
id.setReadOnly(true);
mediaActorFiles.setColumns("media_actor.name");
mediaActorFiles.getColumnByKey("media_actor.name").setHeader("Actor");
add(id, 2);
add(url, 2);
add(title, 2);
add(fileName, 2);
add(cloudLink, 2);
add(review, shouldDownload, createButtonsLayout());
add(review, shouldDownload);
add(mediaActorFiles, 2);
add(createButtonsLayout());
}
private HorizontalLayout createButtonsLayout() {
@@ -70,6 +81,10 @@ public class MediaFileForm extends FormLayout {
binder.setBean(mediaFile);
}
public void setMediaActorFiles(List<MediaActorFile> actorFiles) {
mediaActorFiles.setItems(actorFiles);
}
@Getter
public abstract static class MediaFileFormEvent extends ComponentEvent<MediaFileForm> {
private final MediaFile mediaFile;
@@ -20,8 +20,10 @@ import de.thpeetz.kontor.media.data.MediaFile;
import de.thpeetz.kontor.media.services.MediaFileService;
import jakarta.annotation.security.RolesAllowed;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
@Slf4j
@SpringComponent
@Scope("prototype")
@RolesAllowed("MEDIA")
@@ -164,6 +166,12 @@ public class MediaFileView extends VerticalLayout {
closeEditor();
} else {
form.setMediaFile(mediaFile);
if (mediaFile.getMediaActorFiles() == null) {
log.info("no MediaActorFiles");
} else {
log.info("MediaActorFiles size: {}", mediaFile.getMediaActorFiles().size());
}
form.setMediaActorFiles(mediaFile.getMediaActorFiles());
form.setVisible(true);
addClassName("editing");
}
@@ -1,7 +1,6 @@
package de.thpeetz.kontor.tysc.data;
import java.util.List;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+36 -20
View File
@@ -1,5 +1,3 @@
server:
port: 8085
app:
name: 'Kontor'
shortName: 'Kontor'
@@ -7,24 +5,6 @@ app:
spring:
profiles:
active: local,dev,test,prod
devtools:
add-properties: false
datasource:
driverClassName: org.mariadb.jdbc.Driver
url: jdbc:mariadb://localhost:3306/kontor
username: 'kontor'
password: 'kontor'
#driverClassName: org.hsqldb.jdbc.JDBCDriver
#url: jdbc:hsqldb:file:kontorHSQLDB
#username: 'sa'
#password: 'sa'
#jpa
#database-platform: org.hibernate.community.dialect.SQLiteDialect
#datasource
#driverClassName: org.sqlite.JDBC
#url: "jdbc:sqlite:file:./kontorDb?cache=shared"
#username=sa
#password=sa
jpa:
defer-datasource-initialization: true
#hibernate.ddl-auto=create-drop
@@ -65,3 +45,39 @@ mail:
userName: 'thomas.peetz@thpeetz.de'
password: 'fS9f4JYDIO7A'
starttls: true
---
spring:
config:
activate:
on-profile: prod
datasource:
driverClassName: org.mariadb.jdbc.Driver
url: jdbc:mariadb://mariadb:3306/kontor
username: 'kontor'
password: 'kontor'
server:
port: 8000
---
spring:
config:
activate:
on-profile: local, dev, test
devtools:
add-properties: false
datasource:
driverClassName: org.mariadb.jdbc.Driver
url: jdbc:mariadb://localhost:3306/kontor
username: 'kontor'
password: 'kontor'
#driverClassName: org.hsqldb.jdbc.JDBCDriver
#url: jdbc:hsqldb:file:kontorHSQLDB
#username: 'sa'
#password: 'sa'
#driverClassName: org.sqlite.JDBC
#url: "jdbc:sqlite:file:./kontorDb?cache=shared"
#username=sa
#password=sa
#jpa
#database-platform: org.hibernate.community.dialect.SQLiteDialect
server:
port: 8085