Add session edit page
This commit is contained in:
@ -44,6 +44,8 @@ fn main() -> io::Result<()> {
|
||||
rocket::routes![
|
||||
routes::pages::index,
|
||||
routes::pages::history,
|
||||
routes::pages::session_edit,
|
||||
routes::api::edit_session,
|
||||
routes::api::create_category,
|
||||
routes::api::start_session,
|
||||
routes::api::end_session,
|
||||
|
||||
@ -2,13 +2,14 @@ use crate::database::latest::trees::{categories, past_sessions};
|
||||
use crate::routes::pages;
|
||||
use crate::status_json::StatusJson;
|
||||
use bincode::{deserialize, serialize};
|
||||
use chrono::NaiveDateTime;
|
||||
use chrono::{Duration, Utc};
|
||||
use rocket::http::Status;
|
||||
use rocket::request::{Form, FromForm};
|
||||
use rocket::response::Redirect;
|
||||
use rocket::{post, uri, State};
|
||||
use rocket_contrib::uuid::Uuid;
|
||||
use sled::Transactional;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(FromForm)]
|
||||
pub struct NewCategory {
|
||||
@ -25,7 +26,7 @@ pub fn create_category(
|
||||
|
||||
let categories_tree = db.open_tree(categories::NAME)?;
|
||||
categories_tree.insert(
|
||||
serialize(&Uuid::new_v4())?,
|
||||
serialize(&uuid::Uuid::new_v4())?,
|
||||
serialize(&categories::V {
|
||||
name: category.name,
|
||||
color: category.color,
|
||||
@ -38,29 +39,25 @@ pub fn create_category(
|
||||
|
||||
#[post("/category/<category_uuid>/start_session")]
|
||||
pub fn start_session(
|
||||
category_uuid: String,
|
||||
category_uuid: Uuid,
|
||||
db: State<'_, sled::Db>,
|
||||
) -> Result<StatusJson, StatusJson> {
|
||||
toggle_category_session(category_uuid, true, db)
|
||||
}
|
||||
|
||||
#[post("/category/<category_uuid>/end_session")]
|
||||
pub fn end_session(
|
||||
category_uuid: String,
|
||||
db: State<'_, sled::Db>,
|
||||
) -> Result<StatusJson, StatusJson> {
|
||||
pub fn end_session(category_uuid: Uuid, db: State<'_, sled::Db>) -> Result<StatusJson, StatusJson> {
|
||||
toggle_category_session(category_uuid, false, db)
|
||||
}
|
||||
|
||||
#[post("/category/<category_uuid>/bump_session/minutes/<minutes>")]
|
||||
pub fn bump_session(
|
||||
category_uuid: String,
|
||||
category_uuid: Uuid,
|
||||
minutes: i64,
|
||||
db: State<'_, sled::Db>,
|
||||
) -> Result<Redirect, StatusJson> {
|
||||
let duration = Duration::minutes(minutes);
|
||||
let category_uuid = Uuid::parse_str(&category_uuid)?;
|
||||
let category_uuid_s = sled::IVec::from(serialize(&category_uuid)?);
|
||||
let category_uuid_s = sled::IVec::from(serialize(&category_uuid.into_inner())?);
|
||||
|
||||
let categories_tree = db.open_tree(categories::NAME)?;
|
||||
|
||||
@ -75,7 +72,12 @@ pub fn bump_session(
|
||||
tx_categories.insert(&category_uuid_s, serialize(&category).unwrap())?;
|
||||
Ok(Ok(Redirect::to(uri!(pages::index))))
|
||||
}
|
||||
None => return Ok(Err(StatusJson::new(Status::BadRequest, "No active session"))),
|
||||
None => {
|
||||
return Ok(Err(StatusJson::new(
|
||||
Status::BadRequest,
|
||||
"No active session",
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,12 +85,11 @@ pub fn bump_session(
|
||||
}
|
||||
|
||||
pub fn toggle_category_session(
|
||||
category_uuid: String,
|
||||
category_uuid: Uuid,
|
||||
set_active: bool,
|
||||
db: State<'_, sled::Db>,
|
||||
) -> Result<StatusJson, StatusJson> {
|
||||
let category_uuid = Uuid::parse_str(&category_uuid)?;
|
||||
let category_uuid_s = sled::IVec::from(serialize(&category_uuid)?);
|
||||
let category_uuid_s = sled::IVec::from(serialize(&category_uuid.into_inner())?);
|
||||
|
||||
let categories_tree = db.open_tree(categories::NAME)?;
|
||||
let past_sessions_tree = db.open_tree(past_sessions::NAME)?;
|
||||
@ -106,9 +107,9 @@ pub fn toggle_category_session(
|
||||
// only save sessions longer than 5 minutes
|
||||
let duration = now - started;
|
||||
if duration > Duration::minutes(5) {
|
||||
let session_uuid = serialize(&Uuid::new_v4()).unwrap();
|
||||
let session_uuid = serialize(&uuid::Uuid::new_v4()).unwrap();
|
||||
let past_session = past_sessions::V {
|
||||
category: category_uuid,
|
||||
category: category_uuid.into_inner(),
|
||||
started,
|
||||
ended: now,
|
||||
};
|
||||
@ -134,13 +135,47 @@ pub fn toggle_category_session(
|
||||
)??)
|
||||
}
|
||||
|
||||
#[post("/session/<session_uuid>/delete")]
|
||||
pub fn delete_session(
|
||||
session_uuid: String,
|
||||
#[derive(Debug, FromForm)]
|
||||
pub struct EditSession {
|
||||
category: Uuid,
|
||||
started: String,
|
||||
ended: String,
|
||||
}
|
||||
|
||||
#[post("/session/<session_uuid>/edit", data = "<session>")]
|
||||
pub fn edit_session(
|
||||
session_uuid: Uuid,
|
||||
session: Form<EditSession>,
|
||||
db: State<'_, sled::Db>,
|
||||
) -> Result<Redirect, StatusJson> {
|
||||
let session_uuid = Uuid::parse_str(&session_uuid)?;
|
||||
let session_uuid_s = sled::IVec::from(serialize(&session_uuid)?);
|
||||
let session_uuid_s = sled::IVec::from(serialize(&session_uuid.into_inner())?);
|
||||
|
||||
dbg!(&session);
|
||||
|
||||
let session = past_sessions::V {
|
||||
category: session.category.into_inner(),
|
||||
started: NaiveDateTime::parse_from_str(&session.started, "%Y-%m-%d %H:%M")?,
|
||||
ended: NaiveDateTime::parse_from_str(&session.ended, "%Y-%m-%d %H:%M")?,
|
||||
};
|
||||
|
||||
if session.started >= session.ended {
|
||||
return Err(StatusJson::new(
|
||||
Status::BadRequest,
|
||||
"started must be earlier than ended",
|
||||
));
|
||||
}
|
||||
|
||||
db.open_tree(past_sessions::NAME)?
|
||||
.insert(session_uuid_s, serialize(&session)?)?;
|
||||
|
||||
// FIXME: Uuid does not implement FromUriParam for some reason... File an issue?
|
||||
//Ok(Redirect::to(uri!(pages::session_edit: session_uuid)))
|
||||
Ok(Redirect::to(format!("/session/{}/edit", session_uuid)))
|
||||
}
|
||||
|
||||
#[post("/session/<session_uuid>/delete")]
|
||||
pub fn delete_session(session_uuid: Uuid, db: State<'_, sled::Db>) -> Result<Redirect, StatusJson> {
|
||||
let session_uuid_s = sled::IVec::from(serialize(&session_uuid.into_inner())?);
|
||||
|
||||
let past_sessions_tree = db.open_tree(past_sessions::NAME)?;
|
||||
|
||||
|
||||
@ -1,18 +1,20 @@
|
||||
use crate::database::latest::trees::{categories, past_sessions};
|
||||
use crate::status_json::StatusJson;
|
||||
use bincode::deserialize;
|
||||
use bincode::serialize;
|
||||
use rocket::http::Status;
|
||||
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::time::Duration;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[get("/")]
|
||||
pub fn index(db: State<'_, sled::Db>) -> Result<Template, StatusJson> {
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct TemplateContext {
|
||||
categories: Vec<(Uuid, categories::V)>,
|
||||
categories: Vec<(uuid::Uuid, categories::V)>,
|
||||
}
|
||||
|
||||
let categories_tree = db.open_tree(categories::NAME)?;
|
||||
@ -29,13 +31,37 @@ pub fn index(db: State<'_, sled::Db>) -> Result<Template, StatusJson> {
|
||||
Ok(Template::render("index", &context))
|
||||
}
|
||||
|
||||
#[get("/session/<session_uuid>/edit")]
|
||||
pub fn session_edit(session_uuid: Uuid, db: State<'_, sled::Db>) -> Result<Template, StatusJson> {
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct SessionPageContext {
|
||||
session: past_sessions::V,
|
||||
session_id: uuid::Uuid,
|
||||
}
|
||||
|
||||
let session_uuid_s = sled::IVec::from(serialize(&session_uuid.into_inner())?);
|
||||
|
||||
let past_sessions_tree = db.open_tree(past_sessions::NAME)?;
|
||||
match past_sessions_tree.get(session_uuid_s)? {
|
||||
None => Err(Status::NotFound)?,
|
||||
Some(data) => {
|
||||
let context = SessionPageContext {
|
||||
session: deserialize(&data).unwrap(),
|
||||
session_id: session_uuid.into_inner(),
|
||||
};
|
||||
|
||||
Ok(Template::render("edit_session", &context))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/history")]
|
||||
pub fn history(db: State<'_, sled::Db>) -> Result<Template, StatusJson> {
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct HistoryEntryContext {
|
||||
category: categories::V,
|
||||
session: past_sessions::V,
|
||||
session_id: Uuid,
|
||||
session_id: uuid::Uuid,
|
||||
duration: Duration,
|
||||
}
|
||||
|
||||
|
||||
@ -67,6 +67,7 @@ impl<'r> Responder<'r> for StatusJson {
|
||||
[ Status::InternalServerError ] [ sled::transaction::TransactionError ];
|
||||
[ Status::InternalServerError ] [ bincode::Error ];
|
||||
[ Status::BadRequest ] [ uuid::Error ];
|
||||
[ Status::BadRequest ] [ chrono::ParseError ];
|
||||
)]
|
||||
impl From<T> for StatusJson {
|
||||
fn from(e: T) -> StatusJson {
|
||||
|
||||
Reference in New Issue
Block a user