i18n+filtering fork - fluent-templates v2
at main 114 lines 3.6 kB view raw
1use crate::http::utils::stringify; 2use serde::{Deserialize, Serialize}; 3 4pub const PAGE_DEFAULT: i64 = 1; 5pub const PAGE_MIN: i64 = 1; 6pub const PAGE_MAX: i64 = 100; 7pub const PAGE_SIZE_DEFAULT: i64 = 10; 8pub const PAGE_SIZE_MIN: i64 = 5; 9pub const PAGE_SIZE_MAX: i64 = 100; 10 11pub const LIMITED_PAGE_DEFAULT: i64 = 1; 12pub const LIMITED_PAGE_MIN: i64 = 1; 13pub const LIMITED_PAGE_MAX: i64 = 5; 14pub const LIMITED_PAGE_SIZE_DEFAULT: i64 = 5; 15pub const LIMITED_PAGE_SIZE_MIN: i64 = 5; 16pub const LIMITED_PAGE_SIZE_MAX: i64 = 5; 17 18#[derive(Deserialize, Default)] 19pub struct Pagination { 20 pub page: Option<i64>, 21 pub page_size: Option<i64>, 22} 23 24#[derive(Serialize, Debug)] 25pub struct PaginationView { 26 // Legacy fields for backwards compatibility 27 pub previous: Option<i64>, 28 pub previous_url: Option<String>, 29 pub next: Option<i64>, 30 pub next_url: Option<String>, 31 32 // New fields for template compatibility 33 pub current_page: i64, 34 pub has_prev: bool, 35 pub prev_page: i64, 36 pub has_next: bool, 37 pub next_page: i64, 38 pub page_range: Vec<i64>, 39} 40 41impl Pagination { 42 pub fn admin_clamped(&self) -> (i64, i64) { 43 let page = self.page.unwrap_or(1).clamp(1, 25000); 44 let page_size = self.page_size.unwrap_or(1).clamp(20, 100); 45 (page, page_size) 46 } 47 48 pub fn clamped(&self) -> (i64, i64) { 49 let page = self.page.unwrap_or(PAGE_DEFAULT).clamp(PAGE_MIN, PAGE_MAX); 50 let page_size = self 51 .page_size 52 .unwrap_or(PAGE_SIZE_DEFAULT) 53 .clamp(PAGE_SIZE_MIN, PAGE_SIZE_MAX); 54 (page, page_size) 55 } 56} 57 58impl PaginationView { 59 pub fn new(page_size: i64, total: i64, page: i64, params: Vec<(&str, &str)>) -> Self { 60 let total_pages = if total == 0 { 1 } else { (total + page_size - 1) / page_size }; 61 62 // Legacy fields for backwards compatibility 63 let (previous, previous_url) = { 64 if page > 1 { 65 let page_value = (page - 1).to_string(); 66 let mut page_args: Vec<(&str, &str)> = vec![("page", &page_value)]; 67 page_args.extend(params.clone()); 68 (Some(page - 1), Some(stringify(page_args))) 69 } else { 70 (None, None) 71 } 72 }; 73 74 let (next, next_url) = { 75 if page < total_pages { 76 let page_value = (page + 1).to_string(); 77 let mut page_args: Vec<(&str, &str)> = vec![("page", &page_value)]; 78 page_args.extend(params.clone()); 79 (Some(page + 1), Some(stringify(page_args))) 80 } else { 81 (None, None) 82 } 83 }; 84 85 // New fields for template compatibility 86 let current_page = page; 87 let has_prev = page > 1; 88 let prev_page = if has_prev { page - 1 } else { 1 }; 89 let has_next = page < total_pages; 90 let next_page = if has_next { page + 1 } else { page }; 91 92 // Create page range (show 5 pages around current page) 93 let mut page_range = Vec::new(); 94 let range_start = if current_page <= 3 { 1 } else { current_page - 2 }; 95 let range_end = std::cmp::min(total_pages, range_start + 4); 96 97 for page_num in range_start..=range_end { 98 page_range.push(page_num); 99 } 100 101 Self { 102 previous, 103 previous_url, 104 next, 105 next_url, 106 current_page, 107 has_prev, 108 prev_page, 109 has_next, 110 next_page, 111 page_range, 112 } 113 } 114}