From 2610f9b67e4a915859c029da9b17e9d262b6564e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20J=C3=B8rgensen?= Date: Sat, 25 May 2024 11:53:43 +0200 Subject: Add task ui and editing --- db.go | 42 +++++++++++++------ model.go | 17 ++++++-- page.go | 38 ++++++++++++++++- templates/index.html | 62 +++++++++++++++------------- templates/parts/entry.html | 12 +++--- templates/parts/entryRows.html | 2 +- templates/parts/task.html | 18 +++++++++ templates/parts/taskRows.html | 11 +++++ tidsreg.go | 92 ++++++++++++++++++++++++++++++++++++++---- 9 files changed, 235 insertions(+), 59 deletions(-) create mode 100644 templates/parts/task.html create mode 100644 templates/parts/taskRows.html diff --git a/db.go b/db.go index 45296d6..363bc93 100644 --- a/db.go +++ b/db.go @@ -19,9 +19,9 @@ type Database interface { } type InMemDb struct { - entries []*Entry + entries []*Entry current *Entry - tasks []*Task + tasks []*Task } var ( @@ -30,7 +30,7 @@ var ( ) func NewInMemDb() Database { - return &InMemDb { + return &InMemDb{ entries: []*Entry{}, current: nil, } @@ -65,12 +65,12 @@ func (db *InMemDb) QueryEntry(id *int, date *Date) ([]*Entry, error) { } func (db *InMemDb) StartNewEntry(now time.Time, task *Entry) (*Entry, error) { - newTask := &Entry { - Id: len(db.entries), - From: task.From, - To: nil, - Date: DateFromStd(now), - Tag: task.Tag, + newTask := &Entry{ + Id: len(db.entries), + From: task.From, + To: nil, + Date: DateFromStd(now), + Tag: task.Tag, Comment: task.Comment, } @@ -139,8 +139,26 @@ func (db *InMemDb) QueryTask(id *int, group *string, ident *string) ([]*Task, er res = append(res, task) } - return res, ErrNotFound + return res, nil } -func (db *InMemDb) SaveTask(task *Task) (*Task, error) { - return nil, nil +func (db *InMemDb) SaveTask(task *Task) (newTask *Task, err error) { + var tasks []*Task + + tasks, err = db.QueryTask(&task.Id, nil, nil) + if err != nil { + return + } + if len(tasks) > 0 { + newTask = tasks[0] + newTask.Text = task.Text + newTask.Group = task.Group + newTask.Ident = task.Ident + } else { + taskCopy := *task + taskCopy.Id = len(db.tasks) + db.tasks = append(db.tasks, &taskCopy) + newTask = &taskCopy + } + + return } diff --git a/model.go b/model.go index b8d174c..93a988c 100644 --- a/model.go +++ b/model.go @@ -17,10 +17,10 @@ type Entry struct { } type Task struct { - Id int - Group *string - Ident *string - Text string + Id int + Group *string + Ident *string + Text string } type Date string @@ -47,6 +47,15 @@ func NewEntry(date Date) *Entry { } +func NewTask() *Task { + return &Task{ + Id: -1, + Group: nil, + Ident: nil, + Text: "", + } +} + func TimeFromStd(time time.Time) Time { return Time(time.Format("15:04")) } diff --git a/page.go b/page.go index b58436d..8e2074e 100644 --- a/page.go +++ b/page.go @@ -24,12 +24,18 @@ type RootPage struct { DateInfo DateInfo Entry *EntryPage Entries []*Entry + Task *TaskPage + Tasks []*Task } type TasksPage struct { Tasks []*Task } +type TaskPage struct { + Task *Task +} + func NewService(db Database) *Service { return &Service{ Db: db, @@ -45,6 +51,23 @@ func NewDateInfo(t time.Time) DateInfo { } } +func (srv *Service) GetTaskPage(id *int, task *Task) (*TaskPage, error) { + if task == nil { + tasks, err := srv.Db.QueryTask(id, nil, nil) + if err != nil { + return nil, err + } + if len(tasks) < 1 { + return nil, ErrNotFound + } + task = tasks[0] + } + + return &TaskPage{ + Task: task, + }, nil +} + func (srv *Service) GetTasksPage() (*TasksPage, error) { tasks, err := srv.Db.GetTasks() if err != nil { @@ -54,6 +77,7 @@ func (srv *Service) GetTasksPage() (*TasksPage, error) { Tasks: tasks, }, nil } + func (srv *Service) GetEntryPage(detached *Entry, dt DateInfo) (*EntryPage, error) { tracking, err := srv.Db.GetTracking() if err != nil { @@ -81,7 +105,7 @@ func (srv *Service) GetRootPage(date Date) (*RootPage, error) { // If not today detach entry = NewEntry(date) } - + entryPage, err := srv.GetEntryPage(entry, NewDateInfo(date.ToStd())) if err != nil { return nil, err @@ -91,9 +115,21 @@ func (srv *Service) GetRootPage(date Date) (*RootPage, error) { return nil, err } + tasks, err := srv.Db.GetTasks() + if err != nil { + return nil, err + } + + task, err := srv.GetTaskPage(nil, NewTask()) + if err != nil { + return nil, err + } + return &RootPage{ DateInfo: entryPage.DateInfo, Entry: entryPage, Entries: entries, + Task: task, + Tasks: tasks, }, nil } diff --git a/templates/index.html b/templates/index.html index b2dc6b0..18ca5f0 100644 --- a/templates/index.html +++ b/templates/index.html @@ -14,6 +14,10 @@ display: flex; } +.dir-column { + flex-direction: column; +} + .flex-grow { flex-grow: 1; } @@ -22,26 +26,39 @@ justify-content: flex-start; } -.week-bar { +.just-space-between { + justify-content: space-between; +} + +#task-bar { margin-left: 10px; border: 1px solid black; } +.short { + max-width: 50px; +} + .status-started { - border-color: green; + background-color: lightgreen; } .status-stopped { - border-color: red; + background-color: lightblue; } + .status-detached { - border-color: blue; + background-color: lightyellow; } #entry-bar { - border-width: 3px; - border-style: solid; + border: 1px solid black; + padding-top: 10px; +} + +#entry-form { padding: 10px; + margin-buttom: 10px; } .entry-box { @@ -50,6 +67,12 @@ #controls-bar { margin-bottom: 10px; } + +#taskForm { + background-color: lightblue; + padding: 10px; + max-width: 500px; +} @@ -60,7 +83,7 @@
-
+
{{template "entry.html" .Entry}}
@@ -80,8 +103,8 @@
-
-
+
+ - - - - - - - - - - - - -
Trifork - -
- SVT-112: fdsa Dsa ds wqw fdsf fds -
- Helligdag -
+ {{ template "task.html" .Task }} + {{ template "taskRows.html" . }}
diff --git a/templates/parts/entry.html b/templates/parts/entry.html index 300f543..52f2eb3 100644 --- a/templates/parts/entry.html +++ b/templates/parts/entry.html @@ -1,4 +1,4 @@ -
+ {{ if .Detached }} {{ if gt .Entry.Id -1 }}Redigerer opgave {{ .Entry.Id }}{{else}}Redigerer ny opgave{{end}}{{ if .Tracking }}, med opgave i baggrunden!{{else}}.{{end}}
@@ -43,7 +43,7 @@ @@ -53,7 +53,7 @@ {{ end }} @@ -62,21 +62,21 @@ {{ else }} {{ end }} {{ end }} diff --git a/templates/parts/entryRows.html b/templates/parts/entryRows.html index 9e9c0eb..8f10ee3 100644 --- a/templates/parts/entryRows.html +++ b/templates/parts/entryRows.html @@ -7,7 +7,7 @@ {{ if $entry.Tag}}{{ $entry.Tag }}{{end}} {{ $entry.Comment }} - {{ if $entry.To }}{{end}} + {{ if $entry.To }}{{end}} {{ end }} diff --git a/templates/parts/task.html b/templates/parts/task.html new file mode 100644 index 0000000..a366dcf --- /dev/null +++ b/templates/parts/task.html @@ -0,0 +1,18 @@ + + {{if gt .Task.Id -1}} + + +
+ {{end}} +
+ +
+
+ + +
+ +
+
+ +
diff --git a/templates/parts/taskRows.html b/templates/parts/taskRows.html new file mode 100644 index 0000000..a2a6020 --- /dev/null +++ b/templates/parts/taskRows.html @@ -0,0 +1,11 @@ + + + {{ range $task := .Tasks }} + + + + {{ end }} + +
Trifork + +
diff --git a/tidsreg.go b/tidsreg.go index 43e4adb..e327f74 100644 --- a/tidsreg.go +++ b/tidsreg.go @@ -18,7 +18,46 @@ type Server struct { srv *Service } -func parseTaskFromForm(r *http.Request, useToday bool) (*Entry, error) { +func parseTaskFromForm(r *http.Request) (*Task, error) { + err := r.ParseForm() + if err != nil { + return nil, err + } + + var id int64 + if r.PostFormValue("id") == "" { + id = -1 + } else { + id, err = strconv.ParseInt(r.PostFormValue("id"), 10, 32) + if err != nil { + return nil, err + } + } + + var group *string + { + groupStr := r.PostFormValue("group") + if groupStr != "" { + group = &groupStr + } + } + var ident *string + { + identStr := r.PostFormValue("ident") + if identStr != "" { + ident = &identStr + } + } + + return &Task{ + Id: int(id), + Group: group, + Ident: ident, + Text: r.PostFormValue("text"), + }, nil +} + +func parseEntryFromForm(r *http.Request, useToday bool) (*Entry, error) { err := r.ParseForm() if err != nil { return nil, err @@ -59,7 +98,7 @@ func parseTaskFromForm(r *http.Request, useToday bool) (*Entry, error) { task := &Entry{ Id: int(id), From: from, - Date: date, + Date: date, To: to, Comment: r.PostFormValue("comment"), } @@ -67,7 +106,7 @@ func parseTaskFromForm(r *http.Request, useToday bool) (*Entry, error) { } func (s *Server) renderTemplate(w http.ResponseWriter, name string, page interface{}) { - tmpl, err := template.ParseFiles("templates/index.html", "templates/parts/entry.html", "templates/parts/entryRows.html") + tmpl, err := template.ParseFiles("templates/index.html", "templates/parts/entry.html", "templates/parts/entryRows.html", "templates/parts/task.html", "templates/parts/taskRows.html") if err != nil { writeError(w, err.Error(), http.StatusInternalServerError) return @@ -127,7 +166,7 @@ func (s *Server) rootHandle(w http.ResponseWriter, r *http.Request) { func (s *Server) postStart(w http.ResponseWriter, r *http.Request) { now := time.Now() - task, err := parseTaskFromForm(r, true) + task, err := parseEntryFromForm(r, true) if err != nil { writeError(w, err.Error(), http.StatusBadRequest) return @@ -150,7 +189,7 @@ func (s *Server) postStart(w http.ResponseWriter, r *http.Request) { func (s *Server) postStop(w http.ResponseWriter, r *http.Request) { now := time.Now() - task, err := parseTaskFromForm(r, true) + task, err := parseEntryFromForm(r, true) if err != nil { writeError(w, err.Error(), http.StatusBadRequest) return @@ -183,7 +222,7 @@ func (s *Server) getTracking(w http.ResponseWriter, _ *http.Request) { } func (s *Server) putSave(w http.ResponseWriter, r *http.Request) { - task, err := parseTaskFromForm(r, false) + task, err := parseEntryFromForm(r, false) if err != nil { writeError(w, err.Error(), http.StatusBadRequest) return @@ -280,7 +319,44 @@ func (s *Server) getTasksList(w http.ResponseWriter, _ *http.Request) { return } - s.renderTemplate(w, "tasksPage.html", page) + s.renderTemplate(w, "taskRows.html", page) +} + +func (s *Server) postTaskSave(w http.ResponseWriter, r *http.Request) { + task, err := parseTaskFromForm(r) + if err != nil { + writeError(w, err.Error(), http.StatusBadRequest) + return + } + + task, err = s.srv.Db.SaveTask(task) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + log.Printf("Hej %+v\n", task) + + page, err := s.srv.GetTaskPage(nil, task) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Add("HX-Trigger", "changedTasks") + + s.renderTemplate(w, "task.html", page) +} + +func (s *Server) getTaskEmpty(w http.ResponseWriter, _ *http.Request) { + task := NewTask() + + page, err := s.srv.GetTaskPage(nil, task) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + s.renderTemplate(w, "task.html", page) } func main() { @@ -300,6 +376,8 @@ func main() { r.HandleFunc("/entryRows", s.getEntries).Methods("GET") r.HandleFunc("/edit", s.getEdit).Methods("GET") r.HandleFunc("/task/list", s.getTasksList).Methods("GET") + r.HandleFunc("/task/save", s.postTaskSave).Methods("POST") + r.HandleFunc("/task/empty", s.getTaskEmpty).Methods("GET") r.HandleFunc("/", s.rootHandle) http.Handle("/", r) -- cgit v1.2.3