task project

This commit is contained in:
Erik Winter 2024-12-31 08:37:00 +01:00
parent 23a3f59f48
commit 8dc93f227e
11 changed files with 65 additions and 13 deletions

BIN
dist/plan vendored

Binary file not shown.

View File

@ -10,6 +10,7 @@ import (
type TaskBody struct { type TaskBody struct {
Title string `json:"title"` Title string `json:"title"`
Project string `json:"project"`
Time Time `json:"time"` Time Time `json:"time"`
Duration time.Duration `json:"duration"` Duration time.Duration `json:"duration"`
} }

View File

@ -53,6 +53,7 @@ func TestNewTask(t *testing.T) {
Recurrer: item.NewRecurrer("2024-12-08, daily"), Recurrer: item.NewRecurrer("2024-12-08, daily"),
Body: `{ Body: `{
"title":"title", "title":"title",
"project":"project",
"time":"08:00", "time":"08:00",
"duration":"1h" "duration":"1h"
}`, }`,
@ -63,6 +64,7 @@ func TestNewTask(t *testing.T) {
Recurrer: item.NewRecurrer("2024-12-08, daily"), Recurrer: item.NewRecurrer("2024-12-08, daily"),
TaskBody: item.TaskBody{ TaskBody: item.TaskBody{
Title: "title", Title: "title",
Project: "project",
Time: item.NewTime(8, 0), Time: item.NewTime(8, 0),
Duration: oneHour, Duration: oneHour,
}, },
@ -102,7 +104,7 @@ func TestTaskItem(t *testing.T) {
expItem: item.Item{ expItem: item.Item{
Kind: item.KindTask, Kind: item.KindTask,
Updated: time.Time{}, Updated: time.Time{},
Body: `{"duration":"0s","title":"","time":""}`, Body: `{"duration":"0s","title":"","project":"","time":""}`,
}, },
}, },
{ {
@ -112,6 +114,7 @@ func TestTaskItem(t *testing.T) {
Date: item.NewDate(2024, 9, 23), Date: item.NewDate(2024, 9, 23),
TaskBody: item.TaskBody{ TaskBody: item.TaskBody{
Title: "title", Title: "title",
Project: "project",
Time: item.NewTime(8, 0), Time: item.NewTime(8, 0),
Duration: oneHour, Duration: oneHour,
}, },
@ -121,7 +124,7 @@ func TestTaskItem(t *testing.T) {
Kind: item.KindTask, Kind: item.KindTask,
Updated: time.Time{}, Updated: time.Time{},
Date: item.NewDate(2024, 9, 23), Date: item.NewDate(2024, 9, 23),
Body: `{"duration":"1h0m0s","title":"title","time":"08:00"}`, Body: `{"duration":"1h0m0s","title":"title","project":"project","time":"08:00"}`,
}, },
}, },
} { } {

View File

@ -19,6 +19,7 @@ func NewAddArgs() AddArgs {
fieldTPL: map[string][]string{ fieldTPL: map[string][]string{
"date": {"d", "date", "on"}, "date": {"d", "date", "on"},
"time": {"t", "time", "at"}, "time": {"t", "time", "at"},
"project": {"p", "project"},
"duration": {"dur", "duration", "for"}, "duration": {"dur", "duration", "for"},
"recurrer": {"rec", "recurrer"}, "recurrer": {"rec", "recurrer"},
}, },
@ -45,6 +46,9 @@ func (aa AddArgs) Parse(main []string, fields map[string]string) (Command, error
}, },
} }
if val, ok := fields["project"]; ok {
tsk.Project = val
}
if val, ok := fields["date"]; ok { if val, ok := fields["date"]; ok {
d := item.NewDateFromString(val) d := item.NewDateFromString(val)
if d.IsZero() { if d.IsZero() {

View File

@ -38,9 +38,10 @@ func TestAdd(t *testing.T) {
expErr: true, expErr: true,
}, },
{ {
name: "date time duration", name: "all",
main: []string{"add", "title"}, main: []string{"add", "title"},
fields: map[string]string{ fields: map[string]string{
"project": "project",
"date": aDate.String(), "date": aDate.String(),
"time": aTime.String(), "time": aTime.String(),
"duration": anHourStr, "duration": anHourStr,
@ -50,6 +51,7 @@ func TestAdd(t *testing.T) {
Date: aDate, Date: aDate,
TaskBody: item.TaskBody{ TaskBody: item.TaskBody{
Title: "title", Title: "title",
Project: "project",
Time: aTime, Time: aTime,
Duration: anHour, Duration: anHour,
}, },

View File

@ -105,9 +105,15 @@ type ListResult struct {
} }
func (lr ListResult) Render() string { func (lr ListResult) Render() string {
data := [][]string{{"id", "date", "dur", "title"}} data := [][]string{{"id", "project", "date", "dur", "title"}}
for _, tl := range lr.Tasks { for _, tl := range lr.Tasks {
data = append(data, []string{fmt.Sprintf("%d", tl.LocalID), tl.Task.Date.String(), tl.Task.Duration.String(), tl.Task.Title}) data = append(data, []string{
fmt.Sprintf("%d", tl.LocalID),
tl.Task.Project,
tl.Task.Date.String(),
tl.Task.Duration.String(),
tl.Task.Title,
})
} }
return fmt.Sprintf("\n%s\n", format.Table(data)) return fmt.Sprintf("\n%s\n", format.Table(data))

View File

@ -72,6 +72,7 @@ func (sr ShowResult) Render() string {
data := [][]string{ data := [][]string{
{"title", sr.Task.Title}, {"title", sr.Task.Title},
{"local id", fmt.Sprintf("%d", sr.LocalID)}, {"local id", fmt.Sprintf("%d", sr.LocalID)},
{"project", sr.Task.Project},
{"date", sr.Task.Date.String()}, {"date", sr.Task.Date.String()},
{"time", sr.Task.Time.String()}, {"time", sr.Task.Time.String()},
{"duration", sr.Task.Duration.String()}, {"duration", sr.Task.Duration.String()},

View File

@ -15,6 +15,7 @@ type UpdateArgs struct {
fieldTPL map[string][]string fieldTPL map[string][]string
LocalID int LocalID int
Title string Title string
Project string
Date item.Date Date item.Date
Time item.Time Time item.Time
Duration time.Duration Duration time.Duration
@ -24,6 +25,7 @@ type UpdateArgs struct {
func NewUpdateArgs() UpdateArgs { func NewUpdateArgs() UpdateArgs {
return UpdateArgs{ return UpdateArgs{
fieldTPL: map[string][]string{ fieldTPL: map[string][]string{
"project": {"p", "project"},
"date": {"d", "date", "on"}, "date": {"d", "date", "on"},
"time": {"t", "time", "at"}, "time": {"t", "time", "at"},
"duration": {"dur", "duration", "for"}, "duration": {"dur", "duration", "for"},
@ -49,6 +51,9 @@ func (ua UpdateArgs) Parse(main []string, fields map[string]string) (Command, er
Title: strings.Join(main[2:], " "), Title: strings.Join(main[2:], " "),
} }
if val, ok := fields["project"]; ok {
args.Project = val
}
if val, ok := fields["date"]; ok { if val, ok := fields["date"]; ok {
d := item.NewDateFromString(val) d := item.NewDateFromString(val)
if d.IsZero() { if d.IsZero() {
@ -102,6 +107,9 @@ func (u *Update) Do(deps Dependencies) (CommandResult, error) {
if u.args.Title != "" { if u.args.Title != "" {
tsk.Title = u.args.Title tsk.Title = u.args.Title
} }
if u.args.Project != "" {
tsk.Project = u.args.Project
}
if !u.args.Date.IsZero() { if !u.args.Date.IsZero() {
tsk.Date = u.args.Date tsk.Date = u.args.Date
} }

View File

@ -20,6 +20,7 @@ func TestUpdateExecute(t *testing.T) {
t.Errorf("exp nil, got %v", err) t.Errorf("exp nil, got %v", err)
} }
title := "title" title := "title"
project := "project"
aDate := item.NewDate(2024, 10, 6) aDate := item.NewDate(2024, 10, 6)
aTime := item.NewTime(10, 0) aTime := item.NewTime(10, 0)
twoHour, err := time.ParseDuration("2h") twoHour, err := time.ParseDuration("2h")
@ -54,6 +55,25 @@ func TestUpdateExecute(t *testing.T) {
Date: item.NewDate(2024, 10, 6), Date: item.NewDate(2024, 10, 6),
TaskBody: item.TaskBody{ TaskBody: item.TaskBody{
Title: "updated", Title: "updated",
Project: project,
Time: aTime,
Duration: oneHour,
},
},
},
{
name: "project",
localID: lid,
main: []string{"update", fmt.Sprintf("%d", lid)},
fields: map[string]string{
"p": "updated",
},
expTask: item.Task{
ID: tskID,
Date: item.NewDate(2024, 10, 2),
TaskBody: item.TaskBody{
Title: title,
Project: "updated",
Time: aTime, Time: aTime,
Duration: oneHour, Duration: oneHour,
}, },
@ -80,6 +100,7 @@ func TestUpdateExecute(t *testing.T) {
Date: item.NewDate(2024, 10, 2), Date: item.NewDate(2024, 10, 2),
TaskBody: item.TaskBody{ TaskBody: item.TaskBody{
Title: title, Title: title,
Project: project,
Time: aTime, Time: aTime,
Duration: oneHour, Duration: oneHour,
}, },
@ -106,6 +127,7 @@ func TestUpdateExecute(t *testing.T) {
Date: item.NewDate(2024, 10, 6), Date: item.NewDate(2024, 10, 6),
TaskBody: item.TaskBody{ TaskBody: item.TaskBody{
Title: title, Title: title,
Project: project,
Time: item.NewTime(11, 0), Time: item.NewTime(11, 0),
Duration: oneHour, Duration: oneHour,
}, },
@ -132,6 +154,7 @@ func TestUpdateExecute(t *testing.T) {
Date: item.NewDate(2024, 10, 6), Date: item.NewDate(2024, 10, 6),
TaskBody: item.TaskBody{ TaskBody: item.TaskBody{
Title: title, Title: title,
Project: project,
Time: aTime, Time: aTime,
Duration: twoHour, Duration: twoHour,
}, },
@ -157,6 +180,7 @@ func TestUpdateExecute(t *testing.T) {
Recurrer: item.NewRecurrer("2024-12-08, daily"), Recurrer: item.NewRecurrer("2024-12-08, daily"),
TaskBody: item.TaskBody{ TaskBody: item.TaskBody{
Title: title, Title: title,
Project: project,
Time: aTime, Time: aTime,
Duration: oneHour, Duration: oneHour,
}, },
@ -173,6 +197,7 @@ func TestUpdateExecute(t *testing.T) {
Date: aDate, Date: aDate,
TaskBody: item.TaskBody{ TaskBody: item.TaskBody{
Title: title, Title: title,
Project: project,
Time: aTime, Time: aTime,
Duration: oneHour, Duration: oneHour,
}, },

View File

@ -40,4 +40,5 @@ var migrations = []string{
SELECT id, local_id FROM localids_backup`, SELECT id, local_id FROM localids_backup`,
`DROP TABLE localids_backup`, `DROP TABLE localids_backup`,
`ALTER TABLE items ADD COLUMN date TEXT NOT NULL DEFAULT ''`, `ALTER TABLE items ADD COLUMN date TEXT NOT NULL DEFAULT ''`,
`ALTER TABLE tasks ADD COLUMN project TEXT NOT NULL DEFAULT ''`,
} }

View File

@ -20,19 +20,20 @@ func (t *SqliteTask) Store(tsk item.Task) error {
} }
if _, err := t.db.Exec(` if _, err := t.db.Exec(`
INSERT INTO tasks INSERT INTO tasks
(id, title, date, time, duration, recurrer) (id, title, project, date, time, duration, recurrer)
VALUES VALUES
(?, ?, ?, ?, ?, ?) (?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE ON CONFLICT(id) DO UPDATE
SET SET
title=?, title=?,
project=?,
date=?, date=?,
time=?, time=?,
duration=?, duration=?,
recurrer=? recurrer=?
`, `,
tsk.ID, tsk.Title, tsk.Date.String(), tsk.Time.String(), tsk.Duration.String(), recurStr, tsk.ID, tsk.Title, tsk.Project, tsk.Date.String(), tsk.Time.String(), tsk.Duration.String(), recurStr,
tsk.Title, tsk.Date.String(), tsk.Time.String(), tsk.Duration.String(), recurStr); err != nil { tsk.Title, tsk.Project, tsk.Date.String(), tsk.Time.String(), tsk.Duration.String(), recurStr); err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
return nil return nil
@ -42,9 +43,9 @@ func (t *SqliteTask) FindOne(id string) (item.Task, error) {
var tsk item.Task var tsk item.Task
var dateStr, timeStr, recurStr, durStr string var dateStr, timeStr, recurStr, durStr string
err := t.db.QueryRow(` err := t.db.QueryRow(`
SELECT id, title, date, time, duration, recurrer SELECT id, title, project, date, time, duration, recurrer
FROM tasks FROM tasks
WHERE id = ?`, id).Scan(&tsk.ID, &tsk.Title, &dateStr, &timeStr, &durStr, &recurStr) WHERE id = ?`, id).Scan(&tsk.ID, &tsk.Title, &tsk.Project, &dateStr, &timeStr, &durStr, &recurStr)
switch { switch {
case err == sql.ErrNoRows: case err == sql.ErrNoRows:
return item.Task{}, fmt.Errorf("event not found: %w", err) return item.Task{}, fmt.Errorf("event not found: %w", err)
@ -64,7 +65,7 @@ WHERE id = ?`, id).Scan(&tsk.ID, &tsk.Title, &dateStr, &timeStr, &durStr, &recur
} }
func (t *SqliteTask) FindMany(params storage.TaskListParams) ([]item.Task, error) { func (t *SqliteTask) FindMany(params storage.TaskListParams) ([]item.Task, error) {
query := `SELECT id, title, date, time, duration, recurrer FROM tasks` query := `SELECT id, title, project, date, time, duration, recurrer FROM tasks`
args := []interface{}{} args := []interface{}{}
where := []string{} where := []string{}
@ -96,7 +97,7 @@ func (t *SqliteTask) FindMany(params storage.TaskListParams) ([]item.Task, error
for rows.Next() { for rows.Next() {
var tsk item.Task var tsk item.Task
var dateStr, timeStr, recurStr, durStr string var dateStr, timeStr, recurStr, durStr string
if err := rows.Scan(&tsk.ID, &tsk.Title, &dateStr, &timeStr, &durStr, &recurStr); err != nil { if err := rows.Scan(&tsk.ID, &tsk.Title, &tsk.Project, &dateStr, &timeStr, &durStr, &recurStr); err != nil {
return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err) return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
dur, err := time.ParseDuration(durStr) dur, err := time.ParseDuration(durStr)