11use axum:: {
2- extract:: { Json , State } ,
2+ extract:: { Json , Query , State } ,
33 http:: StatusCode ,
44 response:: { IntoResponse , Response } ,
55} ;
@@ -12,6 +12,7 @@ use crate::application::dtos::folder_dto::FolderDto;
1212use crate :: application:: services:: batch_operations:: {
1313 BatchOperationService , BatchResult , BatchStats ,
1414} ;
15+ use crate :: interfaces:: api:: deserializer;
1516use crate :: interfaces:: api:: handlers:: ApiResult ;
1617use crate :: interfaces:: middleware:: auth:: AuthUser ;
1718
@@ -646,6 +647,24 @@ pub struct BatchDownloadRequest {
646647 pub folder_ids : Vec < String > ,
647648}
648649
650+ #[ derive( Debug , Deserialize ) ]
651+ pub struct BatchDownloadQuery {
652+ #[ serde( default , deserialize_with = "deserializer::deserialize_csv" ) ]
653+ pub file_ids : Vec < String > , // will deserialize query string "1,2,3" into Vec<String>
654+ #[ serde( default , deserialize_with = "deserializer::deserialize_csv" ) ]
655+ pub folder_ids : Vec < String > , // will deserialize query string "1,2,3" into Vec<String>
656+ }
657+
658+ // convert BatchDownloadQuery into BatchDownloadRequest
659+ impl From < BatchDownloadQuery > for BatchDownloadRequest {
660+ fn from ( q : BatchDownloadQuery ) -> Self {
661+ Self {
662+ file_ids : q. file_ids ,
663+ folder_ids : q. folder_ids ,
664+ }
665+ }
666+ }
667+
649668/// Handler for moving multiple files and folders to trash in batch
650669#[ utoipa:: path(
651670 post,
@@ -832,6 +851,29 @@ pub async fn move_folders_batch(
832851 Ok ( ( status_code, Json ( response) ) . into_response ( ) )
833852}
834853
854+ // Hander as a workarround for drag & drop (does not support POST requests)
855+ #[ utoipa:: path(
856+ get,
857+ path = "/api/batch/download" ,
858+ params(
859+ ( "file_ids" = Option <String >, Query , description = "Comma-separated file IDs" ) ,
860+ ( "folder_ids" = Option <String >, Query , description = "Comma-separated folder IDs" ) ,
861+ ) ,
862+ responses(
863+ ( status = 200 , description = "ZIP archive stream" ) ,
864+ ( status = 400 , description = "Bad request" ) ,
865+ ( status = 401 , description = "Unauthorized" ) ,
866+ ( status = 500 , description = "ZIP creation failed" )
867+ ) ,
868+ tag = "batch"
869+ ) ]
870+ pub async fn download_batch_querystring (
871+ State ( state) : State < BatchHandlerState > ,
872+ auth_user : AuthUser ,
873+ Query ( params) : Query < BatchDownloadQuery > ,
874+ ) -> Result < Response , ( StatusCode , String ) > {
875+ process_download_batch ( state, auth_user, params. into ( ) ) . await
876+ }
835877/// Handler for downloading multiple files and folders as a single ZIP.
836878///
837879/// The ZIP is written to a temporary file and streamed to the client,
@@ -847,10 +889,18 @@ pub async fn move_folders_batch(
847889 ) ,
848890 tag = "batch"
849891) ]
850- pub async fn download_batch (
892+ pub async fn download_batch_post (
851893 State ( state) : State < BatchHandlerState > ,
852894 auth_user : AuthUser ,
853895 Json ( request) : Json < BatchDownloadRequest > ,
896+ ) -> Result < Response , ( StatusCode , String ) > {
897+ process_download_batch ( state, auth_user, request) . await
898+ }
899+
900+ async fn process_download_batch (
901+ state : BatchHandlerState ,
902+ auth_user : AuthUser ,
903+ request : BatchDownloadRequest ,
854904) -> Result < Response , ( StatusCode , String ) > {
855905 if request. file_ids . is_empty ( ) && request. folder_ids . is_empty ( ) {
856906 return Err ( (
0 commit comments