add views for MediaActor and adapt MediaFile

This commit is contained in:
Thomas Peetz
2025-02-10 12:25:39 +01:00
parent 6d54c7f315
commit 8ffd421c1b
11 changed files with 302 additions and 14 deletions
@@ -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);
@@ -17,6 +17,8 @@ public class MediaConstants {
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";
@@ -27,4 +27,8 @@ public class MediaActorFile extends AbstractEntity {
@JoinColumn(name = "media_actor_id")
@NotNull
private MediaActor media_actor;
public String getTitle() {
return media_file.getTitle();
}
}
@@ -11,12 +11,13 @@ import java.util.List;
public class MediaFileService {
private final MediaFileRepository mediaFileRepository;
private final MediaActorRepository mediaActorRepository;
private final MediaActorFileRepository mediaActorFileRepository;
public MediaFileService(MediaFileRepository mediaFileRepository, MediaActorRepository mediaActorRepository) {
public MediaFileService(MediaFileRepository mediaFileRepository, MediaActorRepository mediaActorRepository, MediaActorFileRepository mediaActorFileRepository) {
this.mediaFileRepository = mediaFileRepository;
this.mediaActorRepository = mediaActorRepository;
this.mediaActorFileRepository = mediaActorFileRepository;
}
public List<MediaFile> findAllMediaFiles(String stringFilter) {
@@ -64,4 +65,26 @@ public class MediaFileService {
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());
}
}
@@ -7,6 +7,7 @@ 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;
@@ -21,7 +22,7 @@ import java.util.List;
public class MediaActorForm extends FormLayout {
TextField name = new TextField("Name");
// Grid<MediaActorFile> mediaActorFiles = new Grid<>(MediaActorFile.class);
Grid<MediaActorFile> mediaActorFiles = new Grid<>(MediaActorFile.class);
Button save = new Button("Save");
Button delete = new Button("Delete");
@@ -33,11 +34,11 @@ public class MediaActorForm extends FormLayout {
addClassName("media-actor-form");
binder.bindInstanceFields(this);
// mediaActorFiles.setColumns("media_file.title");
// mediaActorFiles.getColumnByKey("mediaFile.title").setHeader("MediaFile");
// mediaActorFiles.getColumns().forEach(col -> col.setAutoWidth(true));
// add(name, mediaActorFiles, createButtonsLayout());
add(name, createButtonsLayout());
mediaActorFiles.setColumns("media_file.title");
mediaActorFiles.getColumnByKey("media_file.title").setHeader("File Title");
add(name, 2);
add(mediaActorFiles, 2);
add(createButtonsLayout());
}
private HorizontalLayout createButtonsLayout() {
@@ -67,8 +68,8 @@ public class MediaActorForm extends FormLayout {
}
public void setMediaActorFiles(List<MediaActorFile> mediaActorFiles) {
log.info("Setting comic works: {}", mediaActorFiles);
// this.mediaActorFiles.setItems(mediaActorFiles);
log.info("Setting mediaActorFiles: {}", mediaActorFiles);
this.mediaActorFiles.setItems(mediaActorFiles);
}
public abstract static class MediaActorFormEvent extends ComponentEvent<MediaActorForm> {
@@ -10,8 +10,6 @@ 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.comics.data.Artist;
import de.thpeetz.kontor.comics.views.ArtistForm;
import de.thpeetz.kontor.common.views.MainLayout;
import de.thpeetz.kontor.media.MediaConstants;
import de.thpeetz.kontor.media.data.MediaActor;
@@ -55,7 +53,7 @@ public class MediaActorView extends VerticalLayout {
private void configureForm() {
form = new MediaActorForm();
form.setWidth("25em");
form.setWidth("75em");
form.setVisible(false);
form.addSaveListener(this::saveMediaActor);
form.addDeleteListener(this::deleteMediaActor);
@@ -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");
}