Compare commits

..

2 Commits

4 changed files with 221 additions and 3 deletions

View File

@ -3,7 +3,9 @@ package com.primefactorsolutions.repositories;
import com.primefactorsolutions.model.TimeOffRequest; import com.primefactorsolutions.model.TimeOffRequest;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID; import java.util.UUID;
public interface TimeOffRequestRepository extends JpaRepository<TimeOffRequest, UUID> { public interface TimeOffRequestRepository extends JpaRepository<TimeOffRequest, UUID> {
List<TimeOffRequest> findByEmployee_Id(UUID id_employee);
} }

View File

@ -85,4 +85,8 @@ public class TimeOffRequestService {
int end = Math.min(start + pageSize, timeOffRequests.size()); int end = Math.min(start + pageSize, timeOffRequests.size());
return timeOffRequests.subList(start, end); return timeOffRequests.subList(start, end);
} }
public List<TimeOffRequest> findRequestsByEmployeeId(UUID id_employee) {
return timeOffRequestRepository.findByEmployee_Id(id_employee);
}
} }

View File

@ -0,0 +1,193 @@
package com.primefactorsolutions.views;
import com.primefactorsolutions.model.Employee;
import com.primefactorsolutions.model.TimeOffRequest;
import com.primefactorsolutions.model.TimeOffRequestType;
import com.primefactorsolutions.service.EmployeeService;
import com.primefactorsolutions.service.TimeOffRequestService;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.grid.GridSortOrder;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.provider.SortDirection;
import com.vaadin.flow.router.BeforeEvent;
import com.vaadin.flow.router.HasUrlParameter;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent;
import jakarta.annotation.security.PermitAll;
import org.apache.commons.beanutils.BeanComparator;
import org.springframework.context.annotation.Scope;
import org.vaadin.firitin.components.grid.PagingGrid;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@SpringComponent
@PermitAll
@Scope("prototype")
@PageTitle("Request")
@Route(value = "/requests", layout = MainLayout.class)
public class RequestView extends Div implements HasUrlParameter<String> {
private final TimeOffRequestService requestService;
private final EmployeeService employeeService;
private final PagingGrid<TimeOffRequest> requestGrid = new PagingGrid<>(TimeOffRequest.class);
private List<TimeOffRequest> requests;
private ComboBox<TimeOffRequestType> categoryFilter;
private ComboBox<TimeOffRequest.Status> stateFilter;
private UUID employeeId;
public RequestView(TimeOffRequestService requestService, EmployeeService employeeService) {
this.requestService = requestService;
this.employeeService = employeeService;
this.requests = Collections.emptyList();
setupFilters();
setupGrid();
add(requestGrid);
add(createSummaryLayout());
add(createActionButtons());
refreshRequestGrid(null, null);
}
private void setupFilters() {
categoryFilter = createCategoryFilter();
stateFilter = createStateFilter();
add(categoryFilter, stateFilter);
}
private ComboBox<TimeOffRequestType> createCategoryFilter() {
categoryFilter = new ComboBox<>("Category");
categoryFilter.setItems(TimeOffRequestType.values());
categoryFilter.setValue(TimeOffRequestType.values()[0]);
categoryFilter.addValueChangeListener(event -> refreshRequestGrid(event.getValue(), stateFilter.getValue()));
return categoryFilter;
}
private ComboBox<TimeOffRequest.Status> createStateFilter() {
stateFilter = new ComboBox<>("State");
stateFilter.setItems(TimeOffRequest.Status.values());
stateFilter.setValue(TimeOffRequest.Status.values()[0]);
stateFilter.addValueChangeListener(event -> refreshRequestGrid(categoryFilter.getValue(), event.getValue()));
return stateFilter;
}
private void setupGrid() {
requestGrid.setColumns(
"category",
"state",
"availableDays",
"expiration",
"startDate",
"endDate",
"daysToBeTake",
"daysBalance"
);
}
private VerticalLayout createSummaryLayout() {
int totalVacations = 15;
int totalTimeOff = 2;
int totalAvailableDays = totalVacations + totalTimeOff;
Span holidaysLabel = new Span("TOTAL HOLIDAYS: " + totalVacations);
Span timeOffLabel = new Span("TOTAL TIME OFF: " + totalTimeOff);
Span availableDaysLabel = new Span("TOTAL AVAILABLE DAYS: " + totalAvailableDays);
return new VerticalLayout(holidaysLabel, timeOffLabel, availableDaysLabel);
}
private HorizontalLayout createActionButtons() {
Button viewButton = new Button("View");
Button editButton = new Button("Edit");
Button saveButton = new Button("Save");
Button closeButton = new Button("Close", event -> navigateToRequestsListView());
return new HorizontalLayout(viewButton, editButton, saveButton, closeButton);
}
private void navigateToRequestsListView() {
getUI().ifPresent(ui -> ui.navigate(RequestsListView.class));
}
private void refreshRequestGrid(final TimeOffRequestType category,
final TimeOffRequest.Status state) {
requestGrid.setPagingDataProvider((page, pageSize) -> {
if (allFiltersAreNull(category, state)) {
return fetchTimeOffRequests((int) page, pageSize);
} else {
return fetchFilteredTimeOffRequests((int) page, pageSize,category, state);
}
});
requestGrid.getDataProvider().refreshAll();
}
private boolean allFiltersAreNull(TimeOffRequestType category, TimeOffRequest.Status state) {
return category == null && state == null;
}
private List<TimeOffRequest> fetchTimeOffRequests(int page, int pageSize) {
int start = page * pageSize;
if (requestGrid.getSortOrder().isEmpty()) {
int end = Math.min(start + pageSize, requests.size());
return requests.subList(start, end);
} else {
return fetchSortedTimeOffRequests(start, pageSize);
}
}
private List<TimeOffRequest> fetchSortedTimeOffRequests(int start, int pageSize) {
GridSortOrder<TimeOffRequest> sortOrder = requestGrid.getSortOrder().getFirst();
int end = Math.min(start + pageSize, requests.size());
requests.sort(new BeanComparator<>(sortOrder.getSorted().getKey()));
if (sortOrder.getDirection() != SortDirection.ASCENDING) {
Collections.reverse(requests);
}
return requests.subList(start, end);
}
private List<TimeOffRequest> fetchFilteredTimeOffRequests(int page, int pageSize, TimeOffRequestType category, TimeOffRequest.Status state) {
requests = requestService.findRequestsByEmployeeId(employeeId);
if (category != null && !"ALL".equals(category.name())) {
requests = requests.stream()
.filter(req -> req.getCategory().equals(category))
.collect(Collectors.toList());
}
if (state != null && !"ALL".equals(state.name())) {
requests = requests.stream()
.filter(req -> req.getState().equals(state))
.collect(Collectors.toList());
}
int end = Math.min(page + pageSize, requests.size());
return requests.subList(page, end);
}
@Override
public void setParameter(BeforeEvent event, String parameter) {
try {
employeeId = UUID.fromString(parameter);
Employee employee = employeeService.getEmployee(employeeId);
String employeeName = employee.getFirstName() + " " + employee.getLastName();
String employeeTeam = employee.getTeam();
setViewTitle(employeeName, employeeTeam);
requests = requestService.findRequestsByEmployeeId(employeeId);
requestGrid.setItems(requests);
} catch (IllegalArgumentException e) {
requestGrid.setItems();
}
}
private void setViewTitle(String employeeName, String employeeTeam) {
H3 employeeTitle = new H3("Name: " + employeeName);
H3 teamTitle = new H3("Team: " + employeeTeam);
addComponentAsFirst(employeeTitle);
addComponentAtIndex(1, teamTitle);
}
}

View File

@ -9,6 +9,7 @@ import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.grid.GridSortOrder; import com.vaadin.flow.component.grid.GridSortOrder;
import com.vaadin.flow.component.html.Main; import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.component.html.Span; import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.data.provider.SortDirection; import com.vaadin.flow.data.provider.SortDirection;
import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.PageTitle;
@ -19,6 +20,7 @@ import org.springframework.context.annotation.Scope;
import org.vaadin.firitin.components.grid.PagingGrid; import org.vaadin.firitin.components.grid.PagingGrid;
import java.util.List; import java.util.List;
import java.util.UUID;
@SpringComponent @SpringComponent
@Scope("prototype") @Scope("prototype")
@ -35,6 +37,7 @@ public class RequestsListView extends Main {
private ComboBox<Team> teamFilter; private ComboBox<Team> teamFilter;
private ComboBox<TimeOffRequestType> categoryFilter; private ComboBox<TimeOffRequestType> categoryFilter;
private ComboBox<TimeOffRequest.Status> stateFilter; private ComboBox<TimeOffRequest.Status> stateFilter;
private UUID selectedEmployeeId;
public RequestsListView(final TimeOffRequestService requestService, public RequestsListView(final TimeOffRequestService requestService,
final EmployeeService employeeService, final EmployeeService employeeService,
@ -76,13 +79,25 @@ public class RequestsListView extends Main {
requestGrid.addComponentColumn(this::createTeamSpan).setHeader("Team"); requestGrid.addComponentColumn(this::createTeamSpan).setHeader("Team");
requestGrid.setPaginationBarMode(PagingGrid.PaginationBarMode.BOTTOM); requestGrid.setPaginationBarMode(PagingGrid.PaginationBarMode.BOTTOM);
requestGrid.setPageSize(5); requestGrid.setPageSize(5);
requestGrid.asSingleSelect().addValueChangeListener(event -> {
TimeOffRequest selectedRequest = event.getValue();
if (selectedRequest != null) {
selectedEmployeeId = selectedRequest.getEmployee().getId();
}
});
} }
private HorizontalLayout createActionButtons() { private HorizontalLayout createActionButtons() {
Button viewButton = new Button("View"); Button viewButton = new Button("View", event -> {
if (selectedEmployeeId != null) {
navigateToTimeOffRequestView(selectedEmployeeId);
} else {
Notification.show("Please select a request to view.", 3000, Notification.Position.MIDDLE);
}
});
Button editButton = new Button("Edit"); Button editButton = new Button("Edit");
Button saveButton = new Button("Save"); Button saveButton = new Button("Save");
Button closeButton = new Button("Close", event -> closeView()); Button closeButton = new Button("Close", event -> navigateToMainView());
return new HorizontalLayout(viewButton, editButton, saveButton, closeButton); return new HorizontalLayout(viewButton, editButton, saveButton, closeButton);
} }
@ -230,7 +245,11 @@ public class RequestsListView extends Main {
return "ALL".equals(team.getName()) ? "ALL" : team.getName(); return "ALL".equals(team.getName()) ? "ALL" : team.getName();
} }
private void closeView() { private void navigateToMainView() {
getUI().ifPresent(ui -> ui.navigate(MainView.class)); getUI().ifPresent(ui -> ui.navigate(MainView.class));
} }
private void navigateToTimeOffRequestView(final UUID id_employee) {
getUI().ifPresent(ui -> ui.navigate("requests/" + id_employee.toString()));
}
} }