pagnation
This commit is contained in:
+46
-3
@@ -19,7 +19,7 @@ pub use pads_public::*;
|
||||
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Multipart, Path, State},
|
||||
extract::{Multipart, Path, Query, State},
|
||||
http::{HeaderMap, HeaderName, HeaderValue, StatusCode, header},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
@@ -283,6 +283,31 @@ pub struct WorkspaceInfo {
|
||||
pub struct WorkspaceOpenResponse {
|
||||
workspace: WorkspaceInfo,
|
||||
notes: Vec<NoteListItem>,
|
||||
pagination: ListPaginationMeta,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct WorkspaceNotesQuery {
|
||||
#[serde(default)]
|
||||
q: String,
|
||||
#[serde(default = "default_list_page")]
|
||||
page: usize,
|
||||
#[serde(default = "default_list_per_page")]
|
||||
per_page: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ListPaginationMeta {
|
||||
page: usize,
|
||||
per_page: usize,
|
||||
total: usize,
|
||||
total_pages: usize,
|
||||
}
|
||||
|
||||
fn default_list_page() -> usize { 1 }
|
||||
fn default_list_per_page() -> usize { 25 }
|
||||
fn normalize_list_per_page(value: usize) -> usize {
|
||||
match value { 25 | 50 | 100 => value, _ => 25 }
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@@ -552,6 +577,7 @@ pub async fn open_workspace(
|
||||
State(state): State<SharedState>,
|
||||
headers: HeaderMap,
|
||||
Path(workspace_slug): Path<String>,
|
||||
Query(query): Query<WorkspaceNotesQuery>,
|
||||
Json(payload): Json<PasswordRequest>,
|
||||
) -> Result<Json<WorkspaceOpenResponse>, ApiError> {
|
||||
let workspace = authorized_workspace(
|
||||
@@ -573,9 +599,16 @@ pub async fn open_workspace(
|
||||
.into_iter()
|
||||
.map(|stats| (stats.note_id, stats))
|
||||
.collect::<std::collections::HashMap<_, _>>();
|
||||
let notes = db::list_notes(&state.db, workspace.id)
|
||||
let search = query.q.trim().to_lowercase();
|
||||
let mut notes = db::list_notes(&state.db, workspace.id)
|
||||
.await?
|
||||
.into_iter()
|
||||
.filter(|note| {
|
||||
search.is_empty()
|
||||
|| note.title.to_lowercase().contains(&search)
|
||||
|| note.slug.to_lowercase().contains(&search)
|
||||
|| note.created_by.as_deref().unwrap_or_default().to_lowercase().contains(&search)
|
||||
})
|
||||
.map(|note| {
|
||||
let stats = stats.get(¬e.id);
|
||||
NoteListItem {
|
||||
@@ -592,11 +625,21 @@ pub async fn open_workspace(
|
||||
revision_count: stats.map_or(0, |value| value.revision_count),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
.collect::<Vec<_>>();
|
||||
notes.sort_by(|left, right| right.updated_at.cmp(&left.updated_at));
|
||||
|
||||
let page = query.page.max(1);
|
||||
let per_page = normalize_list_per_page(query.per_page);
|
||||
let total = notes.len();
|
||||
let total_pages = ((total + per_page - 1) / per_page).max(1);
|
||||
let page = page.min(total_pages);
|
||||
let start = (page - 1) * per_page;
|
||||
let notes = notes.into_iter().skip(start).take(per_page).collect();
|
||||
|
||||
Ok(Json(WorkspaceOpenResponse {
|
||||
workspace: workspace_info_from(&workspace),
|
||||
notes,
|
||||
pagination: ListPaginationMeta { page, per_page, total, total_pages },
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user