diff --git a/.gitignore b/.gitignore index 2fafa98..a547bf3 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,3 @@ dist-ssr *.njsproj *.sln *.sw? - -# Fuckin tauri man -stupid_env.txt diff --git a/src-tauri/src/db.rs b/src-tauri/src/db.rs index b27e2c5..3d94b6c 100644 --- a/src-tauri/src/db.rs +++ b/src-tauri/src/db.rs @@ -458,6 +458,20 @@ pub mod ops { } } + #[tauri::command(rename_all = "snake_case")] + pub fn edit_task_or_group(table: &str, name: &str, id: u64) { + let db = DB_SINGLETON.lock().unwrap(); + + if let Some(conn) = &db.db_conn { + let command = format!("UPDATE {table} SET name=(?1) WHERE id=(?2)"); + + match conn.execute(&command, params![name, id]) { + Ok(_) => (), + Err(err) => println!("[ERROR] Could not update task: {}", err.to_string()), + } + } + } + /* ----------------------------------------------------------------------------- */ /* -------------------------------HELPER FUNCTIONS------------------------------ */ /* ----------------------------------------------------------------------------- */ diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 0df8c85..5f7939d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -26,6 +26,7 @@ fn main() { ops::commands::add_task_group, ops::commands::delete_task, ops::commands::delete_task_group, + ops::commands::edit_task_or_group, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src/App.css b/src/App.css index 6e5ac6e..1b17390 100644 --- a/src/App.css +++ b/src/App.css @@ -487,6 +487,26 @@ form .form-group select { user-select: none; } +.edit-area { + height: 25px; + width: 100%; + align-items: center; +} + +.edit-task-inp { + height: inherit; + width: inherit; + background: transparent; + border: none; + font-size: 20px; + color: white; + font-family: Inter; + caret-color: white; + outline: none; + animation: phase-caret 1s ease-in-out infinite; + overflow: visible; +} + /* ---------- */ /* Task Group */ /* ---------- */ @@ -695,7 +715,7 @@ form .form-group select { } .featured-day-name { - margin-top: 10px; + margin-top: 10px; font-size: 20px; text-align: center; color: wheat; diff --git a/src/Constants.jsx b/src/Constants.jsx index 4f036fa..5c21d2c 100644 --- a/src/Constants.jsx +++ b/src/Constants.jsx @@ -15,6 +15,7 @@ const TAURI_ADD_TASK = "add_task"; const TAURI_ADD_TASKGROUP = "add_task_group"; const TAURI_DELETE_TASK = "delete_task"; const TAURI_DELETE_GROUP = "delete_task_group"; +const TAURI_EDIT_TASK_OR_GROUP = "edit_task_or_group"; export { // Table names @@ -34,4 +35,5 @@ export { TAURI_ADD_TASKGROUP, TAURI_DELETE_TASK, TAURI_DELETE_GROUP, + TAURI_EDIT_TASK_OR_GROUP, }; diff --git a/src/utility/AddRemoveItems.jsx b/src/utility/AddRemoveUpdateItems.jsx similarity index 78% rename from src/utility/AddRemoveItems.jsx rename to src/utility/AddRemoveUpdateItems.jsx index 6701018..d6c727c 100644 --- a/src/utility/AddRemoveItems.jsx +++ b/src/utility/AddRemoveUpdateItems.jsx @@ -24,7 +24,7 @@ const removeItem = (id, node) => { return child.id !== id; }); - node.children.sort(tasksFirstGroupsNext) + node.children.sort(tasksFirstGroupsNext); // If item not found in node.children, search and remove it from each child of node.children. node.children.forEach((child) => removeItem(id, child)); } @@ -40,4 +40,14 @@ function tasksFirstGroupsNext(child1, child2) { } } -export { addItem, removeItem }; +const updateItem = (id, name, node) => { + if (node.id === id) { + console.log("previous name: " + node.name); + node.name = name; + console.log("updated name: " + node.name); + } else if (node.children) { + node.children.forEach((child) => updateItem(id, name, child)); + } +}; + +export { addItem, removeItem, updateItem }; diff --git a/src/views/TasksView/DragDropContext.jsx b/src/views/TasksView/DragDropContext.jsx index 0182c1b..fb175d6 100644 --- a/src/views/TasksView/DragDropContext.jsx +++ b/src/views/TasksView/DragDropContext.jsx @@ -1,6 +1,6 @@ import React, { createContext, useEffect, useState } from "react"; -import { addItem, removeItem } from "../../utility/AddRemoveItems"; +import { addItem, removeItem } from "../../utility/AddRemoveUpdateItems"; import { TASKS_VIEW } from "../../Constants"; const DragDropContext = createContext(); diff --git a/src/views/TasksView/Task.jsx b/src/views/TasksView/Task.jsx index f74645d..66040b3 100644 --- a/src/views/TasksView/Task.jsx +++ b/src/views/TasksView/Task.jsx @@ -1,63 +1,145 @@ -import React from "react"; -import { useContext } from "react"; +import React, { useState, useEffect, useContext } from "react"; import { invoke } from "@tauri-apps/api"; // Icon Imports import DeleteIcon from "@mui/icons-material/Delete"; import EditIcon from "@mui/icons-material/Edit"; +import CheckIcon from "@mui/icons-material/Check"; // Local Resources import { DragDropContext } from "./DragDropContext"; -import { TASK, TASKS_VIEW, TAURI_DELETE_TASK, TODAY } from "../../Constants"; -import { removeItem } from "../../utility/AddRemoveItems"; +import { + TASK, + TASKS_VIEW, + TODAY, + TAURI_DELETE_TASK, + TAURI_EDIT_TASK_OR_GROUP, +} from "../../Constants"; +import { removeItem, updateItem } from "../../utility/AddRemoveUpdateItems"; const Task = (props) => { // Adds ID of dragged task to DragEvent datastore and changes state of the DragDropContext. const { handleOnDrag } = useContext(DragDropContext); + const [editingTaskId, setEditingTaskId] = useState(null); + const [editedName, setEditedName] = useState(null); + + useEffect(() => { + if (editingTaskId) { + window.addEventListener('keydown', handleKeyDown); + } else { + window.removeEventListener('keydown', handleKeyDown); + } + + return () => { + window.removeEventListener('keydown', handleKeyDown); + } + }, [editingTaskId]); + const handleDelete = (e) => { e.preventDefault(); + // Delete task from the database. invoke(TAURI_DELETE_TASK, { table: TODAY, id: props.id, }); + // Delete task from the frontend. let storedView = JSON.parse(sessionStorage.getItem(TASKS_VIEW)); - removeItem(props.id, storedView); - sessionStorage.setItem(TASKS_VIEW, JSON.stringify(storedView)); - props.onDelete(); + props.onChangeTasksView(); }; + function handleEdit() { + if (editingTaskId) { + setEditingTaskId(null); + } else { + setEditingTaskId(props.id); + } + } + + function onChange(e) { + setEditedName(e.target.value); + } + + function handleConfirmEdit() { + // Update name in the database. + invoke(TAURI_EDIT_TASK_OR_GROUP, { + table: TODAY, + name: editedName, + id: props.id, + }); + + // Update name on the frontend. + const storedView = JSON.parse(sessionStorage.getItem(TASKS_VIEW)); + updateItem(props.id, editedName, storedView); + sessionStorage.setItem(TASKS_VIEW, JSON.stringify(storedView)); + + setEditingTaskId(null); + props.onChangeTasksView(); + } + + const handleKeyDown = (e) => { + if (e.key === 'Escape') { + cancelEdit(); + } + } + + function cancelEdit() { + setEditedName(null); + setEditingTaskId(null); + } + return (
loading...