feat: added expense status indicator
This commit is contained in:
parent
e36d4b49e7
commit
23b9e09aab
5 changed files with 35 additions and 3 deletions
|
@ -63,4 +63,10 @@ public class Expense {
|
||||||
|
|
||||||
@Column(name = "Date", nullable = false, columnDefinition = "DATE DEFAULT CURRENT_DATE")
|
@Column(name = "Date", nullable = false, columnDefinition = "DATE DEFAULT CURRENT_DATE")
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the isResolved field starts as always false, cause at creation an expense cant be already be resolved
|
||||||
|
*/
|
||||||
|
@Column(name = "isResolved", nullable = false)
|
||||||
|
private Boolean isResolved = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,4 +20,6 @@ public interface ExpenseRepository extends JpaRepository<Expense, Long>, JpaSpec
|
||||||
|
|
||||||
@Query("SELECT e FROM Expense e WHERE YEAR(e.date) = :year")
|
@Query("SELECT e FROM Expense e WHERE YEAR(e.date) = :year")
|
||||||
List<Expense> findAllByYear(@Param("year") int year);
|
List<Expense> findAllByYear(@Param("year") int year);
|
||||||
|
|
||||||
|
boolean existsByIdAndIsResolvedTrue(Long id);
|
||||||
}
|
}
|
|
@ -58,4 +58,8 @@ public class ExpenseService {
|
||||||
return this.repository.findAllByYear(year);
|
return this.repository.findAllByYear(year);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isExpenseResolved(final Expense expense) {
|
||||||
|
return this.repository.existsByIdAndIsResolvedTrue(expense.getId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ 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.grid.GridVariant;
|
||||||
import com.vaadin.flow.component.html.Div;
|
import com.vaadin.flow.component.html.Div;
|
||||||
|
import com.vaadin.flow.component.html.Span;
|
||||||
import com.vaadin.flow.component.icon.Icon;
|
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.notification.Notification.Position;
|
import com.vaadin.flow.component.notification.Notification.Position;
|
||||||
|
@ -28,13 +29,17 @@ import com.vaadin.flow.component.textfield.TextArea;
|
||||||
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.data.binder.ValidationException;
|
import com.vaadin.flow.data.binder.ValidationException;
|
||||||
|
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||||
import com.vaadin.flow.data.renderer.LitRenderer;
|
import com.vaadin.flow.data.renderer.LitRenderer;
|
||||||
import com.vaadin.flow.router.*;
|
import com.vaadin.flow.router.*;
|
||||||
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
|
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.orm.ObjectOptimisticLockingFailureException;
|
import org.springframework.orm.ObjectOptimisticLockingFailureException;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@PageTitle("Expenses")
|
@PageTitle("Expenses")
|
||||||
@Route(value = "/:expenseID?/:action?(edit)", layout = MainLayout.class)
|
@Route(value = "/:expenseID?/:action?(edit)", layout = MainLayout.class)
|
||||||
|
@ -92,6 +97,8 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
|
||||||
grid.addColumn(Expense::getPeriodUnit).setHeader("Period Unit").setSortable(true);
|
grid.addColumn(Expense::getPeriodUnit).setHeader("Period Unit").setSortable(true);
|
||||||
grid.addColumn(Expense::getDate).setHeader("Date").setSortable(true).setSortProperty("date");
|
grid.addColumn(Expense::getDate).setHeader("Date").setSortable(true).setSortProperty("date");
|
||||||
// grid.addColumn(expenseEvent -> expenseEvent.getEvent().getName()).setHeader("Event").setSortable(true);
|
// grid.addColumn(expenseEvent -> expenseEvent.getEvent().getName()).setHeader("Event").setSortable(true);
|
||||||
|
|
||||||
|
grid.addColumn(new ComponentRenderer<>(expense1 -> createBadge(expenseService.isExpenseResolved(expense1)))).setHeader("Status").setSortable(true);
|
||||||
grid.getColumns().forEach(col -> col.setAutoWidth(true));
|
grid.getColumns().forEach(col -> col.setAutoWidth(true));
|
||||||
|
|
||||||
grid.setItems(query -> expenseService.list(
|
grid.setItems(query -> expenseService.list(
|
||||||
|
@ -287,4 +294,16 @@ public class ExpensesView extends Div implements BeforeEnterObserver {
|
||||||
periodUnit.setVisible(isPeriodicChecked);
|
periodUnit.setVisible(isPeriodicChecked);
|
||||||
periodInterval.setVisible(isPeriodicChecked);
|
periodInterval.setVisible(isPeriodicChecked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Span createBadge(Boolean isExpenseResolved) {
|
||||||
|
Span badge = new Span();
|
||||||
|
if (Boolean.TRUE.equals(isExpenseResolved)) {
|
||||||
|
badge.setText("Resolved");
|
||||||
|
badge.getElement().getThemeList().add("badge success");
|
||||||
|
} else {
|
||||||
|
badge.setText("To be Resolved");
|
||||||
|
badge.getElement().getThemeList().add("badge error");
|
||||||
|
}
|
||||||
|
return badge;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,4 +234,5 @@ public class PeopleView extends Div implements BeforeEnterObserver {
|
||||||
badge.getElement().getThemeList().add("badge contrast");
|
badge.getElement().getThemeList().add("badge contrast");
|
||||||
}
|
}
|
||||||
return badge;
|
return badge;
|
||||||
}}
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue