Rama-Ricardo #14

Merged
alex merged 8 commits from Rama-Ricardo into main 2024-09-04 17:53:01 +00:00
4 changed files with 182 additions and 163 deletions
Showing only changes of commit 4eebdf6f01 - Show all commits

View File

@ -110,6 +110,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@ -1,51 +1,59 @@
package com.primefactorsolutions.model;
package com.primefactorsolutions.model;
Review

quitar espacios blancos al inicio de cada linea

quitar espacios blancos al inicio de cada linea
import io.hypersistence.utils.hibernate.type.json.JsonType;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Type;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Type;
import java.time.LocalDate;
import java.util.List;
import java.time.LocalDate;
import java.util.List;
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class Employee extends BaseEntity {
private String firstName;
private String lastName;
private LocalDate birthday;
private String birthCity;
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class Employee extends BaseEntity {
private String firstName;
private String lastName;
private LocalDate birthday;
private String birthCity;
@Enumerated(EnumType.STRING)
private MaritalStatus maritalStatus;
@Enumerated(EnumType.STRING)
private MaritalStatus maritalStatus;
private String residenceAddress;
private String phoneNumber;
private String personalEmail;
private String residenceAddress;
private String phoneNumber;
private String personalEmail;
private String emergencyCName;
private String emergencyCAddress;
private String emergencyCPhone;
private String emergencyCEmail;
private String emergencyCName;
private String emergencyCAddress;
private String emergencyCPhone;
private String emergencyCEmail;
@Enumerated(EnumType.STRING)
private Status status;
@Enumerated(EnumType.STRING)
private Status status;
public enum Status {
ACTIVE,
INACTIVE
public enum Status {
ACTIVE,
INACTIVE
}
public enum MaritalStatus {
SINGLE,
MARRIED,
WIDOWED,
DIVORCED
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
public enum MaritalStatus {
SINGLE,
MARRIED,
WIDOWED,
DIVORCED
}
}

View File

@ -1,49 +1,65 @@
package com.primefactorsolutions.service;
import com.primefactorsolutions.model.Employee;
import org.apache.commons.beanutils.BeanComparator;
import com.primefactorsolutions.repositories.EmployeeRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import lombok.Data;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
import java.util.Optional;
import java.util.Collections;
@Service
@Data
public class EmployeeService {
private final EmployeeRepository employeeRepository;
private List<Employee> pagedBase;
public EmployeeService(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
private void initializePagedBase() {
if (pagedBase == null) {
Outdated
Review

no se puede guardar en un campo de la clase porque la clase es un singleton (si hay varios llamados van a haber problemas de concurrencia). solucion: no usar un campo en la clase y simplemente retornar toda la lista cada vez sin guardar en un campo.

no se puede guardar en un campo de la clase porque la clase es un singleton (si hay varios llamados van a haber problemas de concurrencia). solucion: no usar un campo en la clase y simplemente retornar toda la lista cada vez sin guardar en un campo.
this.pagedBase = employeeRepository.findAll();
}
}
public List<Employee> findEmployees(int start, int pageSize, String sortProperty, boolean asc) {
initializePagedBase(); // Asegurarse de que pagedBase esté inicializada
System.err.println("findAll " + start + " " + pageSize + " sort " + sortProperty + " asc:" + asc );
Outdated
Review

usar logger en vez de system println. ver lombok @Slf4j https://projectlombok.org/features/log

usar logger en vez de system println. ver lombok @Slf4j https://projectlombok.org/features/log
int end = (int) (start + pageSize);
if (end > pagedBase.size()) {
end = pagedBase.size();
}
Collections.sort(pagedBase, new BeanComparator<Employee>(sortProperty));
if(!asc) {
Collections.reverse(pagedBase);
}
return pagedBase.subList((int) start, end);
}
public List<Employee> findEmployees(int start, int pageSize) {
initializePagedBase(); // Asegurarse de que pagedBase esté inicializada
System.err.println("findAll " + start + " " + pageSize);
int end = (int) (start + pageSize);
if (end > pagedBase.size()) {
end = pagedBase.size();
}
return pagedBase.subList((int) start, end);
}
public Employee createOrUpdate(final Employee employee) {
final Employee saved = employeeRepository.save(employee);
return saved;
}
public List<Employee> getEmployees() {
return employeeRepository.findAll();
}
public Employee getEmployee(final UUID id) {
Optional<Employee> employee = employeeRepository.findById(id);
return employee.orElse(null);
}
public Page<Employee> getEmployeesPaginated(int pageNo, int pageSize, String sortField, boolean ascending) {
Sort sort = ascending ? Sort.by(sortField).ascending() : Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
return employeeRepository.findAll(pageable);
}
public boolean hasNextPage(int currentPage, int pageSize, String sortField, boolean ascending) {
return getEmployeesPaginated(currentPage, pageSize, sortField, ascending).hasNext();
}
}

View File

@ -3,18 +3,20 @@ package com.primefactorsolutions.views;
import com.primefactorsolutions.model.Employee;
import com.primefactorsolutions.service.EmployeeService;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent;
import org.vaadin.firitin.components.grid.PagingGrid;
import com.vaadin.flow.component.grid.GridSortOrder;
import com.vaadin.flow.data.provider.SortDirection;
import jakarta.annotation.security.PermitAll;
import org.springframework.context.annotation.Scope;
import org.vaadin.firitin.components.grid.VGrid;
import org.springframework.data.domain.Page;
import java.util.List;
@SpringComponent
@Scope("prototype")
@ -24,111 +26,99 @@ import org.springframework.data.domain.Page;
public class EmployeesListView extends Main {
private final EmployeeService employeeService;
private final int pageSize = 5;
private int currentPage = 1;
private String sortField = "firstName";
private boolean ascending = true;
private VGrid<Employee> grid;
private Button previous;
private Button next;
private final PagingGrid<Employee> table = new PagingGrid<>(Employee.class);
public EmployeesListView(EmployeeService employeeService) {
this.employeeService = employeeService;
addComponents();
updateGrid();
setupView();
refreshGrid();
}
private void addComponents() {
addTitle();
addOrderButtons();
configureGrid();
addNavigationButtons();
private void setupView() {
add(new H2("Employee List"));
configureTable();
add(createAddEmployeeButton());
add(table);
}
private void addTitle() {
final H2 title = new H2("Employees list");
add(title);
private void configureTable() {
table.setColumns("firstName", "lastName", "status");
addStatusColumn();
addEditButtonColumn("Edit", this::navigateToEditView);
addEditButtonColumn("Save", this::navigateToSaveChangeStatus);
setupPagingGrid();
}
private void addOrderButtons() {
final HorizontalLayout hl = new HorizontalLayout();
hl.add(createOrderButton("Employee List in Ascending Order", true));
hl.add(createOrderButton("Employee List in Descending Order", false));
add(hl);
private void addStatusColumn() {
table.addComponentColumn(this::createStatusCheckbox)
.setHeader("Change Status");
}
private Button createOrderButton(String label, boolean isAscending) {
private Checkbox createStatusCheckbox(Employee employee) {
Checkbox statusCheckbox = new Checkbox( employee.getStatus() == Employee.Status.ACTIVE);
return statusCheckbox;
}
private void updateEmployeeStatus(Employee employee, boolean isActive) {
employee.setStatus(isActive ? Employee.Status.ACTIVE : Employee.Status.INACTIVE);
employeeService.createOrUpdate(employee);
refreshGrid();
}
private void addEditButtonColumn(String label, ButtonClickHandler handler) {
table.addComponentColumn(employee -> createButton(label, () -> handler.handle(employee)));
}
Outdated
Review

podemos usar el componente PagingGrid de la llibreria Viritin (ya esta incluida). Ejemplo: https://addons.dokku1.parttio.org/paginggrid y codigo https://github.com/parttio/addon-demos/blob/main/src/main/java/org/example/views/PagingGridView.java

asi ya no necesitamos crear los botones y navegacion manualmente.

podemos usar el componente PagingGrid de la llibreria Viritin (ya esta incluida). Ejemplo: https://addons.dokku1.parttio.org/paginggrid y codigo https://github.com/parttio/addon-demos/blob/main/src/main/java/org/example/views/PagingGridView.java asi ya no necesitamos crear los botones y navegacion manualmente.
private Button createButton(String label, Runnable onClickAction) {
Button button = new Button(label);
button.addClickListener(event -> {
sortField = "firstName";
ascending = isAscending;
updateGrid();
});
button.addClickListener(event -> onClickAction.run());
return button;
}
private void configureGrid() {
grid = new VGrid<>(Employee.class);
grid.setColumns("firstName", "lastName", "status");
grid.setAllRowsVisible(true);
grid.addComponentColumn(employee -> createStatusComboBox()).setHeader("Change Status");
grid.addComponentColumn(employee -> createEditButton());
grid.addComponentColumn(employee -> createSaveButton());
add(grid);
}
private ComboBox<String> createStatusComboBox() {
ComboBox<String> statusComboBox = new ComboBox<>();
statusComboBox.setItems("Active", "Inactive");
return statusComboBox;
}
private Button createEditButton() {
return new Button("Edit");
}
private Button createSaveButton() {
return new Button("Save");
}
private void addNavigationButtons() {
final HorizontalLayout hf = new HorizontalLayout();
previous = createNavigationButton("Previous", -1);
next = createNavigationButton("Next", 1);
hf.add(previous, next, createAddEmployeeButton());
add(hf);
}
private Button createNavigationButton(String label, int increment) {
Button button = new Button(label);
button.addClickListener(event -> handlePageChange(increment));
return button;
}
private void handlePageChange(int increment) {
if (isPageChangeValid(increment)) {
currentPage += increment;
updateGrid();
} else {
showNotification("No existen más datos en lista.");
}
}
private boolean isPageChangeValid(int increment) {
if (increment < 0) {
return currentPage > 1;
} else if (increment > 0) {
return employeeService.hasNextPage(currentPage, pageSize, sortField, ascending);
}
return false;
}
private void showNotification(String message) {
Notification notification = new Notification(message, 3000, Notification.Position.BOTTOM_END);
notification.open();
}
private Button createAddEmployeeButton() {
return new Button("Add Employee", event ->
getUI().flatMap(ui -> ui.navigate(EmployeeView.class, "new"))
);
return createButton("Add Employee", this::navigateToAddEmployeeView);
}
private void updateGrid() {
Page<Employee> page = employeeService.getEmployeesPaginated(currentPage, pageSize, sortField, ascending);
grid.setItems(page.getContent());
private void navigateToEditView(Employee employee) {
getUI().ifPresent(ui -> ui.navigate(EmployeeView.class, employee.getId().toString()));
}
private void navigateToAddEmployeeView() {
getUI().ifPresent(ui -> ui.navigate(EmployeeView.class, "new"));
}
private void navigateToSaveChangeStatus(Employee employee) {
// no-op
}
private void setupPagingGrid() {
table.setPaginationBarMode(PagingGrid.PaginationBarMode.BOTTOM);
table.setPageSize(5);
}
private void refreshGrid() {
table.setPagingDataProvider((page, pageSize) -> fetchEmployees((int) page, pageSize));
}
private List<Employee> fetchEmployees(int page, int pageSize) {
int start = page * pageSize;
if (hasSortOrder()) {
return fetchSortedEmployees(start, pageSize);
}
return employeeService.findEmployees(start, pageSize);
}
private boolean hasSortOrder() {
return !table.getSortOrder().isEmpty();
}
private List<Employee> fetchSortedEmployees(int start, int pageSize) {
GridSortOrder<Employee> sortOrder = table.getSortOrder().getFirst();
return employeeService.findEmployees(start, pageSize, sortOrder.getSorted().getKey(), sortOrder.getDirection() == SortDirection.ASCENDING);
}
@FunctionalInterface
private interface ButtonClickHandler {
void handle(Employee employee);
}
}