Feat: Add bulk actions for case analysis and deletion
Introduces a new `/web/cases/bulk` endpoint to handle multiple case actions simultaneously. This change adds the following: - A new `bulk` module for handling bulk operations. - The `handle_bulk_action` function in `bulk.rs` to dispatch to specific actions. - `bulk_analyze` and `bulk_delete` functions to process the actions. - Updates `Cargo.toml` and `Cargo.lock` to include necessary dependencies: `form_urlencoded`, `serde_core`, `serde_html_form`, and `serde_path_to_error`. - Modified `axum-extra` features to include `form`. - Adds checks for deleted cases in `collect_pending` for both analysis and transcription recovery. - Renames and modifies `handle_close_case` to `handle_analyze_case` in `case_actions.rs` to better reflect its functionality. - Adds a new `handle_delete_case` and `handle_undo_delete` to `case_actions.rs`. - Updates `my_cases.html` and `case_detail.html` to support bulk actions, including checkboxes, a bulk action bar, and an "Undo last delete" feature. - Modifies `handle_audio` and `scan_cases` in `web.rs` to respect delete markers. - Updates `analyze_test.rs` with new request builders for analyze and delete actions.
This commit is contained in:
@@ -56,7 +56,11 @@ pub async fn handle_audio(
|
||||
.map_err(|_| AppError::BadRequest("Invalid case_id (not a UUID)".into()))?;
|
||||
validate_filename(&filename)?;
|
||||
|
||||
let file_path = crate::paths::case_dir(&config.data_path, &user, &case_id).join(&filename);
|
||||
let case_path = crate::paths::case_dir(&config.data_path, &user, &case_id);
|
||||
if crate::paths::is_deleted(&case_path).await {
|
||||
return Err(AppError::NotFound("Audio file not found".into()));
|
||||
}
|
||||
let file_path = case_path.join(&filename);
|
||||
if !tokio::fs::try_exists(&file_path).await.unwrap_or(false) {
|
||||
return Err(AppError::NotFound("Audio file not found".into()));
|
||||
}
|
||||
@@ -129,6 +133,9 @@ async fn scan_cases(data_path: &Path) -> Vec<CaseView> {
|
||||
}
|
||||
|
||||
let case_path = case_entry.path();
|
||||
if crate::paths::is_deleted(&case_path).await {
|
||||
continue;
|
||||
}
|
||||
let recordings = scan_recordings(&case_path).await;
|
||||
if recordings.is_empty() {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user