Browse Source

feat: do not delete completed TODOs but rather mark them as done and preserve

master
parent
commit
58255b0393
  1. 6
      pages/index.html
  2. 2
      src/db/db.go
  3. 26
      src/db/todo.go
  4. 27
      src/server/api.go

6
pages/index.html

@ -59,7 +59,11 @@ document.addEventListener('DOMContentLoaded', async function() {
if (response.ok && todosJson != null) { if (response.ok && todosJson != null) {
let todosDiv = document.getElementById("todos"); let todosDiv = document.getElementById("todos");
todosJson.forEach((item) => { todosJson.forEach((item) => {
console.log(item); // Do not work with completed TODOs yet
if (item.isDone == true) {
return;
}
todos.push(item); todos.push(item);
let todoCompleteBtnID = "btn-complete-" + String(item.id); let todoCompleteBtnID = "btn-complete-" + String(item.id);

2
src/db/db.go

@ -61,6 +61,8 @@ func setUpTables(db *DB) error {
time_created_unix INTEGER, time_created_unix INTEGER,
due_unix INTEGER, due_unix INTEGER,
owner_username TEXT NOT NULL, owner_username TEXT NOT NULL,
is_done INTEGER,
completion_time_unix INTEGER,
FOREIGN KEY(group_id) REFERENCES todo_groups(id), FOREIGN KEY(group_id) REFERENCES todo_groups(id),
FOREIGN KEY(owner_username) REFERENCES users(username))`, FOREIGN KEY(owner_username) REFERENCES users(username))`,
) )

26
src/db/todo.go

@ -30,12 +30,14 @@ type TodoGroup struct {
// Todo structure // Todo structure
type Todo struct { type Todo struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
GroupID uint64 `json:"groupId"` GroupID uint64 `json:"groupId"`
Text string `json:"text"` Text string `json:"text"`
TimeCreatedUnix uint64 `json:"timeCreatedUnix"` TimeCreatedUnix uint64 `json:"timeCreatedUnix"`
DueUnix uint64 `json:"dueUnix"` DueUnix uint64 `json:"dueUnix"`
OwnerUsername string `json:"ownerUsername"` OwnerUsername string `json:"ownerUsername"`
IsDone bool `json:"isDone"`
CompletionTimeUnix uint64 `json:"completionTimeUnix"`
} }
// Creates a new TODO group in the database // Creates a new TODO group in the database
@ -136,6 +138,8 @@ func scanTodo(rows *sql.Rows) (*Todo, error) {
&newTodo.TimeCreatedUnix, &newTodo.TimeCreatedUnix,
&newTodo.DueUnix, &newTodo.DueUnix,
&newTodo.OwnerUsername, &newTodo.OwnerUsername,
&newTodo.IsDone,
&newTodo.CompletionTimeUnix,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -188,12 +192,14 @@ func (db *DB) GetTodos() ([]*Todo, error) {
// Creates a new TODO in the database // Creates a new TODO in the database
func (db *DB) CreateTodo(todo Todo) error { func (db *DB) CreateTodo(todo Todo) error {
_, err := db.Exec( _, err := db.Exec(
"INSERT INTO todos(group_id, text, time_created_unix, due_unix, owner_username) VALUES(?, ?, ?, ?, ?)", "INSERT INTO todos(group_id, text, time_created_unix, due_unix, owner_username, is_done, completion_time_unix) VALUES(?, ?, ?, ?, ?, ?, ?)",
todo.GroupID, todo.GroupID,
todo.Text, todo.Text,
todo.TimeCreatedUnix, todo.TimeCreatedUnix,
todo.DueUnix, todo.DueUnix,
todo.OwnerUsername, todo.OwnerUsername,
todo.IsDone,
todo.CompletionTimeUnix,
) )
return err return err
@ -209,13 +215,15 @@ func (db *DB) DeleteTodo(id uint64) error {
return err return err
} }
// Updates TODO's due date, text and group id // Updates TODO's due date, text, done state, completion time and group id
func (db *DB) UpdateTodo(todoID uint64, updatedTodo Todo) error { func (db *DB) UpdateTodo(todoID uint64, updatedTodo Todo) error {
_, err := db.Exec( _, err := db.Exec(
"UPDATE todos SET group_id=?, due_unix=?, text=? WHERE id=?", "UPDATE todos SET group_id=?, due_unix=?, text=?, is_done=?, completion_time_unix=? WHERE id=?",
updatedTodo.GroupID, updatedTodo.GroupID,
updatedTodo.DueUnix, updatedTodo.DueUnix,
updatedTodo.Text, updatedTodo.Text,
updatedTodo.IsDone,
updatedTodo.CompletionTimeUnix,
todoID, todoID,
) )

27
src/server/api.go

@ -150,16 +150,33 @@ func (s *Server) TodoEndpoint(w http.ResponseWriter, req *http.Request) {
return return
} }
// Now delete // Mark TODO as done and assign a completion time
err = s.db.DeleteTodo(todoID) updatedTodo, err := s.db.GetTodo(todoID)
if err != nil { if err != nil {
logger.Error("[Server] Failed to delete %s's TODO: %s", GetUsernameFromAuth(req), err) logger.Error("[Server] Failed to get todo with id %d for marking completion: %s", todoID, err)
http.Error(w, "Failed to delete TODO", http.StatusInternalServerError) http.Error(w, "TODO retrieval error", http.StatusInternalServerError)
return return
} }
updatedTodo.IsDone = true
updatedTodo.CompletionTimeUnix = uint64(time.Now().Unix())
err = s.db.UpdateTodo(todoID, *updatedTodo)
if err != nil {
logger.Error("[Server] Failed to update TODO with id %d: %s", todoID, err)
http.Error(w, "Failed to update TODO information", http.StatusInternalServerError)
return
}
// Now delete
// err = s.db.DeleteTodo(todoID)
// if err != nil {
// logger.Error("[Server] Failed to delete %s's TODO: %s", GetUsernameFromAuth(req), err)
// http.Error(w, "Failed to delete TODO", http.StatusInternalServerError)
// return
// }
// Success! // Success!
logger.Info("[Server] deleted TODO with ID %d", todoID) logger.Info("[Server] updated (marked as done) TODO with ID %d", todoID)
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
case http.MethodPost: case http.MethodPost:

Loading…
Cancel
Save