From d8dc642ab6ecfe4131db9d8b418e6f56335aa732 Mon Sep 17 00:00:00 2001 From: Noah Gillard Date: Wed, 22 May 2024 22:46:57 +0200 Subject: [PATCH] :sparkles: Add start date and end date option parameters to list command --- README.md | 55 ++++++++++++++++++++++++++++++++++++------------ commands/list.js | 48 +++++++++++++++++++++--------------------- index.js | 4 +++- 3 files changed, 68 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 7a484c9..9ba783c 100644 --- a/README.md +++ b/README.md @@ -5,44 +5,58 @@ # Toggl2Timeshit -This is a simple tool to convert Toggl reports to a timesheet format. +Toggl2Timeshit is a simple yet powerful tool to convert Toggl Track reports into a user-friendly timesheet format. -## Usage +## Features +- Fetch time entries from Toggl Track. +- Group and display time entries by project. +- Summarize total hours spent per project and per day. +- Support for custom date ranges. -1. Install the package globally: +## Installation +Install the package globally using npm: ```bash npm install -g toggl2timeshit ``` -2. Authenticate with your Toggle API key: - -> You can find it in your [Toggl Track Profile](https://track.toggl.com/profile).` +## Authentication + +You can find it in your [Toggl Track Profile](https://track.toggl.com/profile).` ```bash npx timeshit login ``` -3. Run the command to generate the timesheet: +## Usage +### Generate Timesheet for Today +Run the command to generate the timesheet for today: ```bash npx timeshit list ``` -This will prompt you to select the workspace you want to generate the timesheet for. +## Generate Timesheet for a Custom Date Range +You can also specify a custom date range using the --startDate (-sd) and --endDate (-ed) options: -Type the number of the workspace and press enter. +```bash +npx timeshit list --startDate YYYY-MM-DD --endDate YYYY-MM-DD +``` -![Select workspace](./docs/images/select-workspace.png) +## Generate Timesheet for a Specific Date +You can also specify a specific date using the --startDate (-sd) option alone: -OUPUT: +```bash +npx timeshit list --startDate YYYY-MM-DD +``` +## Example Output ```bash Your current time entries: Project A +++++++++ -Total hours today: 0.60 +Total hours: 0.60 Tickets: • Entry 1 name (0.27) @@ -52,7 +66,7 @@ Tickets: Project B +++++++++ -Total hours today: 1.56 +Total hours: 1.56 Tickets: • Entry 1 name (0.61) @@ -63,7 +77,7 @@ Tickets: Project C +++++++++ -Total hours today: 0.53 +Total hours: 0.53 Tickets: • Entry 1 name (0.53) @@ -74,3 +88,16 @@ Tickets: Total hours today: 3.49 Total hours yesterday: 0.00 ``` + +## Contributing +We welcome contributions to Toggl2Timeshit! If you have any improvements or bug fixes, please open an issue or submit a pull request on GitHub. + +## License +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. + +## Connect +- Follow me on Twitter: [@does_it_code](https://twitter.com/does_it_code) +- Connect with me on LinkedIn: [Noah Nxumalo](https://www.linkedin.com/in/noah-gillard/) + +Feel free to reach out with any questions or feedback! Enjoy using Toggl2Timeshit to simplify your timesheet generation. + diff --git a/commands/list.js b/commands/list.js index 36d4054..581a2ad 100644 --- a/commands/list.js +++ b/commands/list.js @@ -9,6 +9,7 @@ import fs from "fs"; import path from "path"; import os from "os"; import createPrompt from "prompt-sync"; +import { program } from "commander"; const prompt = createPrompt({}); @@ -31,12 +32,8 @@ const yesterday = dayjs() const today = dayjs().tz(currTz).startOf("day").toISOString(); const tomorrow = dayjs().add(1, "days").tz(currTz).startOf("day").toISOString(); -const timeEntriesUrl = `https://api.track.toggl.com/api/v9/me/time_entries?start_date=${today}&end_date=${tomorrow}`; - -const timeEntriesJson = await fetchTimeEntries(); - -async function fetchTimeEntries() { - const timeEntriesResponse = await fetch(timeEntriesUrl, { +async function fetchTimeEntries(url) { + const timeEntriesResponse = await fetch(url, { method: "GET", headers: { "Content-Type": "application/json", @@ -101,12 +98,25 @@ async function selectWorkspaceId() { return workspaces[selectedIndex - 1].id; } -export async function list() { +export async function list(options) { + const { startDate, endDate } = options; + const workspaceId = await selectWorkspaceId(); if (!workspaceId) { return; } + // Use provided dates or default to today and tomorrow + const start = startDate + ? dayjs(startDate).tz(currTz).startOf("day").toISOString() + : today; + const end = endDate + ? dayjs(endDate).tz(currTz).startOf("day").toISOString() + : tomorrow; + + const timeEntriesUrl = `https://api.track.toggl.com/api/v9/me/time_entries?start_date=${start}&end_date=${end}`; + const timeEntriesJson = await fetchTimeEntries(timeEntriesUrl); + const projectsUrl = `https://api.track.toggl.com/api/v9/workspaces/${workspaceId}/projects`; const projectsResponse = await fetch(projectsUrl, { @@ -164,7 +174,7 @@ export async function list() { console.log(chalk.green("+".repeat(projectName.length))); console.log( - chalk.white(`Total hours today: ${projectData.totalHours.toFixed(2)}`), + chalk.white(`Total hours: ${projectData.totalHours.toFixed(2)}`), ); console.log(); @@ -179,29 +189,19 @@ export async function list() { console.log(); }); - const yesterdayEntries = validTimeEntries.filter((entry) => - dayjs(entry.start).isBetween(yesterday, today), + const filteredEntries = validTimeEntries.filter((entry) => + dayjs(entry.start).isBetween(start, end), ); - const totalHoursYesterday = yesterdayEntries.reduce( + const totalHours = filteredEntries.reduce( (acc, entry) => acc + entry.duration / 3600, 0, ); console.log(chalk.yellow("=============================")); - const totalHoursToday = Object.values(groupedEntries).reduce( - (acc, project) => acc + project.totalHours, - 0, - ); - if (totalHoursToday < 8) { - console.log(chalk.red(`Total hours today: ${totalHoursToday.toFixed(2)}`)); + if (totalHours < 8) { + console.log(chalk.red(`Total hours: ${totalHours.toFixed(2)}`)); } else { - console.log( - chalk.green(`Total hours today: ${totalHoursToday.toFixed(2)}`), - ); + console.log(chalk.green(`Total hours: ${totalHours.toFixed(2)}`)); } - console.log( - chalk.yellow(`Total hours yesterday: ${totalHoursYesterday.toFixed(2)}`), - ); - console.log(); } diff --git a/index.js b/index.js index a29b3e8..7ab9911 100755 --- a/index.js +++ b/index.js @@ -7,9 +7,11 @@ import { login } from "./commands/login.js"; program .command("list") + .option("-sd, --start-date ", "Start date for time entries YYYY-MM-DD") + .option("-ed, --end-date ", "End date for time entries YYYY-MM-DD") .description("List tracked time registries per project.") .action(list); program.command("login").description("Login to Toggl.").action(login); -program.parse(); +program.parse(process.argv);