pagnation

This commit is contained in:
Mateusz Gruszczyński
2026-08-02 14:26:32 +02:00
parent 464660a274
commit f71ebefa82
7 changed files with 290 additions and 20 deletions
+46 -3
View File
@@ -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(&note.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 },
}))
}