From d1eaad0cba111c479810910807705789d7f60408 Mon Sep 17 00:00:00 2001 From: Parkreiner Date: Tue, 3 Oct 2023 22:40:40 +0000 Subject: [PATCH 1/2] docs: update frontend contribution docs --- docs/contributing/frontend.md | 84 ++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/docs/contributing/frontend.md b/docs/contributing/frontend.md index c4d1f22e789d0..76f8ccae72411 100644 --- a/docs/contributing/frontend.md +++ b/docs/contributing/frontend.md @@ -36,7 +36,7 @@ important ones: fetching data - [XState](https://xstate.js.org/docs/) for handling complex state flows - [axios](https://github.com/axios/axios) as fetching lib -- [Playwright](https://playwright.dev/) for E2E testing +- [Playwright](https://playwright.dev/) for end-to-end (E2E) testing - [Jest](https://jestjs.io/) for integration testing - [Storybook](https://storybook.js.org/) and [Chromatic](https://www.chromatic.com/) for visual testing @@ -47,20 +47,18 @@ important ones: All the code related to the UI is inside the `site` folder and we defined a few conventions to help people to navigate through it. -- **e2e** - E2E tests +- **e2e** - End-to-end (E2E) tests - **src** - Source code - **mocks** - [Manual mocks](https://jestjs.io/docs/manual-mocks) used by Jest - - **@types** - Custom types for dependencies that don't have defined types + - **@types** - Custom types for dependencies that don't have defined types (largely code that has no server-side equivalent) - **api** - API code as function calls and types - **components** - UI components - **hooks** - Hooks that can be used across the application - - **i18n** - Translations - **pages** - Page components - **testHelpers** - Helper functions to help with integration tests - **util** - Helper functions that can be used across the application - - **xServices** - XState machines used to fetch data and handle complex - scenarios -- **static** - UI static assets like images, fonts, icons, etc + - **xServices** - XState machines used to handle complex state representations +- **static** - Static UI assets like images, fonts, icons, etc ## Routing @@ -88,10 +86,10 @@ to the view. We explain this decision a bit better in the next section. ### States -A page usually has at least three states: **loading**, **ready** or **success**, -and **error** so remember to always handle these scenarios while you are coding +A page usually has at least three states: **loading**, **ready**/**success**, +and **error**, so always remember to handle these scenarios while you are coding a page. We also encourage you to add visual testing for these three states using -the `*.stories.ts` file. +a `*.stories.ts` file. ## Fetching data @@ -107,8 +105,8 @@ states and transitions. ### Where to fetch data -Finding the right place to fetch data in React apps is the one million dollar -question but we decided to make it only in the page components and pass the +Finding the right place to fetch data in React apps is the million-dollar +question, but we decided to make it only in the page components and pass the props down to the views. This makes it easier to find where data is being loaded and easy to test using Storybook. So you will see components like `UsersPage` and `UsersPageView`. @@ -118,8 +116,8 @@ and `UsersPageView`. We are using [axios](https://github.com/axios/axios) as our fetching library and writing the API functions in the `site/src/api/api.ts` files. We also have auto-generated types from our Go server on `site/src/api/typesGenerated.ts`. -Usually, every endpoint has its own ` Request` and `Response` types but -sometimes you need to pass extra parameters to make the call like the example +Usually, every endpoint has its own ` Request` and `Response` types, but +sometimes you need to pass extra parameters to make the call, like in the example below: ```ts @@ -133,8 +131,8 @@ export const getAgentListeningPorts = async ( }; ``` -Sometimes, a FE operation can have multiple API calls so it is ok to wrap it as -a single function. +Sometimes, a frontend operation can have multiple API calls, so it is okay to +wrap it as a single function. ```ts export const updateWorkspaceVersion = async ( @@ -150,10 +148,11 @@ separated and use XState for that. ## Components -We are using [Material V4](https://v4.mui.com/) in our UI and we don't have any -short-term plans to update or even replace it. It still provides good value for -us and changing it would cost too much work which is not valuable right now but -of course, it can change in the future. +The codebase is currently using MUI v5. Please see the +[official documentation](https://mui.com/material-ui/getting-started/). In +general, favor building a custom component via MUI instead of plain React/HTML, +as MUI's suite of components is thoroughly battle-tested and accessible right +out of the box. ### Structure @@ -163,29 +162,52 @@ remain easy to navigate, healthy and maintainable for all contributors. ### Accessibility -We strive to keep our UI accessible. When using colors, avoid adding new -elements with low color contrast. Always use labels on inputs, not just -placeholders. These are important for screen-readers. +We strive to keep our UI accessible. + +In general, colors should come from the app theme, but if there is a need to add +a custom color, please ensure that the foreground and background have a minimum +contrast ratio of 4.5:1 to meet WCAG level AA compliance. WebAIM has [a great tool for checking your colors directly](https://webaim.org/resources/contrastchecker/), but tools like +[Dequeue's axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd) +can also do automated checks in certain situations. + +When using any kind of input element, always make sure that there is a label +associated with that element (the label can be made invisible for aesthetic +reasons, but it should always be in the HTML markup). Labels are important for +screen-readers; a placeholder text value is not enough for all users. + +When possible, make sure that all image/graphic elements have accompanying text +that describes the image. `` elements should have an `alt` text value. In +other situations, it might make sense to place invisible, descriptive text +inside the component itself using MUI's `visuallyHidden` utility function. + +```tsx +import { visuallyHidden } from "@mui/utils"; + + +``` ### Should I create a new component? As with most things in the world, it depends. If you are creating a new component to encapsulate some UI abstraction like `UsersTable` it is ok but you should always try to use the base components that are provided by the library or -from the codebase so I recommend you to always do a quick search before creating -a custom primitive component like dialogs, popovers, buttons, etc. +from the codebase. It's recommended that you always do a quick search before +creating a custom primitive component like dialogs, popovers, buttons, etc. ## Testing -We use three types of testing in our app: **E2E**, **Integration** and **Visual +We use three types of testing in our app: **End-to-end (E2E)**, **Integration** and **Visual Testing**. -### E2E (end-to-end) +### End-to-End (E2E) -Are useful to test complete flows like "Create a user", "Import template", etc. -For this one, we use [Playwright](https://playwright.dev/). If you only need to -test if the page is being rendered correctly, you should probably consider using -the **Visual Testing** approach. +These are useful for testing complete flows like "Create a user", +"Import template", etc. We use [Playwright](https://playwright.dev/). If you +only need to test if the page is being rendered correctly, you should consider +using the **Visual Testing** approach. > ℹ️ For scenarios where you need to be authenticated, you can use > `test.use({ storageState: getStatePath("authState") })`. From a4f7fe668a47f443a6e57e27164e661823d1f164 Mon Sep 17 00:00:00 2001 From: Parkreiner Date: Tue, 3 Oct 2023 22:52:29 +0000 Subject: [PATCH 2/2] fix: update docs formatting --- docs/contributing/frontend.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/docs/contributing/frontend.md b/docs/contributing/frontend.md index 76f8ccae72411..b1e4858ce5485 100644 --- a/docs/contributing/frontend.md +++ b/docs/contributing/frontend.md @@ -50,7 +50,8 @@ conventions to help people to navigate through it. - **e2e** - End-to-end (E2E) tests - **src** - Source code - **mocks** - [Manual mocks](https://jestjs.io/docs/manual-mocks) used by Jest - - **@types** - Custom types for dependencies that don't have defined types (largely code that has no server-side equivalent) + - **@types** - Custom types for dependencies that don't have defined types + (largely code that has no server-side equivalent) - **api** - API code as function calls and types - **components** - UI components - **hooks** - Hooks that can be used across the application @@ -117,8 +118,8 @@ We are using [axios](https://github.com/axios/axios) as our fetching library and writing the API functions in the `site/src/api/api.ts` files. We also have auto-generated types from our Go server on `site/src/api/typesGenerated.ts`. Usually, every endpoint has its own ` Request` and `Response` types, but -sometimes you need to pass extra parameters to make the call, like in the example -below: +sometimes you need to pass extra parameters to make the call, like in the +example below: ```ts export const getAgentListeningPorts = async ( @@ -166,7 +167,9 @@ We strive to keep our UI accessible. In general, colors should come from the app theme, but if there is a need to add a custom color, please ensure that the foreground and background have a minimum -contrast ratio of 4.5:1 to meet WCAG level AA compliance. WebAIM has [a great tool for checking your colors directly](https://webaim.org/resources/contrastchecker/), but tools like +contrast ratio of 4.5:1 to meet WCAG level AA compliance. WebAIM has +[a great tool for checking your colors directly](https://webaim.org/resources/contrastchecker/), +but tools like [Dequeue's axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd) can also do automated checks in certain situations. @@ -185,8 +188,10 @@ import { visuallyHidden } from "@mui/utils"; + + Settings + +; ``` ### Should I create a new component? @@ -199,15 +204,15 @@ creating a custom primitive component like dialogs, popovers, buttons, etc. ## Testing -We use three types of testing in our app: **End-to-end (E2E)**, **Integration** and **Visual -Testing**. +We use three types of testing in our app: **End-to-end (E2E)**, **Integration** +and **Visual Testing**. ### End-to-End (E2E) -These are useful for testing complete flows like "Create a user", -"Import template", etc. We use [Playwright](https://playwright.dev/). If you -only need to test if the page is being rendered correctly, you should consider -using the **Visual Testing** approach. +These are useful for testing complete flows like "Create a user", "Import +template", etc. We use [Playwright](https://playwright.dev/). If you only need +to test if the page is being rendered correctly, you should consider using the +**Visual Testing** approach. > ℹ️ For scenarios where you need to be authenticated, you can use > `test.use({ storageState: getStatePath("authState") })`.