add paginator
This commit is contained in:
+47
-20
@@ -30,24 +30,41 @@ use indexmap::map::IndexMap;
|
||||
pub struct ListContext<'a> {
|
||||
pub fields: Vec<RenderedField<'a>>,
|
||||
pub cards: Vec<RenderedCard<'a>>,
|
||||
pub page: usize,
|
||||
pub pages: usize,
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
fn route_index(store: State<RwLock<Store>>) -> Template {
|
||||
#[get("/?<page>&<card>")]
|
||||
fn route_index(store: State<RwLock<Store>>, page: Option<usize>, card: Option<usize>) -> Template {
|
||||
let rg = store.read();
|
||||
|
||||
let per_page: usize = 20;
|
||||
let mut page = page.unwrap_or_default();
|
||||
let n_pages = (rg.data.cards.len() as f64 / per_page as f64).ceil() as usize;
|
||||
|
||||
if let Some(card_id) = card {
|
||||
if let Some((n, _)) = rg.data.cards.iter().enumerate().find(|(_n, (id, _card))| **id == card_id) {
|
||||
page = n / per_page;
|
||||
}
|
||||
}
|
||||
|
||||
let context = ListContext {
|
||||
fields: render_empty_fields(&rg),
|
||||
cards: rg.data.cards.iter().filter_map(|(id, card)| {
|
||||
if let Value::Object(map) = card {
|
||||
Some(RenderedCard {
|
||||
fields: render_card_fields(&rg, map),
|
||||
id: *id,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect(),
|
||||
pages: n_pages,
|
||||
page,
|
||||
cards: rg.data.cards.iter()
|
||||
.skip(page * per_page)
|
||||
.take(per_page)
|
||||
.filter_map(|(id, card)| {
|
||||
if let Value::Object(ref map) = card {
|
||||
Some(RenderedCard {
|
||||
fields: render_card_fields(&rg, map),
|
||||
id: *id,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect(),
|
||||
};
|
||||
|
||||
Template::render("index", context)
|
||||
@@ -71,7 +88,7 @@ impl<'a> FromForm<'a> for MapFromForm {
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_card_form(store : &Store, mut form : MapFromForm) -> IndexMap::<String, Value> {
|
||||
fn collect_card_form(store: &Store, mut form: MapFromForm) -> IndexMap::<String, Value> {
|
||||
let mut card = IndexMap::new();
|
||||
|
||||
for (k, field) in &store.model.fields {
|
||||
@@ -179,7 +196,7 @@ struct AddCardContext<'a> {
|
||||
#[derive(Serialize)]
|
||||
struct EditCardContext<'a> {
|
||||
pub fields: Vec<RenderedField<'a>>,
|
||||
pub id : usize,
|
||||
pub id: usize,
|
||||
}
|
||||
|
||||
#[get("/add")]
|
||||
@@ -198,16 +215,16 @@ fn route_add_save(form: Form<MapFromForm>, store: State<RwLock<Store>>) -> Redir
|
||||
let mut rg = store.write();
|
||||
|
||||
let card = collect_card_form(&rg, form.into_inner());
|
||||
rg.add_card(card);
|
||||
let id = rg.add_card(card);
|
||||
|
||||
Redirect::found(uri!(route_index))
|
||||
Redirect::found(uri!(route_index: page=_, card=id))
|
||||
}
|
||||
|
||||
#[get("/edit/<id>")]
|
||||
fn route_edit(id : usize, store: State<RwLock<Store>>) -> Option<Template> {
|
||||
fn route_edit(id: usize, store: State<RwLock<Store>>) -> Option<Template> {
|
||||
let rg = store.read();
|
||||
|
||||
if let Some(Value::Object(map)) = rg.data.cards.get(&id) {
|
||||
if let Some(Value::Object(ref map)) = rg.data.cards.get(&id) {
|
||||
let context = EditCardContext {
|
||||
fields: render_card_fields(&rg, map),
|
||||
id,
|
||||
@@ -220,13 +237,22 @@ fn route_edit(id : usize, store: State<RwLock<Store>>) -> Option<Template> {
|
||||
}
|
||||
|
||||
#[post("/edit/<id>", data = "<form>")]
|
||||
fn route_edit_save(id : usize, form: Form<MapFromForm>, store: State<RwLock<Store>>) -> Option<Redirect> {
|
||||
fn route_edit_save(id: usize, form: Form<MapFromForm>, store: State<RwLock<Store>>) -> Option<Redirect> {
|
||||
let mut rg = store.write();
|
||||
|
||||
let card = collect_card_form(&rg, form.into_inner());
|
||||
rg.update_card(id, card);
|
||||
|
||||
Some(Redirect::found(uri!(route_index)))
|
||||
Some(Redirect::found(uri!(route_index: page=_, card=id)))
|
||||
}
|
||||
|
||||
#[get("/delete/<id>")]
|
||||
fn route_delete(id: usize, store: State<RwLock<Store>>) -> Redirect {
|
||||
let mut rg = store.write();
|
||||
|
||||
rg.delete_card(id);
|
||||
|
||||
Redirect::found(uri!(route_index: page=_, card=_))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@@ -244,5 +270,6 @@ fn main() {
|
||||
route_add_save,
|
||||
route_edit,
|
||||
route_edit_save,
|
||||
route_delete,
|
||||
]).launch();
|
||||
}
|
||||
|
||||
+9
-2
@@ -75,16 +75,17 @@ impl Store {
|
||||
file.write(serialized.as_bytes()).expect("Error write data file");
|
||||
}
|
||||
|
||||
pub fn add_card(&mut self, values : IndexMap::<String, Value>) {
|
||||
pub fn add_card(&mut self, values : IndexMap::<String, Value>) -> usize {
|
||||
let packed = serde_json::to_value(values).expect("Error serialize");
|
||||
if let p @ Value::Object(_) = packed {
|
||||
let id = self.data.counter;
|
||||
self.data.counter += 1;
|
||||
self.data.cards.insert(id, p);
|
||||
self.persist();
|
||||
id
|
||||
} else {
|
||||
panic!("Packing did not produce a map.");
|
||||
}
|
||||
self.persist()
|
||||
}
|
||||
|
||||
pub fn update_card(&mut self, id : usize, values : IndexMap::<String, Value>) {
|
||||
@@ -102,6 +103,12 @@ impl Store {
|
||||
|
||||
self.persist()
|
||||
}
|
||||
|
||||
pub fn delete_card(&mut self, id : usize) {
|
||||
self.data.cards.remove(&id);
|
||||
|
||||
self.persist()
|
||||
}
|
||||
}
|
||||
|
||||
fn load_file(path: impl AsRef<Path>) -> String {
|
||||
|
||||
Reference in New Issue
Block a user