fix desktop pet and product dialogs
This commit is contained in:
@@ -44,6 +44,33 @@ public class Validator {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the input is a positive double
|
||||||
|
* @param value input of string
|
||||||
|
* @param name name of input
|
||||||
|
* @return error msg if input is not a number or not positive, otherwise empty
|
||||||
|
*/
|
||||||
|
public static String isPositiveDouble(String value, String name){
|
||||||
|
String msg ="";
|
||||||
|
if (value == null) {
|
||||||
|
msg += name + " must be a number.\n";
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
double result;
|
||||||
|
try {
|
||||||
|
result = Double.parseDouble(value);
|
||||||
|
if (result <= 0){
|
||||||
|
msg += name + " must be greater than 0. \n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e){
|
||||||
|
msg += name + " must be a number.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the input is a double in 2 different range
|
* Checks if the input is a double in 2 different range
|
||||||
* @param value input of string
|
* @param value input of string
|
||||||
@@ -95,6 +122,28 @@ public class Validator {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the input is a positive integer
|
||||||
|
* @param value input of string
|
||||||
|
* @param name name of input
|
||||||
|
* @return error msg if input is not a number or not positive, otherwise empty
|
||||||
|
*/
|
||||||
|
public static String isPositiveInteger(String value, String name){
|
||||||
|
String msg ="";
|
||||||
|
int result;
|
||||||
|
try {
|
||||||
|
result = Integer.parseInt(value);
|
||||||
|
if (result <= 0){
|
||||||
|
msg += name + " must be greater than 0. \n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e){
|
||||||
|
msg += name + " must be a whole number.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if the string is a given amount of characters or fewer
|
* check if the string is a given amount of characters or fewer
|
||||||
* @param value input of string
|
* @param value input of string
|
||||||
|
|||||||
@@ -224,15 +224,21 @@ public class ApiClient {
|
|||||||
try {
|
try {
|
||||||
if (response.body() != null && !response.body().isEmpty()) {
|
if (response.body() != null && !response.body().isEmpty()) {
|
||||||
var errorNode = objectMapper.readTree(response.body());
|
var errorNode = objectMapper.readTree(response.body());
|
||||||
if (errorNode.has("message")) {
|
|
||||||
return errorNode.get("message").asText();
|
|
||||||
}
|
|
||||||
if (errorNode.has("errors")) {
|
if (errorNode.has("errors")) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
errorNode.get("errors").fields().forEachRemaining(entry -> {
|
errorNode.get("errors").fields().forEachRemaining(entry -> {
|
||||||
sb.append(entry.getValue().asText()).append("\n");
|
String errorText = entry.getValue().asText();
|
||||||
|
if (errorText != null && !errorText.isBlank()) {
|
||||||
|
sb.append(errorText).append("\n");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return sb.toString().trim();
|
if (sb.length() > 0) {
|
||||||
|
String message = errorNode.has("message") ? errorNode.get("message").asText() : null;
|
||||||
|
return (message != null && !message.isBlank() ? message + "\n" : "") + sb.toString().trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errorNode.has("message")) {
|
||||||
|
return errorNode.get("message").asText();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.example.petshopdesktop.util.FilePickerSupport;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
public class PetDialogController {
|
public class PetDialogController {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@@ -120,7 +121,7 @@ public class PetDialogController {
|
|||||||
|
|
||||||
//Check validation (format)
|
//Check validation (format)
|
||||||
errorMsg += Validator.isNonNegativeDouble(txtPetPrice.getText(), "Price");
|
errorMsg += Validator.isNonNegativeDouble(txtPetPrice.getText(), "Price");
|
||||||
errorMsg += Validator.isNonNegativeInteger(txtPetAge.getText(), "Age");
|
errorMsg += Validator.isPositiveInteger(txtPetAge.getText(), "Age");
|
||||||
|
|
||||||
if(errorMsg.isEmpty()){
|
if(errorMsg.isEmpty()){
|
||||||
PetRequest request = buildPetRequest();
|
PetRequest request = buildPetRequest();
|
||||||
@@ -252,6 +253,7 @@ public class PetDialogController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyImageChanges(Long petId) throws Exception {
|
private void applyImageChanges(Long petId) throws Exception {
|
||||||
|
String previousImageUrl = currentImageUrl;
|
||||||
if (removeImageRequested) {
|
if (removeImageRequested) {
|
||||||
try {
|
try {
|
||||||
PetApi.getInstance().deletePetImage(petId);
|
PetApi.getInstance().deletePetImage(petId);
|
||||||
@@ -260,7 +262,15 @@ public class PetDialogController {
|
|||||||
}
|
}
|
||||||
if (selectedImageFile != null) {
|
if (selectedImageFile != null) {
|
||||||
PetApi.getInstance().uploadPetImage(petId, selectedImageFile.toPath());
|
PetApi.getInstance().uploadPetImage(petId, selectedImageFile.toPath());
|
||||||
|
currentImageUrl = "/api/v1/pets/" + petId + "/image";
|
||||||
|
} else if (removeImageRequested) {
|
||||||
|
currentImageUrl = null;
|
||||||
}
|
}
|
||||||
|
DesktopImageSupport.evict(previousImageUrl);
|
||||||
|
DesktopImageSupport.evict(currentImageUrl);
|
||||||
|
selectedImageFile = null;
|
||||||
|
removeImageRequested = false;
|
||||||
|
refreshImagePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshImagePreview() {
|
private void refreshImagePreview() {
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public class ProductDialogController {
|
|||||||
errorMsg += Validator.isLessThanVarChars(txtProdPrice.getText(), "Product Price", 12);
|
errorMsg += Validator.isLessThanVarChars(txtProdPrice.getText(), "Product Price", 12);
|
||||||
|
|
||||||
//Check Validation (format)
|
//Check Validation (format)
|
||||||
errorMsg += Validator.isNonNegativeDouble(txtProdPrice.getText(), "Product Price");
|
errorMsg += Validator.isPositiveDouble(txtProdPrice.getText(), "Product Price");
|
||||||
|
|
||||||
if (errorMsg.isEmpty()) {
|
if (errorMsg.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
@@ -258,6 +258,7 @@ public class ProductDialogController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyImageChanges(Long productId) throws Exception {
|
private void applyImageChanges(Long productId) throws Exception {
|
||||||
|
String previousImageUrl = currentImageUrl;
|
||||||
if (removeImageRequested) {
|
if (removeImageRequested) {
|
||||||
try {
|
try {
|
||||||
ProductApi.getInstance().deleteProductImage(productId);
|
ProductApi.getInstance().deleteProductImage(productId);
|
||||||
@@ -266,7 +267,15 @@ public class ProductDialogController {
|
|||||||
}
|
}
|
||||||
if (selectedImageFile != null) {
|
if (selectedImageFile != null) {
|
||||||
ProductApi.getInstance().uploadProductImage(productId, selectedImageFile.toPath());
|
ProductApi.getInstance().uploadProductImage(productId, selectedImageFile.toPath());
|
||||||
|
currentImageUrl = "/api/v1/products/" + productId + "/image";
|
||||||
|
} else if (removeImageRequested) {
|
||||||
|
currentImageUrl = null;
|
||||||
}
|
}
|
||||||
|
DesktopImageSupport.evict(previousImageUrl);
|
||||||
|
DesktopImageSupport.evict(currentImageUrl);
|
||||||
|
selectedImageFile = null;
|
||||||
|
removeImageRequested = false;
|
||||||
|
refreshImagePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshImagePreview() {
|
private void refreshImagePreview() {
|
||||||
|
|||||||
@@ -20,12 +20,21 @@ public final class DesktopImageSupport {
|
|||||||
imageView.setFitWidth(width);
|
imageView.setFitWidth(width);
|
||||||
imageView.setFitHeight(height);
|
imageView.setFitHeight(height);
|
||||||
imageView.setPreserveRatio(true);
|
imageView.setPreserveRatio(true);
|
||||||
|
imageView.setSmooth(true);
|
||||||
imageView.setImage(null);
|
imageView.setImage(null);
|
||||||
|
|
||||||
if (imageUrl == null || imageUrl.isBlank()) {
|
if (imageUrl == null || imageUrl.isBlank()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (imageUrl.startsWith("file:")) {
|
||||||
|
Image image = new Image(imageUrl, 0, 0, true, true);
|
||||||
|
if (!image.isError()) {
|
||||||
|
imageView.setImage(image);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Image cached = IMAGE_CACHE.get(imageUrl);
|
Image cached = IMAGE_CACHE.get(imageUrl);
|
||||||
if (cached != null) {
|
if (cached != null) {
|
||||||
imageView.setImage(cached);
|
imageView.setImage(cached);
|
||||||
@@ -35,7 +44,7 @@ public final class DesktopImageSupport {
|
|||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
byte[] bytes = ApiClient.getInstance().getBytes(imageUrl);
|
byte[] bytes = ApiClient.getInstance().getBytes(imageUrl);
|
||||||
Image image = new Image(new ByteArrayInputStream(bytes), width, height, true, true);
|
Image image = new Image(new ByteArrayInputStream(bytes));
|
||||||
if (!image.isError()) {
|
if (!image.isError()) {
|
||||||
IMAGE_CACHE.put(imageUrl, image);
|
IMAGE_CACHE.put(imageUrl, image);
|
||||||
Platform.runLater(() -> imageView.setImage(image));
|
Platform.runLater(() -> imageView.setImage(image));
|
||||||
|
|||||||
@@ -10,11 +10,10 @@
|
|||||||
<?import javafx.scene.layout.GridPane?>
|
<?import javafx.scene.layout.GridPane?>
|
||||||
<?import javafx.scene.layout.HBox?>
|
<?import javafx.scene.layout.HBox?>
|
||||||
<?import javafx.scene.layout.Region?>
|
<?import javafx.scene.layout.Region?>
|
||||||
<?import javafx.scene.layout.RowConstraints?>
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
|
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="560.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
|
||||||
<children>
|
<children>
|
||||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||||
<children>
|
<children>
|
||||||
@@ -63,18 +62,13 @@
|
|||||||
<Insets left="15.0" right="15.0" />
|
<Insets left="15.0" right="15.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</HBox>
|
</HBox>
|
||||||
<VBox prefHeight="370.0" prefWidth="750.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 2; -fx-border-color: #5580b5; -fx-border-radius: 14;">
|
<VBox prefHeight="405.0" prefWidth="750.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 2; -fx-border-color: #5580b5; -fx-border-radius: 14;">
|
||||||
<children>
|
<children>
|
||||||
<GridPane hgap="25.0" VBox.vgrow="ALWAYS">
|
<GridPane hgap="25.0" vgap="10.0">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
|
||||||
</rowConstraints>
|
|
||||||
<children>
|
<children>
|
||||||
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0">
|
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0">
|
||||||
<children>
|
<children>
|
||||||
|
|||||||
@@ -10,11 +10,10 @@
|
|||||||
<?import javafx.scene.layout.GridPane?>
|
<?import javafx.scene.layout.GridPane?>
|
||||||
<?import javafx.scene.layout.HBox?>
|
<?import javafx.scene.layout.HBox?>
|
||||||
<?import javafx.scene.layout.Region?>
|
<?import javafx.scene.layout.Region?>
|
||||||
<?import javafx.scene.layout.RowConstraints?>
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ProductDialogController">
|
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="560.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ProductDialogController">
|
||||||
<children>
|
<children>
|
||||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||||
<children>
|
<children>
|
||||||
@@ -63,19 +62,14 @@
|
|||||||
<Insets left="15.0" right="15.0" />
|
<Insets left="15.0" right="15.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</HBox>
|
</HBox>
|
||||||
<VBox prefHeight="370.0" prefWidth="750.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 2; -fx-border-color: #5580b5; -fx-border-radius: 14;">
|
<VBox prefHeight="405.0" prefWidth="750.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 2; -fx-border-color: #5580b5; -fx-border-radius: 14;">
|
||||||
<children>
|
<children>
|
||||||
<GridPane hgap="25.0" VBox.vgrow="ALWAYS">
|
<GridPane hgap="25.0" vgap="10.0">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<children>
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
|
||||||
</rowConstraints>
|
|
||||||
<children>
|
|
||||||
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0">
|
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0">
|
||||||
<children>
|
<children>
|
||||||
<Label text="Product Name:" textFill="#2c3e50">
|
<Label text="Product Name:" textFill="#2c3e50">
|
||||||
|
|||||||
Reference in New Issue
Block a user