fix desktop forms

This commit is contained in:
2026-04-08 07:55:55 -06:00
parent 548d7629d3
commit 56ffecba92
12 changed files with 127 additions and 48 deletions

View File

@@ -83,8 +83,9 @@ public class AdoptionController {
tvAdoptions.getSelectionModel().selectedItemProperty().addListener( tvAdoptions.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> { (observable, oldValue, newValue) -> {
btnEdit.setDisable(false); boolean hasSelection = newValue != null;
btnDelete.setDisable(false); btnEdit.setDisable(!hasSelection);
btnDelete.setDisable(!hasSelection);
}); });
txtSearch.textProperty().addListener((observable, oldValue, newValue) -> { txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {

View File

@@ -47,7 +47,8 @@ public class AppointmentController {
@FXML @FXML
public void initialize(){ public void initialize(){
btnEdit.setDisable(true);
btnDelete.setDisable(true);
tvAppointments.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE); tvAppointments.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE);
colAppointmentId.setCellValueFactory(new PropertyValueFactory<>("appointmentId")); colAppointmentId.setCellValueFactory(new PropertyValueFactory<>("appointmentId"));
@@ -66,6 +67,12 @@ public class AppointmentController {
txtSearch.textProperty().addListener((obs, o, n) -> applyFilter(n)); txtSearch.textProperty().addListener((obs, o, n) -> applyFilter(n));
} }
tvAppointments.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
boolean hasSelection = newValue != null;
btnEdit.setDisable(!hasSelection);
btnDelete.setDisable(!hasSelection);
});
tvAppointments.setOnKeyPressed(event -> { tvAppointments.setOnKeyPressed(event -> {
if (event.getCode() == javafx.scene.input.KeyCode.DELETE) { if (event.getCode() == javafx.scene.input.KeyCode.DELETE) {
if (tvAppointments.getSelectionModel().getSelectedItem() != null) { if (tvAppointments.getSelectionModel().getSelectedItem() != null) {

View File

@@ -73,8 +73,9 @@ public class InventoryController {
tvInventory.getSelectionModel().selectedItemProperty().addListener( tvInventory.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> { (observable, oldValue, newValue) -> {
btnEdit.setDisable(false); boolean hasSelection = newValue != null;
btnDelete.setDisable(false); btnEdit.setDisable(!hasSelection);
btnDelete.setDisable(!hasSelection);
}); });
txtSearch.textProperty().addListener((observable, oldValue, newValue) -> { txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {

View File

@@ -175,8 +175,9 @@ public class PetController {
tvPets.getSelectionModel().selectedItemProperty().addListener( tvPets.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> { (observable, oldValue, newValue) -> {
btnEdit.setDisable(false); boolean hasSelection = newValue != null;
btnDelete.setDisable(false); btnEdit.setDisable(!hasSelection);
btnDelete.setDisable(!hasSelection);
}); });
txtSearch.textProperty().addListener((observable, oldValue, newValue) -> { txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {

View File

@@ -99,8 +99,9 @@ public class ProductController {
//EventListener to Enable buttons when a row is selected //EventListener to Enable buttons when a row is selected
tvProducts.getSelectionModel().selectedItemProperty().addListener( tvProducts.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> { (observable, oldValue, newValue) -> {
btnEdit.setDisable(false); boolean hasSelection = newValue != null;
btnDelete.setDisable(false); btnEdit.setDisable(!hasSelection);
btnDelete.setDisable(!hasSelection);
} }
); );

View File

@@ -80,8 +80,9 @@ public class ProductSupplierController {
//EventListener to Enable buttons when a row is selected //EventListener to Enable buttons when a row is selected
tvProductSuppliers.getSelectionModel().selectedItemProperty().addListener( tvProductSuppliers.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> { (observable, oldValue, newValue) -> {
btnEdit.setDisable(false); boolean hasSelection = newValue != null;
btnDelete.setDisable(false); btnEdit.setDisable(!hasSelection);
btnDelete.setDisable(!hasSelection);
} }
); );

View File

@@ -186,7 +186,7 @@ public class SaleController {
spQuantity.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 999, 1)); spQuantity.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 999, 1));
spQuantity.setEditable(true); spQuantity.setEditable(true);
cbPaymentMethod.setItems(FXCollections.observableArrayList("Cash", "Card")); cbPaymentMethod.setItems(FXCollections.observableArrayList("Cash", "Card", "Debit"));
cbPaymentMethod.getSelectionModel().selectFirst(); cbPaymentMethod.getSelectionModel().selectFirst();
updateCartTotal(); updateCartTotal();

View File

@@ -57,8 +57,9 @@ public class ServiceController {
tvServices.getSelectionModel().selectedItemProperty().addListener( tvServices.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> { (observable, oldValue, newValue) -> {
btnEdit.setDisable(false); boolean hasSelection = newValue != null;
btnDelete.setDisable(false); btnEdit.setDisable(!hasSelection);
btnDelete.setDisable(!hasSelection);
} }
); );

View File

@@ -82,8 +82,9 @@ public class SupplierController {
//EventListener to Enable buttons when a row is selected //EventListener to Enable buttons when a row is selected
tvSuppliers.getSelectionModel().selectedItemProperty().addListener( tvSuppliers.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> { (observable, oldValue, newValue) -> {
btnEdit.setDisable(false); boolean hasSelection = newValue != null;
btnDelete.setDisable(false); btnEdit.setDisable(!hasSelection);
btnDelete.setDisable(!hasSelection);
} }
); );
@@ -285,16 +286,18 @@ public class SupplierController {
} }
private Supplier mapToSupplier(SupplierResponse response) { private Supplier mapToSupplier(SupplierResponse response) {
String contactPerson = response.getSupContactFirstName() + " " + response.getSupContactLastName() != null ? response.getSupContactFirstName() + " " + response.getSupContactLastName() : ""; String firstName = response.getSupContactFirstName() != null ? response.getSupContactFirstName().trim() : "";
String lastName = response.getSupContactLastName() != null ? response.getSupContactLastName().trim() : "";
String contactPerson = (firstName + " " + lastName).trim();
String[] nameParts = contactPerson.split(" ", 2); String[] nameParts = contactPerson.split(" ", 2);
String firstName = nameParts.length > 0 ? nameParts[0] : ""; String mappedFirstName = nameParts.length > 0 ? nameParts[0] : "";
String lastName = nameParts.length > 1 ? nameParts[1] : ""; String mappedLastName = nameParts.length > 1 ? nameParts[1] : "";
return new Supplier( return new Supplier(
response.getSupId().intValue(), response.getSupId().intValue(),
response.getSupCompany(), response.getSupCompany(),
firstName, mappedFirstName,
lastName, mappedLastName,
response.getSupEmail(), response.getSupEmail(),
response.getSupPhone() response.getSupPhone()
); );

View File

@@ -9,6 +9,7 @@ import javafx.scene.Node;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.example.petshopdesktop.Validator; import org.example.petshopdesktop.Validator;
import org.example.petshopdesktop.api.dto.common.DropdownOption; import org.example.petshopdesktop.api.dto.common.DropdownOption;
@@ -48,6 +49,12 @@ public class PetDialogController {
@FXML @FXML
private ComboBox<DropdownOption> cbStore; private ComboBox<DropdownOption> cbStore;
@FXML
private VBox vbCustomerField;
@FXML
private VBox vbStoreField;
@FXML @FXML
private Label lblMode; private Label lblMode;
@@ -84,7 +91,7 @@ public class PetDialogController {
private Long pendingStoreId = null; private Long pendingStoreId = null;
private ObservableList<String> statusList = FXCollections.observableArrayList( private ObservableList<String> statusList = FXCollections.observableArrayList(
"Available", "Adopted", "Owned" "Available", "Adopted", "Owned", "Pending"
); );
@FXML @FXML
@@ -118,14 +125,11 @@ public class PetDialogController {
} }
}); });
cbCustomer.setVisible(false); setFieldVisibility(vbCustomerField, false);
cbStore.setVisible(false); setFieldVisibility(vbStoreField, false);
cbPetStatus.valueProperty().addListener((obs, oldVal, newVal) -> { cbPetStatus.valueProperty().addListener((obs, oldVal, newVal) -> {
boolean isOwned = "Owned".equalsIgnoreCase(newVal); updateStatusFieldVisibility(newVal);
boolean isAvailable = "Available".equalsIgnoreCase(newVal) || "Unadopted".equalsIgnoreCase(newVal);
cbCustomer.setVisible(isOwned);
cbStore.setVisible(isAvailable);
}); });
btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() { btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() {
@@ -166,6 +170,9 @@ public class PetDialogController {
if ("Owned".equalsIgnoreCase(selectedStatus) && cbCustomer.getValue() == null) { if ("Owned".equalsIgnoreCase(selectedStatus) && cbCustomer.getValue() == null) {
errorMsg += "Customer is required for Owned status\n"; errorMsg += "Customer is required for Owned status\n";
} }
if (requiresStore(selectedStatus) && cbStore.getValue() == null) {
errorMsg += "Store is required for " + selectedStatus + " status\n";
}
//Check validation (length size) //Check validation (length size)
errorMsg += Validator.isLessThanVarChars(txtPetName.getText(), "Pet Name", 50); errorMsg += Validator.isLessThanVarChars(txtPetName.getText(), "Pet Name", 50);
@@ -243,7 +250,7 @@ public class PetDialogController {
if ("Owned".equalsIgnoreCase(status) && cbCustomer.getValue() != null) { if ("Owned".equalsIgnoreCase(status) && cbCustomer.getValue() != null) {
request.setCustomerId(cbCustomer.getValue().getId()); request.setCustomerId(cbCustomer.getValue().getId());
} }
if (("Available".equalsIgnoreCase(status) || "Unadopted".equalsIgnoreCase(status)) && cbStore.getValue() != null) { if (requiresStore(status) && cbStore.getValue() != null) {
request.setStoreId(cbStore.getValue().getId()); request.setStoreId(cbStore.getValue().getId());
} }
@@ -339,8 +346,10 @@ public class PetDialogController {
for (String status : cbPetStatus.getItems()) { for (String status : cbPetStatus.getItems()) {
if(status.equals(pet.getPetStatus())){ if(status.equals(pet.getPetStatus())){
cbPetStatus.getSelectionModel().select(status); cbPetStatus.getSelectionModel().select(status);
break;
} }
} }
updateStatusFieldVisibility(cbPetStatus.getValue());
} }
} }
@@ -358,6 +367,7 @@ public class PetDialogController {
lblPetId.setVisible(true); lblPetId.setVisible(true);
refreshImagePreview(); refreshImagePreview();
} }
updateStatusFieldVisibility(cbPetStatus.getValue());
} }
private void handleChangeImage() { private void handleChangeImage() {
@@ -421,4 +431,25 @@ public class PetDialogController {
btnRemoveImage.setDisable(true); btnRemoveImage.setDisable(true);
} }
private void updateStatusFieldVisibility(String status) {
boolean owned = "Owned".equalsIgnoreCase(status);
boolean storeBased = requiresStore(status);
setFieldVisibility(vbCustomerField, owned);
setFieldVisibility(vbStoreField, storeBased);
}
private boolean requiresStore(String status) {
return "Available".equalsIgnoreCase(status)
|| "Pending".equalsIgnoreCase(status)
|| "Unadopted".equalsIgnoreCase(status);
}
private void setFieldVisibility(VBox field, boolean visible) {
if (field == null) {
return;
}
field.setVisible(visible);
field.setManaged(visible);
}
} }

View File

@@ -19,6 +19,7 @@ import org.example.petshopdesktop.api.endpoints.ProductSupplierApi;
import org.example.petshopdesktop.util.ActivityLogger; import org.example.petshopdesktop.util.ActivityLogger;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
public class ProductSupplierDialogController { public class ProductSupplierDialogController {
@@ -46,6 +47,8 @@ public class ProductSupplierDialogController {
private String mode = null; private String mode = null;
private int selectedSupId = -1; private int selectedSupId = -1;
private int selectedProdId = -1; private int selectedProdId = -1;
private Long pendingSupplierId = null;
private Long pendingProductId = null;
/** /**
* add event listeners to buttons and set up combobox * add event listeners to buttons and set up combobox
@@ -120,9 +123,11 @@ public class ProductSupplierDialogController {
Platform.runLater(() -> { Platform.runLater(() -> {
if (suppliers != null) { if (suppliers != null) {
cbSupplier.setItems(FXCollections.observableArrayList(suppliers)); cbSupplier.setItems(FXCollections.observableArrayList(suppliers));
applyPendingSupplierSelection();
} }
if (products != null) { if (products != null) {
cbProduct.setItems(FXCollections.observableArrayList(products)); cbProduct.setItems(FXCollections.observableArrayList(products));
applyPendingProductSelection();
} }
}); });
} catch (Exception e) { } catch (Exception e) {
@@ -220,21 +225,14 @@ public class ProductSupplierDialogController {
* @param productSupplier * @param productSupplier
*/ */
public void displayProductSupplierDetails(ProductSupplierDTO productSupplier){ public void displayProductSupplierDetails(ProductSupplierDTO productSupplier){
if(productSupplier != null){ if (productSupplier == null) {
txtCost.setText(productSupplier.getCost() + ""); return;
}
for (DropdownOption product : cbProduct.getItems()) {
if(product.getId() == productSupplier.getProdId()){
cbProduct.getSelectionModel().select(product);
}
}
for (DropdownOption supplier : cbSupplier.getItems()) {
if (supplier.getId() == productSupplier.getSupId()) {
cbSupplier.getSelectionModel().select(supplier);
}
} }
txtCost.setText(productSupplier.getCost() + "");
pendingProductId = (long) productSupplier.getProdId();
pendingSupplierId = (long) productSupplier.getSupId();
applyPendingProductSelection();
applyPendingSupplierSelection();
} }
/** /**
@@ -253,7 +251,7 @@ public class ProductSupplierDialogController {
*/ */
public void setMode(String mode) { public void setMode(String mode) {
this.mode = mode; this.mode = mode;
lblMode.setText(mode + " Product"); lblMode.setText(mode + " Product-Supplier");
lblProductSupplierId.setVisible(false); lblProductSupplierId.setVisible(false);
} }
@@ -267,4 +265,38 @@ public class ProductSupplierDialogController {
this.selectedProdId = prodId; this.selectedProdId = prodId;
} }
private void applyPendingProductSelection() {
if (pendingProductId == null) {
return;
}
DropdownOption product = findOptionById(cbProduct.getItems(), pendingProductId);
if (product != null) {
cbProduct.getSelectionModel().select(product);
pendingProductId = null;
}
}
private void applyPendingSupplierSelection() {
if (pendingSupplierId == null) {
return;
}
DropdownOption supplier = findOptionById(cbSupplier.getItems(), pendingSupplierId);
if (supplier != null) {
cbSupplier.getSelectionModel().select(supplier);
pendingSupplierId = null;
}
}
private DropdownOption findOptionById(List<DropdownOption> options, Long id) {
if (options == null || id == null) {
return null;
}
for (DropdownOption option : options) {
if (option.getId() != null && option.getId().equals(id)) {
return option;
}
}
return null;
}
} }

View File

@@ -153,7 +153,7 @@
</TextField> </TextField>
</children> </children>
</VBox> </VBox>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.rowIndex="3"> <VBox fx:id="vbCustomerField" prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.rowIndex="3">
<children> <children>
<Label text="Customer:" textFill="#2c3e50"> <Label text="Customer:" textFill="#2c3e50">
<font> <font>
@@ -167,7 +167,7 @@
</ComboBox> </ComboBox>
</children> </children>
</VBox> </VBox>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.columnIndex="1" GridPane.rowIndex="3"> <VBox fx:id="vbStoreField" prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
<children> <children>
<Label text="Store:" textFill="#2c3e50"> <Label text="Store:" textFill="#2c3e50">
<font> <font>