Display category children & Add calendar stats
This commit is contained in:
@ -9,25 +9,81 @@ use rocket::{get, State};
|
||||
use rocket_contrib::templates::Template;
|
||||
use rocket_contrib::uuid::Uuid;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::time::Duration;
|
||||
|
||||
#[get("/")]
|
||||
pub fn index(_auth: Authorized, db: State<'_, sled::Db>) -> Result<Template, StatusJson> {
|
||||
#[derive(Debug, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq)]
|
||||
struct Node {
|
||||
category: category::V,
|
||||
children: BTreeMap<category::K, Node>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct TemplateContext {
|
||||
categories: Vec<(category::K, category::V)>,
|
||||
categories: BTreeMap<category::K, Node>,
|
||||
}
|
||||
|
||||
let categories_tree = db.open_tree(category::NAME)?;
|
||||
let mut categories = category::get_all(&categories_tree)?;
|
||||
|
||||
// filter archived categories
|
||||
categories.retain(|_, category| !category.deleted);
|
||||
|
||||
// collect the top-level categories (those without a parent)
|
||||
let mut top_level_nodes: BTreeMap<category::K, Node> = categories
|
||||
.iter()
|
||||
.filter(|(_, c)| c.parent.is_none())
|
||||
.map(|(&id, category)| {
|
||||
let node = Node {
|
||||
category: category.clone(),
|
||||
children: Default::default(),
|
||||
};
|
||||
(id, node)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// remove top-level categories from the list
|
||||
for id in top_level_nodes.keys() {
|
||||
categories.remove(id);
|
||||
}
|
||||
|
||||
/// populate `node.children with entries from `remaining`
|
||||
fn populate_node(
|
||||
node_id: category::K,
|
||||
node: &mut Node,
|
||||
remaining: &mut HashMap<category::K, category::V>,
|
||||
) {
|
||||
// make a list of the nodes children
|
||||
let mut new_children = vec![];
|
||||
for (&id, category) in remaining.iter() {
|
||||
if category.parent == Some(node_id) {
|
||||
new_children.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
// move the children from `remaining` to `node.children`
|
||||
for &id in &new_children {
|
||||
let child_node = Node {
|
||||
category: remaining.remove(&id).unwrap(),
|
||||
children: Default::default(),
|
||||
};
|
||||
node.children.insert(id, child_node);
|
||||
}
|
||||
|
||||
// recursively populate the childrens children
|
||||
for (child_id, child) in node.children.iter_mut() {
|
||||
populate_node(*child_id, child, remaining);
|
||||
}
|
||||
}
|
||||
|
||||
for (id, node) in top_level_nodes.iter_mut() {
|
||||
populate_node(*id, node, &mut categories);
|
||||
}
|
||||
|
||||
let context = TemplateContext {
|
||||
categories: categories_tree
|
||||
.iter()
|
||||
.map(|result| {
|
||||
result.map(|(k, v)| deserialize(&k).and_then(|k| deserialize(&v).map(|v| (k, v))))
|
||||
})
|
||||
.collect::<Result<Result<_, _>, _>>()??,
|
||||
categories: top_level_nodes,
|
||||
};
|
||||
|
||||
Ok(Template::render("index", &context))
|
||||
@ -49,7 +105,7 @@ pub fn session_edit(
|
||||
|
||||
let sessions_tree = db.open_tree(session::NAME)?;
|
||||
match sessions_tree.get(session_uuid_s)? {
|
||||
None => Err(Status::NotFound)?,
|
||||
None => Err(Status::NotFound.into()),
|
||||
Some(data) => {
|
||||
let context = SessionPageContext {
|
||||
session: deserialize(&data).unwrap(),
|
||||
|
||||
Reference in New Issue
Block a user