Skip to content

Latest commit

 

History

History
117 lines (82 loc) · 4.78 KB

README.md

File metadata and controls

117 lines (82 loc) · 4.78 KB

example workflow

Space rocket launcher 🚀

You have been tasked with building a re-usable button for a mission control dashboard.

The button needs to make a GET request to a mission control server to ignite the rocket fuel and launch the rocket ship. However, if the rocket fuel takes too long to ignite then something is not right and the request should be abandoned. Also, launching rockets is scary, if the user gets cold feet they need to be able to abort a launch request before it completes.

Instructions

Install package dependencies

yarn install

Start the application

yarn start

Run the battery of unit tests

yarn test

Build and open storybook

yarn build-storybook
yarn storybook

Test the Components

2022-07-28 10 35 20

2022-07-28 10 34 58

Design

Structure decomposition

rocket-launcher/
└── src/
    ├── lib/
    │   ├── hooks/
    │   │   └── useCancellableFetch.ts
    │   └── components/
    │       ├── primitives/
    │       │   ├── Button.ts
    │       │   ├── Tooltip.ts
    │       │   └── Spinner.ts
    │       ├── SmartButton.ts
    │       └── CancellableRequestButton.ts
    └── components/
        └── RocketLauncher.ts

Modules (components, hooks) living inside /lib are shareable and intended to exist within the scope of a UI library.

High level architecture

image

Primitives

Primitives are basic building blocks that can be used to compose more complex components. <Button>, <Tooltip> and <Spinner> can be combined in different ways to fulfill other use cases.

SmartButton

Encapsulates the presentation logic for state transitions. It represents the glue between a normal Button, a Tooltip and their relation. It can be used for use cases where the main operation is not necessarily a Fetch request.

CancellableRequestButton

It is an abstraction on top of <SmartButton> that incorporates HTTP fetching management. It is designed to be used in scenarios similar to Rocket Launching, where we want the user to be able to initiate a request to an HTTP endpoint and apply the same set of transition rules.

State transitions

image

  • By default, the button loads in Ready state.
  • From Ready, the launch button can transition to Working when the user press the button, starting the ignition process.
  • If the launch button is again pressed while its working, it will transition to Errored (canceling the ongoing request inmediately)
  • If the request takes too long to complete, the button will transition to Errored.
  • If there is an error with the fetch operation, the button will transition to Errored.
  • It will be possible to transition from Errored back to Working only if the user has manually aborted the request before so they can retry again.

Stack

Possible improvements

  • Add unit tests to all components
  • Improve the design system and create a design language using tokens.
  • Enhance useCancellabeFetch. HTTP Service could be defined in a global scope and injected into the hook (either via ContextProvider or some form of Service Locator pattern). This way we would have more granular control over HTTP headers, authentication, params/body validation, logging, etc.
  • Add Integration tests for components (Cypress component tests)
  • Add Visual regression tests
  • Fix issues with Tooltip Top placement and potentially remove dependency with Floating-UI. Write custom logic with getBoundingClientRect().
  • Move Common elements to a separate UI library or make the system a monorepo.