Refactored searches into a tab thing, not sure whether I like it though.

This commit is contained in:
Andrew Lalis 2024-07-09 13:39:41 -04:00
parent 2dbb3d944d
commit 72d624afdc
2 changed files with 72 additions and 78 deletions

View File

@ -3,7 +3,6 @@ package com.andrewlalis.perfin.control;
import com.andrewlalis.javafx_scene_router.RouteSelectionListener; import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
import com.andrewlalis.perfin.data.AccountRepository; import com.andrewlalis.perfin.data.AccountRepository;
import com.andrewlalis.perfin.data.TransactionRepository; import com.andrewlalis.perfin.data.TransactionRepository;
import com.andrewlalis.perfin.data.TransactionVendorRepository;
import com.andrewlalis.perfin.data.impl.JdbcDataSource; import com.andrewlalis.perfin.data.impl.JdbcDataSource;
import com.andrewlalis.perfin.data.pagination.Page; import com.andrewlalis.perfin.data.pagination.Page;
import com.andrewlalis.perfin.data.pagination.PageRequest; import com.andrewlalis.perfin.data.pagination.PageRequest;
@ -14,7 +13,6 @@ import com.andrewlalis.perfin.data.util.Pair;
import com.andrewlalis.perfin.model.Account; import com.andrewlalis.perfin.model.Account;
import com.andrewlalis.perfin.model.Profile; import com.andrewlalis.perfin.model.Profile;
import com.andrewlalis.perfin.model.Transaction; import com.andrewlalis.perfin.model.Transaction;
import com.andrewlalis.perfin.model.TransactionVendor;
import com.andrewlalis.perfin.view.BindingUtil; import com.andrewlalis.perfin.view.BindingUtil;
import com.andrewlalis.perfin.view.SceneUtil; import com.andrewlalis.perfin.view.SceneUtil;
import com.andrewlalis.perfin.view.component.AccountSelectionBox; import com.andrewlalis.perfin.view.component.AccountSelectionBox;
@ -26,7 +24,8 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.CheckBox; import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
@ -34,8 +33,8 @@ import javafx.scene.layout.VBox;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture;
import static com.andrewlalis.perfin.PerfinApp.router; import static com.andrewlalis.perfin.PerfinApp.router;
@ -54,14 +53,10 @@ public class TransactionsViewController implements RouteSelectionListener {
public record RouteContext(Long selectedTransactionId) {} public record RouteContext(Long selectedTransactionId) {}
@FXML public BorderPane transactionsListBorderPane; @FXML public BorderPane transactionsListBorderPane;
@FXML public TabPane searchTabPane;
@FXML public TextField searchField; @FXML public TextField searchField;
@FXML public AccountSelectionBox filterByAccountComboBox; @FXML public AccountSelectionBox filterByAccountComboBox;
@FXML public TextArea customSearchSqlTextArea;
@FXML public CheckBox advancedSearchFeaturesCheckBox;
@FXML public VBox advancedSearchFeaturesVBox;
@FXML public VBox advancedSearchAccountChoicesVBox;
@FXML public VBox advancedSearchTagChoicesVBox;
@FXML public VBox advancedSearchVendorChoicesVBox;
@FXML public VBox transactionsVBox; @FXML public VBox transactionsVBox;
@ -85,13 +80,10 @@ public class TransactionsViewController implements RouteSelectionListener {
selectedTransaction.set(null); selectedTransaction.set(null);
}); });
// Initialize advanced search feature toggling. // Add listener to reset search when a different search tab is selected.
BindingUtil.bindManagedAndVisible(filterByAccountComboBox.getParent(), advancedSearchFeaturesCheckBox.selectedProperty().not()); searchTabPane.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> {
BindingUtil.bindManagedAndVisible(advancedSearchFeaturesVBox, advancedSearchFeaturesCheckBox.selectedProperty()); paginationControls.setPage(1);
advancedSearchFeaturesCheckBox.selectedProperty().addListener((observable, oldValue, newValue) -> { selectedTransaction.set(null);
if (newValue) {
initializeAdvancedSearchFeatures();
}
}); });
this.paginationControls = new DataSourcePaginationControls( this.paginationControls = new DataSourcePaginationControls(
@ -140,42 +132,6 @@ public class TransactionsViewController implements RouteSelectionListener {
}); });
} }
private void initializeAdvancedSearchFeatures() {
Profile.getCurrent().dataSource().useRepoAsync(AccountRepository.class, repo -> {
List<Account> allAccounts = repo.findAll(PageRequest.unpaged(Sort.asc("name"))).items();
Platform.runLater(() -> {
advancedSearchAccountChoicesVBox.getChildren().clear();
for (Account account : allAccounts) {
CheckBox checkBox = new CheckBox(account.getShortName());
checkBox.setSelected(false);
advancedSearchAccountChoicesVBox.getChildren().add(checkBox);
}
});
});
Profile.getCurrent().dataSource().useRepoAsync(TransactionRepository.class, repo -> {
List<String> tags = repo.findAllTags();
Platform.runLater(() -> {
advancedSearchTagChoicesVBox.getChildren().clear();
for (var tag : tags) {
CheckBox checkBox = new CheckBox(tag);
checkBox.setSelected(false);
advancedSearchTagChoicesVBox.getChildren().add(checkBox);
}
});
});
Profile.getCurrent().dataSource().useRepoAsync(TransactionVendorRepository.class, repo -> {
List<TransactionVendor> vendors = repo.findAll();
Platform.runLater(() -> {
advancedSearchVendorChoicesVBox.getChildren().clear();
for (var vendor : vendors) {
CheckBox checkBox = new CheckBox(vendor.getName());
checkBox.setSelected(false);
advancedSearchVendorChoicesVBox.getChildren().add(checkBox);
}
});
});
}
@Override @Override
public void onRouteSelected(Object context) { public void onRouteSelected(Object context) {
paginationControls.sorts.setAll(DEFAULT_SORTS); paginationControls.sorts.setAll(DEFAULT_SORTS);
@ -217,7 +173,24 @@ public class TransactionsViewController implements RouteSelectionListener {
Popups.message(transactionsListBorderPane, "Exporting transactions is not yet supported."); Popups.message(transactionsListBorderPane, "Exporting transactions is not yet supported.");
} }
@FXML public void executeSqlQuery() {
paginationControls.setPage(1);
selectedTransaction.set(null);
}
private List<SearchFilter> getCurrentSearchFilters() { private List<SearchFilter> getCurrentSearchFilters() {
if (searchTabPane.getSelectionModel().isSelected(0)) {
return getBasicSearchFilters();
} else if (searchTabPane.getSelectionModel().isSelected(1)) {
return Collections.emptyList();
} else if (searchTabPane.getSelectionModel().isSelected(2) && !customSearchSqlTextArea.getText().isBlank()) {
var filter = new SearchFilter.Builder().where(customSearchSqlTextArea.getText().strip()).build();
return List.of(filter);
}
return Collections.emptyList();
}
private List<SearchFilter> getBasicSearchFilters() {
List<SearchFilter> filters = new ArrayList<>(); List<SearchFilter> filters = new ArrayList<>();
if (searchField.getText() != null && !searchField.getText().isBlank()) { if (searchField.getText() != null && !searchField.getText().isBlank()) {
final String text = searchField.getText().strip(); final String text = searchField.getText().strip();

View File

@ -21,33 +21,54 @@
<HBox> <HBox>
<BorderPane fx:id="transactionsListBorderPane" HBox.hgrow="ALWAYS"> <BorderPane fx:id="transactionsListBorderPane" HBox.hgrow="ALWAYS">
<top> <top>
<TabPane fx:id="searchTabPane">
<Tab text="Basic Search" closable="false">
<VBox styleClass="padding-extra,std-spacing"> <VBox styleClass="padding-extra,std-spacing">
<TextField fx:id="searchField" promptText="Search" maxWidth="300" prefWidth="300" minWidth="100"/> <TextField fx:id="searchField" promptText="Search" maxWidth="300" prefWidth="300" minWidth="100"/>
<PropertiesPane hgap="5" vgap="5"> <PropertiesPane hgap="5" vgap="5">
<Label text="Filter by Account"/> <Label text="Filter by Account"/>
<AccountSelectionBox fx:id="filterByAccountComboBox" allowNone="true" showBalance="false"/> <AccountSelectionBox fx:id="filterByAccountComboBox" allowNone="true" showBalance="false"/>
</PropertiesPane> </PropertiesPane>
<CheckBox fx:id="advancedSearchFeaturesCheckBox" text="Advanced Search"/>
<VBox fx:id="advancedSearchFeaturesVBox" styleClass="std-spacing">
<Label text="Advanced search features shown here!"/>
<PropertiesPane hgap="5" vgap="5">
<Label text="Filter by Accounts"/>
<ScrollPane maxHeight="100">
<VBox fx:id="advancedSearchAccountChoicesVBox" styleClass="std-spacing"/>
</ScrollPane>
<Label text="Filter by Tags"/>
<ScrollPane maxHeight="100">
<VBox fx:id="advancedSearchTagChoicesVBox" styleClass="std-spacing"/>
</ScrollPane>
<Label text="Filter by Vendor"/>
<ScrollPane maxHeight="100">
<VBox fx:id="advancedSearchVendorChoicesVBox" styleClass="std-spacing"/>
</ScrollPane>
</PropertiesPane>
</VBox> </VBox>
</Tab>
<Tab text="Advanced Search" closable="false">
<Label text="Advanced search filters will go here once they're ready."/>
</Tab>
<Tab text="Custom Search" closable="false">
<HBox styleClass="std-spacing,std-padding" maxWidth="600">
<VBox styleClass="std-spacing" HBox.hgrow="ALWAYS">
<ScrollPane VBox.vgrow="ALWAYS" fitToHeight="true" fitToWidth="true">
<TextArea
fx:id="customSearchSqlTextArea"
promptText="Write your SQL query here..."
styleClass="mono-font"
maxWidth="Infinity"
minHeight="50"
prefHeight="150"
/>
</ScrollPane>
<HBox styleClass="std-spacing">
<Button text="Execute" onAction="#executeSqlQuery"/>
<Button text="View Schema"/>
<Button text="Save Query"/>
</HBox>
</VBox> </VBox>
<VBox HBox.hgrow="NEVER" minWidth="200">
<Label text="Saved Queries"/>
<ScrollPane VBox.vgrow="ALWAYS">
<VBox>
<Label text="Query A"/>
<Label text="Query B"/>
<Label text="Query C"/>
<Label text="Query D"/>
</VBox>
</ScrollPane>
</VBox>
</HBox>
</Tab>
</TabPane>
</top> </top>
<center> <center>
<ScrollPane styleClass="tile-container-scroll"> <ScrollPane styleClass="tile-container-scroll">