Add error dialog for view loading failures and fix btnPurchaseOrdersClicked signature
This commit is contained in:
@@ -5,16 +5,14 @@ import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
|
||||
/*
|
||||
Petshop Desktop
|
||||
Purpose: Main application shell controller, includes navigation and UI level role based access control.
|
||||
*/
|
||||
public class MainLayoutController {
|
||||
|
||||
@FXML
|
||||
@@ -50,6 +48,9 @@ public class MainLayoutController {
|
||||
@FXML
|
||||
private Button btnSuppliers;
|
||||
|
||||
@FXML
|
||||
private Button btnStaffAccounts;
|
||||
|
||||
@FXML
|
||||
private Label lblUsername;
|
||||
|
||||
@@ -102,11 +103,17 @@ public class MainLayoutController {
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnPurchaseOrdersClicked() {
|
||||
void btnPurchaseOrdersClicked(ActionEvent event) {
|
||||
loadView("purchase-order-view.fxml");
|
||||
updateButtons(btnPurchaseOrders);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnStaffAccountsClicked(ActionEvent event) {
|
||||
loadView("staff-accounts-view.fxml");
|
||||
updateButtons(btnStaffAccounts);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnServicesClicked(ActionEvent event) {
|
||||
loadView("service-view.fxml");
|
||||
@@ -117,14 +124,10 @@ public class MainLayoutController {
|
||||
void btnSuppliersClicked(ActionEvent event) {
|
||||
loadView("supplier-view.fxml");
|
||||
updateButtons(btnSuppliers);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@FXML
|
||||
void btnLogoutClicked(ActionEvent event) {
|
||||
// Logout clears session state before returning to the login view.
|
||||
UserSession.getInstance().logout();
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(
|
||||
@@ -134,6 +137,10 @@ public class MainLayoutController {
|
||||
stage.setScene(scene);
|
||||
stage.setTitle("Pet Shop Manager - Login");
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"MainLayoutController.btnLogoutClicked",
|
||||
e,
|
||||
"Loading login view after logout");
|
||||
System.err.println("Error loading login view: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -141,22 +148,22 @@ public class MainLayoutController {
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
// RBAC state is applied once during initial layout load.
|
||||
applyRBAC();
|
||||
|
||||
// Default landing view after successful authentication.
|
||||
loadView("pet-view.fxml");
|
||||
updateButtons(btnPets);
|
||||
}
|
||||
|
||||
private void applyRBAC() {
|
||||
UserSession session = UserSession.getInstance();
|
||||
|
||||
// Session identity is displayed in the header for clarity and auditing.
|
||||
lblUsername.setText(session.getUsername());
|
||||
lblRole.setText(session.getRole().toString());
|
||||
String displayName = session.getEmployeeName();
|
||||
if (displayName == null || displayName.isBlank()) {
|
||||
displayName = session.getUsername();
|
||||
}
|
||||
lblUsername.setText(displayName == null ? "" : displayName);
|
||||
lblRole.setText("Leon's Petstore");
|
||||
|
||||
// UI level RBAC hides admin only navigation entries for non admin users.
|
||||
// setManaged(false) removes the node from layout calculations to avoid empty spacing.
|
||||
boolean isAdmin = session.isAdmin();
|
||||
btnInventory.setVisible(isAdmin);
|
||||
btnInventory.setManaged(isAdmin);
|
||||
@@ -165,47 +172,65 @@ public class MainLayoutController {
|
||||
btnProductSuppliers.setVisible(isAdmin);
|
||||
btnProductSuppliers.setManaged(isAdmin);
|
||||
|
||||
// Privileged operations should still be enforced within the relevant controllers and database methods.
|
||||
btnPurchaseOrders.setVisible(isAdmin);
|
||||
btnPurchaseOrders.setManaged(isAdmin);
|
||||
|
||||
btnStaffAccounts.setVisible(isAdmin);
|
||||
btnStaffAccounts.setManaged(isAdmin);
|
||||
|
||||
btnSalesHistory.setText(isAdmin ? "Sales History" : "Sales");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a view when a button is clicked on the navigation
|
||||
* @param fxmlFile the fxmlFile name to be loaded
|
||||
*/
|
||||
private void loadView(String fxmlFile) {
|
||||
try {
|
||||
//Get the location of the fxml for view
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/modelviews/" + fxmlFile));
|
||||
Parent view = loader.load();
|
||||
//Clear any content that is in the stack pane and add the new view to display
|
||||
spContentArea.getChildren().clear();
|
||||
spContentArea.getChildren().add(view);
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException(
|
||||
"MainLayoutController.loadView",
|
||||
e,
|
||||
"Loading view: " + fxmlFile);
|
||||
System.err.println("Error loading view: " + fxmlFile);
|
||||
e.printStackTrace();
|
||||
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("View Load Error");
|
||||
alert.setHeaderText("Failed to load: " + fxmlFile);
|
||||
alert.setContentText("Error: " + e.getMessage() + "\n\nCheck console for details.");
|
||||
alert.showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update the button visuals when a button is clicked on the navigation
|
||||
* @param activeButton the button to be set active
|
||||
*/
|
||||
private void updateButtons(Button activeButton) {
|
||||
//reset all buttons
|
||||
Button[] BUTTONS = {btnAdoptions, btnPets, btnAppointments, btnInventory,
|
||||
btnSalesHistory, btnServices, btnSuppliers, btnProductSuppliers, btnProducts};
|
||||
for (Button button : BUTTONS) {
|
||||
//set all buttons to inactive
|
||||
button.setStyle("-fx-background-color: transparent; " +
|
||||
"-fx-text-fill: #CCCCCC; " +
|
||||
"-fx-cursor: hand");
|
||||
String base = "-fx-background-color: transparent; -fx-text-fill: #D5DDE6; -fx-cursor: hand; -fx-background-radius: 10; -fx-alignment: CENTER_LEFT;";
|
||||
String active = "-fx-background-color: #FF6B6B; -fx-text-fill: white; -fx-cursor: hand; -fx-background-radius: 10; -fx-alignment: CENTER_LEFT;";
|
||||
|
||||
Button[] buttons = {
|
||||
btnAdoptions,
|
||||
btnPets,
|
||||
btnAppointments,
|
||||
btnInventory,
|
||||
btnSalesHistory,
|
||||
btnServices,
|
||||
btnSuppliers,
|
||||
btnProductSuppliers,
|
||||
btnProducts,
|
||||
btnPurchaseOrders,
|
||||
btnStaffAccounts
|
||||
};
|
||||
|
||||
for (Button button : buttons) {
|
||||
if (button != null) {
|
||||
button.setStyle(base);
|
||||
}
|
||||
}
|
||||
|
||||
//set active button
|
||||
activeButton.setStyle("-fx-background-color: #FF6B6B; " +
|
||||
"-fx-text-fill: white; " +
|
||||
"-fx-cursor: hand; " +
|
||||
"-fx-background-radius: 8");
|
||||
if (activeButton != null) {
|
||||
activeButton.setStyle(active);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user