Skip to content

Commit

Permalink
feat: dynamic width for reports
Browse files Browse the repository at this point in the history
  • Loading branch information
dhth committed Jun 14, 2024
1 parent ce665ea commit d909896
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 96 deletions.
2 changes: 1 addition & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ brews:
directory: Formula
license: MIT
homepage: "https://github.com/dhth/hours"
description: "A no-frills command-line app for tracking time on tasks"
description: "A no-frills time tracking toolkit for the command line"

changelog:
sort: asc
Expand Down
151 changes: 65 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# hours

✨ Overview
---
`hours` is a no-frills time tracking toolkit for the command line.

It's designed for users who want basic time tracking for their tasks/projects
right in the terminal. With a simple and minimalistic UI, almost everything in
`hours` can be achieved with one or two keypresses. It can also generate
plaintext reports, summary statistics, and logs based on time tracked.

![Usage](https://tools.dhruvs.space/images/hours/hours.gif)

`hours` is a no-frills command-line app for tracking time on tasks. It's
designed for users who want basic time tracking for their tasks/projects, right
in the terminal. With a simple and minimalistic UI, almost everything in `hours`
can be achieved with one or two keypresses. It can also generate plaintext
reports, summary statistics, and logs based on time tracked.
[Link to Video][2]

🤔 Motivation
---
Expand All @@ -22,6 +24,12 @@ precisely fit these needs, so I decided to build one for myself.
💾 Install
---

**homebrew**:

```sh
brew install dhth/tap/hours
```

**go**:

```sh
Expand All @@ -31,6 +39,8 @@ go install github.com/dhth/hours@latest
⚡️ Usage
---

### TUI

Open the TUI by simply running `hours`. The TUI lets you do the following:

- create/update tasks
Expand All @@ -39,125 +49,93 @@ Open the TUI by simply running `hours`. The TUI lets you do the following:
- deactivate/activate a task
- view historical task log entries

![Usage](https://tools.dhruvs.space/images/hours/tui-1.png)

![Usage](https://tools.dhruvs.space/images/hours/tui-2.png)

![Usage](https://tools.dhruvs.space/images/hours/tui-3.png)

Besides a TUI, `hours` also offers reports, statistics, and logs based on the
time tracking you do. These can be viewed using the subcommands `report`,
`stats`, and `log` respectively.

### Reports

```bash
hours report [flags] [arg]
```
hours report -h

Output a report based on task log entries.

Reports show time spent on tasks per day in the time period you specify. These
can also be aggregated (using -a) to consolidate all task entries and show the
can also be aggregated (using `-a`) to consolidate all task entries and show the
cumulative time spent on each task per day.

Accepts an argument, which can be one of the following:

today: for today's report
yest: for yesterday's report
3d: for a report on the last 3 days (default)
week: for a report on the current week
date: for a report for a specific date (eg. "2024/06/08")
range: for a report for a date range (eg. "2024/06/08...2024/06/12")
today: for today's report
yest: for yesterday's report
3d: for a report on the last 3 days (default)
week: for a report on the current week
date: for a report for a specific date (eg. "2024/06/08")
range: for a report for a date range (eg. "2024/06/08...2024/06/12")

Note: If a task log continues past midnight in your local timezone, it
will be reported on the day it ends.
*Note: If a task log continues past midnight in your local timezone, it will be
reported on the day it ends.*

Usage:
hours report [flags]
![Usage](https://tools.dhruvs.space/images/hours/report-1.png)

Flags:
-a, --agg whether to aggregate data by task for each day in report
-p, --plain whether to output report without any formatting
```
### Logs

```bash
# see report from last 3 days
hours report

# see aggregated time spent on tasks
hours report -a

# see report for the 7 days
hours report week

# see report for a specific date range
hours report 2024/06/08...2024/06/12
```

Statistics
---

hours log [flags] [arg]
```
hours stats -h

Output statistics for tracked time.
Output task log entries.

Accepts an argument, which can be one of the following:

today: show stats for today
yest: show stats for yesterday
3d: show stats for the last 3 days (default)
week: show stats for the current week
month: show stats for the current month
date: show stats for a specific date (eg. "2024/06/08")
range: show stats for a specific date range (eg. "2024/06/08...2024/06/12")
all: show stats for all log entries
Note: If a task log continues past midnight in your local timezone, it'll
be considered in the stats for the day it ends.
today: for log entries from today
yest: for log entries from yesterday
3d: for log entries from the last 3 days (default)
week: for log entries from the current week
date: for log entries from a specific date (eg. "2024/06/08")
range: for log entries from a specific date range (eg. "2024/06/08...2024/06/12")

Usage:
hours stats [flags]
*Note: If a task log continues past midnight in your local timezone, it'll
appear in the log for the day it ends.*

Flags:
-p, --plain whether to output stats without any formatting
```
![Usage](https://tools.dhruvs.space/images/hours/log-1.png)

### Logs
Statistics
---

```bash
hours stats [flag] [arg]
```
hours log -h

Output task log entries.
Output statistics for tracked time.

Accepts an argument, which can be one of the following:

today: for log entries from today
yest: for log entries from yesterday
3d: for log entries from the last 3 days (default)
week: for log entries from the current week
date: for log entries from a specific date (eg. "2024/06/08")
range: for log entries from a specific date range (eg. "2024/06/08...2024/06/12")
Note: If a task log continues past midnight in your local timezone, it'll
appear in the log for the day it ends.
Usage:
hours log [flags]
Flags:
-p, --plain whether to output log without any formatting
```
today: show stats for today
yest: show stats for yesterday
3d: show stats for the last 3 days (default)
week: show stats for the current week
month: show stats for the current month
date: show stats for a specific date (eg. "2024/06/08")
range: show stats for a specific date range (eg. "2024/06/08...2024/06/12")
all: show stats for all log entries

```bash
# see log entries from today
hours log today
*Note: If a task log continues past midnight in your local timezone, it'll
be considered in the stats for the day it ends.*

# see log entries from a specific day
hours log 2024/06/08

# see log entries from a specific date range
hours log 2024/06/08...2024/06/12
```
![Usage](https://tools.dhruvs.space/images/hours/stats-1.png)

📋 TUI Reference Manual
---

```
```text
"hours" has 5 panes:
- Tasks List View Shows your tasks
- Task Management View Allows you to create/update tasks
Expand Down Expand Up @@ -213,3 +191,4 @@ Acknowledgements
`hours` is built using the TUI framework [bubbletea][1].

[1]: https://github.com/charmbracelet/bubbletea
[2]: https://www.youtube.com/watch?v=o244r1nyxac
7 changes: 6 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ func die(msg string, args ...any) {

var rootCmd = &cobra.Command{
Use: "hours",
Short: "Track time on your tasks via a simple TUI.",
Short: "\"hours\" is a no-frills time tracking toolkit for the command line",
Long: `"hours" is a no-frills time tracking toolkit for the command line.
You can use "hours" to track time on your tasks, or view logs, reports, and
summary statistics for your tracked time.
`,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
if dbPath == "" {
die("dbpath cannot be empty")
Expand Down
40 changes: 32 additions & 8 deletions internal/ui/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,18 @@ func renderNDaysReport(db *sql.DB, writer io.Writer, start time.Time, numDays in

rs := getReportStyles(plain)

var summaryBudget int
switch numDays {
case 7:
summaryBudget = 8
case 6:
summaryBudget = 10
case 5:
summaryBudget = 14
default:
summaryBudget = 16
}

styleCache := make(map[string]lipgloss.Style)
for rowIndex := 0; rowIndex < maxEntryForADay; rowIndex++ {
row := make([]string, numDays)
Expand All @@ -166,8 +178,8 @@ func renderNDaysReport(db *sql.DB, writer io.Writer, start time.Time, numDays in
timeSpentStr := humanizeDuration(tr.secsSpent)

if plain {
row[colIndex] = fmt.Sprintf("%s %s",
RightPadTrim(tr.taskSummary, 8, false),
row[colIndex] = fmt.Sprintf("%s %s",
RightPadTrim(tr.taskSummary, summaryBudget, false),
timeSpentStr,
)
} else {
Expand All @@ -178,8 +190,8 @@ func renderNDaysReport(db *sql.DB, writer io.Writer, start time.Time, numDays in
styleCache[tr.taskSummary] = reportStyle
}

row[colIndex] = fmt.Sprintf("%s %s",
reportStyle.Render(RightPadTrim(tr.taskSummary, 8, false)),
row[colIndex] = fmt.Sprintf("%s %s",
reportStyle.Render(RightPadTrim(tr.taskSummary, summaryBudget, false)),
reportStyle.Render(timeSpentStr),
)
}
Expand Down Expand Up @@ -268,6 +280,18 @@ func renderNDaysReportAgg(db *sql.DB, writer io.Writer, start time.Time, numDays

rs := getReportStyles(plain)

var summaryBudget int
switch numDays {
case 7:
summaryBudget = 8
case 6:
summaryBudget = 10
case 5:
summaryBudget = 14
default:
summaryBudget = 16
}

styleCache := make(map[string]lipgloss.Style)
for rowIndex := 0; rowIndex < maxEntryForADay; rowIndex++ {
row := make([]string, numDays)
Expand All @@ -281,8 +305,8 @@ func renderNDaysReportAgg(db *sql.DB, writer io.Writer, start time.Time, numDays
timeSpentStr := humanizeDuration(tr.secsSpent)

if plain {
row[colIndex] = fmt.Sprintf("%s %s",
RightPadTrim(tr.taskSummary, 8, false),
row[colIndex] = fmt.Sprintf("%s %s",
RightPadTrim(tr.taskSummary, summaryBudget, false),
timeSpentStr,
)
} else {
Expand All @@ -292,8 +316,8 @@ func renderNDaysReportAgg(db *sql.DB, writer io.Writer, start time.Time, numDays
styleCache[tr.taskSummary] = reportStyle
}

row[colIndex] = fmt.Sprintf("%s %s",
reportStyle.Render(RightPadTrim(tr.taskSummary, 8, false)),
row[colIndex] = fmt.Sprintf("%s %s",
reportStyle.Render(RightPadTrim(tr.taskSummary, summaryBudget, false)),
reportStyle.Render(timeSpentStr),
)
}
Expand Down

0 comments on commit d909896

Please sign in to comment.