forked from OrgGo/Tasks
Ability to add comments & a little HTML formatting
This commit is contained in:
parent
04640d0159
commit
ca9a110526
64
db/tasks.go
64
db/tasks.go
|
@ -68,16 +68,15 @@ func Close() {
|
||||||
//GetTasks retrieves all the tasks depending on the
|
//GetTasks retrieves all the tasks depending on the
|
||||||
//status pending or trashed or completed
|
//status pending or trashed or completed
|
||||||
func GetTasks(status, category string) (types.Context, error) {
|
func GetTasks(status, category string) (types.Context, error) {
|
||||||
var task []types.Task
|
var tasks []types.Task
|
||||||
var context types.Context
|
var task types.Task
|
||||||
var TaskID int
|
|
||||||
var TaskTitle string
|
|
||||||
var TaskContent string
|
|
||||||
var TaskCreated time.Time
|
var TaskCreated time.Time
|
||||||
var TaskPriority string
|
var context types.Context
|
||||||
var getTasksql string
|
var getTasksql string
|
||||||
var rows *sql.Rows
|
var rows *sql.Rows
|
||||||
|
|
||||||
|
comments := GetComments()
|
||||||
|
|
||||||
basicSQL := "select id, title, content, created_date, priority from task t"
|
basicSQL := "select id, title, content, created_date, priority from task t"
|
||||||
if status == "pending" && category == "" {
|
if status == "pending" && category == "" {
|
||||||
getTasksql = basicSQL + " where finish_date is null and is_deleted='N' order by priority desc, created_date asc"
|
getTasksql = basicSQL + " where finish_date is null and is_deleted='N' order by priority desc, created_date asc"
|
||||||
|
@ -99,17 +98,24 @@ func GetTasks(status, category string) (types.Context, error) {
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
err := rows.Scan(&TaskID, &TaskTitle, &TaskContent, &TaskCreated, &TaskPriority)
|
task = types.Task{}
|
||||||
TaskContent = string(md.Markdown([]byte(TaskContent)))
|
err := rows.Scan(&task.Id, &task.Title, &task.Content, &TaskCreated, &task.Priority)
|
||||||
|
task.Content = string(md.Markdown([]byte(task.Content)))
|
||||||
// TaskContent = strings.Replace(TaskContent, "\n", "<br>", -1)
|
// TaskContent = strings.Replace(TaskContent, "\n", "<br>", -1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if comments[task.Id] != nil {
|
||||||
|
task.Comments = comments[task.Id]
|
||||||
|
}
|
||||||
|
|
||||||
TaskCreated = TaskCreated.Local()
|
TaskCreated = TaskCreated.Local()
|
||||||
a := types.Task{Id: TaskID, Title: TaskTitle, Content: TaskContent, Created: TaskCreated.Format(time.UnixDate)[0:20], Priority: TaskPriority}
|
task.Created = TaskCreated.Format(time.UnixDate)[0:20]
|
||||||
task = append(task, a)
|
|
||||||
|
tasks = append(tasks, task)
|
||||||
}
|
}
|
||||||
context = types.Context{Tasks: task, Navigation: status}
|
context = types.Context{Tasks: tasks, Navigation: status}
|
||||||
return context, nil
|
return context, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,3 +254,39 @@ func SearchTask(query string) types.Context {
|
||||||
context = types.Context{Tasks: task, Search: query}
|
context = types.Context{Tasks: task, Search: query}
|
||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//GetComments is used to get comments, all of them.
|
||||||
|
//We do not want 100 different pages to show tasks, we want to use as few pages as possible
|
||||||
|
//so we are going to populate everything on the damn home pages
|
||||||
|
func GetComments() map[int][]types.Comment {
|
||||||
|
commentMap := make(map[int][]types.Comment)
|
||||||
|
|
||||||
|
var id int
|
||||||
|
var message types.Comment
|
||||||
|
|
||||||
|
stmt := "select taskID, content from comments;"
|
||||||
|
rows := database.query(stmt)
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
err := rows.Scan(&id, &message.Content)
|
||||||
|
if err != nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
commentMap[id] = append(commentMap[id], message)
|
||||||
|
}
|
||||||
|
return commentMap
|
||||||
|
}
|
||||||
|
|
||||||
|
//AddComments will be used to add comments in the database
|
||||||
|
func AddComments(id int, comment string) error {
|
||||||
|
stmt := "insert into comments(taskID, content) values (?,?)"
|
||||||
|
err := taskQuery(stmt, id, comment)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("added comment to task ID ", id)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
1
main.go
1
main.go
|
@ -17,6 +17,7 @@ func main() {
|
||||||
views.PopulateTemplates()
|
views.PopulateTemplates()
|
||||||
http.HandleFunc("/", views.ShowAllTasksFunc)
|
http.HandleFunc("/", views.ShowAllTasksFunc)
|
||||||
http.HandleFunc("/add-category/", views.AddCategoryFunc)
|
http.HandleFunc("/add-category/", views.AddCategoryFunc)
|
||||||
|
http.HandleFunc("/add-comment/", views.AddCommentFunc)
|
||||||
http.HandleFunc("/del-category/", views.DeleteCategoryFunc)
|
http.HandleFunc("/del-category/", views.DeleteCategoryFunc)
|
||||||
http.HandleFunc("/upd-category/", views.UpdateCategoryFunc)
|
http.HandleFunc("/upd-category/", views.UpdateCategoryFunc)
|
||||||
http.HandleFunc("/category/", views.ShowCategoryFunc)
|
http.HandleFunc("/category/", views.ShowCategoryFunc)
|
||||||
|
|
|
@ -17,8 +17,14 @@ ul{
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border:none;
|
||||||
|
border-bottom:1px solid gray;
|
||||||
|
box-shadow:none;
|
||||||
|
}
|
||||||
|
|
||||||
.badge{
|
.badge{
|
||||||
background-color: #7D8EF0;
|
background-color: #1a78c9;
|
||||||
margin-right:10px;
|
margin-right:10px;
|
||||||
float:right;
|
float:right;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,12 @@ $(document).ready(function(){
|
||||||
$('#toggleAddFileGrp').addClass('hidden') ;
|
$('#toggleAddFileGrp').addClass('hidden') ;
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($('#actlMsg').html()==' <button id="btnMessage" class="btn btn-default">OK</button>'){
|
$("#noti").click(
|
||||||
|
function(){
|
||||||
|
this.fadeOut();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if ($('#actlMsg').html()==''){
|
||||||
$('.notification').addClass('hidden');
|
$('.notification').addClass('hidden');
|
||||||
} else {
|
} else {
|
||||||
$('.notification').fadeOut(9000);
|
$('.notification').fadeOut(9000);
|
||||||
|
@ -53,6 +58,22 @@ $(document).ready(function(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);*/
|
);*/
|
||||||
|
|
||||||
|
$("#addNoteBtn").on("click", function() {
|
||||||
|
this.preventDefaults();
|
||||||
|
var task_id = $("#task-id").val();
|
||||||
|
$.ajax({
|
||||||
|
url: "/tasks/" + task_id,
|
||||||
|
type: "POST",
|
||||||
|
data: {'title':'randome note', 'content':'this and that'}
|
||||||
|
}).done(function(res, status) {
|
||||||
|
console.log(status, res);
|
||||||
|
var response = res
|
||||||
|
$("#timeline").append(response)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
$('.toggle').click(function(){
|
$('.toggle').click(function(){
|
||||||
$(this).next().toggle();
|
$(this).next().toggle();
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<!-- The navigation bar-->
|
<!-- The navigation bar-->
|
||||||
<div class='notification {{if eq .Message ""}} hidden {{end}}'><span id="message"><p id="actlMsg">{{.Message}} <button id="btnMessage" class="btn btn-default">OK</button></p> </span> </div>
|
<div id = "noti" class='notification {{if eq .Message ""}} hidden {{end}}'><span id="message"><p id="actlMsg">{{.Message}}</div>
|
||||||
<nav class="navbar navbar-default navbar-fixed-top mainHeader">
|
<nav class="navbar navbar-default navbar-fixed-top mainHeader">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
{{$url := ""}}
|
{{$url := ""}}
|
||||||
|
@ -55,12 +55,12 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form action="/upd-category/{{.Navigation}}" method="POST" class="hidden" id="EditForm">
|
<form action="/upd-category/{{.Navigation}}" method="POST" class="hidden" id="EditForm">
|
||||||
<input type="text" name="catname" placeholder="new cat name" style="border:none;border-bottom:1px solid gray; box-shadow:none;">
|
<input type="text" name="catname" placeholder="new cat name" >
|
||||||
<input type="submit" value="Submit" class="btn btn-default" />
|
<input type="submit" value="Submit" class="btn btn-default" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form action="/search/" method="POST" class="hidden" id="SearchForm">
|
<form action="/search/" method="POST" class="hidden" id="SearchForm">
|
||||||
<input type="text" name="query" placeholder="Search" style="border:none;border-bottom:1px solid gray; box-shadow:none;">
|
<input type="text" name="query" placeholder="Search" >
|
||||||
<input type="submit" value="Submit" class="btn btn-default" />
|
<input type="submit" value="Submit" class="btn btn-default" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form action="/update/" method="POST">
|
<form action="/update/" method="POST">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" name="title" value="{{ $task.Title}}" class="form-control" id="add-note-title" placeholder="Title" style="border:none;border-bottom:1px solid gray; box-shadow:none;">
|
<input type="text" name="title" value="{{ $task.Title}}" class="form-control" id="add-note-title" placeholder="Title">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<textarea class="form-control" name="content" id="add-note-content" placeholder="Content" rows="10" style="border:none;border-bottom:1px solid gray; box-shadow:none;">{{ $task.Content}}</textarea>
|
<textarea class="form-control" name="content" id="add-note-content" placeholder="Content" rows="10" >{{ $task.Content}}</textarea>
|
||||||
|
|
||||||
<input type="text" name="id" value="{{.Id}}" class="hidden" /> Priority:
|
<input type="text" name="id" value="{{.Id}}" class="hidden" /> Priority:
|
||||||
<input type="radio" name="priority" value="3" {{if eq .Priority "3"}} checked="checked" {{end}} /> High
|
<input type="radio" name="priority" value="3" {{if eq .Priority "3"}} checked="checked" {{end}} /> High
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
<form enctype="multipart/form-data" action="/add/" method="POST">
|
<form enctype="multipart/form-data" action="/add/" method="POST">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
||||||
<input type="text" name="title" class="form-control" id="add-note-title" placeholder="Title" style="border:none;border-bottom:1px solid gray; box-shadow:none;">
|
<input type="text" name="title" class="form-control" id="add-note-title" placeholder="Title" >
|
||||||
<input type="hidden" name="CSRFToken" value={{.CSRFToken}}>
|
<input class="hidden"" name="CSRFToken" value={{.CSRFToken}}>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
||||||
<textarea class="form-control" name="content" id="add-note-content" placeholder="Content" rows="10" style="border:none;border-bottom:1px solid gray; box-shadow:none;"></textarea>
|
<textarea class="form-control" name="content" id="add-note-content" placeholder="Content" rows="10" ></textarea>
|
||||||
<a id="toggleAddFileGrp">Add File</a>
|
<a id="toggleAddFileGrp">Add File</a>
|
||||||
<span id="file-group" class="hidden">
|
<span id="file-group" class="hidden">
|
||||||
File: <input type="file" name="uploadfile" />
|
File: <input type="file" name="uploadfile" />
|
||||||
|
@ -33,15 +33,14 @@
|
||||||
Category:
|
Category:
|
||||||
<select name="category" class="dropdown">
|
<select name="category" class="dropdown">
|
||||||
<option>---</option>
|
<option>---</option>
|
||||||
{{$navigation := .Navigation}} {{$categories := .Categories}}
|
{{$navigation := .Navigation}} {{$categories := .Categories}} {{range $cat := $categories}}
|
||||||
{{range $cat := $categories}}
|
|
||||||
<option value="{{$cat.Name}}" {{if eq $cat.Name $navigation }} selected="true" {{end}}> {{$cat.Name}} </option>
|
<option value="{{$cat.Name}}" {{if eq $cat.Name $navigation }} selected="true" {{end}}> {{$cat.Name}} </option>
|
||||||
{{end}}
|
{{end}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
|
||||||
<input type="submit" value="Submit" class="btn btn-default" id="addNoteBtn" />
|
<input type="submit" value="Submit" class="btn btn-primary" id="addNoteBtn" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,10 +49,28 @@
|
||||||
|
|
||||||
<div class="timeline">
|
<div class="timeline">
|
||||||
{{ if .Tasks}} {{range $key, $value := .Tasks}}
|
{{ if .Tasks}} {{range $key, $value := .Tasks}}
|
||||||
<div class="note" id ="{{$value.Id}}">
|
<div class="note" id="{{$value.Id}}">
|
||||||
<p class="noteHeading">{{ $value.Title}}</p> <span class="toggle glyphicon glyphicon-resize-full"></span>
|
<p class="noteHeading">{{ $value.Title}}</p> <span class="toggle glyphicon glyphicon-resize-full"></span>
|
||||||
|
|
||||||
<span class="noteContent">{{$value.Content}}</span>
|
<span class="noteContent">
|
||||||
|
{{$value.Content}}
|
||||||
|
<span class="noteComments">
|
||||||
|
<ul>
|
||||||
|
{{range $value.Comments}}
|
||||||
|
<li>{{.Content}}</li>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<form method="POST" action="/add-comment/">
|
||||||
|
<textarea rows="2" cols="30" name="commentText" placeholder="Add Comment"></textarea>
|
||||||
|
<input type="text" class="hidden" name="taskID" value="{{$value.Id}}">
|
||||||
|
<input type="submit" value="Comment" class="btn btn-primary" />
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
<span class="notefooter">
|
<span class="notefooter">
|
||||||
<ul class="menu">
|
<ul class="menu">
|
||||||
<li role="presentation">Priority: {{$value.Priority}}</li>
|
<li role="presentation">Priority: {{$value.Priority}}</li>
|
||||||
|
@ -84,8 +101,8 @@
|
||||||
<div class="note">
|
<div class="note">
|
||||||
<p class="noteHeading">No Tasks here</p>
|
<p class="noteHeading">No Tasks here</p>
|
||||||
<p class="notefooter">Create new task
|
<p class="notefooter">Create new task
|
||||||
<button class="floating-action-icon-add" style="border:none;border-bottom:1px solid gray; box-shadow:none;">
|
<button class="floating-action-icon-add" >
|
||||||
here </button>
|
here </button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -13,6 +13,12 @@ type Task struct {
|
||||||
Priority string
|
Priority string
|
||||||
Category string
|
Category string
|
||||||
Referer string
|
Referer string
|
||||||
|
Comments []Comment
|
||||||
|
}
|
||||||
|
|
||||||
|
//Comment is the struct used to populate comments per tasks
|
||||||
|
type Comment struct {
|
||||||
|
Content string
|
||||||
}
|
}
|
||||||
|
|
||||||
//Context is the struct passed to templates
|
//Context is the struct passed to templates
|
||||||
|
|
|
@ -160,3 +160,31 @@ func EditTaskFunc(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, "/", http.StatusFound)
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AddCommentFunc will be used
|
||||||
|
func AddCommentFunc(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method == "POST" {
|
||||||
|
r.ParseForm()
|
||||||
|
text := r.Form.Get("commentText")
|
||||||
|
id := r.Form.Get("taskID")
|
||||||
|
|
||||||
|
idInt, err := strconv.Atoi(id)
|
||||||
|
|
||||||
|
if (err != nil) || (text == "") {
|
||||||
|
log.Println("unable to convert into integer")
|
||||||
|
message = "Error adding comment"
|
||||||
|
} else {
|
||||||
|
err = db.AddComments(idInt, text)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println("unable to insert into db")
|
||||||
|
message = "Comment not added"
|
||||||
|
} else {
|
||||||
|
message = "Comment added"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -107,9 +107,13 @@ func UpdateTaskFunc(w http.ResponseWriter, r *http.Request) {
|
||||||
message = "Error updating task"
|
message = "Error updating task"
|
||||||
} else {
|
} else {
|
||||||
message = "Task updated"
|
message = "Task updated"
|
||||||
|
log.Println(message)
|
||||||
}
|
}
|
||||||
log.Println("redirecting to somewhere else")
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
http.Redirect(w, r, "/", 301)
|
|
||||||
|
} else {
|
||||||
|
message = "Method not allowed"
|
||||||
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue