include_documents for /contents
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
extract::{Json, Path, State},
|
extract::{Json, Path, Query, State},
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
};
|
};
|
||||||
use diesel::{dsl::exists, prelude::*, PgConnection};
|
use diesel::{dsl::exists, prelude::*, PgConnection};
|
||||||
@@ -50,6 +50,16 @@ pub struct FolderContentsResponse {
|
|||||||
pub documents: Vec<DocumentResponse>,
|
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)]
|
#[derive(Serialize)]
|
||||||
pub struct FolderInfo {
|
pub struct FolderInfo {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
@@ -150,6 +160,7 @@ pub async fn create_folder(
|
|||||||
pub async fn list_folder_contents(
|
pub async fn list_folder_contents(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Path(folder_identifier): Path<String>,
|
Path(folder_identifier): Path<String>,
|
||||||
|
Query(query): Query<FolderContentsQuery>,
|
||||||
user: AuthenticatedUser,
|
user: AuthenticatedUser,
|
||||||
) -> AppResult<Json<FolderContentsResponse>> {
|
) -> AppResult<Json<FolderContentsResponse>> {
|
||||||
let mut conn = state.db()?;
|
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 subfolders = child_folders.into_iter().map(folder_to_info).collect();
|
||||||
|
|
||||||
let docs_query = documents::table
|
let documents = if query.include_documents {
|
||||||
.filter(documents::deleted_at.is_null())
|
let docs_query = documents::table
|
||||||
.order(documents::uploaded_at.desc());
|
.filter(documents::deleted_at.is_null())
|
||||||
|
.order(documents::uploaded_at.desc());
|
||||||
|
|
||||||
let docs: Vec<Document> = if let Some(current_folder) = folder_id {
|
let docs: Vec<Document> = if let Some(current_folder) = folder_id {
|
||||||
docs_query
|
docs_query
|
||||||
.filter(documents::folder_id.eq(current_folder))
|
.filter(documents::folder_id.eq(current_folder))
|
||||||
.load(&mut conn)?
|
.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 {
|
} else {
|
||||||
docs_query
|
Vec::new()
|
||||||
.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,
|
|
||||||
)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Json(FolderContentsResponse {
|
Ok(Json(FolderContentsResponse {
|
||||||
folder,
|
folder,
|
||||||
subfolders,
|
subfolders,
|
||||||
|
|||||||
@@ -287,6 +287,20 @@ async fn folder_rename_updates_name_and_child_paths() -> Result<()> {
|
|||||||
.expect("renamed folder present");
|
.expect("renamed folder present");
|
||||||
assert_eq!(renamed.name, "Archive");
|
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
|
let child_contents = app
|
||||||
.get(
|
.get(
|
||||||
&format!("/api/folders/{}/contents", child.folder.id),
|
&format!("/api/folders/{}/contents", child.folder.id),
|
||||||
|
|||||||
Reference in New Issue
Block a user