From 588ca2c47f076176e64e373fe92e9c7350ab0dd2 Mon Sep 17 00:00:00 2001 From: suri-codes Date: Tue, 14 Apr 2026 09:31:43 -0700 Subject: [PATCH] feat: Task creation --- crates/dto/src/entity/task.rs | 2 +- crates/dto/src/entity/zettel.rs | 2 +- src/cli/process.rs | 67 ++------------------ src/tui/components/todo/explorer.rs | 2 +- src/tui/components/todo/mod.rs | 15 ++++- src/tui/signal.rs | 8 ++- src/types/kasten/todo_tree.rs | 2 - src/types/task.rs | 95 ++++++++++++++++++++++++++--- 8 files changed, 113 insertions(+), 80 deletions(-) diff --git a/crates/dto/src/entity/task.rs b/crates/dto/src/entity/task.rs index f6922be..45d7ef5 100644 --- a/crates/dto/src/entity/task.rs +++ b/crates/dto/src/entity/task.rs @@ -2,8 +2,8 @@ use migration::prelude::Local; use migration::types::*; -use sea_orm::entity::prelude::*; use sea_orm::ActiveValue::Set; +use sea_orm::entity::prelude::*; use std::future::ready; use std::pin::Pin; diff --git a/crates/dto/src/entity/zettel.rs b/crates/dto/src/entity/zettel.rs index f02d968..0cc494d 100644 --- a/crates/dto/src/entity/zettel.rs +++ b/crates/dto/src/entity/zettel.rs @@ -1,8 +1,8 @@ //! `SeaORM` Entity, @generated by sea-orm-codegen 2.0 use migration::{prelude::Local, types::*}; -use sea_orm::entity::prelude::*; use sea_orm::ActiveValue::Set; +use sea_orm::entity::prelude::*; use std::{future::ready, pin::Pin}; #[sea_orm::model] diff --git a/src/cli/process.rs b/src/cli/process.rs index d2fedb2..6d34212 100644 --- a/src/cli/process.rs +++ b/src/cli/process.rs @@ -4,11 +4,7 @@ use std::{ io::Write, }; -use color_eyre::eyre::{Context, Result, eyre}; -use dto::{ - Date, DateTime, GroupEntity, HasOne, IntoActiveModel, TagEntity, TaskActiveModel, TaskEntity, - Time, ZettelEntity, -}; +use color_eyre::eyre::{Context, Result}; use tower_lsp::{LspService, Server}; use crate::{ @@ -19,7 +15,6 @@ use crate::{ }; impl Commands { - #[expect(clippy::too_many_lines)] pub async fn process(self) -> Result<()> { match self { Self::Init { name } => { @@ -86,63 +81,9 @@ impl Commands { println!("created group {group:#?}"); } super::TodoSubcommand::Task { name, parent_id } => { - // need to create the task - let parent = GroupEntity::load() - .with(TagEntity) - .filter_by_nano_id(parent_id) - .one(&kt.db) - .await - .with_context(|| "failed to communicate with db")? - .ok_or_else(|| eyre!("could not find the group"))?; - - let HasOne::Loaded(tag) = parent.tag else { - panic!("this has to be loaded since we just loaded it right above") - }; - - let zettel = - Zettel::new(name.clone(), &mut kt, vec![(*tag).into()]).await?; - - let inserted = TaskActiveModel::builder() - .set_name(name) - .set_group_id(parent.nano_id.clone()) - .set_priority(Priority::default()) - .set_zettel( - ZettelEntity::load() - .filter_by_nano_id(zettel.id) - .one(&kt.db) - .await? - .expect("Zettel must exist since we just created it") - .into_active_model(), - ) - .set_due(Some(DateTime::new( - Date::from_ymd_opt(2026, 1, 31).unwrap(), - Time::from_hms_opt(10, 10, 10).unwrap(), - ))) - .insert(&kt.db) - .await?; - - let group = GroupEntity::load() - .with(TagEntity) - .with((ZettelEntity, TagEntity)) - .filter_by_nano_id(parent.nano_id) - .one(&kt.db) - .await? - .expect("We just inserted it"); - - let mut task = TaskEntity::load() - .with((ZettelEntity, TagEntity)) - .filter_by_nano_id(inserted.nano_id) - .one(&kt.db) - .await? - .expect("We just inserted it"); - - task.group = HasOne::Loaded(Box::new(group)); - - println!("task: {task:#?}"); - - let task: Task = task.into(); - - println!("created task: {task:#?}"); + let task = + Task::new(name, parent_id, &mut kt, None, Priority::default()).await?; + println!("created task {task:#?}"); } } } diff --git a/src/tui/components/todo/explorer.rs b/src/tui/components/todo/explorer.rs index ff34edc..2314740 100644 --- a/src/tui/components/todo/explorer.rs +++ b/src/tui/components/todo/explorer.rs @@ -3,7 +3,7 @@ use ratatui::{ text::{Line, Span, Text}, widgets::{Block, BorderType, Borders, List, ListState}, }; -use tracing::{debug, info}; +use tracing::debug; use tree::NodeId; use crate::types::{TodoNode, TodoNodeKind, TodoTree}; diff --git a/src/tui/components/todo/mod.rs b/src/tui/components/todo/mod.rs index be1d82a..b65208d 100644 --- a/src/tui/components/todo/mod.rs +++ b/src/tui/components/todo/mod.rs @@ -8,7 +8,7 @@ use ratatui::{ use serde::{Deserialize, Serialize}; use strum::{Display, EnumIter}; use tokio::sync::mpsc::UnboundedSender; -use tracing::{debug, info}; +use tracing::debug; use crate::{ tui::{Page, Signal, components::Component}, @@ -317,7 +317,18 @@ impl Component for Todo<'_> { self.update_inspector_from_selection().await; } - Signal::NewGroup => { + Signal::NewTask => { + if self.active != TodoRegion::Explorer { + return Ok(None); + } + + debug!("Creating Task!"); + let _kt = self.kh.write().await; + todo!(); + // let task = Task::new("wahoo", ); + } + + Signal::NewSubGroup => { if self.active != TodoRegion::Explorer { return Ok(None); } diff --git a/src/tui/signal.rs b/src/tui/signal.rs index 9b0facc..c2d86c7 100644 --- a/src/tui/signal.rs +++ b/src/tui/signal.rs @@ -56,9 +56,15 @@ pub enum Signal { zid: ZettelId, }, - /// Create a new `Group` + /// Create a new `Group` inside the currently selected group + NewSubGroup, + + /// Create a new `Group` in the current scope NewGroup, + /// Create a new `Task` + NewTask, + /// this is fucking temporary Helix { path: PathBuf, diff --git a/src/types/kasten/todo_tree.rs b/src/types/kasten/todo_tree.rs index 09a4652..858b02d 100644 --- a/src/types/kasten/todo_tree.rs +++ b/src/types/kasten/todo_tree.rs @@ -71,8 +71,6 @@ impl TodoTree { Ok(todo_tree) } - - #[async_recursion::async_recursion] async fn add_group_to_tree( &mut self, diff --git a/src/types/task.rs b/src/types/task.rs index 1f910c6..4876813 100644 --- a/src/types/task.rs +++ b/src/types/task.rs @@ -1,12 +1,16 @@ -use dto::{ DateTime, NanoId, TaskModelEx}; +use color_eyre::eyre::{Context, Result, eyre}; +use dto::{ + Date, DateTime, GroupEntity, HasOne, IntoActiveModel as _, NanoId, TagEntity, TaskActiveModel, + TaskEntity, TaskModelEx, Time, ZettelEntity, +}; -use crate::types::{Group, Priority, Zettel, frontmatter}; +use crate::types::{Group, Kasten, Priority, Zettel, frontmatter}; /// a `Task` that you have to complete! #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Task { /// Should only be constructed from models. - _private:(), + _private: (), pub id: NanoId, pub name: String, @@ -22,18 +26,92 @@ pub struct Task { } impl Task { + #[allow(clippy::unused_async)] + #[allow(clippy::needless_pass_by_ref_mut)] + pub async fn new( + name: impl Into, + parent_id: NanoId, + kt: &mut Kasten, + due: Option, + priority: Priority, + ) -> Result { + let name = name.into(); + + let parent = GroupEntity::load() + .with(TagEntity) + .filter_by_nano_id(parent_id) + .one(&kt.db) + .await + .with_context(|| "failed to communicate with db")? + .ok_or_else(|| eyre!("could not find the group"))?; + + let HasOne::Loaded(tag) = parent.tag else { + panic!("this has to be loaded since we just loaded it right above") + }; + + let zettel = Zettel::new(name.clone(), kt, vec![(*tag).into()]).await?; + + let inserted = TaskActiveModel::builder() + .set_name(name) + .set_group_id(parent.nano_id.clone()) + .set_priority(priority) + .set_zettel( + ZettelEntity::load() + .filter_by_nano_id(zettel.id) + .one(&kt.db) + .await? + .expect("Zettel must exist since we just created it") + .into_active_model(), + ) + .set_due(due) + // .set_due(Some(DateTime::new( + // Date::from_ymd_opt(2026, 1, 31).unwrap(), + // Time::from_hms_opt(10, 10, 10).unwrap(), + // ))) + .insert(&kt.db) + .await?; + + let group = GroupEntity::load() + .with(TagEntity) + .with((ZettelEntity, TagEntity)) + .filter_by_nano_id(parent.nano_id) + .one(&kt.db) + .await? + .expect("We just inserted it"); + + let mut task = TaskEntity::load() + .with((ZettelEntity, TagEntity)) + .filter_by_nano_id(inserted.nano_id) + .one(&kt.db) + .await? + .expect("We just inserted it"); + + task.group = HasOne::Loaded(Box::new(group)); + + println!("task: {task:#?}"); + + // Ok(task.into()) + + todo!() + } + pub fn due(&self) -> Option { - self.due.map(|due|due.format(frontmatter::DATE_FMT_STR).to_string()) + self.due + .map(|due| due.format(frontmatter::DATE_FMT_STR).to_string()) } pub fn finished_at(&self) -> Option { - self.finished_at. - map(|finished_at|finished_at.format(frontmatter::DATE_FMT_STR).to_string()) + self.finished_at + .map(|finished_at| finished_at.format(frontmatter::DATE_FMT_STR).to_string()) } pub fn created_at(&self) -> String { - self.created_at.format(frontmatter::DATE_FMT_STR).to_string() + self.created_at + .format(frontmatter::DATE_FMT_STR) + .to_string() } pub fn modified_at(&self) -> String { - self.modified_at.format(frontmatter::DATE_FMT_STR).to_string() + self.modified_at + .format(frontmatter::DATE_FMT_STR) + .to_string() } } @@ -63,7 +141,6 @@ impl From for Task { "When fetching a Task from the database, we expect to always have the Group loaded!!", ) .into(), - } } } -- 2.51.2