From 2f83424ce8a0653e6e158318df1511daecf1a42d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20J=C3=B8rgensen?= Date: Fri, 24 May 2024 21:30:23 +0200 Subject: Time format rework --- db.go | 43 ++++++++++++++--------------- model.go | 59 +++++++++++++++++++++++++++++++++++++--- page.go | 14 +++++----- templates/parts/entry.html | 20 +++++++------- templates/parts/entryRows.html | 18 ++++++------ tidsreg.go | 62 +++++++++++++++++++++++------------------- 6 files changed, 137 insertions(+), 79 deletions(-) diff --git a/db.go b/db.go index ccee504..76cb4e7 100644 --- a/db.go +++ b/db.go @@ -6,17 +6,17 @@ import ( ) type Database interface { - GetTracking() (*Task, error) - GetTasks() ([]*Task, error) - QueryTask(id *int) (*Task, error) - StartNewEntry(now time.Time, task *Task) (*Task, error) + GetTracking() (*Entry, error) + GetTasks() ([]*Entry, error) + QueryTask(id *int) (*Entry, error) + StartNewEntry(now time.Time, task *Entry) (*Entry, error) StopEntry(now time.Time) error - SaveEntry(task *Task) (*Task, error) + SaveEntry(task *Entry) (*Entry, error) } type InMemDb struct { - tasks []*Task - current *Task + tasks []*Entry + current *Entry } var ( @@ -26,17 +26,17 @@ var ( func NewInMemDb() Database { return &InMemDb { - tasks: []*Task{}, + tasks: []*Entry{}, current: nil, } } -func (db *InMemDb) GetTracking() (*Task, error) { +func (db *InMemDb) GetTracking() (*Entry, error) { return db.current, nil } -func (db *InMemDb) GetTasks() ([]*Task, error) { - res := make([]*Task, 0, len(db.tasks)) +func (db *InMemDb) GetTasks() ([]*Entry, error) { + res := make([]*Entry, 0, len(db.tasks)) for _, task := range db.tasks { res = append(res, task) } @@ -44,18 +44,15 @@ func (db *InMemDb) GetTasks() ([]*Task, error) { return res, nil } -func (db *InMemDb) QueryTask(id *int) (*Task, error) { - for _, task := range db.tasks { - if id != nil && task.Id == *id { - return task, nil - } +func (db *InMemDb) QueryTask(id *int) (*Entry, error) { + if id != nil && *id >= 0 || *id < len(db.tasks) { + return db.tasks[*id], nil } - return nil, ErrNotFound } -func (db *InMemDb) StartNewEntry(now time.Time, task *Task) (*Task, error) { - newTask := &Task { +func (db *InMemDb) StartNewEntry(now time.Time, task *Entry) (*Entry, error) { + newTask := &Entry { Id: len(db.tasks), From: task.From, To: nil, @@ -64,7 +61,8 @@ func (db *InMemDb) StartNewEntry(now time.Time, task *Task) (*Task, error) { } if newTask.From == nil { - newTask.From = &now + from := TimeFromStd(now) + newTask.From = &from } db.tasks = append(db.tasks, newTask) @@ -75,7 +73,8 @@ func (db *InMemDb) StartNewEntry(now time.Time, task *Task) (*Task, error) { func (db *InMemDb) StopEntry(now time.Time) error { if db.current != nil { - db.current.To = &now + to := TimeFromStd(now) + db.current.To = &to db.current = nil } else { return ErrNotRunning @@ -83,7 +82,7 @@ func (db *InMemDb) StopEntry(now time.Time) error { return nil } -func (db *InMemDb) SaveEntry(task *Task) (*Task, error) { +func (db *InMemDb) SaveEntry(task *Entry) (*Entry, error) { if task.Id < 0 || task.Id >= len(db.tasks) { copyTask := *task copyTask.Id = len(db.tasks) diff --git a/model.go b/model.go index 0f52ef9..b6d5c79 100644 --- a/model.go +++ b/model.go @@ -1,11 +1,62 @@ package main -import "time" +import ( + "errors" + "regexp" + "time" +) -type Task struct { +type Entry struct { Id int - From *time.Time - To *time.Time + Date time.Time + From *Time + To *Time Tag *string Comment string } + +type Date string + +type Time string + +var timeMatch = regexp.MustCompile("\\d\\d:\\d\\d") +var dateMatch = regexp.MustCompile("\\d\\d\\d\\d-\\d\\d-\\d\\d") + +var ( + ErrInvalidTime = errors.New("Invalid time string") + ErrInvalidDate = errors.New("Invalid date string") +) + +func TimeFromStd(time time.Time) Time { + return Time(time.Format("15:04")) +} + +func TimeFromString(str string) (*Time, error) { + if str == "" { + return nil, nil + } + + matched := timeMatch.MatchString(str) + if !matched { + return nil, ErrInvalidTime + } + time := Time(str) + return &time, nil +} + +func DateFromStd(time time.Time) Date { + return Date(time.Format("2006-01-02")) +} + +func DateFromString(str string) (*Date, error) { + if str == "" { + return nil, nil + } + + matched := dateMatch.MatchString(str) + if !matched { + return nil, ErrInvalidTime + } + date := Date(str) + return &date, nil +} diff --git a/page.go b/page.go index 384ca57..c3ab160 100644 --- a/page.go +++ b/page.go @@ -5,14 +5,14 @@ type Service struct { } type EntryPage struct { - Task *Task + Entry *Entry Detached bool - Tracking *Task + Tracking *Entry } type RootPage struct { Entry *EntryPage - Tasks []*Task + Entries []*Entry } func NewService(db Database) *Service { @@ -21,20 +21,20 @@ func NewService(db Database) *Service { } } -func (srv *Service) GetEntryPage(detached *Task) (*EntryPage, error) { +func (srv *Service) GetEntryPage(detached *Entry) (*EntryPage, error) { tracking, err := srv.Db.GetTracking() if err != nil { return nil, err } page := &EntryPage { - Task: tracking, + Entry: tracking, Detached: false, Tracking: tracking, } if detached != nil { - page.Task = detached + page.Entry = detached page.Detached = true } @@ -54,6 +54,6 @@ func (srv *Service) GetRootPage() (*RootPage, error) { return &RootPage { Entry: entry, - Tasks: tasks, + Entries: tasks, }, nil } diff --git a/templates/parts/entry.html b/templates/parts/entry.html index f99fb90..9f05ffa 100644 --- a/templates/parts/entry.html +++ b/templates/parts/entry.html @@ -1,18 +1,18 @@ -
- + + {{ if .Detached }} - {{ if gt .Task.Id -1 }}Redigerer opgave {{ .Task.Id }}{{else}}Redigerer ny opgave{{end}}{{ if .Tracking }}, med opgave i baggrunden!{{else}}.{{end}}
+ {{ if gt .Entry.Id -1 }}Redigerer opgave {{ .Entry.Id }}{{else}}Redigerer ny opgave{{end}}{{ if .Tracking }}, med opgave i baggrunden!{{else}}.{{end}}
{{end}}
Interval
- +
- +
@@ -30,16 +30,16 @@
Kommentar
- +
Status
- {{ if not .Detached}}{{ if .Task }}I gang{{ else }}Stoppet{{ end }}
{{end}} - {{ if .Task }}1:34 timer{{ end }} + {{ if not .Detached}}{{ if .Entry }}I gang{{ else }}Stoppet{{ end }}
{{end}} + {{ if .Entry }}1:34 timer{{ end }}
- {{ if .Task }} + {{ if .Entry }} {{ else }} - {{ if .Task }} + {{ if .Entry }} {{end}} + {{ end }} diff --git a/tidsreg.go b/tidsreg.go index 410a5b5..28dea95 100644 --- a/tidsreg.go +++ b/tidsreg.go @@ -16,32 +16,17 @@ type Server struct { srv *Service } -func funcMapFormatTime(t *time.Time) string { - if t == nil { - return "" - } - return t.Format("15:04") -} - -func parseStringTime(str string) (*time.Time, error) { - if str == "" { - return nil, nil - } - t, err := time.Parse("15:04", str) - return &t, err -} - -func parseTaskFromForm(r *http.Request) (*Task, error) { +func parseTaskFromForm(r *http.Request) (*Entry, error) { err := r.ParseForm() if err != nil { return nil, err } - from, err := parseStringTime(r.PostFormValue("from")) + from, err := TimeFromString(r.PostFormValue("from")) if err != nil { return nil, err } - to, err := parseStringTime(r.PostFormValue("to")) + to, err := TimeFromString(r.PostFormValue("to")) if err != nil { return nil, err } @@ -55,7 +40,7 @@ func parseTaskFromForm(r *http.Request) (*Task, error) { } } - task := &Task { + task := &Entry { Id: int(id), From: from, To: to, @@ -65,10 +50,7 @@ func parseTaskFromForm(r *http.Request) (*Task, error) { } func (s *Server) renderTemplate(w http.ResponseWriter, name string, page interface{}) { - tmpl := template.New("").Funcs(template.FuncMap { - "formatTime": funcMapFormatTime, - }) - tmpl, err := tmpl.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") if err != nil { writeError(w, err.Error(), http.StatusInternalServerError) return @@ -123,7 +105,7 @@ func (s *Server) postStart(w http.ResponseWriter, r *http.Request) { writeError(w, err.Error(), http.StatusInternalServerError) return } - w.Header().Add("HX-Trigger", "changedTasks") + w.Header().Add("HX-Trigger", "changedEntries") s.renderTemplate(w, "entry.html", page) } @@ -146,7 +128,7 @@ func (s *Server) postStop(w http.ResponseWriter, r *http.Request) { return } - w.Header().Add("HX-Trigger", "changedTasks") + w.Header().Add("HX-Trigger", "changedEntries") s.getTracking(w, r) } @@ -174,7 +156,7 @@ func (s *Server) putSave(w http.ResponseWriter, r *http.Request) { return } - var detached *Task = nil + var detached *Entry = nil if r.URL.Query().Get("detached") == "true" { detached = task } @@ -185,13 +167,13 @@ func (s *Server) putSave(w http.ResponseWriter, r *http.Request) { return } - w.Header().Add("HX-Trigger", "changedTasks") + w.Header().Add("HX-Trigger", "changedEntries") s.renderTemplate(w, "entry.html", page) } func (s *Server) getNew(w http.ResponseWriter, _ *http.Request) { - task := &Task { + task := &Entry { Id: -1, From: nil, To: nil, @@ -208,6 +190,29 @@ func (s *Server) getNew(w http.ResponseWriter, _ *http.Request) { s.renderTemplate(w, "entry.html", page) } +func (s *Server) getEdit(w http.ResponseWriter, r *http.Request) { + idLarge, err := strconv.ParseInt(r.URL.Query().Get("id"), 10, 32) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + id := int(idLarge) + + task, err := s.srv.Db.QueryTask(&id) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + page, err := s.srv.GetEntryPage(task) + if err != nil { + writeError(w, err.Error(), http.StatusInternalServerError) + return + } + + s.renderTemplate(w, "entry.html", page) +} + func (s *Server) getEntries(w http.ResponseWriter, _ *http.Request) { page, err := s.srv.GetRootPage() if err != nil { @@ -233,6 +238,7 @@ func main() { r.HandleFunc("/stop", s.postStop).Methods("POST") r.HandleFunc("/save", s.putSave).Methods("PUT") r.HandleFunc("/entryRows", s.getEntries).Methods("GET") + r.HandleFunc("/edit", s.getEdit).Methods("GET") r.HandleFunc("/", s.rootHandle) http.Handle("/", r) -- cgit v1.2.3