include_documents for /contents

This commit is contained in:
2025-10-17 18:01:07 +02:00
parent 831ec1d989
commit f9e798f3b3
2 changed files with 64 additions and 33 deletions
+50 -33
View File
@@ -1,5 +1,5 @@
use axum::{
extract::{Json, Path, State},
extract::{Json, Path, Query, State},
http::StatusCode,
};
use diesel::{dsl::exists, prelude::*, PgConnection};
@@ -50,6 +50,16 @@ pub struct FolderContentsResponse {
pub documents: Vec<DocumentResponse>,
}
#[derive(Deserialize)]
pub struct FolderContentsQuery {
#[serde(default = "default_include_documents")]
pub include_documents: bool,
}
const fn default_include_documents() -> bool {
true
}
#[derive(Serialize)]
pub struct FolderInfo {
pub id: Uuid,
@@ -150,6 +160,7 @@ pub async fn create_folder(
pub async fn list_folder_contents(
State(state): State<AppState>,
Path(folder_identifier): Path<String>,
Query(query): Query<FolderContentsQuery>,
user: AuthenticatedUser,
) -> AppResult<Json<FolderContentsResponse>> {
let mut conn = state.db()?;
@@ -183,42 +194,48 @@ pub async fn list_folder_contents(
};
let subfolders = child_folders.into_iter().map(folder_to_info).collect();
let docs_query = documents::table
.filter(documents::deleted_at.is_null())
.order(documents::uploaded_at.desc());
let documents = if query.include_documents {
let docs_query = documents::table
.filter(documents::deleted_at.is_null())
.order(documents::uploaded_at.desc());
let docs: Vec<Document> = if let Some(current_folder) = folder_id {
docs_query
.filter(documents::folder_id.eq(current_folder))
.load(&mut conn)?
let docs: Vec<Document> = if let Some(current_folder) = folder_id {
docs_query
.filter(documents::folder_id.eq(current_folder))
.load(&mut conn)?
} else {
docs_query
.filter(documents::folder_id.is_null())
.load(&mut conn)?
};
let doc_ids: Vec<Uuid> = docs.iter().map(|doc| doc.id).collect();
let tags_map = load_tags_for_documents(&mut conn, &doc_ids)?;
let mut correspondents_map = load_correspondents_for_documents(&mut conn, &doc_ids)?;
drop(conn);
let primary_versions = load_primary_assets(&state, &docs).await?;
let mut documents = Vec::with_capacity(doc_ids.len());
for doc in docs {
let tags = tags_map.get(&doc.id).cloned();
let correspondents = correspondents_map.remove(&doc.id).unwrap_or_default();
let current_version = primary_versions.get(&doc.id).cloned();
documents.push(to_document_response(
&state,
user.user_id,
doc,
tags,
correspondents,
current_version,
)?);
}
documents
} else {
docs_query
.filter(documents::folder_id.is_null())
.load(&mut conn)?
Vec::new()
};
let doc_ids: Vec<Uuid> = docs.iter().map(|doc| doc.id).collect();
let tags_map = load_tags_for_documents(&mut conn, &doc_ids)?;
let mut correspondents_map = load_correspondents_for_documents(&mut conn, &doc_ids)?;
drop(conn);
let primary_versions = load_primary_assets(&state, &docs).await?;
let mut documents = Vec::with_capacity(doc_ids.len());
for doc in docs {
let tags = tags_map.get(&doc.id).cloned();
let correspondents = correspondents_map.remove(&doc.id).unwrap_or_default();
let current_version = primary_versions.get(&doc.id).cloned();
documents.push(to_document_response(
&state,
user.user_id,
doc,
tags,
correspondents,
current_version,
)?);
}
Ok(Json(FolderContentsResponse {
folder,
subfolders,
+14
View File
@@ -287,6 +287,20 @@ async fn folder_rename_updates_name_and_child_paths() -> Result<()> {
.expect("renamed folder present");
assert_eq!(renamed.name, "Archive");
let folders_only = app
.get(
&format!(
"/api/folders/{}/contents?include_documents=false",
parent.folder.id
),
Some(&token),
)
.await?;
assert_eq!(folders_only.status(), StatusCode::OK);
let folders_only_body = body_to_vec(folders_only.into_body()).await?;
let folders_only_contents: FolderContents = serde_json::from_slice(&folders_only_body)?;
assert!(folders_only_contents.documents.is_empty());
let child_contents = app
.get(
&format!("/api/folders/{}/contents", child.folder.id),