oncall-engine/dev/frontend_guidelines.md
Dominik Broj 3e4407b2b7
add frontend guidelines (#4344)
# What this PR does

Add frontend guidelines as md file


## Checklist

- [ ] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] Added the relevant release notes label (see labels prefixed w/
`release:`). These labels dictate how your PR will
    show up in the autogenerated release notes.

---------

Co-authored-by: Rares Mardare <rares.mardare@grafana.com>
2024-05-16 04:09:32 +00:00

5 KiB
Raw Blame History

OnCall Frontend Guidelines

The base guidelines we decided to follow are:

Anything that is either not covered by the materials above or we decided to do differently is stated in this document.

Ways of working

Code reviews

  • PR can be merged when the following conditions are met:
    • CI pipeline succeeded without bypassing checks
    • There is at least 1 approval from the frontend team and no opened remarks from reviewers other than the approver
    • All comments are replied, answered, addressed or discussed separately
    • We make use of builtin GH PR reviews
    • Minor comments that dont need to be addressed right away and are not a blocker for a merge are marked with “Minor: “ prefix
    • Unless there is some important hotfix to make and no frontend mates are available

Technical conventions

Type-safety

  • Dont use implicit / explicit any or @ts-ignore

Use auto generated types for new features

  • For new features and endpoints that are covered by OpenApi schemas, we should use auto generated types and typed http client

Naming conventions on most used variables such as handlers, booleans etc

  • Use descriptive naming (such as the use of is) that follows natural convention such as isFormVerified or isAuthenticated instead of verified, authenticated etc
  • Use descriptive naming for event handlers such as onIconClick or onInputChange rather than handleChange
  • Include the verb part in the functions names
  • For 3 or more function arguments use object destructuring https://github.com/ryanmcdermott/clean-code-javascript?tab=readme-ov-file#function-arguments-2-or-fewer-ideally
  • For functions that return other functions getBlaBlaHandler (in case of handlers) or getBlaBlaFn (if its not handler that is returned)
  • Dont use higher-ordered functions without clear need

State management

Dont use returned values from MobX actions

  • MobX actions should not return value that is later used within components. Instead MobX actions should update observables and then components should consume observables to reflect data updates.

Leverage small global stores over local state passed as props over multiple levels

  • Create small specialized store in MobX even for small feature instead of relying on local state that is passed down the React tree over multiple levels e.g.: alert_receive_channel_connected_channels.ts alert_receive_channel_webhooks.ts

Use global decorators / custom hooks / utilities consistently

  • For example:
    • @WithGlobalNotification to set successful / failing notification based on MobX actions result
    • @AutoLoadingState to manage loading statuses of async actions
    • useIsLoading to consume loading state
    • useDrawer to manage drawers
    • useConfirmModal to manage confirm modal
    • Global helpers

Code organization

Store files in appropriate places

  • Store files in appropriate places (components, containers, models etc)
  • Helpers and configs should be stored in the same folder with the appropriate name e.g. [container].helper.ts, [container].config.ts
  • Project-wide utilities should be placed in the utils folder`
  • Use named exports for all code you want to export from a file.
  • Export only the code that is meant to be used outside the module.

Dont opt-out from eslint / TS rules

  • Avoid opting out from eslint or TS rules unless there is a strong reason / lack of possibility to follow the rule

Styling

Use Emotion.js with agreed code style

  • Use emotion.js for styling
  • Make use of useStyles2 hook
  • Use css `` syntax
  • Place getStyles function at the end of the same file or in the separate file with X.styles.ts suffix (if its reused by multiple components or its too large for placing in the same components file)

React

Keep components functional and small

  • Use functional components for new features
  • Leverage components composition, use many small components, render list items in dedicated component and dereference values late https://mobx.js.org/react-optimizations.html
  • Keep components small and flat
  • Use dedicated components over render functions in case a there's a risk that a single component grows too much
  • Static values (especially non-primitive) that dont depend on local state, props or store should be extracted out of component
  • Dont create unnecessary local state that duplicates parts of global store
  • Leverage custom hooks to extract repetitive logic
  • Dont use useMemo / useCallback by default

Architecture

Use layered architecture

  • Dont interact with backend directly from components
  • Dont interact with 3rd party (faro, web storage etc) directly but rather through service

Frontend-backend communication

Use typed HTTP request and response payloads

  • HTTP request payload and response payload should always be typed
  • Use typed http client whenever we have auto-generated types available