Activity log filters, staff role, chat fix
This commit is contained in:
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.example.petshopdesktop.api.ApiClient;
|
||||
import org.example.petshopdesktop.api.dto.activity.ActivityLogResponse;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityLogApi {
|
||||
@@ -18,12 +19,18 @@ public class ActivityLogApi {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public List<ActivityLogResponse> getActivityLogs(int limit) throws Exception {
|
||||
String path = "/api/v1/activity-logs?limit=" + limit;
|
||||
String response = apiClient.getRawResponse(path);
|
||||
public List<ActivityLogResponse> getActivityLogs(int limit, LocalDate startDate, LocalDate endDate) throws Exception {
|
||||
StringBuilder path = new StringBuilder("/api/v1/activity-logs?limit=").append(limit);
|
||||
if (startDate != null) path.append("&startDate=").append(startDate);
|
||||
if (endDate != null) path.append("&endDate=").append(endDate);
|
||||
String response = apiClient.getRawResponse(path.toString());
|
||||
return apiClient.getObjectMapper().readValue(
|
||||
response,
|
||||
new TypeReference<List<ActivityLogResponse>>() {}
|
||||
);
|
||||
}
|
||||
|
||||
public List<ActivityLogResponse> getActivityLogs(int limit) throws Exception {
|
||||
return getActivityLogs(limit, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,12 @@ package org.example.petshopdesktop.controllers;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.DatePicker;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
@@ -40,6 +43,15 @@ public class ActivityLogController {
|
||||
@FXML
|
||||
private Button btnRefresh;
|
||||
|
||||
@FXML
|
||||
private DatePicker dpStart;
|
||||
|
||||
@FXML
|
||||
private DatePicker dpEnd;
|
||||
|
||||
@FXML
|
||||
private CheckBox chkHideViewOnly;
|
||||
|
||||
@FXML
|
||||
private Label lblStatus;
|
||||
|
||||
@@ -47,6 +59,7 @@ public class ActivityLogController {
|
||||
private Label lblError;
|
||||
|
||||
private final ObservableList<ActivityLogResponse> activityLogs = FXCollections.observableArrayList();
|
||||
private FilteredList<ActivityLogResponse> filteredLogs;
|
||||
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
private static final int DEFAULT_LIMIT = 2000;
|
||||
|
||||
@@ -71,7 +84,8 @@ public class ActivityLogController {
|
||||
colStore.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(displayStore(data.getValue())));
|
||||
colActivity.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(nullToBlank(data.getValue().getActivity())));
|
||||
|
||||
TableViewSupport.bindSortedItems(tvActivityLogs, new javafx.collections.transformation.FilteredList<>(activityLogs, a -> true));
|
||||
filteredLogs = new FilteredList<>(activityLogs, a -> true);
|
||||
TableViewSupport.bindSortedItems(tvActivityLogs, filteredLogs);
|
||||
loadLogs();
|
||||
}
|
||||
|
||||
@@ -80,18 +94,46 @@ public class ActivityLogController {
|
||||
loadLogs();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onDateChanged(ActionEvent event) {
|
||||
loadLogs();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onHideViewOnlyChanged(ActionEvent event) {
|
||||
applyViewOnlyFilter();
|
||||
}
|
||||
|
||||
private void applyViewOnlyFilter() {
|
||||
boolean hide = chkHideViewOnly != null && chkHideViewOnly.isSelected();
|
||||
if (filteredLogs != null) {
|
||||
filteredLogs.setPredicate(hide
|
||||
? a -> {
|
||||
String act = a.getActivity();
|
||||
if (act == null) return true;
|
||||
String trimmed = act.stripLeading();
|
||||
return !trimmed.startsWith("View");
|
||||
}
|
||||
: a -> true);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadLogs() {
|
||||
lblError.setText("");
|
||||
tvActivityLogs.setDisable(true);
|
||||
btnRefresh.setDisable(true);
|
||||
|
||||
java.time.LocalDate startDate = dpStart != null ? dpStart.getValue() : null;
|
||||
java.time.LocalDate endDate = dpEnd != null ? dpEnd.getValue() : null;
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<ActivityLogResponse> content = ActivityLogApi.getInstance().getActivityLogs(DEFAULT_LIMIT);
|
||||
List<ActivityLogResponse> content = ActivityLogApi.getInstance().getActivityLogs(DEFAULT_LIMIT, startDate, endDate);
|
||||
List<ActivityLogResponse> safeContent = content != null ? content : List.of();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
activityLogs.setAll(safeContent);
|
||||
applyViewOnlyFilter();
|
||||
tvActivityLogs.setDisable(false);
|
||||
btnRefresh.setDisable(false);
|
||||
TableViewSupport.flashStatus(lblStatus, "Refreshed");
|
||||
|
||||
@@ -32,7 +32,6 @@ public class StaffEditDialogController {
|
||||
@FXML private PasswordField txtPassword;
|
||||
@FXML private PasswordField txtPasswordConfirm;
|
||||
@FXML private ComboBox<String> cbRole;
|
||||
@FXML private ComboBox<String> cbStaffRole;
|
||||
@FXML private ComboBox<String> cbActive;
|
||||
@FXML private ComboBox<DropdownOption> cbStore;
|
||||
@FXML private Label lblError;
|
||||
@@ -46,8 +45,6 @@ public class StaffEditDialogController {
|
||||
TextFieldFormatSupport.applyPhoneNumberFormat(txtPhone);
|
||||
|
||||
cbRole.setItems(FXCollections.observableArrayList("STAFF", "ADMIN"));
|
||||
cbStaffRole.setItems(FXCollections.observableArrayList(
|
||||
"STORE_MANAGER", "SALES_ASSOCIATE", "GROOMER", "VETERINARIAN"));
|
||||
cbActive.setItems(FXCollections.observableArrayList("Active", "Inactive"));
|
||||
|
||||
cbStore.setCellFactory(param -> new ListCell<>() {
|
||||
@@ -109,7 +106,6 @@ public class StaffEditDialogController {
|
||||
txtUsername.setText(emp.getUsername());
|
||||
|
||||
if (emp.getRole() != null) cbRole.setValue(emp.getRole());
|
||||
if (emp.getStaffRole() != null) cbStaffRole.setValue(emp.getStaffRole());
|
||||
cbActive.setValue(Boolean.TRUE.equals(emp.getActive()) ? "Active" : "Inactive");
|
||||
|
||||
pendingStoreId = emp.getPrimaryStoreId();
|
||||
@@ -171,10 +167,6 @@ public class StaffEditDialogController {
|
||||
lblError.setText("Role is required.");
|
||||
return;
|
||||
}
|
||||
if (cbStaffRole.getValue() == null) {
|
||||
lblError.setText("Staff role is required.");
|
||||
return;
|
||||
}
|
||||
if (cbStore.getValue() == null) {
|
||||
lblError.setText("Primary store is required.");
|
||||
return;
|
||||
@@ -183,7 +175,6 @@ public class StaffEditDialogController {
|
||||
btnSave.setDisable(true);
|
||||
|
||||
String role = cbRole.getValue();
|
||||
String staffRole = cbStaffRole.getValue();
|
||||
boolean active = "Active".equals(cbActive.getValue());
|
||||
Long storeId = cbStore.getValue().getId();
|
||||
|
||||
@@ -198,7 +189,6 @@ public class StaffEditDialogController {
|
||||
request.setEmail(email);
|
||||
request.setPhone(phone);
|
||||
request.setRole(role);
|
||||
request.setStaffRole(staffRole);
|
||||
request.setActive(active);
|
||||
request.setPrimaryStoreId(storeId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user