|
|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
use std::{marker::PhantomData, rc::Rc};
|
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
use sycamore::prelude::*;
|
|
|
|
|
@ -11,21 +11,36 @@ use crate::{
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[perseus::make_rx(PaginatedTableStateRx)]
|
|
|
|
|
pub struct PaginatedTableState<M>
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct PaginatedTableStateRx<M, F, C>
|
|
|
|
|
where
|
|
|
|
|
M: 'static,
|
|
|
|
|
C: Fn(Option<String>, i64, i64) -> F,
|
|
|
|
|
F: std::future::Future<Output = Result<PaginatedResponse<M>, ()>>,
|
|
|
|
|
{
|
|
|
|
|
pub req: String,
|
|
|
|
|
pub ph_data: PhantomData<M>,
|
|
|
|
|
pub route: C,
|
|
|
|
|
pub filter: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[component(PaginatedTable<G>)]
|
|
|
|
|
pub fn component<M>(PaginatedTableStateRx { req, ph_data }: PaginatedTableStateRx<M>) -> View<G>
|
|
|
|
|
impl<M, F, C> PaginatedTableStateRx<M, F, C>
|
|
|
|
|
where
|
|
|
|
|
M: 'static,
|
|
|
|
|
PaginatedResponse<M>: IntoTableData<G> + Clone,
|
|
|
|
|
C: Fn(Option<String>, i64, i64) -> F,
|
|
|
|
|
F: std::future::Future<Output = Result<PaginatedResponse<M>, ()>>,
|
|
|
|
|
{
|
|
|
|
|
async fn get_data(&self, page: i64, size: i64) -> Result<PaginatedResponse<M>, ()> {
|
|
|
|
|
(self.route)(self.filter.clone(), page, size).await
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[component(PaginatedTable<G>)]
|
|
|
|
|
pub fn component<M, F, C>(state: PaginatedTableStateRx<M, F, C>) -> View<G>
|
|
|
|
|
where
|
|
|
|
|
M: 'static + Clone,
|
|
|
|
|
PaginatedResponse<M>: IntoTableData<G>,
|
|
|
|
|
for<'de> M: Deserialize<'de>,
|
|
|
|
|
C: Fn(Option<String>, i64, i64) -> F + 'static,
|
|
|
|
|
F: std::future::Future<Output = Result<PaginatedResponse<M>, ()>> + 'static,
|
|
|
|
|
{
|
|
|
|
|
let paginated_data: Signal<Option<PaginatedResponse<M>>> = Signal::new(None);
|
|
|
|
|
let table_prop: TableContentRx<G> = TableContentRx {
|
|
|
|
|
@ -51,26 +66,16 @@ where
|
|
|
|
|
|
|
|
|
|
let page_size_string = Signal::new("20".to_string());
|
|
|
|
|
let page_size_string2 = page_size_string.clone();
|
|
|
|
|
let state_rc = Rc::new(state);
|
|
|
|
|
create_effect(
|
|
|
|
|
cloned!((page_size_string, paginated_data, page, req, n_page, n_rows) => move || {
|
|
|
|
|
cloned!((page_size_string, paginated_data, page, n_page, n_rows, state_rc) => move || {
|
|
|
|
|
let page = *page.get();
|
|
|
|
|
let page_size_s = page_size_string.get();
|
|
|
|
|
let page_size = page_size_s.parse().unwrap_or(20);
|
|
|
|
|
let url = (*req.get()).clone();
|
|
|
|
|
if G::IS_BROWSER {
|
|
|
|
|
perseus::spawn_local(
|
|
|
|
|
cloned!((table_prop2, page, paginated_data, n_page, n_rows) => async move {
|
|
|
|
|
let res = reqwasm::http::Request::get(&format!(
|
|
|
|
|
"{}?page={}&size={}",
|
|
|
|
|
url,
|
|
|
|
|
page, page_size,
|
|
|
|
|
))
|
|
|
|
|
.send()
|
|
|
|
|
.await
|
|
|
|
|
.unwrap()
|
|
|
|
|
.json::<PaginatedResponse<M>>()
|
|
|
|
|
.await
|
|
|
|
|
.unwrap();
|
|
|
|
|
cloned!((table_prop2, page, paginated_data, n_page, n_rows, state_rc) => async move {
|
|
|
|
|
let res = state_rc.get_data(page, page_size).await.unwrap();
|
|
|
|
|
paginated_data.set(Some(res.clone()));
|
|
|
|
|
n_rows.set(res.count);
|
|
|
|
|
let table_content = res.into_table_data();
|
|
|
|
|
|