diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 8a431a62..59cafbb3 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -139,13 +139,13 @@ opens org.chainoptim.desktop.shared.common.uielements.performance to javafx.fxml, com.google.guice; opens org.chainoptim.desktop.shared.common.uielements.info to javafx.fxml, com.google.guice; opens org.chainoptim.desktop.shared.common.uielements.settings to javafx.fxml, com.google.guice; - opens org.chainoptim.desktop.shared.common.uielements to com.google.guice; // - Enums opens org.chainoptim.desktop.shared.enums to com.fasterxml.jackson.databind; // - Table opens org.chainoptim.desktop.shared.table to javafx.fxml, com.google.guice; + opens org.chainoptim.desktop.shared.table.util to com.google.guice; // - Location opens org.chainoptim.desktop.shared.features.location.model to com.fasterxml.jackson.databind; diff --git a/src/main/java/org/chainoptim/desktop/AppModule.java b/src/main/java/org/chainoptim/desktop/AppModule.java index 53c1d6b1..042d6739 100644 --- a/src/main/java/org/chainoptim/desktop/AppModule.java +++ b/src/main/java/org/chainoptim/desktop/AppModule.java @@ -47,6 +47,7 @@ import org.chainoptim.desktop.features.scanalysis.supply.service.SupplierPerformanceService; import org.chainoptim.desktop.features.scanalysis.supply.service.SupplierPerformanceServiceImpl; import org.chainoptim.desktop.features.supplier.model.Supplier; +import org.chainoptim.desktop.features.supplier.model.SupplierOrder; import org.chainoptim.desktop.features.supplier.service.*; import org.chainoptim.desktop.features.warehouse.model.Warehouse; import org.chainoptim.desktop.features.warehouse.service.WarehouseService; @@ -137,6 +138,7 @@ protected void configure() { bind(SupplierService.class).to(SupplierServiceImpl.class); bind(SupplierWriteService.class).to(SupplierWriteServiceImpl.class); bind(SupplierOrdersService.class).to(SupplierOrdersServiceImpl.class); + bind(SupplierOrdersWriteService.class).to(SupplierOrdersWriteServiceImpl.class); // - Components bind(ComponentService.class).to(ComponentServiceImpl.class); @@ -168,15 +170,23 @@ protected void configure() { // - Caching bind(new TypeLiteral>>() {}) - .to(new TypeLiteral>>() {}); + .to(new TypeLiteral>>() {}) + .in(Singleton.class); bind(new TypeLiteral>>() {}) - .to(new TypeLiteral>>() {}); + .to(new TypeLiteral>>() {}) + .in(Singleton.class); bind(new TypeLiteral>>() {}) - .to(new TypeLiteral>>() {}); + .to(new TypeLiteral>>() {}) + .in(Singleton.class); bind(new TypeLiteral>>() {}) - .to(new TypeLiteral>>() {}); + .to(new TypeLiteral>>() {}) + .in(Singleton.class); + bind(new TypeLiteral>>() {}) + .to(new TypeLiteral>>() {}) + .in(Singleton.class); bind(new TypeLiteral>>() {}) - .to(new TypeLiteral>>() {}); + .to(new TypeLiteral>>() {}) + .in(Singleton.class); bind(new TypeLiteral>() {}) .to(new TypeLiteral>() {}) .in(Singleton.class); diff --git a/src/main/java/org/chainoptim/desktop/features/client/service/ClientServiceImpl.java b/src/main/java/org/chainoptim/desktop/features/client/service/ClientServiceImpl.java index 7d1ff3c0..fd7cd909 100644 --- a/src/main/java/org/chainoptim/desktop/features/client/service/ClientServiceImpl.java +++ b/src/main/java/org/chainoptim/desktop/features/client/service/ClientServiceImpl.java @@ -65,7 +65,7 @@ public CompletableFuture>> getClientsByOrganiz SearchParams searchParams ) { String rootAddress = "http://localhost:8080/api/v1/"; - String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("products", organizationId, searchParams); + String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("products", "organization", organizationId, searchParams); String routeAddress = rootAddress + cacheKey; String jwtToken = TokenManager.getToken(); diff --git a/src/main/java/org/chainoptim/desktop/features/factory/service/FactoryServiceImpl.java b/src/main/java/org/chainoptim/desktop/features/factory/service/FactoryServiceImpl.java index f3235e03..9688b1b0 100644 --- a/src/main/java/org/chainoptim/desktop/features/factory/service/FactoryServiceImpl.java +++ b/src/main/java/org/chainoptim/desktop/features/factory/service/FactoryServiceImpl.java @@ -92,7 +92,7 @@ public CompletableFuture>> getFactoriesByOrga SearchParams searchParams ) { String rootAddress = "http://localhost:8080/api/v1/"; - String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("factories", organizationId, searchParams); + String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("factories", "organization", organizationId, searchParams); String routeAddress = rootAddress + cacheKey; String jwtToken = TokenManager.getToken(); diff --git a/src/main/java/org/chainoptim/desktop/features/product/service/ProductServiceImpl.java b/src/main/java/org/chainoptim/desktop/features/product/service/ProductServiceImpl.java index 97f3dde8..d1cfda07 100644 --- a/src/main/java/org/chainoptim/desktop/features/product/service/ProductServiceImpl.java +++ b/src/main/java/org/chainoptim/desktop/features/product/service/ProductServiceImpl.java @@ -67,7 +67,7 @@ public CompletableFuture>> getProductsByOrgan SearchParams searchParams ) { String rootAddress = "http://localhost:8080/api/v1/"; - String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("products", organizationId, searchParams); + String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("products", "organization", organizationId, searchParams); String routeAddress = rootAddress + cacheKey; String jwtToken = TokenManager.getToken(); diff --git a/src/main/java/org/chainoptim/desktop/features/supplier/controller/SupplierOrdersController.java b/src/main/java/org/chainoptim/desktop/features/supplier/controller/SupplierOrdersController.java index cea89f6d..e3b74434 100644 --- a/src/main/java/org/chainoptim/desktop/features/supplier/controller/SupplierOrdersController.java +++ b/src/main/java/org/chainoptim/desktop/features/supplier/controller/SupplierOrdersController.java @@ -1,10 +1,6 @@ package org.chainoptim.desktop.features.supplier.controller; -import org.chainoptim.desktop.MainApplication; -import org.chainoptim.desktop.core.abstraction.ControllerFactory; import org.chainoptim.desktop.core.context.TenantContext; -import org.chainoptim.desktop.core.main.service.CurrentSelectionService; -import org.chainoptim.desktop.core.main.service.NavigationServiceImpl; import org.chainoptim.desktop.core.user.model.User; import org.chainoptim.desktop.features.productpipeline.model.Component; import org.chainoptim.desktop.features.supplier.dto.CreateSupplierOrderDTO; @@ -12,7 +8,7 @@ import org.chainoptim.desktop.features.supplier.model.Supplier; import org.chainoptim.desktop.features.supplier.model.SupplierOrder; import org.chainoptim.desktop.features.supplier.service.SupplierOrdersService; -import org.chainoptim.desktop.shared.common.uielements.SelectComponentController; +import org.chainoptim.desktop.features.supplier.service.SupplierOrdersWriteService; import org.chainoptim.desktop.shared.confirmdialog.controller.GenericConfirmDialogController; import org.chainoptim.desktop.shared.confirmdialog.controller.RunnableConfirmDialogActionListener; import org.chainoptim.desktop.shared.confirmdialog.model.ConfirmDialogInput; @@ -21,13 +17,14 @@ import org.chainoptim.desktop.shared.search.model.PaginatedResults; import org.chainoptim.desktop.shared.search.model.SearchParams; import org.chainoptim.desktop.shared.table.TableToolbarController; -import org.chainoptim.desktop.shared.table.edit.cells.ComboBoxEditableCell; -import org.chainoptim.desktop.shared.table.edit.cells.EditableCell; +import org.chainoptim.desktop.shared.table.edit.cell.ComboBoxEditableCell; +import org.chainoptim.desktop.shared.table.edit.cell.EditableCell; import org.chainoptim.desktop.shared.table.model.TableData; import org.chainoptim.desktop.shared.table.util.TableConfigurer; +import org.chainoptim.desktop.shared.table.util.SelectComponentLoader; + import org.chainoptim.desktop.shared.util.DataReceiver; import org.chainoptim.desktop.shared.util.resourceloader.CommonViewsLoader; -import org.chainoptim.desktop.shared.util.resourceloader.FXMLLoaderService; import com.google.inject.Inject; import javafx.application.Platform; @@ -36,12 +33,9 @@ import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.layout.StackPane; -import java.io.IOException; import java.time.LocalDateTime; import java.util.*; import java.util.function.Consumer; @@ -50,16 +44,13 @@ public class SupplierOrdersController implements DataReceiver { // Services private final SupplierOrdersService supplierOrdersService; - private final CurrentSelectionService currentSelectionService; - private final NavigationServiceImpl navigationService; + private final SupplierOrdersWriteService supplierOrdersWriteService; private final CommonViewsLoader commonViewsLoader; - private final FXMLLoaderService fxmlLoaderService; - private final ControllerFactory controllerFactory; // Controllers private TableToolbarController tableToolbarController; private PageSelectorController pageSelectorController; - private SelectComponentController selectComponentController; + private final SelectComponentLoader selectComponentLoader; private GenericConfirmDialogController> confirmSupplierOrderUpdateController; private GenericConfirmDialogController> confirmSupplierOrderDeleteController; private GenericConfirmDialogController> confirmSupplierOrderCreateController; @@ -67,8 +58,14 @@ public class SupplierOrdersController implements DataReceiver { // State private final FallbackManager fallbackManager; private final SearchParams searchParams; + private final Map sortOptions = Map.of( + "orderDate", "Order Date", + "estimatedDeliveryDate", "Estimated Delivery Date", + "deliveryDate", "Delivery Date", + "quantity", "Quantity" + ); private Supplier supplier; - private List statusOptions = Arrays.asList(SupplierOrder.Status.values()); + private final List statusOptions = Arrays.asList(SupplierOrder.Status.values()); private long totalRowsCount; private int newOrderCount = 0; private final List selectedRowsIndices = new ArrayList<>(); @@ -120,43 +117,53 @@ public class SupplierOrdersController implements DataReceiver { @Inject public SupplierOrdersController(SupplierOrdersService supplierOrdersService, - NavigationServiceImpl navigationService, - CurrentSelectionService currentSelectionService, + SupplierOrdersWriteService supplierOrdersWriteService, CommonViewsLoader commonViewsLoader, FallbackManager fallbackManager, SearchParams searchParams, - FXMLLoaderService fxmlLoaderService, - ControllerFactory controllerFactory, - SelectComponentController selectComponentController) { + SelectComponentLoader selectComponentLoader) { this.supplierOrdersService = supplierOrdersService; - this.navigationService = navigationService; - this.currentSelectionService = currentSelectionService; + this.supplierOrdersWriteService = supplierOrdersWriteService; this.commonViewsLoader = commonViewsLoader; this.fallbackManager = fallbackManager; this.searchParams = searchParams; - this.fxmlLoaderService = fxmlLoaderService; - this.controllerFactory = controllerFactory; - this.selectComponentController = selectComponentController; + this.selectComponentLoader = selectComponentLoader; } @Override public void setData(Supplier supplier) { this.supplier = supplier; + pageSelectorController = commonViewsLoader.loadPageSelector(pageSelectorContainer); tableToolbarController = commonViewsLoader.initializeTableToolbar(tableToolbarContainer); - tableToolbarController.initialize(() -> loadSupplierOrders(supplier.getId())); - selectComponentController.initialize(); + tableToolbarController.initialize(searchParams, sortOptions, () -> loadSupplierOrders(supplier.getId())); + selectComponentLoader.initialize(); TableConfigurer.configureTableView(tableView, selectRowColumn); configureTableColumns(); + loadConfirmDialogs(); setUpListeners(); loadSupplierOrders(supplier.getId()); - loadConfirmDeleteDialog(); - loadConfirmUpdateDialog(); - loadConfirmCreateDialog(); } + // Loading + private void loadConfirmDialogs() { + confirmSupplierOrderCreateController = commonViewsLoader.loadConfirmDialog(confirmCreateDialogContainer); + confirmSupplierOrderCreateController.setActionListener(confirmDialogCreateListener); + closeConfirmCreateDialog(); + + confirmSupplierOrderUpdateController = commonViewsLoader.loadConfirmDialog(confirmUpdateDialogContainer); + confirmSupplierOrderUpdateController.setActionListener(confirmDialogUpdateListener); + closeConfirmUpdateDialog(); + + confirmSupplierOrderDeleteController = commonViewsLoader.loadConfirmDialog(confirmDeleteDialogContainer); + confirmSupplierOrderDeleteController.setActionListener(confirmDialogDeleteListener); + closeConfirmDeleteDialog(); + } + + // Configuration + // - Table columns private void configureTableColumns() { // Bind columns to data selectRowColumn.setCellValueFactory(data -> data.getValue().isSelectedProperty()); @@ -164,11 +171,9 @@ private void configureTableColumns() { companyIdColumn.setCellValueFactory(data -> new SimpleObjectProperty<>(data.getValue().getData().getCompanyId() != null ? data.getValue().getData().getCompanyId() : "N/A")); supplierNameColumn.setCellValueFactory(data -> new SimpleObjectProperty<>(this.supplier.getName())); componentNameColumn.setCellValueFactory(data -> { - if (data.getValue().getData().getComponent() != null) { - return new SimpleObjectProperty<>(data.getValue().getData().getComponent().getName()); - } else { - return new SimpleObjectProperty<>("N/A"); - } + Component component = data.getValue().getData().getComponent(); + String componentName = component != null ? component.getName() : "N/A"; + return new SimpleObjectProperty<>(componentName); }); quantityColumn.setCellValueFactory(data -> new SimpleObjectProperty<>(data.getValue().getData().getQuantity())); statusColumn.setCellValueFactory(data -> new SimpleObjectProperty<>(data.getValue().getData().getStatus())); @@ -176,105 +181,92 @@ private void configureTableColumns() { estimatedDeliveryDateColumn.setCellValueFactory(data -> new SimpleObjectProperty<>(data.getValue().getData().getEstimatedDeliveryDate())); deliveryDateColumn.setCellValueFactory(data -> new SimpleObjectProperty<>(data.getValue().getData().getDeliveryDate())); - // Configure columns to use custom editable cells - companyIdColumn.setCellFactory(column -> new EditableCell, String>(isEditMode, selectedRowsIndices) { + configureColumnCellFactories(); + } + + private void configureColumnCellFactories() { + companyIdColumn.setCellFactory(column -> new EditableCell, String>( + isEditMode, selectedRowsIndices, String::toString) { @Override - public void commitEdit(String newValue) { - super.commitEdit(newValue); - SupplierOrder order = getTableView().getItems().get(getIndex()).getData(); - order.setCompanyId(newValue); - getTableView().refresh(); + protected void commitChange(TableData item, String newValue) { + item.getData().setCompanyId(newValue); } }); - quantityColumn.setCellFactory(column -> new EditableCell, Float>(isEditMode, selectedRowsIndices) { + quantityColumn.setCellFactory(column -> new EditableCell, Float>( + isEditMode, selectedRowsIndices, Float::parseFloat) { @Override - public void commitEdit(String newValue) { - try { - Float parsedValue = Float.parseFloat(newValue); - super.commitEdit(parsedValue); - SupplierOrder order = getTableView().getItems().get(getIndex()).getData(); - order.setQuantity(parsedValue); - getTableView().refresh(); - } catch (NumberFormatException e) { - System.out.println("Invalid float value: " + newValue); - } + protected void commitChange(TableData item, Float newValue) { + item.getData().setQuantity(newValue); } }); - estimatedDeliveryDateColumn.setCellFactory(column -> new EditableCell, LocalDateTime>(isEditMode, selectedRowsIndices) { + estimatedDeliveryDateColumn.setCellFactory(column -> new EditableCell, LocalDateTime>( + isEditMode, selectedRowsIndices, LocalDateTime::parse) { @Override - public void commitEdit(String newValue) { - try { - LocalDateTime parsedValue = LocalDateTime.parse(newValue); - super.commitEdit(parsedValue); - SupplierOrder order = getTableView().getItems().get(getIndex()).getData(); - order.setEstimatedDeliveryDate(parsedValue); - getTableView().refresh(); - } catch (Exception e) { - System.out.println("Invalid date value: " + newValue); - } + protected void commitChange(TableData item, LocalDateTime newValue) { + item.getData().setEstimatedDeliveryDate(newValue); } }); - deliveryDateColumn.setCellFactory(column -> new EditableCell, LocalDateTime>(isEditMode, selectedRowsIndices) { + deliveryDateColumn.setCellFactory(column -> new EditableCell, LocalDateTime>( + isEditMode, selectedRowsIndices, LocalDateTime::parse) { @Override - public void commitEdit(String newValue) { - try { - LocalDateTime parsedValue = LocalDateTime.parse(newValue); - super.commitEdit(parsedValue); - SupplierOrder order = getTableView().getItems().get(getIndex()).getData(); - order.setDeliveryDate(parsedValue); - getTableView().refresh(); - } catch (Exception e) { - System.out.println("Invalid date value: " + newValue); - } + protected void commitChange(TableData item, LocalDateTime newValue) { + item.getData().setDeliveryDate(newValue); } }); - - statusColumn.setCellFactory(column -> new ComboBoxEditableCell, SupplierOrder.Status>(isEditMode, selectedRowsIndices, statusOptions) { + statusColumn.setCellFactory(column -> new ComboBoxEditableCell, SupplierOrder.Status>( + isEditMode, selectedRowsIndices, null, statusOptions) { @Override - public void commitEdit(SupplierOrder.Status newValue) { - SupplierOrder order = getTableView().getItems().get(getIndex()).getData(); - order.setStatus(newValue); - getTableView().refresh(); + protected void commitChange(TableData item, SupplierOrder.Status newValue) { + item.getData().setStatus(newValue); } }); - - componentNameColumn.setCellFactory(column -> new ComboBoxEditableCell, String>(isEditMode, selectedRowsIndices, selectComponentController.getComponentsName()) { + componentNameColumn.setCellFactory(column -> new ComboBoxEditableCell, String>( + isEditMode, selectedRowsIndices, null, selectComponentLoader.getComponentsName()) { @Override - public void commitEdit(String newValue) { - super.commitEdit(newValue); - SupplierOrder order = getTableView().getItems().get(getIndex()).getData(); - Integer componentId = selectComponentController.getComponentIdByName(newValue); - if (componentId != null) { - Component component = new Component(); - component.setId(componentId); - component.setName(newValue); - order.setComponent(component); - getTableView().refresh(); - } - } + protected void commitChange(TableData item, String newValue) { + Component component = new Component(); + component.setId(selectComponentLoader.getComponentIdByName(newValue)); + component.setName(newValue); + item.getData().setComponent(component); + } }); - } + // - Listeners private void setUpListeners() { - // Listen to empty fallback state - fallbackManager.isEmptyProperty().addListener((observable, oldValue, newValue) -> { - supplierOrdersScrollPane.setVisible(newValue); - supplierOrdersScrollPane.setManaged(newValue); - }); + setUpSearchListeners(); + setUpTableToolbarListeners(); + setUpConfirmDialogListeners(); + } - //Listen to searchParams + private void setUpSearchListeners() { searchParams.getPageProperty().addListener((observable, oldPage, newPage) -> loadSupplierOrders(supplier.getId())); + searchParams.getSortOptionProperty().addListener((observable, oldValue, newValue) -> loadSupplierOrders(supplier.getId())); searchParams.getAscendingProperty().addListener((observable, oldValue, newValue) -> loadSupplierOrders(supplier.getId())); searchParams.getSearchQueryProperty().addListener((observable, oldValue, newValue) -> loadSupplierOrders(supplier.getId())); + } - // Listen to selectedCount property + private void setUpTableToolbarListeners() { selectedCount.addListener((obs, oldCount, newCount) -> { boolean isAnyRowSelected = newCount.intValue() > 0; tableToolbarController.toggleButtonVisibilityOnSelection(isAnyRowSelected); }); - // Listen to Dialog confirmations + // Listen to the toolbar buttons + tableToolbarController.getCancelRowSelectionButton().setOnAction(e -> cancelSelectionsAndEdit()); + tableToolbarController.getEditSelectedRowsButton().setOnAction(e -> editSelectedRows()); + tableToolbarController.getSaveChangesButton().setOnAction(e -> { + if (isNewOrderMode.get()) { + openConfirmCreateDialog(); + } else { + openConfirmUpdateDialog(selectedRowsIndices); + } + }); + tableToolbarController.getDeleteSelectedRowsButton().setOnAction(e -> openConfirmDeleteDialog(selectedRowsIndices));; + tableToolbarController.getCreateNewOrderButton().setOnAction(e -> addNewOrder()); + } + + private void setUpConfirmDialogListeners() { Consumer> onConfirmDelete = this::handleDeleteOrders; Runnable onCancelDelete = this::closeConfirmDeleteDialog; confirmDialogDeleteListener = new RunnableConfirmDialogActionListener<>(onConfirmDelete, onCancelDelete); @@ -286,21 +278,9 @@ private void setUpListeners() { Consumer> onConfirmCreate = this::handleCreateOrders; Runnable onCancelCreate = this::closeConfirmCreateDialog; confirmDialogCreateListener = new RunnableConfirmDialogActionListener<>(onConfirmCreate, onCancelCreate); - - // Listen to the toolbar buttons - tableToolbarController.getCancelRowSelectionButton().setOnAction(e -> cancelSelectionsAndEdit()); - tableToolbarController.getEditSelectedRowsButton().setOnAction(e -> editSelectedRows()); - tableToolbarController.getSaveChangesButton().setOnAction(e -> { - if (isNewOrderMode.get()) { - openConfirmCreateDialog(); - } else { - openConfirmUpdateDialog(selectedRowsIndices); - } - }); - tableToolbarController.getDeleteSelectedRowsButton().setOnAction(e -> openConfirmDeleteDialog(selectedRowsIndices));; - tableToolbarController.getCreateNewOrderButton().setOnAction(e -> addNewOrder()); } + // Data loading private void loadSupplierOrders(Integer supplierId) { fallbackManager.reset(); fallbackManager.setLoading(true); @@ -337,7 +317,7 @@ private Optional> handleOrdersResponse(Optional< for (SupplierOrder supplierOrder : paginatedResults.results) { SupplierOrder oldData = new SupplierOrder(supplierOrder); TableData tableRow = new TableData<>(supplierOrder, oldData, new SimpleBooleanProperty(false)); - setRowListeners(tableRow); + setUpRowListeners(tableRow); tableView.getItems().add(tableRow); } }); @@ -350,7 +330,7 @@ private Optional> handleOrdersException(Throwabl return Optional.empty(); } - private void setRowListeners(TableData supplierOrder) { + private void setUpRowListeners(TableData supplierOrder) { // Add listener to the selectedProperty supplierOrder.isSelectedProperty().addListener((obs, wasSelected, isSelected) -> { if (Boolean.TRUE.equals(isSelected)) { @@ -362,14 +342,14 @@ private void setRowListeners(TableData supplierOrder) { }); } + // UI Actions private void addNewOrder() { isNewOrderMode.set(true); tableToolbarController.toggleButtonVisibilityOnCreate(isNewOrderMode.get()); - SupplierOrder newOrder = new SupplierOrder(); TableData newOrderRow = new TableData<>(newOrder, newOrder, new SimpleBooleanProperty(false)); - tableView.getItems().add(0, newOrderRow); + tableView.getItems().addFirst(newOrderRow); newOrderRow.setSelected(true); selectedRowsIndices.clear(); @@ -413,84 +393,50 @@ private void cancelSelectionsAndEdit() { // Delete created new orders if (isNewOrderMode.get()) { for (int i = 0; i < newOrderCount; i++) { - tableView.getItems().remove(0); + tableView.getItems().removeFirst(); } - isNewOrderMode.set(false); - newOrderCount = 0; + isNewOrderMode.set(false); + newOrderCount = 0; } selectRowColumn.setEditable(true); tableView.refresh(); } - private void closeConfirmDialogsOnConfirmation() { - isEditMode.set(false); - newOrderCount = 0; - tableView.getSelectionModel().clearSelection(); - tableToolbarController.toggleButtonVisibilityOnCancel(); - List indicesToClear = new ArrayList<>(selectedRowsIndices); - for (Integer rowIndex : indicesToClear) { - TableData tableRow = tableView.getItems().get(rowIndex); - tableRow.setSelected(false); + // Confirm Dialogs + private void openConfirmCreateDialog() { + ConfirmDialogInput confirmDialogInput = new ConfirmDialogInput( + "Confirm Supplier Orders Create", + "Are you sure you want to create new orders?", + null); + List selectedOrders = new ArrayList<>(); + for (Integer index : selectedRowsIndices) { + selectedOrders.add(tableView.getItems().get(index).getData()); } - selectRowColumn.setEditable(true); - selectedRowsIndices.clear(); - tableView.refresh(); + confirmSupplierOrderCreateController.setData(selectedOrders, confirmDialogInput); + toggleDialogVisibility(confirmCreateDialogContainer, true); } - private void loadConfirmDeleteDialog() { - //Load delete dialog - FXMLLoader loader = fxmlLoaderService.setUpLoader( - "/org/chainoptim/desktop/shared/confirmdialog/GenericConfirmDialogView.fxml", - controllerFactory::createController); - - try { - Node confirmDialogView = loader.load(); - confirmSupplierOrderDeleteController = loader.getController(); - confirmSupplierOrderDeleteController.setActionListener(confirmDialogDeleteListener); - confirmDeleteDialogContainer.getChildren().add(confirmDialogView); - closeConfirmDeleteDialog(); - - } catch (IOException ex) { - ex.printStackTrace(); - } - + private void closeConfirmCreateDialog() { + toggleDialogVisibility(confirmCreateDialogContainer, false); } - private void loadConfirmUpdateDialog() { - // Load update dialog - FXMLLoader loader = fxmlLoaderService.setUpLoader( - "/org/chainoptim/desktop/shared/confirmdialog/GenericConfirmDialogView.fxml", - controllerFactory::createController); - - try { - Node confirmDialogView = loader.load(); - confirmSupplierOrderUpdateController = loader.getController(); - confirmSupplierOrderUpdateController.setActionListener(confirmDialogUpdateListener); - confirmUpdateDialogContainer.getChildren().add(confirmDialogView); - closeConfirmUpdateDialog(); - } catch (IOException ex) { - ex.printStackTrace(); + private void openConfirmUpdateDialog(List selectedRowsIndices) { + ConfirmDialogInput confirmDialogInput = new ConfirmDialogInput( + "Confirm Supplier Orders Update", + "Are you sure you want to update selected orders?", + null); + List selectedOrders = new ArrayList<>(); + for (Integer index : selectedRowsIndices) { + selectedOrders.add(tableView.getItems().get(index).getData()); } + confirmSupplierOrderUpdateController.setData(selectedOrders, confirmDialogInput); + toggleDialogVisibility(confirmUpdateDialogContainer, true); } - private void loadConfirmCreateDialog() { - // Load create dialog - FXMLLoader loader = fxmlLoaderService.setUpLoader( - "/org/chainoptim/desktop/shared/confirmdialog/GenericConfirmDialogView.fxml", - controllerFactory::createController); - - try { - Node confirmDialogView = loader.load(); - confirmSupplierOrderCreateController = loader.getController(); - confirmSupplierOrderCreateController.setActionListener(confirmDialogCreateListener); - confirmCreateDialogContainer.getChildren().add(confirmDialogView); - closeConfirmCreateDialog(); - } catch (IOException ex) { - ex.printStackTrace(); - } + private void closeConfirmUpdateDialog() { + toggleDialogVisibility(confirmUpdateDialogContainer, false); } - // Utils private void openConfirmDeleteDialog(List selectedRowsIndices) { ConfirmDialogInput confirmDialogInput = new ConfirmDialogInput( "Confirm Supplier Orders Delete", @@ -501,73 +447,69 @@ private void openConfirmDeleteDialog(List selectedRowsIndices) { selectedOrders.add(tableView.getItems().get(index).getData()); } confirmSupplierOrderDeleteController.setData(selectedOrders, confirmDialogInput); - confirmDeleteDialogContainer.setVisible(true); - confirmDeleteDialogContainer.setManaged(true); + toggleDialogVisibility(confirmDeleteDialogContainer, true); } private void closeConfirmDeleteDialog() { - confirmDeleteDialogContainer.setVisible(false); - confirmDeleteDialogContainer.setManaged(false); + toggleDialogVisibility(confirmDeleteDialogContainer, false); } - private void handleDeleteOrders(List supplierOrders) { - List ordersToRemoveIds = new ArrayList<>(); - for (SupplierOrder order : supplierOrders) { - ordersToRemoveIds.add(order.getId()); - } - try { - supplierOrdersService.deleteSupplierOrderInBulk(ordersToRemoveIds) - .thenAccept(result -> System.out.println("Orders deleted successfully:" + ordersToRemoveIds)); - } catch (Exception e) { - e.printStackTrace(); - } + private void toggleDialogVisibility(StackPane dialogContainer, boolean isVisible) { + dialogContainer.setVisible(isVisible); + dialogContainer.setManaged(isVisible); + } - tableView.getItems().removeIf(tableData -> ordersToRemoveIds.contains(tableData.getData().getId())); + // Backend calls + private void handleCreateOrders(List supplierOrders) { + List createSupplierOrderDTOs = new ArrayList<>(); - closeConfirmDeleteDialog(); - isEditMode.set(false); - tableView.refresh(); - selectedRowsIndices.clear(); - } + for (SupplierOrder order : supplierOrders) { + CreateSupplierOrderDTO createSupplierOrderDTO = getCreateSupplierOrderDTO(order); - private void openConfirmUpdateDialog(List selectedRowsIndices) { - ConfirmDialogInput confirmDialogInput = new ConfirmDialogInput( - "Confirm Supplier Orders Update", - "Are you sure you want to update selected orders?", - null); - List selectedOrders = new ArrayList<>(); - for (Integer index : selectedRowsIndices) { - selectedOrders.add(tableView.getItems().get(index).getData()); + createSupplierOrderDTOs.add(createSupplierOrderDTO); } - confirmSupplierOrderUpdateController.setData(selectedOrders, confirmDialogInput); - confirmUpdateDialogContainer.setVisible(true); - confirmUpdateDialogContainer.setManaged(true); + + supplierOrdersWriteService.createSupplierOrdersInBulk(createSupplierOrderDTOs) + .thenAccept(createdOrders -> { + if (createdOrders != null) { + System.out.println("Orders created successfully: " + createdOrders); + } else { + System.out.println("Error creating orders"); + } + }); + isNewOrderMode.set(false); + closeConfirmCreateDialog(); + updateUIOnSuccessfulOperation(); } - private void closeConfirmUpdateDialog() { - confirmUpdateDialogContainer.setVisible(false); - confirmUpdateDialogContainer.setManaged(false); + private CreateSupplierOrderDTO getCreateSupplierOrderDTO(SupplierOrder order) { + CreateSupplierOrderDTO createSupplierOrderDTO = new CreateSupplierOrderDTO(); + if (supplier == null || supplier.getOrganizationId() == null) { + throw new IllegalArgumentException("Supplier Organization ID is missing"); + } + createSupplierOrderDTO.setOrganizationId(supplier.getOrganizationId()); + createSupplierOrderDTO.setSupplierId(supplier.getId()); + createSupplierOrderDTO.setComponentId(order.getComponent().getId()); + createSupplierOrderDTO.setQuantity(order.getQuantity()); + createSupplierOrderDTO.setOrderDate(order.getOrderDate()); + createSupplierOrderDTO.setEstimatedDeliveryDate(order.getEstimatedDeliveryDate()); + createSupplierOrderDTO.setDeliveryDate(order.getDeliveryDate()); + createSupplierOrderDTO.setStatus(order.getStatus()); + createSupplierOrderDTO.setCompanyId(order.getCompanyId()); + + return createSupplierOrderDTO; } private void handleUpdateOrders(List supplierOrders) { List updateSupplierOrderDTOs = new ArrayList<>(); for (SupplierOrder order : supplierOrders) { - UpdateSupplierOrderDTO updateSupplierOrderDTO = new UpdateSupplierOrderDTO(); - updateSupplierOrderDTO.setId(order.getId()); - updateSupplierOrderDTO.setOrganizationId(order.getOrganizationId()); - updateSupplierOrderDTO.setComponentId(order.getComponent().getId()); - updateSupplierOrderDTO.setQuantity(order.getQuantity()); - updateSupplierOrderDTO.setOrderDate(order.getOrderDate()); - updateSupplierOrderDTO.setEstimatedDeliveryDate(order.getEstimatedDeliveryDate()); - updateSupplierOrderDTO.setDeliveryDate(order.getDeliveryDate()); - updateSupplierOrderDTO.setStatus(order.getStatus()); - updateSupplierOrderDTO.setCompanyId(order.getCompanyId()); + UpdateSupplierOrderDTO updateSupplierOrderDTO = getUpdateSupplierOrderDTO(order); updateSupplierOrderDTOs.add(updateSupplierOrderDTO); } - supplierOrdersService.updateSupplierOrdersInBulk(updateSupplierOrderDTOs) + supplierOrdersWriteService.updateSupplierOrdersInBulk(updateSupplierOrderDTOs) .thenAccept(updatedOrders -> { if (updatedOrders != null) { System.out.println("Orders updated successfully: " + updatedOrders); @@ -576,62 +518,59 @@ private void handleUpdateOrders(List supplierOrders) { } }); closeConfirmUpdateDialog(); - closeConfirmDialogsOnConfirmation(); + updateUIOnSuccessfulOperation(); } - private void openConfirmCreateDialog() { - ConfirmDialogInput confirmDialogInput = new ConfirmDialogInput( - "Confirm Supplier Orders Create", - "Are you sure you want to create new orders?", - null); - List selectedOrders = new ArrayList<>(); - for (Integer index : selectedRowsIndices) { - selectedOrders.add(tableView.getItems().get(index).getData()); - } - confirmSupplierOrderCreateController.setData(selectedOrders, confirmDialogInput); - confirmCreateDialogContainer.setVisible(true); - confirmCreateDialogContainer.setManaged(true); - } - - private void closeConfirmCreateDialog() { - confirmCreateDialogContainer.setVisible(false); - confirmCreateDialogContainer.setManaged(false); + private UpdateSupplierOrderDTO getUpdateSupplierOrderDTO(SupplierOrder order) { + UpdateSupplierOrderDTO updateSupplierOrderDTO = new UpdateSupplierOrderDTO(); + updateSupplierOrderDTO.setId(order.getId()); + updateSupplierOrderDTO.setOrganizationId(order.getOrganizationId()); + updateSupplierOrderDTO.setComponentId(order.getComponent().getId()); + updateSupplierOrderDTO.setQuantity(order.getQuantity()); + updateSupplierOrderDTO.setOrderDate(order.getOrderDate()); + updateSupplierOrderDTO.setEstimatedDeliveryDate(order.getEstimatedDeliveryDate()); + updateSupplierOrderDTO.setDeliveryDate(order.getDeliveryDate()); + updateSupplierOrderDTO.setStatus(order.getStatus()); + updateSupplierOrderDTO.setCompanyId(order.getCompanyId()); + + return updateSupplierOrderDTO; } - private void handleCreateOrders(List supplierOrders) { - List createSupplierOrderDTOs = new ArrayList<>(); - User currentUser = TenantContext.getCurrentUser(); - + private void handleDeleteOrders(List supplierOrders) { + List ordersToRemoveIds = new ArrayList<>(); for (SupplierOrder order : supplierOrders) { - CreateSupplierOrderDTO createSupplierOrderDTO = new CreateSupplierOrderDTO(); - if (currentUser != null && currentUser.getOrganization() != null) { - createSupplierOrderDTO.setOrganizationId(currentUser.getOrganization().getId()); - } - if (this.supplier != null) { - createSupplierOrderDTO.setSupplierId(this.supplier.getId()); - } - createSupplierOrderDTO.setComponentId(order.getComponent().getId()); - createSupplierOrderDTO.setQuantity(order.getQuantity()); - createSupplierOrderDTO.setOrderDate(order.getOrderDate()); - createSupplierOrderDTO.setEstimatedDeliveryDate(order.getEstimatedDeliveryDate()); - createSupplierOrderDTO.setDeliveryDate(order.getDeliveryDate()); - createSupplierOrderDTO.setStatus(order.getStatus()); - createSupplierOrderDTO.setCompanyId(order.getCompanyId()); + ordersToRemoveIds.add(order.getId()); + } - createSupplierOrderDTOs.add(createSupplierOrderDTO); + try { + supplierOrdersWriteService.deleteSupplierOrderInBulk(ordersToRemoveIds) + .thenAccept(result -> System.out.println("Orders deleted successfully:" + ordersToRemoveIds)); + } catch (Exception e) { + e.printStackTrace(); } - supplierOrdersService.createSupplierOrdersInBulk(createSupplierOrderDTOs) - .thenAccept(createdOrders -> { - if (createdOrders != null) { - System.out.println("Orders created successfully: " + createdOrders); - } else { - System.out.println("Error creating orders"); - } - }); - isNewOrderMode.set(false); - closeConfirmCreateDialog(); - closeConfirmDialogsOnConfirmation(); + tableView.getItems().removeIf(tableData -> ordersToRemoveIds.contains(tableData.getData().getId())); + + closeConfirmDeleteDialog(); + isEditMode.set(false); + tableView.refresh(); + selectedRowsIndices.clear(); } + private void updateUIOnSuccessfulOperation() { + isEditMode.set(false); + newOrderCount = 0; + tableView.getSelectionModel().clearSelection(); + tableToolbarController.toggleButtonVisibilityOnCancel(); + + List indicesToClear = new ArrayList<>(selectedRowsIndices); + for (Integer rowIndex : indicesToClear) { + TableData tableRow = tableView.getItems().get(rowIndex); + tableRow.setSelected(false); + } + + selectRowColumn.setEditable(true); + selectedRowsIndices.clear(); + tableView.refresh(); + } } \ No newline at end of file diff --git a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersService.java b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersService.java index 9ddde4fd..d7dbacab 100644 --- a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersService.java +++ b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersService.java @@ -1,15 +1,12 @@ package org.chainoptim.desktop.features.supplier.service; -import org.chainoptim.desktop.features.supplier.dto.CreateSupplierOrderDTO; import org.chainoptim.desktop.features.supplier.model.SupplierOrder; import org.chainoptim.desktop.shared.search.model.PaginatedResults; import org.chainoptim.desktop.shared.search.model.SearchParams; -import org.chainoptim.desktop.features.supplier.dto.UpdateSupplierOrderDTO; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; public interface SupplierOrdersService { @@ -18,12 +15,5 @@ CompletableFuture>> getSuppliersBySuppl Integer supplierId, SearchParams searchParams ); - CompletableFuture createSupplierOrder(CreateSupplierOrderDTO supplierDTO); - - CompletableFuture> deleteSupplierOrderInBulk(List orderIds); - - CompletableFuture> updateSupplierOrdersInBulk(List orderDTOs); - - CompletableFuture> createSupplierOrdersInBulk(List orderDTOs); } diff --git a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersServiceImpl.java b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersServiceImpl.java index ad992a1c..ca5d9887 100644 --- a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersServiceImpl.java +++ b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersServiceImpl.java @@ -1,10 +1,12 @@ package org.chainoptim.desktop.features.supplier.service; import com.fasterxml.jackson.core.type.TypeReference; +import com.google.inject.Inject; import org.chainoptim.desktop.core.user.util.TokenManager; -import org.chainoptim.desktop.features.supplier.dto.CreateSupplierOrderDTO; -import org.chainoptim.desktop.features.supplier.dto.UpdateSupplierOrderDTO; +import org.chainoptim.desktop.features.supplier.model.Supplier; import org.chainoptim.desktop.features.supplier.model.SupplierOrder; +import org.chainoptim.desktop.shared.caching.CacheKeyBuilder; +import org.chainoptim.desktop.shared.caching.CachingService; import org.chainoptim.desktop.shared.search.model.PaginatedResults; import org.chainoptim.desktop.shared.search.model.SearchParams; import org.chainoptim.desktop.shared.util.JsonUtil; @@ -14,16 +16,22 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; public class SupplierOrdersServiceImpl implements SupplierOrdersService { + private final CachingService> cachingService; private final HttpClient client = HttpClient.newHttpClient(); private static final String HEADER_KEY = "Authorization"; - private static final String HEADER_VALUE_PREFIX = "Bearer"; + private static final String HEADER_VALUE_PREFIX = "Bearer "; + private static final int STALE_TIME = 30000; + + @Inject + public SupplierOrdersServiceImpl(CachingService> cachingService) { + this.cachingService = cachingService; + } public CompletableFuture>> getSupplierOrdersByOrganizationId(Integer organizationId) { String routeAddress = "http://localhost:8080/api/v1/supplier-orders/organization/" + organizationId.toString(); @@ -57,12 +65,9 @@ public CompletableFuture>> getSuppliers Integer supplierId, SearchParams searchParams ) { - String routeAddress = "http://localhost:8080/api/v1/supplier-orders/organization/advanced/" + supplierId.toString() - + "?searchQuery=" + searchParams.getSearchQuery() - + "&sortBy=" + searchParams.getSortOption() - + "&ascending=" + searchParams.getAscending() - + "&page=" + searchParams.getPage() - + "&itemsPerPage=" + searchParams.getItemsPerPage(); + String rootAddress = "http://localhost:8080/api/v1/"; + String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("supplier-orders", "organization", supplierId, searchParams); + String routeAddress = rootAddress + cacheKey; String jwtToken = TokenManager.getToken(); if (jwtToken == null) return new CompletableFuture<>(); @@ -74,173 +79,25 @@ public CompletableFuture>> getSuppliers .headers(HEADER_KEY, headerValue) .build(); - return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(response -> { - if (response.statusCode() != HttpURLConnection.HTTP_OK) { - return Optional.>empty(); - } - try { - PaginatedResults supplierOrders = JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference>() {}); - return Optional.of(supplierOrders); - } catch (Exception e) { - e.printStackTrace(); - return Optional.>empty(); - } - }); - } - - - public CompletableFuture createSupplierOrder(CreateSupplierOrderDTO orderDTO) { - String routeAddress = "http://localhost:8080/api/v1/supplier-orders/create"; - - String jwtToken = TokenManager.getToken(); - if (jwtToken == null) return new CompletableFuture<>(); - String headerValue = HEADER_VALUE_PREFIX + jwtToken; - - //Serialize DTO - String requestBody = null; - try { - requestBody = JsonUtil.getObjectMapper().writeValueAsString(orderDTO); - } catch (Exception e) { - e.printStackTrace(); + if (cachingService.isCached(cacheKey) && !cachingService.isStale(cacheKey)) { + return CompletableFuture.completedFuture(Optional.of(cachingService.get(cacheKey))); } - assert requestBody != null; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(routeAddress)) - .POST(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8)) - .headers(HEADER_KEY, headerValue) - .header("Content-Type", "application/json") - .build(); - return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenApply(response -> { - if (response.statusCode() != HttpURLConnection.HTTP_OK) return null; - try { - return JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference() {}); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - }); - - } - - public CompletableFuture> deleteSupplierOrderInBulk(List orderIds) { - String routeAddress = "http://localhost:8080/api/v1/supplier-orders/delete/bulk"; - - String jwtToken = TokenManager.getToken(); - if (jwtToken == null) return new CompletableFuture<>(); - String headerValue = HEADER_VALUE_PREFIX + jwtToken; - - String requestBody = null; - try { - requestBody = JsonUtil.getObjectMapper().writeValueAsString(orderIds); - } catch (Exception e) { - e.printStackTrace(); - } - - assert requestBody != null; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(routeAddress)) - .DELETE() - .headers(HEADER_KEY, headerValue) - .header("Content-Type", "application/json") - .build(); - - return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply (response -> { if (response.statusCode() != HttpURLConnection.HTTP_OK) { - System.out.println("Error deleting orders"); - } - return null; - }); - } - - @Override - public CompletableFuture> updateSupplierOrdersInBulk(List orderDTOs) { - System.out.println("Updating SupplierOrders: " + orderDTOs); - - String routeAddress = "http://localhost:8080/api/v1/supplier-orders/update/bulk"; - - String jwtToken = TokenManager.getToken(); - if (jwtToken == null) return new CompletableFuture<>(); - String headerValue = HEADER_VALUE_PREFIX + " " + jwtToken; - - String requestBody = null; - try { - requestBody = JsonUtil.getObjectMapper().writeValueAsString(orderDTOs); - } catch (Exception e) { - e.printStackTrace(); - } - - assert requestBody != null; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(routeAddress)) - .PUT(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8)) - .header(HEADER_KEY, headerValue) - .header("Content-Type", "application/json") - .build(); - - return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(response -> { - if (response.statusCode() != HttpURLConnection.HTTP_OK) { - System.out.println("Error updating orders. HTTP status code: " + response.statusCode()); - System.out.println("Response body: " + response.body()); - return null; + return Optional.>empty(); } try { - List updatedOrders = JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference>() {}); - // Print the updatedOrders to check if they contain the updated data - System.out.println("Updated SupplierOrders: " + updatedOrders); - return updatedOrders; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - }); - } - - @Override - public CompletableFuture> createSupplierOrdersInBulk(List orderDTOs) { - System.out.println("Creating SupplierOrders: " + orderDTOs); - - String routeAddress = "http://localhost:8080/api/v1/supplier-orders/create/bulk"; - - String jwtToken = TokenManager.getToken(); - if (jwtToken == null) return new CompletableFuture<>(); - String headerValue = HEADER_VALUE_PREFIX + " " + jwtToken; - - String requestBody = null; - try { - requestBody = JsonUtil.getObjectMapper().writeValueAsString(orderDTOs); - } catch (Exception e) { - e.printStackTrace(); - } + PaginatedResults supplierOrders = JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference>() {}); - assert requestBody != null; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(routeAddress)) - .POST(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8)) - .header(HEADER_KEY, headerValue) - .header("Content-Type", "application/json") - .build(); + cachingService.remove(cacheKey); // Ensure there isn't a stale cache entry + cachingService.add(cacheKey, supplierOrders, STALE_TIME); - return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) - .thenApply(response -> { - if (response.statusCode() != HttpURLConnection.HTTP_OK) { - System.out.println("Error creating orders. HTTP status code: " + response.statusCode()); - System.out.println("Response body: " + response.body()); - return null; - } - try { - List createdOrders = JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference>() {}); - // Print the createdOrders to check if they contain the created data - System.out.println("Created SupplierOrders: " + createdOrders); - return createdOrders; + return Optional.of(supplierOrders); } catch (Exception e) { e.printStackTrace(); - return null; + return Optional.>empty(); } }); } diff --git a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersWriteService.java b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersWriteService.java new file mode 100644 index 00000000..62817b8e --- /dev/null +++ b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersWriteService.java @@ -0,0 +1,19 @@ +package org.chainoptim.desktop.features.supplier.service; + +import org.chainoptim.desktop.features.supplier.dto.CreateSupplierOrderDTO; +import org.chainoptim.desktop.features.supplier.dto.UpdateSupplierOrderDTO; +import org.chainoptim.desktop.features.supplier.model.SupplierOrder; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public interface SupplierOrdersWriteService { + + CompletableFuture createSupplierOrder(CreateSupplierOrderDTO supplierDTO); + + CompletableFuture> deleteSupplierOrderInBulk(List orderIds); + + CompletableFuture> updateSupplierOrdersInBulk(List orderDTOs); + + CompletableFuture> createSupplierOrdersInBulk(List orderDTOs); +} diff --git a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersWriteServiceImpl.java b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersWriteServiceImpl.java new file mode 100644 index 00000000..57389cb2 --- /dev/null +++ b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierOrdersWriteServiceImpl.java @@ -0,0 +1,180 @@ +package org.chainoptim.desktop.features.supplier.service; + +import org.chainoptim.desktop.core.user.util.TokenManager; +import org.chainoptim.desktop.features.supplier.dto.CreateSupplierOrderDTO; +import org.chainoptim.desktop.features.supplier.dto.UpdateSupplierOrderDTO; +import org.chainoptim.desktop.features.supplier.model.SupplierOrder; +import org.chainoptim.desktop.shared.caching.CachingService; +import org.chainoptim.desktop.shared.search.model.PaginatedResults; +import org.chainoptim.desktop.shared.util.JsonUtil; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.inject.Inject; + +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public class SupplierOrdersWriteServiceImpl implements SupplierOrdersWriteService { + + private final CachingService> cachingService; + private final HttpClient client = HttpClient.newHttpClient(); + private static final String HEADER_KEY = "Authorization"; + private static final String HEADER_VALUE_PREFIX = "Bearer "; + + @Inject + public SupplierOrdersWriteServiceImpl(CachingService> cachingService) { + this.cachingService = cachingService; + } + + public CompletableFuture createSupplierOrder(CreateSupplierOrderDTO orderDTO) { + String routeAddress = "http://localhost:8080/api/v1/supplier-orders/create"; + + String jwtToken = TokenManager.getToken(); + if (jwtToken == null) return new CompletableFuture<>(); + String headerValue = HEADER_VALUE_PREFIX + jwtToken; + + //Serialize DTO + String requestBody = null; + try { + requestBody = JsonUtil.getObjectMapper().writeValueAsString(orderDTO); + } catch (Exception e) { + e.printStackTrace(); + } + assert requestBody != null; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(routeAddress)) + .POST(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8)) + .headers(HEADER_KEY, headerValue) + .header("Content-Type", "application/json") + .build(); + + return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(response -> { + if (response.statusCode() != HttpURLConnection.HTTP_OK) return null; + try { + SupplierOrder order = JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference() {}); + + cachingService.clear(); // Invalidate cache + + return order; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + }); + + } + + public CompletableFuture> createSupplierOrdersInBulk(List orderDTOs) { + String routeAddress = "http://localhost:8080/api/v1/supplier-orders/create/bulk"; + + String jwtToken = TokenManager.getToken(); + if (jwtToken == null) return new CompletableFuture<>(); + String headerValue = HEADER_VALUE_PREFIX + " " + jwtToken; + + String requestBody = null; + try { + requestBody = JsonUtil.getObjectMapper().writeValueAsString(orderDTOs); + } catch (Exception e) { + e.printStackTrace(); + } + assert requestBody != null; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(routeAddress)) + .POST(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8)) + .header(HEADER_KEY, headerValue) + .header("Content-Type", "application/json") + .build(); + + return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(response -> { + System.out.println("Response: " + response); + if (response.statusCode() != HttpURLConnection.HTTP_OK) return null; + try { + List orders = JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference>() {}); + + cachingService.clear(); // Invalidate cache + + return orders; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + }); + } + + public CompletableFuture> updateSupplierOrdersInBulk(List orderDTOs) { + String routeAddress = "http://localhost:8080/api/v1/supplier-orders/update/bulk"; + + String jwtToken = TokenManager.getToken(); + if (jwtToken == null) return new CompletableFuture<>(); + String headerValue = HEADER_VALUE_PREFIX + " " + jwtToken; + + String requestBody = null; + try { + requestBody = JsonUtil.getObjectMapper().writeValueAsString(orderDTOs); + } catch (Exception e) { + e.printStackTrace(); + } + assert requestBody != null; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(routeAddress)) + .PUT(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8)) + .header(HEADER_KEY, headerValue) + .header("Content-Type", "application/json") + .build(); + + return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(response -> { + if (response.statusCode() != HttpURLConnection.HTTP_OK) return null; + try { + List orders = JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference>() {}); + + cachingService.clear(); // Invalidate cache + + return orders; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + }); + } + + public CompletableFuture> deleteSupplierOrderInBulk(List orderIds) { + String routeAddress = "http://localhost:8080/api/v1/supplier-orders/delete/bulk"; + + String jwtToken = TokenManager.getToken(); + if (jwtToken == null) return new CompletableFuture<>(); + String headerValue = HEADER_VALUE_PREFIX + jwtToken; + + String requestBody = null; + try { + requestBody = JsonUtil.getObjectMapper().writeValueAsString(orderIds); + } catch (Exception e) { + e.printStackTrace(); + } + assert requestBody != null; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(routeAddress)) + .DELETE() + .headers(HEADER_KEY, headerValue) + .header("Content-Type", "application/json") + .build(); + + return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(response -> { + cachingService.clear(); // Invalidate cache + return null; + }); + } +} diff --git a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierServiceImpl.java b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierServiceImpl.java index 101f2ce3..210e1bb2 100644 --- a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierServiceImpl.java +++ b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierServiceImpl.java @@ -65,7 +65,7 @@ public CompletableFuture>> getSuppliersByOrg SearchParams searchParams ) { String rootAddress = "http://localhost:8080/api/v1/"; - String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("suppliers", organizationId, searchParams); + String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("suppliers", "organization", organizationId, searchParams); String routeAddress = rootAddress + cacheKey; String jwtToken = TokenManager.getToken(); diff --git a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierWriteServiceImpl.java b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierWriteServiceImpl.java index 2617f6f6..3994e328 100644 --- a/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierWriteServiceImpl.java +++ b/src/main/java/org/chainoptim/desktop/features/supplier/service/SupplierWriteServiceImpl.java @@ -1,12 +1,16 @@ package org.chainoptim.desktop.features.supplier.service; -import com.fasterxml.jackson.core.type.TypeReference; import org.chainoptim.desktop.core.user.util.TokenManager; import org.chainoptim.desktop.features.supplier.dto.CreateSupplierDTO; import org.chainoptim.desktop.features.supplier.dto.UpdateSupplierDTO; import org.chainoptim.desktop.features.supplier.model.Supplier; +import org.chainoptim.desktop.shared.caching.CachingService; +import org.chainoptim.desktop.shared.search.model.PaginatedResults; import org.chainoptim.desktop.shared.util.JsonUtil; +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.inject.Inject; + import java.net.HttpURLConnection; import java.net.URI; import java.net.http.HttpClient; @@ -18,11 +22,17 @@ public class SupplierWriteServiceImpl implements SupplierWriteService { + private final CachingService> cachingService; private final HttpClient client = HttpClient.newHttpClient(); private static final String HEADER_KEY = "Authorization"; private static final String HEADER_VALUE_PREFIX = "Bearer "; + @Inject + public SupplierWriteServiceImpl(CachingService> cachingService) { + this.cachingService = cachingService; + } + public CompletableFuture> createSupplier(CreateSupplierDTO supplierDTO) { String routeAddress = "http://localhost:8080/api/v1/suppliers/create"; @@ -51,6 +61,9 @@ public CompletableFuture> createSupplier(CreateSupplierDTO su if (response.statusCode() != HttpURLConnection.HTTP_OK) return Optional.empty(); try { Supplier supplier = JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference() {}); + + cachingService.clear(); // Invalidate cache + return Optional.of(supplier); } catch (Exception e) { e.printStackTrace(); @@ -87,6 +100,9 @@ public CompletableFuture> updateSupplier(UpdateSupplierDTO su if (response.statusCode() != HttpURLConnection.HTTP_OK) return Optional.empty(); try { Supplier supplier = JsonUtil.getObjectMapper().readValue(response.body(), new TypeReference() {}); + + cachingService.clear(); // Invalidate cache + return Optional.of(supplier); } catch (Exception e) { e.printStackTrace(); @@ -111,6 +127,9 @@ public CompletableFuture> deleteSupplier(Integer supplierId) { return client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenApply(response -> { if (response.statusCode() != HttpURLConnection.HTTP_OK) return Optional.empty(); + + cachingService.clear(); // Invalidate cache + return Optional.of(supplierId); }); } diff --git a/src/main/java/org/chainoptim/desktop/features/warehouse/service/WarehouseServiceImpl.java b/src/main/java/org/chainoptim/desktop/features/warehouse/service/WarehouseServiceImpl.java index cbea4290..f0119690 100644 --- a/src/main/java/org/chainoptim/desktop/features/warehouse/service/WarehouseServiceImpl.java +++ b/src/main/java/org/chainoptim/desktop/features/warehouse/service/WarehouseServiceImpl.java @@ -64,7 +64,7 @@ public CompletableFuture>> getWarehousesByO SearchParams searchParams ) { String rootAddress = "http://localhost:8080/api/v1/"; - String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("warehouses", organizationId, searchParams); + String cacheKey = CacheKeyBuilder.buildAdvancedSearchKey("warehouses", "organization", organizationId, searchParams); String routeAddress = rootAddress + cacheKey; String jwtToken = TokenManager.getToken(); diff --git a/src/main/java/org/chainoptim/desktop/shared/caching/CacheKeyBuilder.java b/src/main/java/org/chainoptim/desktop/shared/caching/CacheKeyBuilder.java index d74ff1fe..62388662 100644 --- a/src/main/java/org/chainoptim/desktop/shared/caching/CacheKeyBuilder.java +++ b/src/main/java/org/chainoptim/desktop/shared/caching/CacheKeyBuilder.java @@ -6,8 +6,8 @@ public class CacheKeyBuilder { private CacheKeyBuilder() {} - public static String buildAdvancedSearchKey(String feature, Integer organizationId, SearchParams searchParams) { - return feature + "/organization/advanced/" + organizationId.toString() + public static String buildAdvancedSearchKey(String feature, String secondaryFeature, Integer secondaryId, SearchParams searchParams) { + return feature + "/" + secondaryFeature + "/advanced/" + secondaryId.toString() + "?searchQuery=" + searchParams.getSearchQuery() + "&sortBy=" + searchParams.getSortOption() + "&ascending=" + searchParams.getAscending() diff --git a/src/main/java/org/chainoptim/desktop/shared/search/model/SearchParamsImpl.java b/src/main/java/org/chainoptim/desktop/shared/search/model/SearchParamsImpl.java index 1d3f0c3c..f7be5888 100644 --- a/src/main/java/org/chainoptim/desktop/shared/search/model/SearchParamsImpl.java +++ b/src/main/java/org/chainoptim/desktop/shared/search/model/SearchParamsImpl.java @@ -46,23 +46,28 @@ public String getSortOption() { public Integer getPage() { return page.get(); } + public Integer getItemsPerPage() { + return itemsPerPage.get(); + } + public void setSearchQuery(String searchQuery) { + this.page.set(1); this.searchQuery.set(searchQuery); } public void setSortOption(String sortOption) { + this.page.set(1); this.sortOption.set(sortOption); } public void setAscending(Boolean ascending) { + this.page.set(1); this.ascending.set(ascending); } public void setPage(Integer page) { this.page.set(page); } public void setItemsPerPage(Integer itemsPerPage) { + this.page.set(1); this.itemsPerPage.set(itemsPerPage); } - public Integer getItemsPerPage() { - return itemsPerPage.get(); - } } \ No newline at end of file diff --git a/src/main/java/org/chainoptim/desktop/shared/table/TableToolbarController.java b/src/main/java/org/chainoptim/desktop/shared/table/TableToolbarController.java index 81bd5d54..cebbc1c4 100644 --- a/src/main/java/org/chainoptim/desktop/shared/table/TableToolbarController.java +++ b/src/main/java/org/chainoptim/desktop/shared/table/TableToolbarController.java @@ -17,6 +17,8 @@ import lombok.Getter; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Consumer; @@ -24,11 +26,8 @@ public class TableToolbarController { // State - private final SearchParams searchParams; - private final Map sortOptionsMap = Map.of( - "createdAt", "Created At", - "updatedAt", "Updated At" - ); + private SearchParams searchParams; + private Map sortOptionsMap; // FXMl @FXML @@ -68,17 +67,15 @@ public class TableToolbarController { private Image saveIcon; private Image plusIcon; - @Inject - public TableToolbarController( - SearchParams searchParams - ) { + public void initialize(SearchParams searchParams, + Map sortOptionsMap, + Runnable refreshAction) { this.searchParams = searchParams; - } - - public void initialize(Runnable refreshAction) { + this.sortOptionsMap = sortOptionsMap; initializeIcons(); setSearchButton(); setOrderingButton(); + setSortOptions(new ArrayList<>(sortOptionsMap.values())); setRefreshButton(refreshAction); setCancelRowSelectionButton(); setDeleteSelectedRowsButton(); @@ -107,8 +104,13 @@ private void setSearchButton() { searchButton.setGraphic(searchImageView); } + private void setSortOptions(List sortOptions) { + this.sortOptions.getItems().addAll(sortOptions); + } + private void setOrderingButton() { - ImageView sortUpImageView = createImageView(sortUpIcon, 16, 16); + ImageView sortUpImageView = createImageView( + Boolean.TRUE.equals(searchParams.getAscending()) ? sortUpIcon : sortDownIcon, 16, 16); orderingButton.setGraphic(sortUpImageView); } @@ -208,7 +210,7 @@ private void handleOrdering() { ImageView sortUpImageView = createImageView(sortUpIcon, 16, 16); orderingButton.setGraphic(sortUpImageView); } else { - ImageView sortDownImageView = createImageView(sortUpIcon, 16, 16); + ImageView sortDownImageView = createImageView(sortDownIcon, 16, 16); orderingButton.setGraphic(sortDownImageView); } } diff --git a/src/main/java/org/chainoptim/desktop/shared/table/edit.cells/ComboBoxEditableCell.java b/src/main/java/org/chainoptim/desktop/shared/table/edit/cell/ComboBoxEditableCell.java similarity index 63% rename from src/main/java/org/chainoptim/desktop/shared/table/edit.cells/ComboBoxEditableCell.java rename to src/main/java/org/chainoptim/desktop/shared/table/edit/cell/ComboBoxEditableCell.java index 026c11cd..329ef50a 100644 --- a/src/main/java/org/chainoptim/desktop/shared/table/edit.cells/ComboBoxEditableCell.java +++ b/src/main/java/org/chainoptim/desktop/shared/table/edit/cell/ComboBoxEditableCell.java @@ -1,5 +1,6 @@ -package org.chainoptim.desktop.shared.table.edit.cells; +package org.chainoptim.desktop.shared.table.edit.cell; +import org.chainoptim.desktop.shared.table.util.StringConverter; import javafx.beans.property.BooleanProperty; import javafx.scene.control.ComboBox; import java.util.List; @@ -7,9 +8,10 @@ public abstract class ComboBoxEditableCell extends EditableCell { private final ComboBox comboBox; - public ComboBoxEditableCell (BooleanProperty isEditMode, List editableRows, List comboBoxItems) { - super(isEditMode, editableRows); + protected ComboBoxEditableCell (BooleanProperty isEditMode, List editableRows, StringConverter converter, List comboBoxItems) { + super(isEditMode, editableRows, converter); this.comboBox = new ComboBox<>(); + this.comboBox.getStyleClass().setAll("table-combo-box"); this.comboBox.getItems().addAll(comboBoxItems); this.comboBox.setOnAction(e -> commitEdit(this.comboBox.getValue())); } @@ -19,10 +21,12 @@ protected void updateItem(T item, boolean empty) { super.updateItem(item, empty); if (empty) { setGraphic(null); + setText(null); } else { if (isEditMode.get() && editableRows.contains(getIndex())) { comboBox.setValue(item); setGraphic(comboBox); + setText(null); } else { setText(getString()); setGraphic(null); @@ -45,10 +49,17 @@ public void cancelEdit() { super.cancelEdit(); setText(getString()); setGraphic(null); + if (isEditMode.get() && editableRows.contains(getIndex())) { + setGraphic(comboBox); + } else { + setGraphic(null); + } } @Override - public void commitEdit(String newValue) {} - - public abstract void commitEdit(T newValue); + public void commitEdit(T newValue) { + super.commitEdit(newValue); + setText(getItem().toString()); + setGraphic(comboBox); + } } diff --git a/src/main/java/org/chainoptim/desktop/shared/table/edit.cells/EditableCell.java b/src/main/java/org/chainoptim/desktop/shared/table/edit/cell/EditableCell.java similarity index 57% rename from src/main/java/org/chainoptim/desktop/shared/table/edit.cells/EditableCell.java rename to src/main/java/org/chainoptim/desktop/shared/table/edit/cell/EditableCell.java index ea1d76c0..dc1c00d1 100644 --- a/src/main/java/org/chainoptim/desktop/shared/table/edit.cells/EditableCell.java +++ b/src/main/java/org/chainoptim/desktop/shared/table/edit/cell/EditableCell.java @@ -1,47 +1,50 @@ -package org.chainoptim.desktop.shared.table.edit.cells; +package org.chainoptim.desktop.shared.table.edit.cell; +import org.chainoptim.desktop.shared.table.util.StringConverter; import javafx.beans.property.BooleanProperty; -import javafx.beans.value.ObservableValue; import javafx.scene.control.TableCell; import javafx.scene.control.TextField; -import java.util.HashMap; import java.util.List; -import java.util.Map; public abstract class EditableCell extends TableCell { protected final BooleanProperty isEditMode; private TextField textField; protected final List editableRows; + private final StringConverter converter; - public EditableCell(BooleanProperty isEditMode, List editableRows) { + protected EditableCell(BooleanProperty isEditMode, List editableRows, StringConverter converter) { this.isEditMode = isEditMode; this.editableRows = editableRows; + this.converter = converter; createTextField(); } - @Override - protected void updateItem(T item, boolean empty) { - super.updateItem(item, empty); - - if (empty) { - setGraphic(null); - setText(null); - } else { - if (isEditMode.get() && editableRows.contains(getIndex())) { - textField.setText(getString()); - setGraphic(textField); - textField.selectAll(); - } else { - setText(getString()); - setGraphic(null); + private void createTextField() { + textField = new TextField(getString()); + textField.getStyleClass().setAll("table-text-field"); + textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); + textField.setOnAction(e -> { + try { + T convertedValue = converter.convert(textField.getText()); + commitEdit(convertedValue); + } catch (Exception ex) { + cancelEdit(); + ex.printStackTrace(); } - } - } - - protected String getString() { - return getItem() == null ? "" : getItem().toString(); + }); + textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> { + if (Boolean.FALSE.equals(isNowFocused)){ + try { + T convertedValue = converter.convert(textField.getText()); + commitEdit(convertedValue); + } catch (Exception e) { + cancelEdit(); + e.printStackTrace(); + } + } + }); } @Override @@ -54,6 +57,16 @@ public void startEdit() { } } + @Override + public void commitEdit(T newValue) { + if (getIndex() >= 0) { + super.commitEdit(newValue); + S currentRowItem = getTableView().getItems().get(getIndex()); + commitChange(currentRowItem, newValue); + updateItem(newValue, false); + } + } + @Override public void cancelEdit() { super.cancelEdit(); @@ -61,19 +74,28 @@ public void cancelEdit() { setGraphic(null); } - private void createTextField() { - textField = new TextField(getString()); - textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); - textField.setOnAction(e -> { - commitEdit(textField.getText()); - }); - textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> { - if (!isNowFocused && getIndex() >= 0){ - commitEdit(textField.getText()); + protected abstract void commitChange(S item, T newValue); + + @Override + protected void updateItem(T item, boolean empty) { + super.updateItem(item, empty); + + if (empty) { + setGraphic(null); + setText(null); + } else { + if (isEditMode.get() && editableRows.contains(getIndex())) { + textField.setText(getString()); + setGraphic(textField); + textField.selectAll(); + } else { + setText(getString()); + setGraphic(null); } - }); + } } - public abstract void commitEdit(String newValue); - + protected String getString() { + return getItem() == null ? "" : getItem().toString(); + } } diff --git a/src/main/java/org/chainoptim/desktop/shared/common/uielements/SelectComponentController.java b/src/main/java/org/chainoptim/desktop/shared/table/util/SelectComponentLoader.java similarity index 58% rename from src/main/java/org/chainoptim/desktop/shared/common/uielements/SelectComponentController.java rename to src/main/java/org/chainoptim/desktop/shared/table/util/SelectComponentLoader.java index 9b31982a..4da91781 100644 --- a/src/main/java/org/chainoptim/desktop/shared/common/uielements/SelectComponentController.java +++ b/src/main/java/org/chainoptim/desktop/shared/table/util/SelectComponentLoader.java @@ -1,4 +1,4 @@ -package org.chainoptim.desktop.shared.common.uielements; +package org.chainoptim.desktop.shared.table.util; import org.chainoptim.desktop.core.context.TenantContext; import org.chainoptim.desktop.core.user.model.User; @@ -6,21 +6,17 @@ import org.chainoptim.desktop.features.productpipeline.service.ComponentService; import com.google.inject.Inject; import javafx.application.Platform; -import javafx.fxml.FXML; -import javafx.scene.control.ComboBox; -import javafx.scene.control.ListCell; + import java.util.*; -public class SelectComponentController { +public class SelectComponentLoader { - private final ComponentService componentService; - private Map componentsMap = new HashMap<>(); -// @FXML -// private ComboBox componentComboBox; + private final ComponentService componentService; + private final Map componentsMap = new HashMap<>(); @Inject - public SelectComponentController(ComponentService componentService) { + public SelectComponentLoader(ComponentService componentService) { this.componentService = componentService; } @@ -28,10 +24,6 @@ public void initialize() { loadComponents(); } -// public ComponentsSearchDTO getSelectedComponent() { -// return componentComboBox.getSelectionModel().getSelectedItem(); -// } - public List getComponentsName() { return new ArrayList<>(componentsMap.values()); } @@ -46,26 +38,6 @@ public Integer getComponentIdByName(String name) { } private void loadComponents() { -// componentComboBox.setCellFactory(lv -> new ListCell() { -// @Override -// protected void updateItem(ComponentsSearchDTO item, boolean empty) { -// super.updateItem(item, empty); -// setText(empty ? "" : item.getName()); -// } -// }); -// -// componentComboBox.setButtonCell(new ListCell() { -// @Override -// protected void updateItem(ComponentsSearchDTO item, boolean empty) { -// super.updateItem(item, empty); -// if (empty || item == null) { -// setText(null); -// } else { -// setText(item.getName()); -// } -// } -// }); - User currentUser = TenantContext.getCurrentUser(); if (currentUser == null) { return; @@ -82,7 +54,6 @@ private Optional> handleComponentsResponse(Optional
  • componentsMap.put(component.getId(), component.getName())); }); diff --git a/src/main/java/org/chainoptim/desktop/shared/table/util/StringConverter.java b/src/main/java/org/chainoptim/desktop/shared/table/util/StringConverter.java new file mode 100644 index 00000000..6358e585 --- /dev/null +++ b/src/main/java/org/chainoptim/desktop/shared/table/util/StringConverter.java @@ -0,0 +1,5 @@ +package org.chainoptim.desktop.shared.table.util; + +public interface StringConverter { + T convert(String input) throws Exception; +} diff --git a/src/main/java/org/chainoptim/desktop/shared/util/resourceloader/CommonViewsLoader.java b/src/main/java/org/chainoptim/desktop/shared/util/resourceloader/CommonViewsLoader.java index a5cac699..ebe70207 100644 --- a/src/main/java/org/chainoptim/desktop/shared/util/resourceloader/CommonViewsLoader.java +++ b/src/main/java/org/chainoptim/desktop/shared/util/resourceloader/CommonViewsLoader.java @@ -2,6 +2,7 @@ import org.chainoptim.desktop.core.main.controller.ListHeaderController; import org.chainoptim.desktop.shared.common.uielements.select.*; +import org.chainoptim.desktop.shared.confirmdialog.controller.GenericConfirmDialogController; import org.chainoptim.desktop.shared.search.controller.PageSelectorController; import org.chainoptim.desktop.shared.table.TableToolbarController; @@ -17,6 +18,8 @@ public interface CommonViewsLoader { void loadTabContent(Tab tab, String fxmlFilepath, T data); + GenericConfirmDialogController loadConfirmDialog(StackPane confirmDialogContainer); + SelectOrCreateLocationController loadSelectOrCreateLocation(StackPane selectOrCreateLocationContainer); SelectOrCreateUnitOfMeasurementController loadSelectOrCreateUnitOfMeasurement(StackPane unitOfMeasurementContainer); SelectDurationController loadSelectDurationView(StackPane durationInputContainer); diff --git a/src/main/java/org/chainoptim/desktop/shared/util/resourceloader/CommonViewsLoaderImpl.java b/src/main/java/org/chainoptim/desktop/shared/util/resourceloader/CommonViewsLoaderImpl.java index 2cdca549..d27a77ce 100644 --- a/src/main/java/org/chainoptim/desktop/shared/util/resourceloader/CommonViewsLoaderImpl.java +++ b/src/main/java/org/chainoptim/desktop/shared/util/resourceloader/CommonViewsLoaderImpl.java @@ -3,7 +3,10 @@ import org.chainoptim.desktop.MainApplication; import org.chainoptim.desktop.core.abstraction.ControllerFactory; import org.chainoptim.desktop.core.main.controller.ListHeaderController; +import org.chainoptim.desktop.features.supplier.model.SupplierOrder; import org.chainoptim.desktop.shared.common.uielements.select.*; +import org.chainoptim.desktop.shared.confirmdialog.controller.GenericConfirmDialogActionListener; +import org.chainoptim.desktop.shared.confirmdialog.controller.GenericConfirmDialogController; import org.chainoptim.desktop.shared.search.controller.PageSelectorController; import org.chainoptim.desktop.shared.table.TableToolbarController; import org.chainoptim.desktop.shared.util.DataReceiver; @@ -14,6 +17,7 @@ import javafx.scene.layout.StackPane; import java.io.IOException; +import java.util.List; public class CommonViewsLoaderImpl implements CommonViewsLoader { @@ -91,6 +95,21 @@ public void loadTabContent(Tab tab, String fxmlFilepath, T data) { } } + public GenericConfirmDialogController loadConfirmDialog(StackPane confirmDialogContainer) { + FXMLLoader loader = fxmlLoaderService.setUpLoader( + "/org/chainoptim/desktop/shared/confirmdialog/GenericConfirmDialogView.fxml", + controllerFactory::createController); + + try { + Node confirmDialogView = loader.load(); + confirmDialogContainer.getChildren().add(confirmDialogView); + return loader.getController(); + } catch (IOException ex) { + ex.printStackTrace(); + return null; + } + } + public SelectOrCreateLocationController loadSelectOrCreateLocation(StackPane selectOrCreateLocationContainer) { FXMLLoader loader = fxmlLoaderService.setUpLoader( "/org/chainoptim/desktop/shared/common/uielements/SelectOrCreateLocationView.fxml", diff --git a/src/main/resources/css/common-elements.css b/src/main/resources/css/common-elements.css index be40e85f..cd37ed09 100644 --- a/src/main/resources/css/common-elements.css +++ b/src/main/resources/css/common-elements.css @@ -45,6 +45,7 @@ .custom-text-field { -fx-min-height: 32px; -fx-max-height: 32px; + -fx-padding: 0px 4px; -fx-background-color: #ffffff; -fx-font-weight: bold; -fx-border-color: #c0c0c0; diff --git a/src/main/resources/css/table.css b/src/main/resources/css/table.css index 1fb43906..d9a60fe9 100644 --- a/src/main/resources/css/table.css +++ b/src/main/resources/css/table.css @@ -46,4 +46,52 @@ .table-view .table-row-cell:selected .table-cell { -fx-text-fill: black; +} + +/* Table elements */ +.table-text-field { + -fx-min-height: 32px; + -fx-max-height: 32px; + -fx-padding: 0px 4px; + -fx-background-color: #ffffff; + -fx-font-weight: bold; + -fx-border-color: #c0c0c0; + -fx-border-width: 1px; + -fx-border-radius: 4px; + -fx-cursor: text; +} + +.table-text-field:focused { + -fx-border-color: #666666; +} + +.table-combo-box { + -fx-pref-height: 32px; + -fx-max-height: 32px; + -fx-min-width: 144px; + -fx-max-width: 144px; + -fx-background-color: #ffffff !important; + -fx-font-weight: bold; + -fx-border-color: #c0c0c0; + -fx-border-width: 1px; + -fx-border-radius: 4px; + -fx-cursor: hand; +} + +.table-combo-box .arrow-button { + -fx-padding: 0px 4px; + -fx-background-color: transparent; + -fx-background-insets: 0; +} + +.table-combo-box .arrow { + -fx-background-color: #c0c0c0; +} + +.table-combo-box .combo-box-popup .list-view .list-cell:hover { + -fx-background-color: #006AEE; +} + +.table-combo-box .combo-box-popup .list-view .list-cell:selected { + -fx-background-color: #006AEE; } \ No newline at end of file diff --git a/src/main/resources/org/chainoptim/desktop/features/supplier/SupplierOrdersView.fxml b/src/main/resources/org/chainoptim/desktop/features/supplier/SupplierOrdersView.fxml index 9d5e9928..ee5396fa 100644 --- a/src/main/resources/org/chainoptim/desktop/features/supplier/SupplierOrdersView.fxml +++ b/src/main/resources/org/chainoptim/desktop/features/supplier/SupplierOrdersView.fxml @@ -31,8 +31,8 @@ - - - + + + \ No newline at end of file diff --git a/src/main/resources/org/chainoptim/desktop/shared/common/uielements/SelectComponentView.fxml b/src/main/resources/org/chainoptim/desktop/shared/common/uielements/SelectComponentView.fxml index 95d7949e..ab79bd55 100644 --- a/src/main/resources/org/chainoptim/desktop/shared/common/uielements/SelectComponentView.fxml +++ b/src/main/resources/org/chainoptim/desktop/shared/common/uielements/SelectComponentView.fxml @@ -8,7 +8,7 @@ + fx:controller="org.chainoptim.desktop.shared.table.util.SelectComponentLoader">