diff --git a/taskoo-cli/src/commands/delete.rs b/taskoo-cli/src/commands/delete.rs index 9fa6a49..6645a18 100644 --- a/taskoo-cli/src/commands/delete.rs +++ b/taskoo-cli/src/commands/delete.rs @@ -11,36 +11,7 @@ pub struct Delete; impl Delete { pub fn delete(delete_config: &Vec) -> Result { info!("Process delete command!"); - let mut task_ids: Vec = vec![]; - - if delete_config.len() == 1 { - if delete_config[0].contains("..") { - let ranged_selection = delete_config[0].split("..").collect::>(); - if ranged_selection.len() != 2 { - eprintln!("Invalid range provided {}", delete_config[0]); - } - let start = ranged_selection[0] - .parse::() - .expect("Can't find valid start from provided range"); - let end = ranged_selection[1] - .parse::() - .expect("Can't find valid end from provided range"); - task_ids = (start..=end).collect::>(); - } else { - task_ids.push(delete_config[0].parse().expect("Invalid task id provided")); - } - } else { - for item in delete_config.iter() { - task_ids.push(item.parse().expect("Invalid task id provided")); - } - } - - debug!("Running DeleteOperation with {:?}", task_ids); - let mut operation = DeleteOperation { - database_manager: None, - task_ids: task_ids, - result: None - }; + let mut operation = DeleteOperation::new(delete_config)?; execute(&mut operation)?; Ok(String::new()) diff --git a/taskoo-cli/src/commands/info.rs b/taskoo-cli/src/commands/info.rs index 2f92aac..133da01 100644 --- a/taskoo-cli/src/commands/info.rs +++ b/taskoo-cli/src/commands/info.rs @@ -5,6 +5,7 @@ use anyhow::Result; use taskoo_core::core::Operation; use taskoo_core::operation::{execute, Get as GetOp}; +use taskoo_core::command::{SimpleCommand, TagCommand}; use crate::error::ClientError; @@ -15,8 +16,18 @@ impl Info { Info } - pub fn run(&self, task_id: &u64, attribute: &Option) -> Result { + pub fn run( + &self, + task_id: &Option, + attribute: &Option, + ) -> Result { info!("Running info command"); + if task_id.is_none() && attribute.is_none() { + return Err(ClientError::MissingAttrError { + attr: String::from("None of task_id or attribute is provided"), + backtrace: Backtrace::capture(), + }); + } // let task_id = match matches.value_of("task_id") { // Some(raw_task_id) => raw_task_id.parse::().map_err(|_error| { // ClientError::ParseError(String::from(raw_task_id), String::from("i64")) @@ -29,33 +40,49 @@ impl Info { // } // }; - let id: i64 = if *task_id > std::i64::MAX as u64 { - return Err(ClientError::MissingAttrError { - attr: String::from(""), - backtrace: Backtrace::capture(), - }); - } else { - *task_id as i64 - }; - info!("Task id: {:?}", task_id); - let mut operation = GetOp::new(); - operation.task_id = Some(id); - execute(&mut operation)?; - - let tasks = &operation.get_result(); - if tasks.is_empty() { - return Err(ClientError::UnexpectedFailure( - String::from(format!("Unable to find task with id : {}", task_id)), - Backtrace::capture(), - )); - } + if let Some(id) = task_id { + if *id > std::i64::MAX as u64 { + return Err(ClientError::MissingAttrError { + attr: String::from("Provided task_id is greater than i64::MAX"), + backtrace: Backtrace::capture(), + }); + } + + let real_id = *id as i64; + info!("Task id: {:?}", real_id); + let mut operation = GetOp::new(); + operation.task_id = Some(real_id); + execute(&mut operation)?; - assert_eq!(tasks.len(), 1); + let tasks = &operation.get_result(); + if tasks.is_empty() { + return Err(ClientError::UnexpectedFailure( + String::from(format!("Unable to find task with id : {}", real_id)), + Backtrace::capture(), + )); + } + + assert_eq!(tasks.len(), 1); + + if let Some(attr) = attribute { + println!("{}", tasks[0].get_property_value(attr)?); + } else { + println!("{:?}", tasks[0]); + } + return Ok(String::new()); + } if let Some(attr) = attribute { - println!("{}", tasks[0].get_property_value(attr)?); - } else { - println!("{:?}", tasks[0]); + match attr.as_str() { + "tag" => { + let mut tag_command = TagCommand::new()?; + let tags = tag_command.get_all()?; + println!("{:?}", tags); + } + _ => { + // Should crash + } + } } Ok(String::new()) } diff --git a/taskoo-cli/src/main.rs b/taskoo-cli/src/main.rs index 766dfe0..26e8855 100644 --- a/taskoo-cli/src/main.rs +++ b/taskoo-cli/src/main.rs @@ -54,6 +54,12 @@ fn handle_result(result: Result) { } } +#[derive(Debug)] +struct InfoCommand { + task_id: Option, + attribute: Option, +} + // Note: this requires the `derive` feature use clap::Parser; #[derive(Parser)] @@ -104,14 +110,9 @@ enum Commands { end_day: Option, }, /// Show information about the given task - Info { - task_id: u64, - attribute: Option, - }, + Info { input: String }, /// Clean context, tag or state - Clean { - provided_type: String - }, + Clean { provided_type: String }, /// Change the state of the given tasks to 'start' Start { task_ids: Vec }, /// Change the state of the given tasks to 'complete' @@ -159,18 +160,26 @@ fn main() -> Result<(), ClientError> { .agenda(&start_day, &end_day) .context("agenda command failed to operate"), ), - Commands::Info { task_id, attribute } => { + Commands::Info { input } => { + let mut info_command = InfoCommand { + task_id: None, + attribute: None, + }; + + // Try to parse the input as a task_id (u64), otherwise treat it as an attribute + if let Ok(task_id) = input.parse::() { + info_command.task_id = Some(task_id); + } else { + info_command.attribute = Some(input.clone()); + } let info = Info::new(); handle_result( - info.run(task_id, attribute) + info.run(&info_command.task_id, &info_command.attribute) .context("info command failed to operate"), ); - }, + } Commands::Clean { provided_type } => { - handle_result( - Clean::run(provided_type) - .context("clean command failed to operate"), - ); + handle_result(Clean::run(provided_type).context("clean command failed to operate")); } Commands::Start { task_ids } => handle_result( StateChanger::to_started() diff --git a/taskoo-core/src/command.rs b/taskoo-core/src/command.rs index e826d40..83562a0 100644 --- a/taskoo-core/src/command.rs +++ b/taskoo-core/src/command.rs @@ -215,6 +215,7 @@ impl<'a> SimpleCommand<'a> for TagCommand<'a> { } fn delete(&mut self, names: Vec) -> Result<(), CoreError> { + println!("got here with names {:?}", names); let tx = match self.db_manager.as_mut() { Some(manager) => manager.conn.transaction()?, None => match self.db_manager_for_test.as_mut() { diff --git a/taskoo-core/src/operation/agenda.rs b/taskoo-core/src/operation/agenda.rs index 485fc2c..95667c0 100644 --- a/taskoo-core/src/operation/agenda.rs +++ b/taskoo-core/src/operation/agenda.rs @@ -4,8 +4,8 @@ use crate::db::task_helper::Task; use crate::db::task_manager::TaskManager; use crate::error::*; -/* Some of the view functionalities are overlap with list, however, - * view should provide better API for clients */ +/* Some of the Agenda functionalities are overlap with list, however, + * Agenda should provide better API for clients */ pub struct Agenda { pub start_day: String, pub end_day: Option, diff --git a/taskoo-core/src/operation/delete.rs b/taskoo-core/src/operation/delete.rs index de64ff2..138a6ac 100644 --- a/taskoo-core/src/operation/delete.rs +++ b/taskoo-core/src/operation/delete.rs @@ -1,6 +1,7 @@ use crate::core::{ConfigManager, Operation}; use crate::db::task_helper::Task; use crate::db::task_manager::TaskManager; +use crate::option_parser::parse_command_option; use crate::error::*; pub struct DeleteOperation { @@ -9,6 +10,24 @@ pub struct DeleteOperation { pub result: Option>, } +impl DeleteOperation { + pub fn new(input_str: &Vec) -> Result { + let option = parse_command_option( + &input_str.iter().map(|s| &**s).collect(), + false, + false, + true, + ) + .unwrap(); + + Ok(DeleteOperation { + task_ids: option.task_ids, + database_manager: None, + result: None, + }) + } +} + impl Operation for DeleteOperation { fn init(&mut self) -> Result<(), InitialError> { self.database_manager = Some(TaskManager::new( @@ -21,6 +40,7 @@ impl Operation for DeleteOperation { } fn set_result(&mut self, _result: Vec) {} fn get_result(&mut self) -> &Vec { + // TODO: Store the deleted task ids return &self.result.as_ref().unwrap(); } } diff --git a/taskoo-core/src/wasm/exports.rs b/taskoo-core/src/wasm/exports.rs index ce606f0..1e7f88d 100644 --- a/taskoo-core/src/wasm/exports.rs +++ b/taskoo-core/src/wasm/exports.rs @@ -75,17 +75,25 @@ pub unsafe fn list(ptr: *mut u8, len: usize) -> *mut c_char { let data = read_data_from_js(ptr, len); let mut operations = operation::Get::new2(&data).expect("Failed to create the get operation"); - let mut ret: Vec<(String, String)> = vec![]; + let mut ret: Vec<(String, &Vec)> = vec![]; for operation_tuple in operations.iter_mut() { let serded_string: String = match operation::execute(&mut operation_tuple.1) { - Ok(_) => serde_json::to_string(&operation_tuple.1.get_result()).unwrap(), - Err(e) => e.to_string(), + Ok(_) => { + println!("got ok here"); + serde_json::to_string(&operation_tuple.1.get_result()).unwrap() + } + Err(e) => { + println!("got err here"); + e.to_string() + } }; - ret.push((operation_tuple.0.to_owned(), serded_string)); + println!("serded_string {} ", serded_string); + ret.push((operation_tuple.0.to_owned(), operation_tuple.1.get_result())); } let serded_ret: String = serde_json::to_string(&ret).unwrap(); + println!("serded_ret {} ", serded_ret); unsafe { LENGTH = serded_ret.len() } let s = CString::new(serded_ret).unwrap(); return s.into_raw(); @@ -113,6 +121,7 @@ pub unsafe fn agenda(ptr: *mut u8, len: usize) -> *mut c_char { Err(e) => e.to_string(), }; + println!("serded_ret for agenda {} ", serded_string); unsafe { LENGTH = serded_string.len() } let s = CString::new(serded_string).unwrap(); return s.into_raw(); @@ -134,3 +143,23 @@ pub unsafe fn state_change(ptr: *mut u8, len: usize) -> *mut c_char { let s = CString::new(serded_string).unwrap(); return s.into_raw(); } + +// Delete Operation +#[no_mangle] +pub unsafe fn delete(ptr: *mut u8, len: usize) { + println!("delete in wasm"); + let data = read_data_from_js(ptr, len); + let mut operation = + operation::DeleteOperation::new(&data).expect("Failed to create the DeleteOperation"); + operation::execute(&mut operation).expect("Failed to execute the operation"); + + // The following doesn't work because taskoo-core doesn't store the delete task ids + + // let deleted_tasks = &operation.get_result(); + // let serded_ret: String = serde_json::to_string(&deleted_tasks).unwrap(); + // println!("serded_ret {} for delete", serded_ret); + // unsafe { LENGTH = serded_ret.len() } + // let s = CString::new(serded_ret).unwrap(); + // Return the delete tasks back to clients + // return s.into_raw(); +} diff --git a/taskoo-web/server/index.mjs b/taskoo-web/server/index.mjs index 59e5c99..6265853 100644 --- a/taskoo-web/server/index.mjs +++ b/taskoo-web/server/index.mjs @@ -103,6 +103,16 @@ export class Endpoints { instance.exports.add(allocated.ptr, allocated.bytes.length); } + static Delete(input) { + const allocated = allocateInput(input); + const offset = instance.exports.delete(allocated.ptr, allocated.bytes.length); + const len = instance.exports.get_shared_buffer_size(); + const buffer = new Uint8Array(instance.exports.memory.buffer, offset, len); + const data = new TextDecoder().decode(buffer); + instance.exports.free_shared_buffer(offset); + return data; + } + static StateChange(input) { const allocated = allocateInput(input); diff --git a/taskoo-web/server/server.js b/taskoo-web/server/server.js index f42fda7..892872b 100644 --- a/taskoo-web/server/server.js +++ b/taskoo-web/server/server.js @@ -8,6 +8,11 @@ const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cors()); +app.use((req, res, next) => { + res.header('Access-Control-Allow-Origin', '*'); // Allow from any origin + res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); + next(); +}); const ENDPOINTS = {}; const server = app.listen(7001, () => { @@ -20,12 +25,17 @@ app.get('/today', (req, res) => { }); app.post('/list', (req, res) => { + console.log("Taskoo server: list endpoint"); const data = Endpoints.List(req.body.data); + console.log("Taskoo server: list endpoint, got data"); + console.log(data); let ret; try { ret = JSON.parse(data); + console.log("parsed success"); } catch(e) { ret = {"error": data}; + console.log("parsed failed"); } res.send(ret); }); @@ -33,6 +43,7 @@ app.post('/list', (req, res) => { app.post('/agenda', (req, res) => { console.log("Taskoo server: agenda endpoint"); const data = Endpoints.Agenda(req.body.data); + console.log(data); let ret; try { ret = JSON.parse(data); @@ -61,3 +72,8 @@ app.post('/state_change', createPost, (req, res) => { console.log("state_change endpoint"); Endpoints.StateChange(req.body.data); }); + +app.post('/delete', createPost, (req, res) => { + console.log("delete endpoint"); + Endpoints.Delete(req.body.data); +}); diff --git a/taskoo-web/server/taskoo_core.wasm b/taskoo-web/server/taskoo_core.wasm index 07f3144..21efadc 100755 Binary files a/taskoo-web/server/taskoo_core.wasm and b/taskoo-web/server/taskoo_core.wasm differ diff --git a/taskoo-web/webpack-ver/dist/index.html b/taskoo-web/webpack-ver/dist/index.html index 6b4f1cd..01ffd81 100644 --- a/taskoo-web/webpack-ver/dist/index.html +++ b/taskoo-web/webpack-ver/dist/index.html @@ -1,30 +1,60 @@ - + - - + + + Taskoo - Managing Todo List -
- + -
-
+
+ Taskoo +
+ +
+
+ +
+
+
+
+ + + + +
+
+ +
+ + + + +
+ +
-
-
- -
-
- -
+
+ + + + + + + + + + +
IdBody
-