feat: CategoriesView
fully functional
This commit is contained in:
parent
386687137e
commit
8b9bfedbfe
1 changed files with 109 additions and 45 deletions
|
@ -5,62 +5,109 @@ import com.application.munera.services.CategoryService;
|
||||||
import com.application.munera.views.MainLayout;
|
import com.application.munera.views.MainLayout;
|
||||||
import com.vaadin.flow.component.UI;
|
import com.vaadin.flow.component.UI;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.button.ButtonVariant;
|
||||||
|
import com.vaadin.flow.component.dependency.Uses;
|
||||||
import com.vaadin.flow.component.formlayout.FormLayout;
|
import com.vaadin.flow.component.formlayout.FormLayout;
|
||||||
import com.vaadin.flow.component.grid.Grid;
|
import com.vaadin.flow.component.grid.Grid;
|
||||||
|
import com.vaadin.flow.component.grid.GridVariant;
|
||||||
|
import com.vaadin.flow.component.html.Div;
|
||||||
|
import com.vaadin.flow.component.icon.Icon;
|
||||||
import com.vaadin.flow.component.notification.Notification;
|
import com.vaadin.flow.component.notification.Notification;
|
||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
import com.vaadin.flow.component.notification.NotificationVariant;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.splitlayout.SplitLayout;
|
||||||
import com.vaadin.flow.component.textfield.TextField;
|
import com.vaadin.flow.component.textfield.TextField;
|
||||||
import com.vaadin.flow.data.binder.BeanValidationBinder;
|
import com.vaadin.flow.data.binder.BeanValidationBinder;
|
||||||
import com.vaadin.flow.router.BeforeEnterEvent;
|
import com.vaadin.flow.data.binder.ValidationException;
|
||||||
import com.vaadin.flow.router.BeforeEnterObserver;
|
import com.vaadin.flow.router.*;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
|
||||||
import com.vaadin.flow.router.Route;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.orm.ObjectOptimisticLockingFailureException;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@PageTitle("Categories")
|
@PageTitle("Categories")
|
||||||
@Route(value = "categories/:categoryID?/:action?(edit)", layout = MainLayout.class)
|
@Route(value = "categories/:categoryID?/:action?(edit)", layout = MainLayout.class)
|
||||||
public class CategoriesView extends VerticalLayout implements BeforeEnterObserver {
|
@Uses(Icon.class)
|
||||||
|
public class CategoriesView extends Div implements BeforeEnterObserver {
|
||||||
|
|
||||||
private final String CATEGORY_ID = "categoryID";
|
private final String CATEGORY_ID = "categoryID";
|
||||||
private final TextField categoryNameField = new TextField("Category Name");
|
private final String CATEGORY_EDIT_ROUTE_TEMPLATE = "categories/%s/edit";
|
||||||
private final Button addButton = new Button("Add Category");
|
|
||||||
private final Grid<Category> categoryGrid = new Grid<>(Category.class);
|
|
||||||
private final Button removeButton = new Button("Remove Category");
|
|
||||||
|
|
||||||
@Autowired
|
private final Grid<Category> grid = new Grid<>(Category.class, false);
|
||||||
private final CategoryService categoryService;
|
|
||||||
|
private final Button cancel = new Button("Cancel");
|
||||||
|
private final Button save = new Button("Save");
|
||||||
|
|
||||||
private final BeanValidationBinder<Category> binder;
|
private final BeanValidationBinder<Category> binder;
|
||||||
|
|
||||||
private Category category;
|
private Category category;
|
||||||
|
|
||||||
|
private final CategoryService categoryService;
|
||||||
|
private TextField name;
|
||||||
|
|
||||||
public CategoriesView(CategoryService categoryService) {
|
public CategoriesView(CategoryService categoryService) {
|
||||||
this.categoryService = categoryService;
|
this.categoryService = categoryService;
|
||||||
|
addClassNames("categories-view");
|
||||||
|
|
||||||
FormLayout formLayout = new FormLayout();
|
// Create UI
|
||||||
formLayout.add(categoryNameField, addButton);
|
SplitLayout splitLayout = new SplitLayout();
|
||||||
|
|
||||||
categoryGrid.setColumns("id", "name");
|
createGridLayout(splitLayout);
|
||||||
categoryGrid.setItems(categoryService.findAll());
|
createEditorLayout(splitLayout);
|
||||||
categoryGrid.asSingleSelect().addValueChangeListener(event -> {
|
|
||||||
if (event.getValue() != null) {
|
add(splitLayout);
|
||||||
UI.getCurrent().navigate(String.format("/manage-categories/%d/edit", event.getValue().getId()));
|
|
||||||
} else {
|
// Configure Grid
|
||||||
|
grid.addColumn(Category::getName).setHeader("Name").setSortable(true);
|
||||||
|
grid.getColumns().forEach(col -> col.setAutoWidth(true));
|
||||||
|
|
||||||
|
grid.setItems(query -> categoryService.list(
|
||||||
|
PageRequest.of(query.getPage(), query.getPageSize(), VaadinSpringDataHelpers.toSpringDataSort(query)))
|
||||||
|
.stream());
|
||||||
|
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER);
|
||||||
|
|
||||||
|
// when a row is selected or deselected, populate form
|
||||||
|
grid.asSingleSelect().addValueChangeListener(event -> {
|
||||||
|
if (event.getValue() != null) UI.getCurrent().navigate(String.format(CATEGORY_EDIT_ROUTE_TEMPLATE, event.getValue().getId()));
|
||||||
|
else {
|
||||||
clearForm();
|
clearForm();
|
||||||
UI.getCurrent().navigate(CategoriesView.class);
|
UI.getCurrent().navigate(CategoriesView.class);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
removeButton.setEnabled(false);
|
// Configure Form
|
||||||
removeButton.addClickListener(event -> removeCategory());
|
|
||||||
|
|
||||||
addButton.addClickListener(event -> addCategory());
|
|
||||||
|
|
||||||
binder = new BeanValidationBinder<>(Category.class);
|
binder = new BeanValidationBinder<>(Category.class);
|
||||||
|
|
||||||
|
// Bind fields. This is where you'd define e.g. validation rules
|
||||||
|
|
||||||
binder.bindInstanceFields(this);
|
binder.bindInstanceFields(this);
|
||||||
|
|
||||||
add(formLayout, categoryGrid, removeButton);
|
cancel.addClickListener(e -> {
|
||||||
|
clearForm();
|
||||||
|
refreshGrid();
|
||||||
|
});
|
||||||
|
|
||||||
|
save.addClickListener(e -> {
|
||||||
|
try {
|
||||||
|
if (this.category == null) {
|
||||||
|
this.category = new Category();
|
||||||
|
}
|
||||||
|
binder.writeBean(this.category);
|
||||||
|
categoryService.update(this.category);
|
||||||
|
clearForm();
|
||||||
|
refreshGrid();
|
||||||
|
Notification.show("Data updated");
|
||||||
|
UI.getCurrent().navigate(CategoriesView.class);
|
||||||
|
} catch (ObjectOptimisticLockingFailureException exception) {
|
||||||
|
Notification n = Notification.show(
|
||||||
|
"Error updating the data. Somebody else has updated the record while you were making changes.");
|
||||||
|
n.setPosition(Notification.Position.MIDDLE);
|
||||||
|
n.addThemeVariants(NotificationVariant.LUMO_ERROR);
|
||||||
|
} catch (ValidationException validationException) {
|
||||||
|
Notification.show("Failed to update the data. Check again that all values are valid");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -77,27 +124,47 @@ public class CategoriesView extends VerticalLayout implements BeforeEnterObserve
|
||||||
// when a row is selected but the data is no longer available,
|
// when a row is selected but the data is no longer available,
|
||||||
// refresh grid
|
// refresh grid
|
||||||
refreshGrid();
|
refreshGrid();
|
||||||
event.forwardTo(ExpensesView.class);
|
event.forwardTo(CategoriesView.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCategory() {
|
private void createEditorLayout(SplitLayout splitLayout) {
|
||||||
Category newCategory = new Category();
|
Div editorLayoutDiv = new Div();
|
||||||
binder.writeBeanIfValid(newCategory);
|
editorLayoutDiv.setClassName("editor-layout");
|
||||||
categoryService.update(newCategory);
|
|
||||||
refreshGrid();
|
Div editorDiv = new Div();
|
||||||
Notification.show("Category added successfully");
|
editorDiv.setClassName("editor");
|
||||||
|
editorLayoutDiv.add(editorDiv);
|
||||||
|
|
||||||
|
FormLayout formLayout = new FormLayout();
|
||||||
|
name = new TextField("Name");
|
||||||
|
formLayout.add(name);
|
||||||
|
editorDiv.add(formLayout);
|
||||||
|
createButtonLayout(editorLayoutDiv);
|
||||||
|
|
||||||
|
splitLayout.addToSecondary(editorLayoutDiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeCategory() {
|
private void createButtonLayout(Div editorLayoutDiv) {
|
||||||
if (category != null) {
|
HorizontalLayout buttonLayout = new HorizontalLayout();
|
||||||
categoryService.delete(category);
|
buttonLayout.setClassName("button-layout");
|
||||||
clearForm();
|
cancel.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
|
||||||
refreshGrid();
|
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
Notification.show("Category removed successfully");
|
buttonLayout.add(save, cancel);
|
||||||
UI.getCurrent().navigate(CategoriesView.class);
|
editorLayoutDiv.add(buttonLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createGridLayout(SplitLayout splitLayout) {
|
||||||
|
Div wrapper = new Div();
|
||||||
|
wrapper.setClassName("grid-wrapper");
|
||||||
|
splitLayout.addToPrimary(wrapper);
|
||||||
|
wrapper.add(grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshGrid() {
|
||||||
|
grid.select(null);
|
||||||
|
grid.getDataProvider().refreshAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearForm() {
|
private void clearForm() {
|
||||||
|
@ -107,9 +174,6 @@ public class CategoriesView extends VerticalLayout implements BeforeEnterObserve
|
||||||
private void populateForm(Category value) {
|
private void populateForm(Category value) {
|
||||||
this.category = value;
|
this.category = value;
|
||||||
binder.readBean(this.category);
|
binder.readBean(this.category);
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshGrid() {
|
|
||||||
categoryGrid.setItems(categoryService.findAll());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue