dwyl / dwyl/app

Start|Stop Timer for Item (Task)

Open
#265 6 comments 2 reactions 0 assignees View on GitHub
awaiting-review discuss enhancement epic MVP please-test priority-2 T1d
Dominant language
Dart
Stars
152
Forks
22
PR merge metrics
No merged PRs in 30d

Description

# Story

As a `person` wanting to _maximise_ my personal effectiveness,
I want be able to associate (`start|stop`) a timer with a task (_todo list item_)
_So that_ I can keep track of how much time I have spent on a given task.

## Context

> _Most_ people listed "_**tracking time** on a **task**_" as highly desirable feature in #262 ❤️

It has _always_ been one of our _core_ objectives to [track time](https://github.com/dwyl/app/blob/4d8af4ca2b723bdd6df7fe42ad663180854e871c/README.md) against tasks.
One of the _most_ frustrating things about _most_ task/todo apps is that they _don't_ have this feature!
_Not_ being able to track the time spent on a task leads to people being distracted/unfocussed.
It's _incredibly_ frustrating to work in a team where it's impossible to see what other teammates are working on or **how _long_** they has spent on a given task. This is a _systematic_ problem of all "ticketing" systems like JIRA, Trello or Asana. It means _everything_ takes longer than it _needs_ to. Let's _fix_ it.

Given that it's a "_core_" feature, we already have the Schema in place for attaching `timers` to `items`.
It's a **`one-to-many`** relationship which means an `item` can have _multiple_ timers.

![image](https://user-images.githubusercontent.com/194400/73312103-db5dd300-421f-11ea-92b5-e81bce094333.png "MVP ER Diagram - Click to view larger!")

This means you can `start|stop` _several_ `timers` for a given `item` and _accumulate_ a _total_ amount of time spent on a task over one or more sessions.

# Todo

+ [x] ***Edit*** the `lib/app_web/templates/item/show.html.eex` template to
+ [x] ***Display*** the `item` _inline_ instead of in a `

  • ` similar to the [TodoMVC UI](https://github.com/dwyl/javascript-todo-list-tutorial#toggle-a-todo-item-to-donetrue)
    + [x] ***Create*** the UI `` to **`start`** & **`stop`** a timer for a task.
    + [x] ***Create*** a `
    ` to display the timer for the task.
    + [x] A timer should appear in the `
    ` when **`start`** button is clicked.
    + [x] ***Create*** a new `test` in `test/app_web/controllers/timer_controller_test.exs`
    + [x] That tests for the insertion of a new `timer` record in the `timers` table.
    + [x] The new timer should be linked to an `item_id`
    + [x] The test should _fail_ before the `function` is written (_because this is new functionality_) ...
    + [x] ***Create*** a new `timer` entry for the `item_id` when the **`start`** button is pressed.
    > In case you are _wondering_ why the `timers` table has both a `start` and `inserted_at` column, it's so that the **`client`** can define the **`start`** (_the time when the timer was started_),
    > but they **cannot** define/change the **`inserted_at`** (_which is controlled by Phoenix/Postgres_)
    > This is to mitigate "time travelling" (_people always "starting" timers in the **past**_) ...
    > The client can still define a `start` in the past, that's "OK" for people who _forget_ to start a timer.
    > But the server will still "_know_" when the `timer` was actually _inserted_ into the DB.
    > So someone waiting till the _end_ of the day to retrospectively start/stop a bunch of timers to make it _look_ like they have been _super_ busy and used their time well will be informed otherwise.
    > People who don't use the app to improve their personal effectiveness by starting timers before they start working on a task, but rather _invent_ a bunch of timers for a time-sheet will be flagged.
    > Don't mistake this for "big brother" _watching_ you, it's "_coach_" making you a _better **teammate**_!
    + [x] ***Write*** the (`Elixir`) `start_timer/1` `function` to be invoked to make the test pass.
    + [x] ***Invoke*** `start_timer/1` when the **`start`** button is clicked/tapped.
    + [x] ***Write*** `JavaScript` code in that _enhances_ the server-rendered page to:
    + [x] ***Render*** a **Clock** in the form `HH:MM:SS` in the `
    ` created above.
    + [x] Only display _relevant_ timer information to keep the UI clean i.e:
    + [x] When only a few seconds have passed show `SS` e.g: `7`, `8`, `9`, etc.
    + [x] When more than 9 seconds have passed show `10`, `11`, `12`, etc.
    + [x] After a _minute_ has passed, show `1:01`, `1:02` etc. where the `0` is now significant.
    + [x] At `9:59` (_nine min and fifty-nine sec_) add the next digit: `10:00`, `10:01`, `10:02`, etc.
    + [x] Once `59:59` has passed add the first _hour_ digit: `1:00:00`
    + [x] Finally if the timer reaches `9:59:59`, add the final digit of significance `10:00:00`
    > **Note**: this format for displaying the time is subject to discussion/change.
    > We just need _something_ for now so that we can _ship_ this feature!
    > For now we do not foresee a timer lasting more than **24 hours**. (_to be tested!_)
    > But if [Goggins](https://youtu.be/TLKxdTmk-zc) starts using our app to time his [runs](https://en.wikipedia.org/wiki/Ultramarathon) we'll craft a UI just for him!
    + [x] ***Update*** the clock each second.
    + [x] ***Create*** a test for the `stop_timer/1` function
    + [x] ***Write*** the `stop_timer/1` function to pass the test
    + [x] `stop_timer/1` should ***Update*** the `timer` record with an `end` value
    + [x] ***Invoke*** `stop_timer/1` when the **`stop`** button is clicked in the UI.

    ## Proposed MVP UI/UX
    This _proposed_ UI/UX is just to create the MVP functionality.
    It _will_ change over time as we _use_ the App and collect _feedback_.
    ![image](https://user-images.githubusercontent.com/194400/73374277-d9445480-42b1-11ea-980a-3fabbfe5a9fd.png)
    https://www.figma.com/file/WrpkKGJNYZbeCzMRDVtvQLbC/dwyl-app?node-id=0%3A1

    ### _Walkthrough_ of UI/UX Screens:

    1. In this UI we can see a `list` with 5 `items` in this case the `list.title` is "Todo List".
    + A **`start`** button is displayed on the _right_ of each `item`
    2. When the **`start`** for a given `item` is clicked:
    + **`start`** button for that `item` is hidden
    + a **`stop`** button appears
    + Hide the **`start`** buttons for all other `items` (_to avoid multiple concurrent timers_)
    + the **`timer`** is displayed above the **`stop`** button.
    + the **`timer`** is updated once per second to show the passing of time.
    3. When the **`stop`** button for a timer that is _running_ is clicked:
    + Hide the **`stop`** button
    + Stop the **`timer`** from counting. (`clearInterval(timer)`)
    + Show the **`start`** timer
    4. If the person clicks/taps the "box" on the left of the `item.text` to signal that the `item` is done:
    + Update the "box" to the "done" arrow version
    + Strikethrough the `item.text` to show that it is complete (_feedback welcome on this UX_)
    + Hide the **`start`** button for this `item` as it's no longer relevant
    + Display the **total** time taken for the `item`

    Feedback on this issue/spec very much welcome. 🙏
    I'm not "precious" about any of it, if you think we can do better UI/UX/functionality, comment!! 💬
    I intend to start _building_ it today. Once it's ready for review I will _assign_ the PR. 📦

Contributor guide

Open the contributing guide

Research direction

Review the checked requirements against lib/app_web/templates/item/show.html.eex and test/app_web/controllers/timer_controller_test.exs, then inspect the existing start_timer/1 and stop_timer/1 entry points. Confirm whether the UI, timer persistence, and tests already satisfy the issue; done is determining the remaining gap, if any, rather than starting the feature from this stale specification.

Written by the indexing model from the issue text.

Assessment

Tech stack
elixir, javascript, postgresql
Domain
backend, databases, frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.