From cc6fa9d28693c8e5c9b78eabd8f384916d12972c Mon Sep 17 00:00:00 2001 From: Onna Nelson <168219771+oanelson@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:14:41 -0800 Subject: [PATCH 1/5] Add files via upload --- .../available-scripts/index.mdx | 53 +++ .../available-scripts/installing-cli.md | 23 ++ .../available-scripts/running-example.md | 15 + .../development-life-cycle.md | 39 +++ .../development-standards.md | 90 +++++ .../building-your-application/index.mdx | 15 + .../patterns/apiservice.md | 214 ++++++++++++ .../patterns/components.md | 64 ++++ .../patterns/debugging.md | 17 + .../patterns/index.mdx | 15 + .../patterns/mock-api.md | 56 ++++ .../patterns/navigation.md | 33 ++ .../patterns/offline-storage.md | 171 ++++++++++ .../patterns/routing.md | 81 +++++ .../patterns/state-management.md | 313 ++++++++++++++++++ .../patterns/testing.md | 116 +++++++ .../service-worker-removal.md | 21 ++ .../concepts/concepts.md | 16 + .../concepts/offline-first.md | 17 + .../concepts/on-device-storage.md | 50 +++ .../examples-and-templates.md | 121 +++++++ .../examples-and-templates/examples/index.mdx | 18 + .../getting-started.md | 89 +++++ .../libraries/index.mdx | 15 + .../libraries/radfish.md | 10 + .../libraries/react-radfish.md | 12 + .../technical-decision-log/dexie.md | 16 + .../technical-decision-log/index.mdx | 17 + .../technical-decision-log/jsdocs.md | 17 + .../mock-service-worker.md | 16 + .../technical-decision-log/prettier.md | 17 + .../technical-decision-log/purpose.md | 18 + .../technical-decision-log/tanstack.md | 13 + .../technical-decision-log/trussworks.md | 17 + .../technical-decision-log/workbox.md | 13 + .../developer-documentation/upgrading.md | 78 +++++ 36 files changed, 1906 insertions(+) create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/available-scripts/index.mdx create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/available-scripts/installing-cli.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/available-scripts/running-example.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/development-life-cycle.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/development-standards.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/index.mdx create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/apiservice.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/components.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/debugging.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/index.mdx create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/mock-api.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/navigation.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/offline-storage.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/routing.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/state-management.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/testing.md create mode 100644 docs/developer-documentation/developer-documentation/building-your-application/service-worker-removal.md create mode 100644 docs/developer-documentation/developer-documentation/concepts/concepts.md create mode 100644 docs/developer-documentation/developer-documentation/concepts/offline-first.md create mode 100644 docs/developer-documentation/developer-documentation/concepts/on-device-storage.md create mode 100644 docs/developer-documentation/developer-documentation/examples-and-templates/examples-and-templates.md create mode 100644 docs/developer-documentation/developer-documentation/examples-and-templates/examples/index.mdx create mode 100644 docs/developer-documentation/developer-documentation/getting-started.md create mode 100644 docs/developer-documentation/developer-documentation/libraries/index.mdx create mode 100644 docs/developer-documentation/developer-documentation/libraries/radfish.md create mode 100644 docs/developer-documentation/developer-documentation/libraries/react-radfish.md create mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/dexie.md create mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/index.mdx create mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/jsdocs.md create mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/mock-service-worker.md create mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/prettier.md create mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/purpose.md create mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/tanstack.md create mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/trussworks.md create mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/workbox.md create mode 100644 docs/developer-documentation/developer-documentation/upgrading.md diff --git a/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/index.mdx b/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/index.mdx new file mode 100644 index 0000000..bc5ff40 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/index.mdx @@ -0,0 +1,53 @@ +--- +sidebar_position: 4 +--- + +# Available Scripts + +There are many CLI scripts available for RADFish projects. Learn more about them in this section. + +```mdx-code-block +import DocCardList from '@theme/DocCardList'; + + +``` + +**`npm start`** + +Starts the Vite development server. It runs the app locally with hot module reloading, allowing for fast development and instant updates as you make changes. Open [http://localhost:3000](http://localhost:3000/) to view it in the browser. + +**`npm run build`** + +This script builds the project for production by using Vite’s build tool. It generates optimized static assets, such as HTML, CSS, and JavaScript, which are output to the `dist` directory. + +**`npm run prebuild`** + +Before the build process starts, this script deletes the `dist` folder (which contains the previous build). This helps prevent old build files from being included in the new build. + +**`npm test`** + +Runs unit and integration tests using Vitest, while excluding end-to-end (e2e) tests located in the `./src/__tests__/e2e/` directory. It ensures that regular tests are executed separately from e2e tests. + +**`npm test:e2e`** + +Runs end-to-end (e2e) tests located in `./src/__tests__/e2e/integration.e2e.test.jsx`. This script uses concurrently to run the Vite server and e2e tests in parallel, automatically stopping other processes if one succeeds. + +**`npm run lint`** + +Runs ESLint with the `--fix` option, which automatically fixes certain linting issues in the code found in the `src/` directory. + +**`npm run format`** + +Formats the code in the `src/` directory using Prettier according to the configuration specified in the `.prettierrc` file. This ensures consistent code formatting across the project. + +**`npm run serve`** + +Starts a local server to preview the production build. It serves the files from the `dist/` folder, allowing you to check how the app will behave in a production environment. + +**`npm run lhci:mobile`** + +Runs **Lighthouse CI (LHCI)** on the application, collecting performance metrics and scores for mobile devices. It automates performance auditing to ensure the app meets mobile optimization standards. + +**`npm run lhci:desktop`** + +Runs **Lighthouse CI (LHCI)** on the application, collecting performance metrics and scores for desktop devices. This script is similar to lhci:mobile but targets desktop performance. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/installing-cli.md b/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/installing-cli.md new file mode 100644 index 0000000..9df7cb0 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/installing-cli.md @@ -0,0 +1,23 @@ +--- +sidebar_position: 1 +--- + +# Installing the CLI + +The RADFish CLI is available as an `npm` package, making the installation process much simpler. Follow these steps to install and use the CLI: + +## Install the CLI + +To install the RADFish CLI globally on your system, run this command: + +```bash +npm install -g @nmfs-radfish/create-radfish-app +``` + +To verify the installation, you can run: + +```bash +create-radfish-app --version +``` + +This should display the version number of the installed CLI. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/running-example.md b/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/running-example.md new file mode 100644 index 0000000..1b92ebc --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/running-example.md @@ -0,0 +1,15 @@ +--- +sidebar_position: 2 +--- + +# Running an Example + +RADFish ships with several different [boilerplate examples](../../examples-and-templates#examples). These examples demonstrate core functions identified as critical for NOAA application development. You can use these examples as a reference point to build out your own implementation. Or, they may serve as inspiration for your own designs and best practices. + +For instance, there's an example that demonstrates how to build a multi-step form that caches each step within IndexedDB. Caching the form allows it to be referenced without a network connection. In order to run this example, you can run this command: + +`npx @nmfs-radfish/create-radfish-app my-app --example multistep-form` + +This will clone the code from the `multistep-form` onto your machine. It also spawns a new web process on port `3000` or another port if that is already taken. + +Feel free to use this code and modify it for your needs! diff --git a/docs/developer-documentation/developer-documentation/building-your-application/development-life-cycle.md b/docs/developer-documentation/developer-documentation/building-your-application/development-life-cycle.md new file mode 100644 index 0000000..a54718b --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/development-life-cycle.md @@ -0,0 +1,39 @@ +--- +sidebar_position: 1 +description: Setting up web projects with RADFish +--- + +# Project Setup + +When creating a web application in the NOAA ecosystem, take time to carefully set up your project. This will make ongoing development easier and reduce maintenance overhead. A proper setup follows best practices around file structure, linting, core frameworks, and build tooling. + +All new NOAA web applications must: + +- support full-featured web forms. +- adhere to compliance regulations. +- follow branding and style guidelines. +- use standard environments and tools that are familiar to other NOAA developers. + +To setup a new NOAA web app project, we recommend following [Getting Started](../getting-started) documentation. + +## React Components + +Trussworks React components are included by default with the RADFish Framework. The components build upon the component library, which adheres to [USWDS standards](https://designsystem.digital.gov/). For detailed information on the available components and what attributes they accept, please see the official storybook documentation: [https://trussworks.github.io/react-uswds/](https://trussworks.github.io/react-uswds/) + +### Why Use React? + +- **Responsive Design.** Automatically adjusts for different screen sizes with a collapsible menu. +- **Customizable.** Allows for easy customization of navigation links. +- **Integrated Search.** Includes a search bar for added functionality. +- **Branding.** Supports branding elements like logos in the header. + +**Additional Notes** + +- The **`@trussworks/react-uswds`** package is required to ensure proper styling and functionality. This package is included by default, so you do not need to import it. +- Custom CSS can be applied for further customization. + +## Resources + +By integrating the [header](https://trussworks.github.io/react-uswds/?path=/docs/components-header--basic-header) components into your React application, you can create a professional and responsive UI with minimal effort. The **`Layout`** and **`HeaderNav`** components work together to provide a structured and navigable interface, enhancing the overall user experience. + +--- diff --git a/docs/developer-documentation/developer-documentation/building-your-application/development-standards.md b/docs/developer-documentation/developer-documentation/building-your-application/development-standards.md new file mode 100644 index 0000000..b603e0b --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/development-standards.md @@ -0,0 +1,90 @@ +--- +sidebar_position: 2 +description: USWDS, NOAA branding and Styling, and 508 compliance +--- + +# Development Standards + +## USWDS + +The U.S. Web Design System (USWDS) is a set of design and development principles and guidelines. It helps deveolpers create standardized, accessible, consistent, and user-friendly websites and applications. It helps developers adhere to 508 compliance guidelines. + +In most cases, RADFish uses standard components from the [`react-uswds`](https://github.com/trussworks/react-uswds) open source project. The RADFish project further extends the react-uswds library. These components maintain the functionality of react-uswds, but are branded with NOAA themes and styles. These components live in the [`react-radfish` directory](https://github.com/NMFS-RADFish/react-components). This allows modern React development with NOAA look and feel. + +For information on the full `react-uswds` library, refer to their [storybook](https://trussworks.github.io/react-uswds/?path=/docs/welcome--docs). + +Building applications with `react-radfish` leads to faster development, consistent design, and ensures compliance with government regulations. The [`react-uswds` storybook](https://trussworks.github.io/react-uswds/?path=/docs/welcome--docs) provides examples of compliant components that can be used to build apps for various use cases. + + + +### Example + +If you wanted to build a `TextInput` component into an existing form, you can use the `@trussworks` [storybook reference](https://trussworks.github.io/react-uswds/?path=/docs/components-text-input--docs) related to component props that are available. + +```jsx + +import { TextInput, Label } from "@trussworks/react-uswds"; + + + handleBlur(e, fullNameValidators)} +/> +``` + +--- + +## NOAA Branding Guidelines and Style Guide + +Branding creates a distinct identity for a product or application. It defines and maintains a set of visual elements that represent the brand. Branding can include logos, colors, and typography standards. + +You might have noticed that the components above do not have any `className` assigned. You may be wondering how to style that component. There are a few things to keep in mind when styling components: + +- Each component in `react-radfish` has it’s own scoped CSS file. This file modifies the existing `@trussworks` CSS to inject NOAA styles. This file should not be touched. If you notice a bug or issue, please consider [contributing to the project](https://nmfs-radfish.github.io/radfish/about/contribute). +- You can modify the general theme of these components in the `styles/theme.css` file. You can change things like color variables, font-family, and line-height here. They will be propagated throughout the application, as well as throughout `react-radfish`. RADFish uses CSS variables, like this: + +```css +// styles/theme.js +:root { + --noaa-dark-blue: #0054a4; +} + +// form.css +.your-custom-class { + background-color: var(--noaa-dark-blue); +} +``` + +- If you need to add additional styles to a particular component, you can add another `className` **after** the component has been imported from `react-radfish`: + +```jsx +import { Label } from "@nmfs-radfish/react-radfish"; + +; +``` + +By following this method, you can use the `uswds` component, while still maintaining the NOAA themes. You can also extend it further to suit your needs as a developer. + +## 508 Compliance (Section 508 of the Rehabilitation Act) + +Section 508 compliance refers to the adherence to accessibility standards outlined in [Section 508 of the Rehabilitation Act](https://www.section508.gov/). For web developers, it means designing and developing content that's accessible to individuals with disabilities. In other words, 508 compliant websites can be navigated and understood by users with various disabilities. For example, there are guidelines that aid those with visual or auditory impairments. Developers must follow these guidelines to ensure their websites are accessible and usable by everyone. This promotes an inclusive and diverse online experience. + +Because NOAA is a governmental agency, Section 508 compliance is required for the development of frontend apps. NOAA provides vital information related to weather, oceans, and atmospheric conditions. Individuals with diverse abilities need to access and use these resources. + +Section 508 compliance is a driving factor for many decisions we make in RADFish about our UX strategies. We have also extended a compliant component library in `@trussworks/react-uswds`. + +### Resources +Read more about 508 compliance here: [https://www.section508.gov/](https://www.section508.gov/) diff --git a/docs/developer-documentation/developer-documentation/building-your-application/index.mdx b/docs/developer-documentation/developer-documentation/building-your-application/index.mdx new file mode 100644 index 0000000..85849fd --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/index.mdx @@ -0,0 +1,15 @@ +--- +sidebar_position: 4 +--- + +# Building Your Application + +Learn how to set up your project and make sure it meets development standards in this section. You can also learn about patterns and scripts that can help you build your application. + +```mdx-code-block +import DocCardList from '@theme/DocCardList'; + + +``` + +{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/apiservice.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/apiservice.md new file mode 100644 index 0000000..45f4fed --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/apiservice.md @@ -0,0 +1,214 @@ +--- +sidebar_position: 3 +description: Use any network library to handle HTTP requests +--- + +# Integrating with Backend Services + +You can use any network library to handle HTTP requests (GET, POST, PUT, DELETE). We’ve provided examples using the native fetch API. You can adapt these examples to the library that best fits your needs. + +## Making API Requests + +A common pattern is to call network requests in a `useEffect` that will trigger whenever a React component loads: + +```jsx +useEffect(() => { + async function fetchData() { + try { + const response = await fetch("https://api.example.com/data", { + headers: { + "X-Access-Token": "your-access-token", + }, + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const data = await response.json(); + console.log(data); + } catch (error) { + console.error("Error:", error); + } + } + + fetchData(); +}, []); +``` + +### `GET` Request +Asynchronous function to perform a `GET` request. +- `@param {string} endpoint` - The API endpoint to perform the GET request. +- `@param {Object} queryParams` - The query parameters for the GET request. +- `@returns {Promise}` - A promise that resolves to the API response data or an error string. + + ```js + async function get(API_ENDPOINT, queryParams) { + const queryString = new URLSearchParams(queryParams).toString(); + const url = `${endpoint}?${queryString}`; + + try { + const response = await fetch(url, { + headers: { + "X-Access-Token": "your-access-token", + }, + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const data = await response.json(); + return data; + } catch (error) { + console.error("Error:", error); + throw error; + } + } + + useEffect(() => { + const API_ENDPOINT = "https://api.example.com/data"; + const params = { param1: "foo" }; + + const fetchData = async () => { + const data = await get(API_ENDPOINT, params); + // handle data as needed + }; + + fetchData(); + }, []); + ``` + +### `POST` Request + +Asynchronous function to perform a `POST` request. +- `@param {string} endpoint` - The API endpoint to perform the POST request. +- `@param {Object} body` - The request body for the POST request. +- `@returns {Promise}` - A promise that resolves to the API response data or an error string. + + ```jsx + async function post(API_ENDPOINT, bodyData) { + try { + const response = await fetch(API_ENDPOINT, { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-Access-Token": "your-access-token", + }, + body: JSON.stringify({ ...bodyData }), + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const data = await response.json(); + return { data }; + } catch (error) { + console.error("Error:", error); + throw error; + } + } + + // Example usage + useEffect(() => { + const API_ENDPOINT = "https://api.example.com/data"; + const bodyData = { key: "value" }; + + const postData = async () => { + const data = await post(API_ENDPOINT, bodyData); + // handle data as needed + }; + + postData(); + }, []); + ``` + +### `PUT` Request + +Asynchronous function to perform a `PUT` request. +- `@param {string} endpoint` - The API endpoint to perform the PUT request. +- `@param {Object} body` - The request body for the PUT request. +- `@returns {Promise}` - A promise that resolves to the API response data or an error string. + + ```jsx + async function update(endpoint, { id, bodyData }) { + const url = `${endpoint}/${id}`; + + try { + const response = await fetch(url, { + method: "PUT", + headers: { + "Content-Type": "application/json", + "X-Access-Token": "your-access-token", + }, + body: JSON.stringify(bodyData), + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const data = await response.json(); + return data; + } catch (error) { + console.error("Error:", error); + throw error; + } + } + + useEffect(() => { + const API_ENDPOINT = "https://api.example.com/data"; + const params = { id: 1, bodyData: { key: "updatedValue" } }; + + const updateData = async () => { + try { + const data = await update(API_ENDPOINT, params); + // handle data as needed + console.log("PUT Request Data:", data); + } catch (error) { + console.error("Failed to update data:", error); + } + }; + + updateData(); + }, []); + ``` + +### `DELETE` Request + +Asynchronous function to perform a `DELETE` request. +- `@param {string} endpoint` - The API endpoint to perform the DELETE request. +- `@param {Object} body` - The request body for the DELETE request. +- `@returns {Promise}` - A promise that resolves to the API response data or an error string. + + ```jsx + async function remove(endpoint, { id }) { + const url = `${endpoint}/${id}`; + + try { + const response = await fetch(url, { + method: "DELETE", + headers: { + "X-Access-Token": "your-access-token", + }, + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + console.log("Data deleted successfully"); + } catch (error) { + console.error("Error:", error); + throw error; + } + } + + useEffect(() => { + const API_ENDPOINT = "https://api.example.com/data"; + const params = { id: 1 }; + + const deleteData = async () => { + await remove(API_ENDPOINT, params); + // handle success if needed + }; + + deleteData(); + }, []); + ``` +--- + +## React Query + +In Progress diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/components.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/components.md new file mode 100644 index 0000000..87ab5be --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/components.md @@ -0,0 +1,64 @@ +--- +sidebar_position: 5 +description: Learn to build and structure your components +--- + +# Components and Usage + +## Building your first page and form + +RADFish uses standard components from the [`react-uswds`](https://github.com/trussworks/react-uswds) open source project. The RADFish project further extends the react-uswds library. These components maintain the functionality of react-uswds, but are branded with NOAA themes and styles. These components live in the [`react-radfish` directory](https://github.com/NMFS-RADFish/react-components). This allows for development in a modern React environment with a NOAA look and feel. + +For more information on the full `react-uswds` library, check out the deployed storybook: [https://trussworks.github.io/react-uswds/](https://trussworks.github.io/react-uswds/?path=/docs/welcome--docs) + +### Example + +If you wanted to build a `TextInput` component into an existing form, you can use the `@trussworks` [storybook reference](https://trussworks.github.io/react-uswds/?path=/docs/components-text-input--docs) related to component props that are available. + +```jsx + +import { TextInput, Label } from "@trussworks/react-uswds"; + + + handleBlur(e, fullNameValidators)} +/> +``` + +### Forms + +Controlled forms are a key aspect of any NOAA application. Forms are used to collect data relevant to that application in the context of the user. For example, forms can intake data related to trip reports or admin applications. + +To learn how to build a form, refer to the [State Management](./state-management.md) documentation. + +### Tables + +Tables are also a key component type for all NOAA applications. These components usually help visualize data in a user-friendly manner. However, there are cases where developers may want this data to be writable (ie: submittable) to a backend. Using caching strategies with IndexedDB ensures that these types of components remain fully functional when offline. + +To learn how to build a table, refer to the [State Management](./state-management.md) documentation. + +## Styling Methodology: BEM + +In our **examples** and **templates**, we follow the **Block Element Modifier (BEM)** methodology for organizing CSS classes. BEM helps create a structured and scalable CSS architecture. This makes it easier to understand where CSS classes belong and how they relate to components. It also promotes consistency and readability, especially in larger codebases. + +We use BEM for other reasons as well: + +- **Clarity.** BEM conventions make it clear how styles are applied across different parts of a component. +- **Modularity.** BEM encourages the separation of styling concerns, making components more modular and reusable. +- **Scalability.** As your project grows, BEM helps maintain organized and manageable CSS. + +For more information on BEM and how it works, you can visit the official BEM documentation: [https://getbem.com](https://getbem.com). + +### Flexibility for Your Project: + +We use BEM in our **examples** and **templates** to enhance code clarity and consistency. However, you are not required to adopt BEM in your own project. Feel free to use any CSS methodology or framework that suits your needs. This might be BEM, CSS Modules, Tailwind, or any other approach. + +Our use of BEM is limited to the examples and templates provided. It doesn’t affect how you structure your own styles. You can implement your own styling approach while using the components in our examples. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/debugging.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/debugging.md new file mode 100644 index 0000000..212a7d9 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/debugging.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 8 +description: Strategies for debugging your applications +--- + +# Debugging + +Debugging is an important part developing Progressive Web Applications (PWAs). Debugging helps developers track real-time performance, identify and fix bugs, optimize code, and enhance user experience. + +There are several common strategies for debugging a web application during development. These include but are not limited to: + +- Adding breakpoints in code editor. [See vscode documentation](https://code.visualstudio.com/docs/editor/debugging#_breakpoints). +- Adding logs to the development console. [See MDN documentation](https://developer.mozilla.org/en-US/blog/learn-javascript-console-methods/). +- Using the network console. [See Chrome DevTools documentation](https://developer.chrome.com/docs/devtools/network). +- Using an HTTP client like Postman to test API calls. [See Postman documentation](https://learning.postman.com/docs/introduction/overview/). + +You can use Postman to emulate a backend server response pattern. Postman works with the Mock Service Worker that is bundled with RadFish. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/index.mdx b/docs/developer-documentation/developer-documentation/building-your-application/patterns/index.mdx new file mode 100644 index 0000000..90632b5 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/index.mdx @@ -0,0 +1,15 @@ +--- +sidebar_position: 3 +--- + +# Patterns + +Patterns are solutions to common problems in software design. In this section, you can learn about several patterns that help with routing, state management, APIs, and other common components of RADFish applications. There are also patterns for testing, debugging, and other parts of the software development lifecycle. + +```mdx-code-block +import DocCardList from '@theme/DocCardList'; + + +``` + +{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/mock-api.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/mock-api.md new file mode 100644 index 0000000..46ccd40 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/mock-api.md @@ -0,0 +1,56 @@ +--- +sidebar_position: 4 +description: Simulate backend responses to unblock your development +--- + +# Mock API + +As a frontend developer, you may be developing a feature that has a dependency on an external API. This dependency sometimes becomes a blocker. You must wait for the external API endpoints to be developed before you can build your feature. The RADFish app ships with a built-in mock server that allows frontend developers to “stub out” and mock API requests. This mock API removes the hard dependency during development. + +More specifically, RADFish ships with [mock service worker](https://mswjs.io/). This service is preconfigured in the boilerplate application. + +At the entrypoint of the React application, we enable API mocking with the `enableMocking` function: + +```jsx +async function enableMocking() { + const { worker } = await import("./mocks/browser"); + + // `worker.start()` returns a Promise that resolves + // once the Service Worker is up and ready to intercept requests. + return worker.start(); +} + +const root = ReactDOM.createRoot(document.getElementById("root")); + +enableMocking().then(() => { + root.render( + + + + ); +}); +``` + +Keep in mind that mocking should only be available during development. It should not ship with the production application. It can be useful to use a `NODE_ENV` environment variable to ensure that API mocks are only used in `DEVELOPMENT`. The `public/mockServiceWorker.js` file installs and configures the mock server. You should not need to modify this file. + +## Configuring mock endpoints: + +In `src/mocks` there is a `browser.js` file and a `handlers.js` file. Developers can add different mock http handlers to their application in the `handlers.js` file. For each handler you create, the mock service worker will intercept the request, and handle that request as defined in the file. + +For instance: + +```jsx +export const handlers = [ + http.get("/species", () => { + return HttpResponse.json({ data: ["grouper", "marlin"] }, { status: 200 }); + }), + http.post("/species", async ({ request }) => { + const response = await request.json(); + return HttpResponse.json({ data: response }, { status: 201 }); + }), +]; +``` + +This file creates two handlers, a `GET` and `POST` request that returns a `HttpResponse` to the application. Refer to the [msw docs](https://mswjs.io/) for more information on customizing this for your needs. + +--- diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/navigation.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/navigation.md new file mode 100644 index 0000000..bcb38f1 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/navigation.md @@ -0,0 +1,33 @@ +--- +sidebar_position: 6 +description: Handle navigation patterns in your application +--- + +# Navigation + +NOAA applications often have application-specific needs for routing and navigation between internal pages. They may also need to follow certain domain-specific rules, such as being hosted on a subdomain route of an existing application. In this documentation, we'll focus on applications that are on hosted on their own domain, and from the root directory of that application’s codebase. + +## Navigation Styling +NOAA applications should maintain a similar navigation style. This provides a familiar interface for users who may be switching between applications. Navigation element styles should be consistent across various platforms. + +Navigation items should always be at the highest vertical “layer” of the application. They should always overlap any other components, except for full page modals. For example, if a navigation item expands downwards, it should not appear beneath an image or some other component. This would make the navigation inaccessible and not comply with 508 compliance regulations. + +Navigation should also appear different on mobile and desktop/tablet devices. + +## Application Routing +In Progressive Web App (PWA) development, application routing provides a seamless user experience. The implementation of application routing can vary based on business needs. However, there are general principles that developers can follow to ensure a consistent and user-friendly navigation experience. + +NOAA applications should have routes to the pages suggested in the [templates](https://designsystem.digital.gov/templates/) portion of the USWDS documentation. This creates an application structure that is both repeatable and familiar to users. + +The U.S. Web Design System (USWDS) documentation provides recommended basic routes for a PWA application. These routes include: + +- **404 Page.** Handling "page not found" scenarios gracefully is essential for user satisfaction. A well-designed 404 page helps users understand that the content they're looking for is not available. +- **Documentation Page.** Including documentation can help users understand the application's features and functionality. This page serves as a reference guide for users seeking information about how to use the app effectively. +- **Landing Page.** The landing page is often the first interaction users have with the application. It should be designed to capture attention, provide key information, and encourage users to explore further. +- **Authentication Page.** Secure authentication is a critical aspect of many applications. Having a dedicated authentication page ensures a smooth and secure login process for users. + +NOAA applications should be designed to work seamlessly even when the user is offline. The routing mechanism should direct users to a page that doesn't depend on external API requests. It should rely solely on cached content. + +The "online usage" documentation explains how the application behaves when the user is offline. This documentation typically outlines strategies for caching important assets, handling offline scenarios, and ensuring that users can still access content even without an internet connection. + +In summary, effective application routing in PWA development involves careful consideration of key routes such as 404, documentation, landing, and authentication pages. Additionally, prioritizing offline use by routing to cached content enhances user experience. Developers should follow best practices and refer to relevant documentation to implement routing that aligns with both business needs and user expectations. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/offline-storage.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/offline-storage.md new file mode 100644 index 0000000..7fa8e98 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/offline-storage.md @@ -0,0 +1,171 @@ +--- +sidebar_position: 8 +title: "Offline Storage" +description: Implement offline storage functionality (Coming soon) +--- + +# Offline Storage + +RADFish app users can be out at sea for an extended period of time. They may not have a reliable internet connection. Offline storage lets users to continue using the app to create and manage data while offline. + +## Storage Models + +The `@nmfs-radfish/radfish`package provides two storage methods available `LocalStorageMethod` and `IndexedDBMethod`. + +### LocalStorage + +In order to save to LocalStorage, we must provide a unique key that will used to store all of the application data. + +```js +import { LocalStorageMethod } from '@nmfs-radfish/radfish'; + +new LocalStorageMethod( + "survey-app-storage" +); +``` + +### IndexedDB + +When using IndexedDB, we also need to provide a schema version and model structures. These are used to manage future data migrations. + +```js +import { IndexedDBMethod } from '@nmfs-radfish/radfish'; + +new IndexedDBMethod( + "survey-app-storage", + "1.0.0", + { + species: "id, name, scientificName", + catches: "id, speciesId, numberOfFish, weight" + } +); +``` + +## React Usage + +The `@nmfs-radfish/react-radfish` package exposes the `OfflineStorageWrapper` component. This creates a storage model available to that React context. + +## **`useOfflineStorage` Hooks API** + +You can then use the `useOfflineStorage` hook to interact directly with the storage model. + +The hook returns an object with these CRUD methods: +- `createOfflineData` creates a new entry. +- `findOfflineData` reads data entries. +- `updateOfflineData` updates data entries. +- `deleteOfflineData` deletes data entries. + +### `createOfflineData` + +Creates a new data entry in the storage. Entries will have a unique `uuid` (`String`) property to be used for future lookups. + +| Parameter | Description | +| ----------- | ------------------------------------- | +| `tableName` | The table the data will be stored in. | +| `data` | The data object to create. | + +**Returns:** A `Promise` that resolves of the `uuid` of the created entry. + +### `findOfflineData` + +Finds data in the storage based on the given criteria, returns all data if not criteria parameter is passed. + +| Parameter | Description | +| ----------- | -------------------------------------------------------------- | +| `tableName` | The table to be searched. | +| `criteria` | The criteria object to use for finding data, eg `{uuid: 123}`. | + +**Returns:** A `Promise` that resolves to an array of objects: + +### `updateOfflineData` + +Updates data in the storage with the matching `criteria`. + +| Parameter | Description | +| ----------- | -------------------------------------------------------------- | +| `tableName` | The table to be searched. | +| `criteria` | The criteria object to use for finding data, eg `{uuid: 123}`. | + +**Returns:** A `Promise` that resolves to an array of `uuid` of the updated entries. + +### `deleteOfflineData` + +Deletes data in the storage. + +| Parameter | Description | +| ----------- | -------------------------------------------------------------- | +| `tableName` | The table to be searched. | +| `criteria` | The criteria object to use for finding data, eg `{uuid: 123}`. | + +**Returns:** A `Promise` that resolves to a boolean value of whether the delete operation succeeded without errors. + +## Usage + +Example usage when using IndexedDB: + +**App.jsx** +```jsx +import React, { useEffect, useState } from "react"; +import { Table } from "@nmfs-radfish/react-radfish"; +import { useOfflineStorage, OfflineStorageWrapper } from "@nmfs-radfish/react-radfish"; + +const offlineStorageConfig = { + type: "indexedDB", + name: import.meta.env.VITE_INDEXED_DB_NAME, + version: import.meta.env.VITE_INDEXED_DB_VERSION, + stores: { + catches: "++id, numberOfFish" + }, +}; + +const Catches = () => { + const { createOfflineData, findOfflineData } = useOfflineStorage(); + + let [allCatches, setCatches] = useState([]); + + const fetchCatches = async () => { + const catches = await findOfflineData("catches"); + setCatches(catches); + }; + + const createNewCatch = async () => { + await createOfflineData("catches", { + numberOfFish: Math.floor(Math.random() * 10) + 1, + }); + await fetchCatches(); + }; + + useEffect(() => { + fetchCatches(); + }, []); + + return ( +
+ + + + ); +}; + +const App = () => { + return ( + + + + ); +}; + +export default App; +``` + +## Interfacing with backend services + +You are free to use any network library of your choice to handle HTTP requests (GET, POST, PUT, DELETE). For your convenience, we’ve provided examples using the native fetch API. You can adapt these examples to the library that best fits your needs. + +Refer to the [Integrating with Backend Services](https://nmfs-radfish.github.io/radfish/developer-documentation/building-your-application/patterns/apiservice) documentation for examples. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/routing.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/routing.md new file mode 100644 index 0000000..c564695 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/routing.md @@ -0,0 +1,81 @@ +--- +sidebar_position: 9 +description: Manage app routes with React Router +--- + +# Routing + +The **Routing** in RADFish applications is handled using `react-router-dom`. This section will guide you through the basic setup and usage of routing in your project. + +## React Router Overview + +React Router provides a declarative, component-based approach to defining routes and managing navigation in React applications. It supports nested routes, dynamic route matching, and lazy loading of components. + +To learn about React Router, refer to the official [React Router documentation](https://reactrouter.com/). + +### Features + +- **Declarative Routing.** Define routes in a declarative manner using components like `Routes`, `Route`, and `Link`. +- **Dynamic Routing.** Easily create routes that can change based on the application's state or URL parameters. +- **Nested Routing.** Support for nested routes, allowing more complex routing configurations. +- **Programmatic Navigation.** Use React Router hooks like `useNavigate` to navigate programmatically. + +### Usage + +In this project, routing is set up in the `App.jsx` file. This section provides a breakdown of the main components used for routing. + +**Basic Setup** + +First, import the necessary components from `react-router-dom`: + +```jsx +import { BrowserRouter, Routes, Route, Link } from "react-router-dom"; +``` + +**Defining Routes** + +Use the BrowserRouter to wrap your application and define routes with the Routes and Route components: + +```jsx + + + } /> + + +``` + +This setup ensures that when users navigate to the root URL (/), the HomePage component is rendered. + +**Navigation Links** + +To navigate between different routes, use the Link component: + +```jsx +Home +``` + +This setup provides a navigation link to the home page. + +### Example Code + +You can view the full example of the routing setup in the `App.jsx` file in the GitHub repository: [github/boilerplate/templates/react-javascript/src/App.jsx](https://github.com/NMFS-RADFish/boilerplate/blob/main/templates/react-javascript/src/App.jsx) + +```jsx +import { BrowserRouter, Routes, Route, Link } from "react-router-dom"; +import HomePage from "./pages/Home"; + +function App() { + return ( + + + + } /> + + + ); +} + +export default App; +``` diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/state-management.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/state-management.md new file mode 100644 index 0000000..2b0c2c4 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/state-management.md @@ -0,0 +1,313 @@ +--- +sidebar_position: 2 +description: An overview of managing application state effectively +--- + +# State Management + +## What is State Management? + +NOAA web apps frequently deal with a variety of data. Data can range from user-generated form data to environmental statistics such as fish populations or weather changes. State management is our tool for keeping track of all these changes efficiently. Think of it as a digital notepad that records every update and change within the app. This ensures we always have the most current information at our fingertips. + +## Why Use State Management in NOAA Apps? + +Our applications are not just repositories of static data. They are dynamic platforms where data constantly evolves. State management is essential for several reasons: + +- **Stay Updated.** Display the most up-to-date information to our users. This ensures accuracy and reliability. +- **Work Offline.** Our apps can function even without an internet connection. We do this by storing data locally and syncing it back to our servers once a connection is re-established. +- **Fast and Responsive.** Our apps to react swiftly to user interactions and data changes, providing a smooth and efficient user experience. + +### A Simple Way to Manage State: Using React Context + +We use a feature called **React Context** to share and manage states across different parts of our applications. This creates a communal space where any component of our app can easily access or update shared information. This feature eliminates the complexity of passing data through multiple layers. + +## How We Implement State Management + +### FormState + +Our approach to managing form state is simple yet effective. Each form should maintain it's own state within the component itself. This is the recommended approach for managing a form's state, rather that reaching for a centralized state machine like React Context or Redux. This approach is more straightforward to implement and removes excess layers of abstraction. + +One downside of this approach is that each form has it's own state management. This can lead to less DRY code. This is an acceptable tradeoff in most cases, however. If you notice that certain patterns should be shared among different components, you will either need to pass these state values as props to child components, or wrap the related components in a `ContextProvider` and expose them via the `useContext` hook. See more about how to use React Context [here](https://react.dev/reference/react/useContext). + +For an example on best practices for implementing this type of form state management, you can run an example implementation with the RADFish CLI: + +`npx @nmfs-radfish/create-radfish-app my-app --example computed-form-fields` + +Here is a simplified code snippet on how to set this form state management up in a React component: + +```jsx +const SimplifiedForm = () => { + const [formData, setFormData] = useState({}); + + const handleSubmit = (event) => { + event.preventDefault(); + dispatchToast({ status: "success", message: "Successful form submission" }); + }; + + return ( + + + { + const { value } = event.target; + setFormData({ + ...formData, + ["fullName"]: value, + }); + }} + /> + + + ); +}; +``` + +### Flexibility and Debugging + +This method allows developers to implement form state within the scope of a single file. This makes it simpler to build out forms for different use cases. If certain repeatable patterns arise, they can be broken out into a separate context provider if needed. Alternatively, they can get passed in as props to child components. + +This approach provides better encapsulation and modularity. It also allows for more straightforward debugging and maintenance of form-related logic. + + +## Offline / Online State Management + +Any NOAA web application must be fully functional offline without a network connection. Fishermen are often on ships far away from network connection. They need to reliably store data that will be uploaded to NOAA services when the app comes back online. Therefore, designing apps to be “offline first” is of vital importance to NOAA web appdevelopment. + +Progressive Web Applications (PWAs) offer a robust solution for offline use at sea. They combine the benefits of an app-like experience, offline access, and efficient data management. These features make PWAs well-suited for maritime environments, where connectivity is often limited or intermittent. + +PWAs leverage service workers, which are scripts that run independently in the background. Service workers enable offline functionality by caching important static resources, such as HTML, CSS, and JavaScript files. This allows the PWA to continue functioning even when there’s no network connectivity. + +Read more about service workers [here](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API). + +Service workers are integrated into the RADFish application by default. After scaffolding the application you will notice the following files: + +`service-worker.js` + +`serviceWorkerRegistration.js` + +And the service workers is integrated into the React app in the app’s `index.js` entrypoint: + +```jsx +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: https://cra.link/PWA +serviceWorkerRegistration.register(); +``` + +This will register the React application as a PWA, which can be downloaded from the browser. For more information on how to download the PWA onto your device, see [this blog article](https://aureatelabs.com/blog/install-pwa-to-device/). + +Additionally, you can query for whether or not the RADFish application is online or offline by leveraging the [navigator API](https://developer.mozilla.org/en-US/docs/Web/API/Navigator). + +> Note: This service worker is preconfigured when using the boilerplate `react-javascript` template. + +It is up to the developer on how or where this API needs to be used. It's a good idea to use it early on in your application, so that the rest of the application can listen for changes in offline state. The `@nmfs-radfish/react-radfish` package exposes a `useOfflineStatus` hook that gives you a simple way to tap into whether or not your application is online: + +```jsx +import { Application, useOfflineStatus } from "@nmfs-radfish/react-radfish"; + +function App() { + const { isOffline } = useOfflineStatus(); + + return ( + +

+ Network Status: {isOffline ? "Offline ❌" : "Online ✅"} +

+
+ ); +} +``` + +This underlying code listens for changes surfaced from the `navigator` API. It notifies the application in the form of a Toast message of the application's online/offline state. + +> 🚨 **Warning:** There is a known issue where if the user's device is in an offline state, and the RADFish application is booted up for the first time, the Navigator API will actually resolve to "offline". On future refreshes, this will appropriately resolve to the "offline" status. This is an issue with the underlying Navigator API and will be addressed in a future release. + +## Caching Strategy + +It is important to fetch and cache required data needed to basic app functionality while the application is online. This can be done by fetching the required data from an API, and storing that data into IndexedDB. To see a basic example of how this can be done, you can run the `server-sync` example from the CLI: + +`npx @nmfs-radfish/create-radfish-app my-app --example server-sync` + +This example fetches several JSON arrays from our Mock API, then stores and caches it in IndexedDB. The application then can reference the data in IndexedDB without a network connection. Keep in mind that it is up to the developer to decide when and how to invalidate this IndexedDB cache based on their application's needs. + +## **Offline Storage** + +To use offline data storage, use the `useOfflineStorage` hook. This React hook provides methods for managing offline form data. There are two storage methods available: `LocalStorageMethod` and `IndexedDBStorageMethod`. + +### Configuration + +Step-by-step instructions to configure offline storage: + +1. **Set the environment variables in the `.env` files. Based on which offline storage method you select, the following `env` variables are required:** + 1. Local Storage + 1. `VITE_LOCAL_STORAGE_KEY` + 2. Indexed DB: + 1. `VITE_INDEXED_DB_NAME` + 2. `VITE_INDEXED_DB_VERSION` + 3. `VITE_INDEXED_DB_TABLE_NAME` + 4. `VITE_INDEXED_DB_SCHEMA` +2. **In the `src/hooks/useOfflineStorage.js` file, initialize one of the these Storage Method instances, and pass the appropriate environment variables using `import.meta.env.REPLACE_WITH_KEY_NAME` as parameters:** + + 1. `LocalStorageMethod` — Requires one parameter, the key name for localStorage. + + ```jsx + const storageMethod = new LocalStorageMethod( + import.meta.env.VITE_LOCAL_STORAGE_KEY + ); + ``` + + 2. `IndexedDBStorageMethod` — Requires four parameters, the db name, db version, db table name, db schema. + + ```jsx + const storageMethod = new IndexedDBStorageMethod( + import.meta.env.VITE_INDEXED_DB_NAME, + import.meta.env.VITE_INDEXED_DB_VERSION, + import.meta.env.VITE_INDEXED_DB_TABLE_NAME, + import.meta.env.VITE_INDEXED_DB_SCHEMA + ); + ``` + +3. **In the `src/hooks/useOfflineStorage.js` file, create the `StorageModelFactory`:** + + ```jsx + // 1. Choose one of the following storage methods: + const storageMethod = new IndexedDBStorageMethod( + import.meta.env.VITE_INDEXED_DB_NAME, + import.meta.env.VITE_INDEXED_DB_VERSION, + import.meta.env.VITE_INDEXED_DB_TABLE_NAME, + import.meta.env.VITE_INDEXED_DB_SCHEMA + ); + const storageMethod = new LocalStorageMethod( + import.meta.env.VITE_LOCAL_STORAGE_KEY + ); + // 2. Create Storage Method + const storageModel = StorageModelFactory.createModel(storageMethod); + ``` + +### `useOfflineStorage` Hooks API + +The `useOfflineStorage` hook returns an object with the following methods: + +- **`createOfflineDataEntry(data)`** creates a new data entry in the storage. + - `data`: The data object to create. + - Returns a promise that resolves when the data is created. +- **`findOfflineData(criteria)`** finds data in the storage based on the given criteria. It returns all data if not criteria parameter is passed. + - `criteria`: The criteria object to use for finding data, eg `{uuid: 123}`. + - Returns a promise that resolves to an array of tuples: + - `[ [ uuid, { key: value } ], [ uuid2, { key: value } ] ]` +- **`updateOfflineDataEntry(criteria, data)`** updates data in the storage. + - `criteria`: The criteria to use for updating data. This should be an object. + - `data`: The updated data object. + - Returns a promise that resolves to the updated data as an object: + - `{ numberOfFish: 10, species: salmon }` + +### Usage + +```jsx +import useOfflineStorage from "./useOfflineStorage"; + +function MyComponent() { + const { createOfflineDataEntry, findOfflineData, updateOfflineDataEntry } = + useOfflineStorage(); + const data = { species: "Grouper", numberOfFish: 100 }; + + // Create new offline data entry + createOfflineDataEntry(data); + // Find all offline data + findOfflineData(); + // Find a specific offline data entry by uuid + findOfflineData({ uuid: "1234" }); + // Update an offline data entry by uuid + updateOfflineDataEntry({ uuid: "1234" }, data); + + // rest of code.... +} + +export default MyComponent; +``` + +--- + +## OfflineStorageWrapper Usage Guide + +`OfflineStorageWrapper` is a context wrapper component that provides offline storage functionality to its child components through a React context. It supports both IndexedDB and LocalStorage methods. + +### How to Use + +**1. Wrap your component with `OfflineStorageWrapper`:** + +```jsx +import { OfflineStorageWrapper } from "@nmfs-radfish/react-radfish"; + + + +; +``` + +The config prop is an object that specifies the storage type and configuration. It should include the `type` set to `indexedDB` or `localStorage`, database name (`string`), database version number (`number`), and stores (`object`). + +The `stores` object should contain a key that is mapped as the table name. The value should be a comma separated string that outlines the schema. For more information on setting up the stores, see the official `Dexie.js` docs: [https://dexie.org/docs/Tutorial/React#3-create-a-file-dbjs-or-dbts](https://dexie.org/docs/Tutorial/React#3-create-a-file-dbjs-or-dbts). + +For IndexedDB, the configuration should look like this: + +```js +const config = { + type: "indexedDB", + name: "your_db_name", + version: 1, + stores: { + table_name_1: "uuid, name", + // Add more stores as needed + }, +}; +``` + +For LocalStorage, the configuration should look like this: + +```js +const config = { + type: "localStorage", + name: "your_storage_name", +}; +``` + +**2. Use the useOfflineStorage hook in child components:** + +```jsx +import { useOfflineStorage } from "@nmfs-radfish/react-radfish"; + +function YourComponent() { + const { + createOfflineData, + findOfflineData, + updateOfflineData, + deleteOfflineData, + } = useOfflineStorage(); + + // Use these functions to interact with offline storage +} +``` + +The `useOfflineStorage` hook provides four functions: + +- `createOfflineData(tableName, data):` Creates a new record in the specified table. +- `findOfflineData(tableName, criteria):` Finds records in the specified table that match the criteria. +- `updateOfflineData(tableName, data):` Updates a record in the specified table. +- `deleteOfflineData(tableName, uuid):` Deletes a record with the specified UUID from the specified table. + +## Error Handling + +If you try to use the `useOfflineStorage` hook outside of an `OfflineStorageWrapper`, it will throw an error. Always make sure to use `useOfflineStorage` within a component that's wrapped with `OfflineStorageWrapper`. + +## Testing during development + +As a developer, you'll often run into an issue where an "offline-first" feature needs to be tested before pushed and merged into the `main` branch. For instance, you may be developing a `Toast` message that notifies the user whenever they go offline. If you are simply running the local vite server, and you go offline to test your feature, you'll notice that the page breaks on page refresh. This is because the `serviceWorker` is not being used until the production build is created. In order to do this, you need to bundle the application and serve it locally to simulate a production environment: + +`npm run build && npm run serve` + +This will bundle the application and serve it. When you turn your browser offline, the cached static assets will remain, and your application will not break when the page is refreshed. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/testing.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/testing.md new file mode 100644 index 0000000..e47d416 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/patterns/testing.md @@ -0,0 +1,116 @@ +--- +sidebar_position: 7 +description: Ensure code quality with Vitest and React Testing Library +--- + +# Testing + +Testing is a critical part of the software development process. Testing ensures the reliability and maintainability of your React application. This section provides an overview of several topics: +- Writing tests using [Vitest](https://vitest.dev/api/) +- Snapshot, unit, and browser testing with frameworks like [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) +- Debugging techniques for broken or failed tests +- Best practices for effective test writing + +Effective testing in React using Vitest and related frameworks builds robust applications. Remember, the goal of testing is not just to find bugs, but to build confidence in your codebase. + +## Running Tests + +Run tests with the following command: `npm test` + +## Writing Unit Tests + +Unit tests focus on testing individual components or functions in isolation. + +1. **Basic Unit Test** + + ```jsx + import { + fullNameValidators, + emailValidators, + phoneNumberValidators, + cityValidators, + stateValidators, + zipcodeValidators, + } from "../../utilities"; + + test("should validate a correct email format", () => { + expect(emailValidators[0].test("example@test.com")).toBe(true); + }); + ``` + +2. **Testing User Interactions** + +Use **`user-event`** or **`fireEvent`** from React Testing Library to simulate user actions. + + ```jsx + import { userEvent } from "@vitest/browser/context"; + import { screen } from "@testing-library/dom"; + + test("triggers a double click on an element", async () => { + const logo = screen.getByRole("img", { name: /logo/ }); + + await userEvent.dblClick(logo); + }); + ``` + +## Writing Browser Tests + +Browser testing involves testing the application in a web browser environment. Tools like [Puppeteer](https://pptr.dev/) can be used alongside Vitest. Please note Puppeteer does not come included by default in the RADFish framework. + +1. **Basic Browser Test** + + ```jsx + const puppeteer = require("puppeteer"); + + it("should display the homepage", async () => { + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + await page.goto("http://localhost:3000"); + await expect(page.title()).resolves.toMatch("Home Page"); + await browser.close(); + }); + ``` + +## Additional Vitest Configuration + +Vitest and React Testing Library are included in the RADFish framework by default. The Vitest test configuration can be modified in the `vite.config.js` file. Refer to the official Vitest docs for the latest configuration options: [https://vitest.dev/config/](https://vitest.dev/config/). + +## Debugging Broken or Failed Tests + +1. **Review Test Output.** Vitest provides detailed error messages. Analyze them to understand the failure. +2. **Use `console.log`.** Temporarily add **`console.log`** statements within your test to inspect values. +3. **Check for Async Issues.** Ensure promises are resolved and state updates are completed. + +## Best Practices + +By following these best practices, you can ensure your code works as expected. Testing also ensures your code will be maintainable over time. + +- **Descriptive Test Names.** Clearly describe what each test is checking. +- **Small and Focused Tests.** Write tests that cover single functionalities. +- **Avoid Over-Mocking.** Use mocks sparingly to ensure tests remain close to real-world scenarios. +- **Test User Interactions.** Simulate how users interact with your application. +- **Continuous Integration**. Integrate testing into your CI/CD pipeline for regular feedback. + +## 508 Compliance +There are special steps to test whether your application meets 508 Compliance guidelines. Section 508 of the Rehabilitation Act mandates that federal agencies' electronic and information technology is accessible to people with disabilities, aligning with the Web Content Accessibility Guidelines (WCAG). + +### 1. Set Up Your React Project + + Make sure your React application is operational locally, typically accessed at `http://localhost:3000`. + +### 2. Automated Testing with Lighthouse + + 1. **Open Google Chrome.** Ensure Google Chrome is installed and open your project by navigating to `http://localhost:3000`. + 2. **Access Chrome DevTools.** Right-click on the page and select "Inspect", or use `Ctrl+Shift+I` (Windows/Linux) or `Cmd+Option+I` (Mac) to open DevTools. + 3. **Run Lighthouse Audit.** + - Click on the "Lighthouse" tab in the DevTools panel. + - Check the "Accessibility" box to focus the audit on accessibility compliance. + - Click "Analyze page load" to start the audit. Review the report that Lighthouse provides, detailing accessibility issues and suggestions for improvements. + +### 3. Implement Recommendations + + Address each listed accessibility issue based on Lighthouse’s suggestions. For example, you might add alt text to images, use proper semantic HTML, or correct ARIA labels. + +### 4. Rerun the Audit + + After making changes, run Lighthouse again. This will verify improvements and ensure no new issues have arisen. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/service-worker-removal.md b/docs/developer-documentation/developer-documentation/building-your-application/service-worker-removal.md new file mode 100644 index 0000000..c6ef252 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/building-your-application/service-worker-removal.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 7 +title: Service Worker Removal +--- + +### Removing the Preconfigured Service Worker + +**Disclaimer:** The service worker in this template is designed to provide offline functionality and improve app performance. Removing it is generally not recommended. However, if needed, follow these steps: + +1. **Uninstall the Service Worker Plugin** + Run the following command to uninstall `vite-plugin-pwa`: + ```bash + npm uninstall vite-plugin-pwa + ``` +2. **Remove Configuration from Vite** + Open `vite.config.js` and remove `vite-plugin-pwa`. + +3. **Remove Service Worker Setup** + In your `src/index.js` file, remove the service worker configurations. + +After these steps, the service worker will be removed from the application. diff --git a/docs/developer-documentation/developer-documentation/concepts/concepts.md b/docs/developer-documentation/developer-documentation/concepts/concepts.md new file mode 100644 index 0000000..96b5b0d --- /dev/null +++ b/docs/developer-documentation/developer-documentation/concepts/concepts.md @@ -0,0 +1,16 @@ +--- +sidebar_position: 2 +--- + +# Concepts + +RADFish developers build applications that serve users in a variety of settings. Many of our users are commercial fishermen who harvest and process fish. Their work takes them to busy ports and the open sea, where internet connectivity can be unreliable or even non-existent. + +Imagine being a commercial fisherman on a vessel in a remote area. You must sort through catch and record weights and species. You need your data to sync with offices back on land. You may have limited storage space on your devices. + +Modern users expect apps to be responsive and reliable, even with limited internet connectivity. This is especially true for professionals such as commercial fishers. These users often operate in remote areas with unstable network access. To meet these expectations, developers can implement on-device storage to enable offline functionality. This increases user satisfaction and also ensures that critical tasks can be performed without interruption. + +Designing apps for these users present unique challenges. To meet these challenges, RADFish developers should be familiar with several concepts: + +* [Offline-First](https://nmfs-radfish.github.io/radfish/developer-documentation/concepts/offline-first) design prioritizes functionalatity even without internet connectivity. +* [On-Device Storage](https://nmfs-radfish.github.io/radfish/developer-documentation/concepts/on-device-storage) is storing data directly on a user's device, without relying on internet connectivity. \ No newline at end of file diff --git a/docs/developer-documentation/developer-documentation/concepts/offline-first.md b/docs/developer-documentation/developer-documentation/concepts/offline-first.md new file mode 100644 index 0000000..85b4783 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/concepts/offline-first.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 2 +--- + +# Offline-First + +Offline-first design prioritizes web app functionality even without internet connectivity. This means building the app so users can interact with it uninterrupted, even without a stable network. + +With offline-first, your application: + +- **Stores data locally.** When the user interacts with the app, data is cached on the device. +- **Synchronizes data automatically.** When internet connectivity returns, the app synchronizes any pending changes with remote servers. +- **Provides a seamless experience.** Whether they're online or offline, users enjoy an uninterrupted experience. + +## Service Workers: The Key to Offline-First + +To achieve offline-first functionality, developers use Service Workers. Service Workers are scripts that run in the background of web applications. They allow network requests and data caching without requiring user interaction. Service Workers help build web applications that function even with internet connectivity issues. \ No newline at end of file diff --git a/docs/developer-documentation/developer-documentation/concepts/on-device-storage.md b/docs/developer-documentation/developer-documentation/concepts/on-device-storage.md new file mode 100644 index 0000000..23a6522 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/concepts/on-device-storage.md @@ -0,0 +1,50 @@ +--- +sidebar_position: 3 +--- + +# On-Device Storage +On-device storage is the practice of storing data directly on a user's device, allowing web applications to function independently of network connectivity. This approach is critical for several reasons: + +- **Uninterrupted User Experience.** Users can use the application without disruption, regardless of their connectivity status. +- **Data Availability.** Essential data remains accessible. Users can perform tasks and access information when they need it most. +- **Improved Performance.** Faster data retrieval and smoother performance by reducing network requests. + +## Implementing On-Device Storage in your application + +When integrating on-device storage into your application, consider these best practices: + +- **Determine Data Requirements.** Assess the types and volumes of data your application needs to store. Choose the storage mechanism that best fits these requirements. +- **Plan for Synchronization.** Make sure your application can synchronize data with remote servers when connectivity is restored. This includes handling potential conflicts and ensuring data consistency. +- **Optimize for Performance.** Use asynchronous operations where possible to avoid blocking the main thread and degrading the user experience. +- **Ensure Data Security.** Implement appropriate security measures to protect stored data, including encryption and secure access controls. + +## Types of On-Device Storage + +There are various on-device storage mechanisms available in modern web development. Each is best for different types of data and use cases. Two prominent options are **LocalStorage** and **IndexedDB**. + +### LocalStorage + +LocalStorage is a simple and synchronous storage system built into web browsers. It stores key-value pairs and is designed to persist data even after the browser is closed. LocalStorage is good for storing small amounts of data, such as user preferences, session information, or basic application state. + +#### Benefits of LocalStorage: + +- **Simplicity.** The API is easy to use, for quick implementation. +- **Persistence.** Data remains available across sessions, ensuring continuity. +- **Wide Browser Support.** LocalStorage is supported by all major browsers, ensuring broad compatibility. + +#### Limitations of LocalStorage: + +- **Storage Capacity.** Typically limited to around 5MB, which may not be sufficient for all applications. +- **String-Only Storage.** Only string data types can be stored. More complex data structures need serialization. +- **Synchronous Nature.** Operations are blocking, which can impact performance for larger datasets. + +### IndexedDB + +For more complex and large-scale storage needs, IndexedDB is a powerful alternative. IndexedDB is an asynchronous, low-level API designed to store significant amounts of structured data, including files and blobs. It supports transactions, allowing for reliable data handling and advanced querying capabilities. + +### Benefits of IndexedDB: + +- **Large Storage Capacity.** Capable of storing much larger datasets compared to LocalStorage. +- **Complex Data Structures.** Supports a variety of data types, including objects and arrays, without requiring serialization. +- **Asynchronous Operations.** Non-blocking operations enhance performance, especially with large volumes of data. +- **Advanced Querying.** Provides robust indexing and querying capabilities for efficient data retrieval. diff --git a/docs/developer-documentation/developer-documentation/examples-and-templates/examples-and-templates.md b/docs/developer-documentation/developer-documentation/examples-and-templates/examples-and-templates.md new file mode 100644 index 0000000..baa24b1 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/examples-and-templates/examples-and-templates.md @@ -0,0 +1,121 @@ +--- +sidebar_position: 3 +--- + +# Examples and Templates + +Examples are small projects designed to demonstrate RADFish ecosystem. Templates are meant to be a clean starting point for a new RADFish project. + +## Examples + +Each exammple is scoped to teach developers how to implement core pieces of functionality. Examples include a detailed `README.md` file that explains its purpose, design pattern, and best practices. + +These examples are meant to be a reference for any RADFish project. These examples can serve as a starting point to build out a new RADFish application. However, we recommend starting with a fresh `react-javascript` template. + +The source code for each example is in the open source repo for RADFish [boilerplate](https://github.com/NMFS-RADFish/boilerplate/tree/main/examples). Each example can be cloned and run separately as you are working with each from the RADFish CLI. To learn how to run these scripts, refer to the [running examples](./building-your-application/available-scripts/running-example) section. + +### List of Examples +Here's a list of pre-built examples that you can use as a starting point for your application. These examples are scoped to one core feature. + +1. [Computed Form Fields](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/computed-form-fields/README.md) +1. [Conditional Form Fields](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/conditional-form-fields/README.md) +1. [Field Validators](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/field-validators/README.md) +1. [Form Structure](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/form-structure/README.md) +1. [Mock API](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/mock-api/README.md) +1. [Multistep Form](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/multistep-form/README.md) +1. [Network Status](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/network-status/README.md) +1. [On Device Storage](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/on-device-storage/README.md) +1. [Persisted Form](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/persisted-form/README.md) +1. [Server Sync](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/server-sync/README.md) +1. [Simple Table](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/simple-table/README.md) + +## Templates + +These templates are framework-specific. At the time of this writing, only the `react-javascript` template is supported. New templates for other frameworks and other languages are planned for the future! + +Templates come pre-configured with everything to start coding your new project right away. This includes RADFish core modules, service-worker configuration, application routing, and offline storage. + +Creating a new project based on a template is similar to running an example. If you want to create a new project from the `react-javascript` library, execute this RADFish CLI command: + + `npx @nmfs-radfish/create-radfish-app my-app --template react-javascript` + +This will create a new RADFish project named `my-app` in your current working directory. Happy hacking! + +**Note:** The `react-javascript` template is the default. Running `npx @nmfs-radfish/create-radfish-app my-app` will create the same project without needing to specify the template. + +### Template Directory Structure + +Once you scaffold a new template radfish app, you'll be given the following file structure: + +```bash +my-app +├── babel.config.js +├── index.html +├── mocks +│ ├── browser.js +│ └── handlers.js +├── node_modules/ +├── package-lock.json +├── package.json +├── public +│ ├── icons +│ ├── manifest.json +│ ├── mockServiceWorker.js +│ ├── noaafavicon.png +│ └── robots.txt +├── src +│ ├── App.jsx +│ ├── index.css +│ ├── index.jsx +│ ├── pages +│ └── Home.jsx +│ ├── service-worker.js +│ └── styles +│ └── theme.css +└── vite.config.js +``` + +#### Root Level + +- **`babel.config.js`** Configuration file for Babel, a JavaScript compiler. It specifies how Babel should transpile your code. This enables modern JavaScript features while maintaining compatibility with older browsers. + +- **`index.html`** The main HTML file that serves as the entry point of your application. It includes references to your compiled JavaScript and CSS files generated by the build process. + +- **`node_modules/`** This directory contains all the project's dependencies installed via npm. It's automatically generated when you run `npm install`. You should not manually modify this folder, as it's managed by npm. + +- **`package-lock.json`** Automatically generated file that records the exact version of each installed package. It locks dependencies to specific versions. This ensures consistent installs across different environments. + +- **`package.json`** A manifest file for your Node.js project. It includes metadata about the project, such as the name, version, scripts, dependencies, and more. This file is essential for managing project configurations and dependencies. + +- **`vite.config.js`** Configuration file for Vite, a fast build tool and development server. It customizes the behavior of the Vite server and build process, including plugins, aliases, and other settings. + +#### mocks/ + +This folder contains files related to mocking API requests for development and testing purposes. + +- **`mocks/browser.js`** Sets up and configures the mock service worker for the browser environment. It intercepts network requests during development to simulate API responses without needing a real backend. + +- **`mocks/handlers.js`** Defines request handlers for the mock service worker. Each handler specifies how to respond to certain API requests, allowing you to test different scenarios and data flows. + +#### public/ + +This folder ontains static assets that will be served directly to the browser. These files are not processed by Webpack. + +- **`public/icons`**: Directory containing icon images of various sizes. Typically used for favicons and Progressive Web App (PWA) requirements. +- **`manifest.json`**: Provides metadata about the web application. Useful for PWAs. +- **`mockServiceWorker.js`**: The automatically generated script for the mock service worker. It's used by the msw library to intercept network requests in the browser. +- **`noaafavicon.png`**: The favicon image for your application. This appears in the browser tab and bookmarks. +- **`robots.txt`**: A file that provides directives to web crawlers and bots about which pages or sections of your site should not be processed or scanned. + +#### src/ + +This folder contains source code for your React application. This is where you will spend most of your development time. + +- **`App.js`**: The root React component of your application. It serves as the main container for your app's components and routes. +- **`index.jsx`**: The entry point for your React application. It renders the App component into the DOM and may include global providers like routers or state management tools. +- **`index.css`**: Provides general styling rules that apply to the entire app. It includes resets, normalizations, and default HTML element styling. +- **`pages/`**: Directory containing React components that represent different pages or routes in your application. Each file typically corresponds to a route managed by your router. +- **`pages/Home.jsx`**: The main landing page of your application. It defines the content and layout for the homepage. It often contains key UI components such as headers, footers, navigation, and other elements relevant to the first impression of your app. +- **`service-worker.js`**: Custom service worker script for handling offline support, caching, and other background tasks. It enables your app to function as a PWA with offline capabilities. +- **`styles/`**: Directory for organizing additional CSS or styling files, such as variables, mixins, or component-specific stylesheets. +- **`styles/theme.css`**: Contains global theme variables and styles for consistency in design like colors, fonts, and spacing. diff --git a/docs/developer-documentation/developer-documentation/examples-and-templates/examples/index.mdx b/docs/developer-documentation/developer-documentation/examples-and-templates/examples/index.mdx new file mode 100644 index 0000000..6cd46a5 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/examples-and-templates/examples/index.mdx @@ -0,0 +1,18 @@ +--- +sidebar_position: 1 +--- + +# Examples + +Examples are small projects designed to demonstrate RADFish ecosystem. Templates are meant to be a clean starting point for a new RADFish project. + +The source code for each example is in the open source repo for RADFish [boilerplate](https://github.com/NMFS-RADFish/boilerplate/tree/main/examples). Each example can be cloned and run separately as you are working with each from the RADFish CLI. To learn how to run these scripts, refer to the [running examples section](https://nmfs-radfish.github.io/radfish/developer-documentation/building-your-application/available-scripts/running-example). + + +```mdx-code-block +import DocCardList from '@theme/DocCardList'; + + +``` + +{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/getting-started.md b/docs/developer-documentation/developer-documentation/getting-started.md new file mode 100644 index 0000000..7c36cde --- /dev/null +++ b/docs/developer-documentation/developer-documentation/getting-started.md @@ -0,0 +1,89 @@ +--- +sidebar_position: 1 +--- + +# Getting Started + +Create RADFish App is the officially supported tool for creating single-page React applications. It offers a modern build setup with no configuration. + +## Prerequisites + +Before you start, make sure you have the following installed: + +- [x] Node.js (v20.17.0 or later) +- [x] npm (v10.8.2 or later) +- [x] git (v2.0 or later) + +## Quick Start + +### Option 1: Scaffold a new app from a template + +Start your app with a barebones and pre-configured [template](./examples-and-templates#templates). + +```bash +npx @nmfs-radfish/create-radfish-app my-app +cd my-app +npm start +``` + +Once the development server starts, visit http://localhost:3000/ in your browser to see your app. + +### Option 2: Scaffold a new app from an example + +Select an [example](/radfish/developer-documentation/examples-and-templates) and run [the command](./building-your-application/available-scripts/running-example.md) using the `--example` tag. + +```bash +npx @nmfs-radfish/create-radfish-app my-app --example multistep-form +cd my-app +npm start +``` + +### Option 3: Clone the boilerplate repository to access all examples + +To get all the examples, clone the [boilerplate repository](https://github.com/NMFS-RADFish/boilerplate): + +```bash +git clone https://github.com/NMFS-RADFish/boilerplate.git +``` + +Then navigate to the example you want to run and start the app: + +```bash +cd boilerplate/examples/[example you want to run] +npm install +npm start +``` + +Once the development server starts, visit http://localhost:3000/ in your browser to see your app. + +### Using the help flag + +The `--help` flag is a common option that displays helpful information about a command or script, including available options and usage instructions. + +```bash +npx @nmfs-radfish/create-radfish-app --help +``` + +### Upgrading package versions in your app + +1. In the root of your project run: + ```bash + npm update + ``` + +2. Check for Changes: + ```bash + npm test + ``` +Please visit [upgrading](./upgrading.md) for more information. + +## Scripts + +**`npm start`** + +This script starts the Vite development server. It runs the app locally with hot module reloading, allowing for fast development and instant updates as you make changes. Open [http://localhost:3000](http://localhost:3000/) to view it in the browser. + +See [Available Scripts](./building-your-application/available-scripts) for full list of commands. + +## Next steps +Now that you are up and running, see the [Components & Usage](./building-your-application/patterns/components.md) section to start building out your first pages! diff --git a/docs/developer-documentation/developer-documentation/libraries/index.mdx b/docs/developer-documentation/developer-documentation/libraries/index.mdx new file mode 100644 index 0000000..f237af0 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/libraries/index.mdx @@ -0,0 +1,15 @@ +--- +sidebar_position: 5 +--- + +# Libraries + +You can learn about the libraries and packages used in RADFish here. + +```mdx-code-block +import DocCardList from '@theme/DocCardList'; + + +``` + +{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/libraries/radfish.md b/docs/developer-documentation/developer-documentation/libraries/radfish.md new file mode 100644 index 0000000..b40b511 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/libraries/radfish.md @@ -0,0 +1,10 @@ +--- +sidebar_position: 1 +description: Core modules to build a RADFish app +--- + +# `radfish` + +The `radfish` NPM package contains the core JavaScript modules for any RADFish project. These modules are framework-agnostic. They should be fully functional whether you are building an application in React, Svelte, or even Vanilla JavaScript. + +This library is open source and can be found here: [https://www.npmjs.com/package/@nmfs-radfish/radfish](https://www.npmjs.com/package/@nmfs-radfish/radfish) diff --git a/docs/developer-documentation/developer-documentation/libraries/react-radfish.md b/docs/developer-documentation/developer-documentation/libraries/react-radfish.md new file mode 100644 index 0000000..c702f46 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/libraries/react-radfish.md @@ -0,0 +1,12 @@ +--- +sidebar_position: 2 +description: Modules to build a RADFish app in React +--- + +# `react-radfish` + +The `react-radfish` NPM package contains the React component library for any RADFish project. It's designed for projects built with React or React-flavored frameworks (like Remix or Next.js). These modules expose components that can be used consistently across different React projects. + +Note that this library is not meant to replace the `@trussworks` library. It's meant to work alongside it. Where possible, you should leverage the `@trussworks` library. However, if there's a component not in `@trussworks`, or there's shortcomings with the `@trussworks` implementation, you can rely on the components in the `@nmfs-radfish/react-radfish` package. + +This library is open source and can be found here: [https://www.npmjs.com/package/@nmfs-radfish/react-radfish](https://www.npmjs.com/package/@nmfs-radfish/react-radfish) diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/dexie.md b/docs/developer-documentation/developer-documentation/technical-decision-log/dexie.md new file mode 100644 index 0000000..bdf08c8 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/technical-decision-log/dexie.md @@ -0,0 +1,16 @@ +--- +sidebar_position: 9 +description: Simplifies working with IndexedDB +--- + +# Dexie for Offline Data +[Dexie](https://dexie.org/) simplifies working with IndexedDB. + +## Why we chose this +Dexie makes IndexedDB development less complex. IndexedDB is crucial for RADFish applications that require offline capabilities. RADFish apps need reliable data storage and retrieval with intermittent internet connectivity. + +## Trade-offs +Using a wrapper around IndexedDB like Dexie abstracts some low-level control. However, it significantly eases development complexity, making it a worthwhile trade-off. + +## Alternatives +[LocalForage](https://github.com/localForage/localForage) and [PouchDB](https://github.com/pouchdb/pouchdb) are alternatives that offer similar abstraction over IndexedDB. They offer additional features like automatic synchronization with remote databases. However, Dexie's simpler API and focus on IndexedDB make it more suitable for RADFish's client-side DB needs. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/index.mdx b/docs/developer-documentation/developer-documentation/technical-decision-log/index.mdx new file mode 100644 index 0000000..9c531ce --- /dev/null +++ b/docs/developer-documentation/developer-documentation/technical-decision-log/index.mdx @@ -0,0 +1,17 @@ +--- +sidebar_position: 6 +--- + +# RADFish Technical Decision Log + +This section provides justification for the technologies and frameworks we chose for RADFish. Most pages include "Why we chose this", "Trade-offs", and "Alternatives" sections. These demonstrate pros, cons, and other options that were considered, respectively. + +For more information about this section, read the [statement of purpose](https://nmfs-radfish.github.io/radfish/developer-documentation/technical-decision-log/purpose). + +```mdx-code-block +import DocCardList from '@theme/DocCardList'; + + +``` + +{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/jsdocs.md b/docs/developer-documentation/developer-documentation/technical-decision-log/jsdocs.md new file mode 100644 index 0000000..78fd333 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/technical-decision-log/jsdocs.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 8 +description: Accessible and easy to adopt +--- + +# JavaScript with JSDoc + +[JSDoc](https://jsdoc.app/about-getting-started) is an automatic API documentation generator. + +## Why we chose this +JavaScript offers broad accessibility and ease of adoption for government contractors. Combined with JS Docs, this helps standardize frontend development. JavaScript’s flexibility allows for broader adoption among government contractors. It also adapts to RADFish's diverse and evolving project requirements. JS Docs also doesn't impose the stricter typing system of TypeScript. + +## Trade-offs +TypeScript provides static typing, offering compile-time type checking, which reduces runtime errors. The absence of TypeScript’s compile-time type checking may increase reliance on runtime testing. However, adopting TypeScript involves a steeper learning curve and potentially longer development times. RADFish leverages most developers' familiarity with JavaScript. JS Docs offers a balanced approach, providing some benefits of TypeScript without its overhead. + +## Alternatives +[TypeScript](https://www.typescriptlang.org/) can still be adopted by teams that wish to use it. Migrating from JS Docs to TypeScript is relatively straightforward. There are tools available to automate this process. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/mock-service-worker.md b/docs/developer-documentation/developer-documentation/technical-decision-log/mock-service-worker.md new file mode 100644 index 0000000..07586e0 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/technical-decision-log/mock-service-worker.md @@ -0,0 +1,16 @@ +--- +sidebar_position: 6 +description: Required for offline functionality +--- + +# Mock Service Worker +[Mock Service Worker (MSW)](https://mswjs.io/) simulates API responses during development and testing. + +## Why we chose this +NOAA applications must work offline. MSW lets developers build and test applications without dependency on real backend services. This helps develop applications with offline functionality without a backend to test against. + +## Trade-offs +Relying on MSW for development might mask integration issues with actual backend services. For example, an error in MWS setup could result in a real endpoint being overridden by the mock endpoint. However, the benefits of offline development and testing are crucial for RADFish's goals. + +## Alternatives +[JSON Server](https://www.npmjs.com/package/json-server) or [Mirage JS](https://miragejs.com/) provide similar mocking capabilities. They emphasize full-fledged backend simulation. They emphasize full-fledged backend simulation and ease of setup for simpler backends. However, MSW's integrates with service workers and can intercept network requests at the browser level. These features offer more realistic testing scenarios for RADFish's offline functionality. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/prettier.md b/docs/developer-documentation/developer-documentation/technical-decision-log/prettier.md new file mode 100644 index 0000000..4132dc5 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/technical-decision-log/prettier.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 7 +description: Ensures consistent code quality and style +--- + +# Prettier and ESLint + +[Prettier](https://prettier.io/) is an automatic code formatter. [ESLint](https://eslint.org/) analyzes code to find problems and errors in a process known as _linting_. + +## Why we chose this +Consistency in code quality and style is crucial for collaborative projects like RADFish. Prettier and ESLint automate formatting and linting. This ensures all code adheres to best practices and is accessible to all developers working on NOAA projects. + +## Trade-offs +Enforcing a specific coding style may require initial adjustments for developers. However, the long-term benefits of maintainable and error-free code outweigh this adjustment period. Also, these standards can be enforced automatically via code editor configuration setups. For example, developers can use the the “on-save” linting of VSCode. + +## Alternatives +[TSLint](https://palantir.github.io/tslint/) (deprecated in favor of ESLint in 2019) and [Stylelint](https://stylelint.io/) are alternatives to ESLint. They focus on on TypeScript and CSS, respectively. While they offer specialized linting capabilities, the combination of Prettier and ESLint covers a broader range of RADFish's code quality needs. Prettier and ESLint provide JavaScript styling and linting with a unified setup, making them more suitable than using separate tools for different languages. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/purpose.md b/docs/developer-documentation/developer-documentation/technical-decision-log/purpose.md new file mode 100644 index 0000000..7f3387f --- /dev/null +++ b/docs/developer-documentation/developer-documentation/technical-decision-log/purpose.md @@ -0,0 +1,18 @@ +--- +sidebar_position: 1 +description: Provides clarity around technical decisions +--- + +# Purpose + +This section provides justification for the technologies and frameworks we chose for RADFish. This provides transparency and clarity around the technical decisions we have made. + +NOAA's frontend applications have unique requirements, such as: + +- **Offline functionality.** Our users do not always have reliable internet access. Our applications must work offline. +- **Cross-platform performance.** Our applications must work on both mobile and desktop devices. They must work on a variety of operating systems and browsers. +- **Regulation compliance.** Federal web applications must meet regulation standards, such as 508 Compliance. + +Our choices must balance ease of use for our developers while meeting these challenges. We selected technologies and frameworks to create a cohesive, efficient, and compliant environment. The chosen stack optimizes developer productivity, application performance, and user experience. + +--- diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/tanstack.md b/docs/developer-documentation/developer-documentation/technical-decision-log/tanstack.md new file mode 100644 index 0000000..36ef3ea --- /dev/null +++ b/docs/developer-documentation/developer-documentation/technical-decision-log/tanstack.md @@ -0,0 +1,13 @@ +--- +sidebar_position: 11 +description: Offers flexible state management +--- + +# TanStack for State Management +[TanStack](https://tanstack.com/) provides utilities for state management, tables, and querying. + +## Why we chose this +TanStack helps manage server state and table state in RADFish applications. NOAA applications have complex data structures and multi-entry forms. TanStack creates an improved user experience with less boilerplate code. + +## Trade-offs +Using Tanstack requires familiarity with its API and concepts, which may present a learning curve. However, it handles NOAA’s data-centric applications and provides an enhanced user experience. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/trussworks.md b/docs/developer-documentation/developer-documentation/technical-decision-log/trussworks.md new file mode 100644 index 0000000..20624db --- /dev/null +++ b/docs/developer-documentation/developer-documentation/technical-decision-log/trussworks.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 5 +description: Adherence to US Web Design Standards +--- + +# Trussworks Component Library + +The [Trussworks component library](https://github.com/trussworks/react-uswds) is a set of standard components from React libraries and the [U.S. Web Design System (USWDS)](https://designsystem.digital.gov/). + +## Why we chose this +Trussworks component library adheres to USWDS standards. This ensures RADFish applications meet federal standards for accessibility and design. It also aligns with NOAA’s branding guidelines and 508 compliance requirements. + +## Trade-offs +Using a specific component library might restrict design flexibility. However, using a single component library provides consistency. Trussworks also meets compliance standards, which is invaluable for government projects. + +## Alternatives +[Material-UI](https://mui.com/material-ui/) and [Ant Design](https://ant.design/) offer extensive component libraries with customizable themes. These provides broader design options. However, Trussworks' specific focus on USWDS compliance and its integration with React makes it a better fit for RADFish. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/workbox.md b/docs/developer-documentation/developer-documentation/technical-decision-log/workbox.md new file mode 100644 index 0000000..1ced0db --- /dev/null +++ b/docs/developer-documentation/developer-documentation/technical-decision-log/workbox.md @@ -0,0 +1,13 @@ +--- +sidebar_position: 10 +description: Service worker management for improved caching +--- + +# Workbox +[Workbox](https://developer.chrome.com/docs/workbox) is a collection of service worker libraries and tooling. + +## Why we chose this +Workbox streamlines service worker management and offline capabilities essential for RADFish. It simplifies caching strategies and offline data handling. This is critical for NOAA PWAs used offline. + +## Trade-offs +Workbox’s abstraction layer may obscure some of the finer details of service worker implementation. However, the ease of integrating robust offline functionalities justifies its use within RADFish. The ease of implementation makes it more approachable for NOAA developers. Developers can easily modify the RADFish-provided setup as well. diff --git a/docs/developer-documentation/developer-documentation/upgrading.md b/docs/developer-documentation/developer-documentation/upgrading.md new file mode 100644 index 0000000..5f2eac7 --- /dev/null +++ b/docs/developer-documentation/developer-documentation/upgrading.md @@ -0,0 +1,78 @@ +--- +sidebar_position: 7 +--- + +# Upgrading + +## How to keep your RADFish project up to date + +Updating your RADFish version ensures stability, security, and the latest features. It also keeps your project free of warnings and errors. This section provides a step-by-step guide on how to update your RADFish packages. + +### 1. Upgrade Packages + + 1. **Run command:** In the root of your project, run: + ```bash + npm update + ``` + + This will update both `@nmfs-radfish/radfish` and `@nmfs-radfish/react-radfish` along with their dependencies to the latest compatible versions. + + 2. **Check for Changes:** After running the update, you should verify that everything is working as expected. It's a good practice to run your test suite to catch any potential issues: + ```bash + npm test + ``` + +### 2. Handling Warnings During Updates + + While updating your packages, you might encounter warnings. These warnings may not necessarily be RADFish-specific. These warnings often occur when certain packages in your project are outdated or incompatible. To get rid of these warnings: + + 1. **Check for outdated packages:** Run the command below to list all outdated packages, including those not related to RADFish. + ```bash + npm outdated + ``` + + 2. **Update dependencies:** You can selectively update non-react-radfish packages by running: + ```bash + npm update + ``` + + 3. **Resolve peer dependency warnings:** Some warnings may be related to peer dependencies. To resolve these, you might need to install or update the required dependencies manually. + ```bash + npm install + ``` + + 4. **Remove deprecated packages:** If the warning is about deprecated packages, it’s a good idea to check if these packages are still necessary and remove them if they’re not. + ```bash + npm uninstall + ``` + +### 3. Overview of Packages Managed in `radfish` and `react-radfish` + +In your RADFish project, these packages are managed and should be kept up to date: +- `@nmfs-radfish/radfish` +- `@nmfs-radfish/react-radfish` + +#### `@nmfs-radfish/radfish` +This package handles the core logic and utilities for RADFish. It manages several dependencies that are essential for the functionality of the RADFish system: + + - **Dependencies:** + - `dexie`: A minimalistic IndexedDB wrapper for managing databases. + - `msw`: A library for mocking API requests in development and testing environments. + - `react`: The core React library required for building user interfaces in RADFish projects. + +#### `@nmfs-radfish/react-radfish` + + This package provides UI components for React applications using RADFish. It manages several dependencies that enhance the user interface and functionality: + + - **Dependencies:** + - `@tanstack/react-table`: A headless table library for building powerful data tables in React. + - `@trussworks/react-uswds`: A component library that implements the U.S. Web Design System (USWDS) for React. + + - **DevDependencies**: + - `@testing-library/dom`: Utility for testing DOM nodes. + - `@testing-library/jest-dom`: Custom Jest matchers for asserting on DOM nodes. + - `@testing-library/react`: Testing utilities for React components. + - `@vitejs/plugin-react`: A Vite plugin that provides React support. + - `jsdom`: JavaScript implementation of the DOM for testing. + - `vite-plugin-css-injected-by-js`: A Vite plugin for injecting CSS in JavaScript. + - `vitest`: A Vite-native unit testing framework. From 3074cd93864a639ec181347fec05af63087cb525 Mon Sep 17 00:00:00 2001 From: Onna Nelson <168219771+oanelson@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:23:02 -0800 Subject: [PATCH 2/5] Add files via upload --- .../building-your-application/available-scripts/index.mdx | 5 +---- .../building-your-application/index.mdx | 3 +-- .../building-your-application/patterns/index.mdx | 3 +-- .../examples-and-templates/examples/index.mdx | 4 +++- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/docs/developer-documentation/building-your-application/available-scripts/index.mdx b/docs/developer-documentation/building-your-application/available-scripts/index.mdx index a646d32..bc5ff40 100644 --- a/docs/developer-documentation/building-your-application/available-scripts/index.mdx +++ b/docs/developer-documentation/building-your-application/available-scripts/index.mdx @@ -4,8 +4,7 @@ sidebar_position: 4 # Available Scripts -{/* Write top text here */} - +There are many CLI scripts available for RADFish projects. Learn more about them in this section. ```mdx-code-block import DocCardList from '@theme/DocCardList'; @@ -13,8 +12,6 @@ import DocCardList from '@theme/DocCardList'; ``` -{/* Write bottom text here */} - **`npm start`** Starts the Vite development server. It runs the app locally with hot module reloading, allowing for fast development and instant updates as you make changes. Open [http://localhost:3000](http://localhost:3000/) to view it in the browser. diff --git a/docs/developer-documentation/building-your-application/index.mdx b/docs/developer-documentation/building-your-application/index.mdx index c1853e7..85849fd 100644 --- a/docs/developer-documentation/building-your-application/index.mdx +++ b/docs/developer-documentation/building-your-application/index.mdx @@ -4,8 +4,7 @@ sidebar_position: 4 # Building Your Application -{/* Write top text here */} - +Learn how to set up your project and make sure it meets development standards in this section. You can also learn about patterns and scripts that can help you build your application. ```mdx-code-block import DocCardList from '@theme/DocCardList'; diff --git a/docs/developer-documentation/building-your-application/patterns/index.mdx b/docs/developer-documentation/building-your-application/patterns/index.mdx index a23e670..90632b5 100644 --- a/docs/developer-documentation/building-your-application/patterns/index.mdx +++ b/docs/developer-documentation/building-your-application/patterns/index.mdx @@ -4,8 +4,7 @@ sidebar_position: 3 # Patterns -{/* Write top text here */} - +Patterns are solutions to common problems in software design. In this section, you can learn about several patterns that help with routing, state management, APIs, and other common components of RADFish applications. There are also patterns for testing, debugging, and other parts of the software development lifecycle. ```mdx-code-block import DocCardList from '@theme/DocCardList'; diff --git a/docs/developer-documentation/examples-and-templates/examples/index.mdx b/docs/developer-documentation/examples-and-templates/examples/index.mdx index 9b962b0..6cd46a5 100644 --- a/docs/developer-documentation/examples-and-templates/examples/index.mdx +++ b/docs/developer-documentation/examples-and-templates/examples/index.mdx @@ -4,7 +4,9 @@ sidebar_position: 1 # Examples -{/* Write top text here */} +Examples are small projects designed to demonstrate RADFish ecosystem. Templates are meant to be a clean starting point for a new RADFish project. + +The source code for each example is in the open source repo for RADFish [boilerplate](https://github.com/NMFS-RADFish/boilerplate/tree/main/examples). Each example can be cloned and run separately as you are working with each from the RADFish CLI. To learn how to run these scripts, refer to the [running examples section](https://nmfs-radfish.github.io/radfish/developer-documentation/building-your-application/available-scripts/running-example). ```mdx-code-block From db2e86e69d99628a12d643633c54e169337f4d8f Mon Sep 17 00:00:00 2001 From: Onna Nelson <168219771+oanelson@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:23:38 -0800 Subject: [PATCH 3/5] Delete docs/developer-documentation/developer-documentation directory --- .../available-scripts/index.mdx | 53 --- .../available-scripts/installing-cli.md | 23 -- .../available-scripts/running-example.md | 15 - .../development-life-cycle.md | 39 --- .../development-standards.md | 90 ----- .../building-your-application/index.mdx | 15 - .../patterns/apiservice.md | 214 ------------ .../patterns/components.md | 64 ---- .../patterns/debugging.md | 17 - .../patterns/index.mdx | 15 - .../patterns/mock-api.md | 56 ---- .../patterns/navigation.md | 33 -- .../patterns/offline-storage.md | 171 ---------- .../patterns/routing.md | 81 ----- .../patterns/state-management.md | 313 ------------------ .../patterns/testing.md | 116 ------- .../service-worker-removal.md | 21 -- .../concepts/concepts.md | 16 - .../concepts/offline-first.md | 17 - .../concepts/on-device-storage.md | 50 --- .../examples-and-templates.md | 121 ------- .../examples-and-templates/examples/index.mdx | 18 - .../getting-started.md | 89 ----- .../libraries/index.mdx | 15 - .../libraries/radfish.md | 10 - .../libraries/react-radfish.md | 12 - .../technical-decision-log/dexie.md | 16 - .../technical-decision-log/index.mdx | 17 - .../technical-decision-log/jsdocs.md | 17 - .../mock-service-worker.md | 16 - .../technical-decision-log/prettier.md | 17 - .../technical-decision-log/purpose.md | 18 - .../technical-decision-log/tanstack.md | 13 - .../technical-decision-log/trussworks.md | 17 - .../technical-decision-log/workbox.md | 13 - .../developer-documentation/upgrading.md | 78 ----- 36 files changed, 1906 deletions(-) delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/available-scripts/index.mdx delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/available-scripts/installing-cli.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/available-scripts/running-example.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/development-life-cycle.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/development-standards.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/index.mdx delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/apiservice.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/components.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/debugging.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/index.mdx delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/mock-api.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/navigation.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/offline-storage.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/routing.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/state-management.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/patterns/testing.md delete mode 100644 docs/developer-documentation/developer-documentation/building-your-application/service-worker-removal.md delete mode 100644 docs/developer-documentation/developer-documentation/concepts/concepts.md delete mode 100644 docs/developer-documentation/developer-documentation/concepts/offline-first.md delete mode 100644 docs/developer-documentation/developer-documentation/concepts/on-device-storage.md delete mode 100644 docs/developer-documentation/developer-documentation/examples-and-templates/examples-and-templates.md delete mode 100644 docs/developer-documentation/developer-documentation/examples-and-templates/examples/index.mdx delete mode 100644 docs/developer-documentation/developer-documentation/getting-started.md delete mode 100644 docs/developer-documentation/developer-documentation/libraries/index.mdx delete mode 100644 docs/developer-documentation/developer-documentation/libraries/radfish.md delete mode 100644 docs/developer-documentation/developer-documentation/libraries/react-radfish.md delete mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/dexie.md delete mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/index.mdx delete mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/jsdocs.md delete mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/mock-service-worker.md delete mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/prettier.md delete mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/purpose.md delete mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/tanstack.md delete mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/trussworks.md delete mode 100644 docs/developer-documentation/developer-documentation/technical-decision-log/workbox.md delete mode 100644 docs/developer-documentation/developer-documentation/upgrading.md diff --git a/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/index.mdx b/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/index.mdx deleted file mode 100644 index bc5ff40..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/index.mdx +++ /dev/null @@ -1,53 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Available Scripts - -There are many CLI scripts available for RADFish projects. Learn more about them in this section. - -```mdx-code-block -import DocCardList from '@theme/DocCardList'; - - -``` - -**`npm start`** - -Starts the Vite development server. It runs the app locally with hot module reloading, allowing for fast development and instant updates as you make changes. Open [http://localhost:3000](http://localhost:3000/) to view it in the browser. - -**`npm run build`** - -This script builds the project for production by using Vite’s build tool. It generates optimized static assets, such as HTML, CSS, and JavaScript, which are output to the `dist` directory. - -**`npm run prebuild`** - -Before the build process starts, this script deletes the `dist` folder (which contains the previous build). This helps prevent old build files from being included in the new build. - -**`npm test`** - -Runs unit and integration tests using Vitest, while excluding end-to-end (e2e) tests located in the `./src/__tests__/e2e/` directory. It ensures that regular tests are executed separately from e2e tests. - -**`npm test:e2e`** - -Runs end-to-end (e2e) tests located in `./src/__tests__/e2e/integration.e2e.test.jsx`. This script uses concurrently to run the Vite server and e2e tests in parallel, automatically stopping other processes if one succeeds. - -**`npm run lint`** - -Runs ESLint with the `--fix` option, which automatically fixes certain linting issues in the code found in the `src/` directory. - -**`npm run format`** - -Formats the code in the `src/` directory using Prettier according to the configuration specified in the `.prettierrc` file. This ensures consistent code formatting across the project. - -**`npm run serve`** - -Starts a local server to preview the production build. It serves the files from the `dist/` folder, allowing you to check how the app will behave in a production environment. - -**`npm run lhci:mobile`** - -Runs **Lighthouse CI (LHCI)** on the application, collecting performance metrics and scores for mobile devices. It automates performance auditing to ensure the app meets mobile optimization standards. - -**`npm run lhci:desktop`** - -Runs **Lighthouse CI (LHCI)** on the application, collecting performance metrics and scores for desktop devices. This script is similar to lhci:mobile but targets desktop performance. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/installing-cli.md b/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/installing-cli.md deleted file mode 100644 index 9df7cb0..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/installing-cli.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Installing the CLI - -The RADFish CLI is available as an `npm` package, making the installation process much simpler. Follow these steps to install and use the CLI: - -## Install the CLI - -To install the RADFish CLI globally on your system, run this command: - -```bash -npm install -g @nmfs-radfish/create-radfish-app -``` - -To verify the installation, you can run: - -```bash -create-radfish-app --version -``` - -This should display the version number of the installed CLI. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/running-example.md b/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/running-example.md deleted file mode 100644 index 1b92ebc..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/available-scripts/running-example.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Running an Example - -RADFish ships with several different [boilerplate examples](../../examples-and-templates#examples). These examples demonstrate core functions identified as critical for NOAA application development. You can use these examples as a reference point to build out your own implementation. Or, they may serve as inspiration for your own designs and best practices. - -For instance, there's an example that demonstrates how to build a multi-step form that caches each step within IndexedDB. Caching the form allows it to be referenced without a network connection. In order to run this example, you can run this command: - -`npx @nmfs-radfish/create-radfish-app my-app --example multistep-form` - -This will clone the code from the `multistep-form` onto your machine. It also spawns a new web process on port `3000` or another port if that is already taken. - -Feel free to use this code and modify it for your needs! diff --git a/docs/developer-documentation/developer-documentation/building-your-application/development-life-cycle.md b/docs/developer-documentation/developer-documentation/building-your-application/development-life-cycle.md deleted file mode 100644 index a54718b..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/development-life-cycle.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -sidebar_position: 1 -description: Setting up web projects with RADFish ---- - -# Project Setup - -When creating a web application in the NOAA ecosystem, take time to carefully set up your project. This will make ongoing development easier and reduce maintenance overhead. A proper setup follows best practices around file structure, linting, core frameworks, and build tooling. - -All new NOAA web applications must: - -- support full-featured web forms. -- adhere to compliance regulations. -- follow branding and style guidelines. -- use standard environments and tools that are familiar to other NOAA developers. - -To setup a new NOAA web app project, we recommend following [Getting Started](../getting-started) documentation. - -## React Components - -Trussworks React components are included by default with the RADFish Framework. The components build upon the component library, which adheres to [USWDS standards](https://designsystem.digital.gov/). For detailed information on the available components and what attributes they accept, please see the official storybook documentation: [https://trussworks.github.io/react-uswds/](https://trussworks.github.io/react-uswds/) - -### Why Use React? - -- **Responsive Design.** Automatically adjusts for different screen sizes with a collapsible menu. -- **Customizable.** Allows for easy customization of navigation links. -- **Integrated Search.** Includes a search bar for added functionality. -- **Branding.** Supports branding elements like logos in the header. - -**Additional Notes** - -- The **`@trussworks/react-uswds`** package is required to ensure proper styling and functionality. This package is included by default, so you do not need to import it. -- Custom CSS can be applied for further customization. - -## Resources - -By integrating the [header](https://trussworks.github.io/react-uswds/?path=/docs/components-header--basic-header) components into your React application, you can create a professional and responsive UI with minimal effort. The **`Layout`** and **`HeaderNav`** components work together to provide a structured and navigable interface, enhancing the overall user experience. - ---- diff --git a/docs/developer-documentation/developer-documentation/building-your-application/development-standards.md b/docs/developer-documentation/developer-documentation/building-your-application/development-standards.md deleted file mode 100644 index b603e0b..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/development-standards.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -sidebar_position: 2 -description: USWDS, NOAA branding and Styling, and 508 compliance ---- - -# Development Standards - -## USWDS - -The U.S. Web Design System (USWDS) is a set of design and development principles and guidelines. It helps deveolpers create standardized, accessible, consistent, and user-friendly websites and applications. It helps developers adhere to 508 compliance guidelines. - -In most cases, RADFish uses standard components from the [`react-uswds`](https://github.com/trussworks/react-uswds) open source project. The RADFish project further extends the react-uswds library. These components maintain the functionality of react-uswds, but are branded with NOAA themes and styles. These components live in the [`react-radfish` directory](https://github.com/NMFS-RADFish/react-components). This allows modern React development with NOAA look and feel. - -For information on the full `react-uswds` library, refer to their [storybook](https://trussworks.github.io/react-uswds/?path=/docs/welcome--docs). - -Building applications with `react-radfish` leads to faster development, consistent design, and ensures compliance with government regulations. The [`react-uswds` storybook](https://trussworks.github.io/react-uswds/?path=/docs/welcome--docs) provides examples of compliant components that can be used to build apps for various use cases. - - - -### Example - -If you wanted to build a `TextInput` component into an existing form, you can use the `@trussworks` [storybook reference](https://trussworks.github.io/react-uswds/?path=/docs/components-text-input--docs) related to component props that are available. - -```jsx - -import { TextInput, Label } from "@trussworks/react-uswds"; - - - handleBlur(e, fullNameValidators)} -/> -``` - ---- - -## NOAA Branding Guidelines and Style Guide - -Branding creates a distinct identity for a product or application. It defines and maintains a set of visual elements that represent the brand. Branding can include logos, colors, and typography standards. - -You might have noticed that the components above do not have any `className` assigned. You may be wondering how to style that component. There are a few things to keep in mind when styling components: - -- Each component in `react-radfish` has it’s own scoped CSS file. This file modifies the existing `@trussworks` CSS to inject NOAA styles. This file should not be touched. If you notice a bug or issue, please consider [contributing to the project](https://nmfs-radfish.github.io/radfish/about/contribute). -- You can modify the general theme of these components in the `styles/theme.css` file. You can change things like color variables, font-family, and line-height here. They will be propagated throughout the application, as well as throughout `react-radfish`. RADFish uses CSS variables, like this: - -```css -// styles/theme.js -:root { - --noaa-dark-blue: #0054a4; -} - -// form.css -.your-custom-class { - background-color: var(--noaa-dark-blue); -} -``` - -- If you need to add additional styles to a particular component, you can add another `className` **after** the component has been imported from `react-radfish`: - -```jsx -import { Label } from "@nmfs-radfish/react-radfish"; - -; -``` - -By following this method, you can use the `uswds` component, while still maintaining the NOAA themes. You can also extend it further to suit your needs as a developer. - -## 508 Compliance (Section 508 of the Rehabilitation Act) - -Section 508 compliance refers to the adherence to accessibility standards outlined in [Section 508 of the Rehabilitation Act](https://www.section508.gov/). For web developers, it means designing and developing content that's accessible to individuals with disabilities. In other words, 508 compliant websites can be navigated and understood by users with various disabilities. For example, there are guidelines that aid those with visual or auditory impairments. Developers must follow these guidelines to ensure their websites are accessible and usable by everyone. This promotes an inclusive and diverse online experience. - -Because NOAA is a governmental agency, Section 508 compliance is required for the development of frontend apps. NOAA provides vital information related to weather, oceans, and atmospheric conditions. Individuals with diverse abilities need to access and use these resources. - -Section 508 compliance is a driving factor for many decisions we make in RADFish about our UX strategies. We have also extended a compliant component library in `@trussworks/react-uswds`. - -### Resources -Read more about 508 compliance here: [https://www.section508.gov/](https://www.section508.gov/) diff --git a/docs/developer-documentation/developer-documentation/building-your-application/index.mdx b/docs/developer-documentation/developer-documentation/building-your-application/index.mdx deleted file mode 100644 index 85849fd..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/index.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Building Your Application - -Learn how to set up your project and make sure it meets development standards in this section. You can also learn about patterns and scripts that can help you build your application. - -```mdx-code-block -import DocCardList from '@theme/DocCardList'; - - -``` - -{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/apiservice.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/apiservice.md deleted file mode 100644 index 45f4fed..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/apiservice.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -sidebar_position: 3 -description: Use any network library to handle HTTP requests ---- - -# Integrating with Backend Services - -You can use any network library to handle HTTP requests (GET, POST, PUT, DELETE). We’ve provided examples using the native fetch API. You can adapt these examples to the library that best fits your needs. - -## Making API Requests - -A common pattern is to call network requests in a `useEffect` that will trigger whenever a React component loads: - -```jsx -useEffect(() => { - async function fetchData() { - try { - const response = await fetch("https://api.example.com/data", { - headers: { - "X-Access-Token": "your-access-token", - }, - }); - if (!response.ok) { - throw new Error("Network response was not ok"); - } - const data = await response.json(); - console.log(data); - } catch (error) { - console.error("Error:", error); - } - } - - fetchData(); -}, []); -``` - -### `GET` Request -Asynchronous function to perform a `GET` request. -- `@param {string} endpoint` - The API endpoint to perform the GET request. -- `@param {Object} queryParams` - The query parameters for the GET request. -- `@returns {Promise}` - A promise that resolves to the API response data or an error string. - - ```js - async function get(API_ENDPOINT, queryParams) { - const queryString = new URLSearchParams(queryParams).toString(); - const url = `${endpoint}?${queryString}`; - - try { - const response = await fetch(url, { - headers: { - "X-Access-Token": "your-access-token", - }, - }); - if (!response.ok) { - throw new Error("Network response was not ok"); - } - const data = await response.json(); - return data; - } catch (error) { - console.error("Error:", error); - throw error; - } - } - - useEffect(() => { - const API_ENDPOINT = "https://api.example.com/data"; - const params = { param1: "foo" }; - - const fetchData = async () => { - const data = await get(API_ENDPOINT, params); - // handle data as needed - }; - - fetchData(); - }, []); - ``` - -### `POST` Request - -Asynchronous function to perform a `POST` request. -- `@param {string} endpoint` - The API endpoint to perform the POST request. -- `@param {Object} body` - The request body for the POST request. -- `@returns {Promise}` - A promise that resolves to the API response data or an error string. - - ```jsx - async function post(API_ENDPOINT, bodyData) { - try { - const response = await fetch(API_ENDPOINT, { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-Access-Token": "your-access-token", - }, - body: JSON.stringify({ ...bodyData }), - }); - if (!response.ok) { - throw new Error("Network response was not ok"); - } - const data = await response.json(); - return { data }; - } catch (error) { - console.error("Error:", error); - throw error; - } - } - - // Example usage - useEffect(() => { - const API_ENDPOINT = "https://api.example.com/data"; - const bodyData = { key: "value" }; - - const postData = async () => { - const data = await post(API_ENDPOINT, bodyData); - // handle data as needed - }; - - postData(); - }, []); - ``` - -### `PUT` Request - -Asynchronous function to perform a `PUT` request. -- `@param {string} endpoint` - The API endpoint to perform the PUT request. -- `@param {Object} body` - The request body for the PUT request. -- `@returns {Promise}` - A promise that resolves to the API response data or an error string. - - ```jsx - async function update(endpoint, { id, bodyData }) { - const url = `${endpoint}/${id}`; - - try { - const response = await fetch(url, { - method: "PUT", - headers: { - "Content-Type": "application/json", - "X-Access-Token": "your-access-token", - }, - body: JSON.stringify(bodyData), - }); - if (!response.ok) { - throw new Error("Network response was not ok"); - } - const data = await response.json(); - return data; - } catch (error) { - console.error("Error:", error); - throw error; - } - } - - useEffect(() => { - const API_ENDPOINT = "https://api.example.com/data"; - const params = { id: 1, bodyData: { key: "updatedValue" } }; - - const updateData = async () => { - try { - const data = await update(API_ENDPOINT, params); - // handle data as needed - console.log("PUT Request Data:", data); - } catch (error) { - console.error("Failed to update data:", error); - } - }; - - updateData(); - }, []); - ``` - -### `DELETE` Request - -Asynchronous function to perform a `DELETE` request. -- `@param {string} endpoint` - The API endpoint to perform the DELETE request. -- `@param {Object} body` - The request body for the DELETE request. -- `@returns {Promise}` - A promise that resolves to the API response data or an error string. - - ```jsx - async function remove(endpoint, { id }) { - const url = `${endpoint}/${id}`; - - try { - const response = await fetch(url, { - method: "DELETE", - headers: { - "X-Access-Token": "your-access-token", - }, - }); - if (!response.ok) { - throw new Error("Network response was not ok"); - } - console.log("Data deleted successfully"); - } catch (error) { - console.error("Error:", error); - throw error; - } - } - - useEffect(() => { - const API_ENDPOINT = "https://api.example.com/data"; - const params = { id: 1 }; - - const deleteData = async () => { - await remove(API_ENDPOINT, params); - // handle success if needed - }; - - deleteData(); - }, []); - ``` ---- - -## React Query - -In Progress diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/components.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/components.md deleted file mode 100644 index 87ab5be..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/components.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -sidebar_position: 5 -description: Learn to build and structure your components ---- - -# Components and Usage - -## Building your first page and form - -RADFish uses standard components from the [`react-uswds`](https://github.com/trussworks/react-uswds) open source project. The RADFish project further extends the react-uswds library. These components maintain the functionality of react-uswds, but are branded with NOAA themes and styles. These components live in the [`react-radfish` directory](https://github.com/NMFS-RADFish/react-components). This allows for development in a modern React environment with a NOAA look and feel. - -For more information on the full `react-uswds` library, check out the deployed storybook: [https://trussworks.github.io/react-uswds/](https://trussworks.github.io/react-uswds/?path=/docs/welcome--docs) - -### Example - -If you wanted to build a `TextInput` component into an existing form, you can use the `@trussworks` [storybook reference](https://trussworks.github.io/react-uswds/?path=/docs/components-text-input--docs) related to component props that are available. - -```jsx - -import { TextInput, Label } from "@trussworks/react-uswds"; - - - handleBlur(e, fullNameValidators)} -/> -``` - -### Forms - -Controlled forms are a key aspect of any NOAA application. Forms are used to collect data relevant to that application in the context of the user. For example, forms can intake data related to trip reports or admin applications. - -To learn how to build a form, refer to the [State Management](./state-management.md) documentation. - -### Tables - -Tables are also a key component type for all NOAA applications. These components usually help visualize data in a user-friendly manner. However, there are cases where developers may want this data to be writable (ie: submittable) to a backend. Using caching strategies with IndexedDB ensures that these types of components remain fully functional when offline. - -To learn how to build a table, refer to the [State Management](./state-management.md) documentation. - -## Styling Methodology: BEM - -In our **examples** and **templates**, we follow the **Block Element Modifier (BEM)** methodology for organizing CSS classes. BEM helps create a structured and scalable CSS architecture. This makes it easier to understand where CSS classes belong and how they relate to components. It also promotes consistency and readability, especially in larger codebases. - -We use BEM for other reasons as well: - -- **Clarity.** BEM conventions make it clear how styles are applied across different parts of a component. -- **Modularity.** BEM encourages the separation of styling concerns, making components more modular and reusable. -- **Scalability.** As your project grows, BEM helps maintain organized and manageable CSS. - -For more information on BEM and how it works, you can visit the official BEM documentation: [https://getbem.com](https://getbem.com). - -### Flexibility for Your Project: - -We use BEM in our **examples** and **templates** to enhance code clarity and consistency. However, you are not required to adopt BEM in your own project. Feel free to use any CSS methodology or framework that suits your needs. This might be BEM, CSS Modules, Tailwind, or any other approach. - -Our use of BEM is limited to the examples and templates provided. It doesn’t affect how you structure your own styles. You can implement your own styling approach while using the components in our examples. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/debugging.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/debugging.md deleted file mode 100644 index 212a7d9..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/debugging.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_position: 8 -description: Strategies for debugging your applications ---- - -# Debugging - -Debugging is an important part developing Progressive Web Applications (PWAs). Debugging helps developers track real-time performance, identify and fix bugs, optimize code, and enhance user experience. - -There are several common strategies for debugging a web application during development. These include but are not limited to: - -- Adding breakpoints in code editor. [See vscode documentation](https://code.visualstudio.com/docs/editor/debugging#_breakpoints). -- Adding logs to the development console. [See MDN documentation](https://developer.mozilla.org/en-US/blog/learn-javascript-console-methods/). -- Using the network console. [See Chrome DevTools documentation](https://developer.chrome.com/docs/devtools/network). -- Using an HTTP client like Postman to test API calls. [See Postman documentation](https://learning.postman.com/docs/introduction/overview/). - -You can use Postman to emulate a backend server response pattern. Postman works with the Mock Service Worker that is bundled with RadFish. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/index.mdx b/docs/developer-documentation/developer-documentation/building-your-application/patterns/index.mdx deleted file mode 100644 index 90632b5..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/index.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Patterns - -Patterns are solutions to common problems in software design. In this section, you can learn about several patterns that help with routing, state management, APIs, and other common components of RADFish applications. There are also patterns for testing, debugging, and other parts of the software development lifecycle. - -```mdx-code-block -import DocCardList from '@theme/DocCardList'; - - -``` - -{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/mock-api.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/mock-api.md deleted file mode 100644 index 46ccd40..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/mock-api.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -sidebar_position: 4 -description: Simulate backend responses to unblock your development ---- - -# Mock API - -As a frontend developer, you may be developing a feature that has a dependency on an external API. This dependency sometimes becomes a blocker. You must wait for the external API endpoints to be developed before you can build your feature. The RADFish app ships with a built-in mock server that allows frontend developers to “stub out” and mock API requests. This mock API removes the hard dependency during development. - -More specifically, RADFish ships with [mock service worker](https://mswjs.io/). This service is preconfigured in the boilerplate application. - -At the entrypoint of the React application, we enable API mocking with the `enableMocking` function: - -```jsx -async function enableMocking() { - const { worker } = await import("./mocks/browser"); - - // `worker.start()` returns a Promise that resolves - // once the Service Worker is up and ready to intercept requests. - return worker.start(); -} - -const root = ReactDOM.createRoot(document.getElementById("root")); - -enableMocking().then(() => { - root.render( - - - - ); -}); -``` - -Keep in mind that mocking should only be available during development. It should not ship with the production application. It can be useful to use a `NODE_ENV` environment variable to ensure that API mocks are only used in `DEVELOPMENT`. The `public/mockServiceWorker.js` file installs and configures the mock server. You should not need to modify this file. - -## Configuring mock endpoints: - -In `src/mocks` there is a `browser.js` file and a `handlers.js` file. Developers can add different mock http handlers to their application in the `handlers.js` file. For each handler you create, the mock service worker will intercept the request, and handle that request as defined in the file. - -For instance: - -```jsx -export const handlers = [ - http.get("/species", () => { - return HttpResponse.json({ data: ["grouper", "marlin"] }, { status: 200 }); - }), - http.post("/species", async ({ request }) => { - const response = await request.json(); - return HttpResponse.json({ data: response }, { status: 201 }); - }), -]; -``` - -This file creates two handlers, a `GET` and `POST` request that returns a `HttpResponse` to the application. Refer to the [msw docs](https://mswjs.io/) for more information on customizing this for your needs. - ---- diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/navigation.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/navigation.md deleted file mode 100644 index bcb38f1..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/navigation.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -sidebar_position: 6 -description: Handle navigation patterns in your application ---- - -# Navigation - -NOAA applications often have application-specific needs for routing and navigation between internal pages. They may also need to follow certain domain-specific rules, such as being hosted on a subdomain route of an existing application. In this documentation, we'll focus on applications that are on hosted on their own domain, and from the root directory of that application’s codebase. - -## Navigation Styling -NOAA applications should maintain a similar navigation style. This provides a familiar interface for users who may be switching between applications. Navigation element styles should be consistent across various platforms. - -Navigation items should always be at the highest vertical “layer” of the application. They should always overlap any other components, except for full page modals. For example, if a navigation item expands downwards, it should not appear beneath an image or some other component. This would make the navigation inaccessible and not comply with 508 compliance regulations. - -Navigation should also appear different on mobile and desktop/tablet devices. - -## Application Routing -In Progressive Web App (PWA) development, application routing provides a seamless user experience. The implementation of application routing can vary based on business needs. However, there are general principles that developers can follow to ensure a consistent and user-friendly navigation experience. - -NOAA applications should have routes to the pages suggested in the [templates](https://designsystem.digital.gov/templates/) portion of the USWDS documentation. This creates an application structure that is both repeatable and familiar to users. - -The U.S. Web Design System (USWDS) documentation provides recommended basic routes for a PWA application. These routes include: - -- **404 Page.** Handling "page not found" scenarios gracefully is essential for user satisfaction. A well-designed 404 page helps users understand that the content they're looking for is not available. -- **Documentation Page.** Including documentation can help users understand the application's features and functionality. This page serves as a reference guide for users seeking information about how to use the app effectively. -- **Landing Page.** The landing page is often the first interaction users have with the application. It should be designed to capture attention, provide key information, and encourage users to explore further. -- **Authentication Page.** Secure authentication is a critical aspect of many applications. Having a dedicated authentication page ensures a smooth and secure login process for users. - -NOAA applications should be designed to work seamlessly even when the user is offline. The routing mechanism should direct users to a page that doesn't depend on external API requests. It should rely solely on cached content. - -The "online usage" documentation explains how the application behaves when the user is offline. This documentation typically outlines strategies for caching important assets, handling offline scenarios, and ensuring that users can still access content even without an internet connection. - -In summary, effective application routing in PWA development involves careful consideration of key routes such as 404, documentation, landing, and authentication pages. Additionally, prioritizing offline use by routing to cached content enhances user experience. Developers should follow best practices and refer to relevant documentation to implement routing that aligns with both business needs and user expectations. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/offline-storage.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/offline-storage.md deleted file mode 100644 index 7fa8e98..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/offline-storage.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -sidebar_position: 8 -title: "Offline Storage" -description: Implement offline storage functionality (Coming soon) ---- - -# Offline Storage - -RADFish app users can be out at sea for an extended period of time. They may not have a reliable internet connection. Offline storage lets users to continue using the app to create and manage data while offline. - -## Storage Models - -The `@nmfs-radfish/radfish`package provides two storage methods available `LocalStorageMethod` and `IndexedDBMethod`. - -### LocalStorage - -In order to save to LocalStorage, we must provide a unique key that will used to store all of the application data. - -```js -import { LocalStorageMethod } from '@nmfs-radfish/radfish'; - -new LocalStorageMethod( - "survey-app-storage" -); -``` - -### IndexedDB - -When using IndexedDB, we also need to provide a schema version and model structures. These are used to manage future data migrations. - -```js -import { IndexedDBMethod } from '@nmfs-radfish/radfish'; - -new IndexedDBMethod( - "survey-app-storage", - "1.0.0", - { - species: "id, name, scientificName", - catches: "id, speciesId, numberOfFish, weight" - } -); -``` - -## React Usage - -The `@nmfs-radfish/react-radfish` package exposes the `OfflineStorageWrapper` component. This creates a storage model available to that React context. - -## **`useOfflineStorage` Hooks API** - -You can then use the `useOfflineStorage` hook to interact directly with the storage model. - -The hook returns an object with these CRUD methods: -- `createOfflineData` creates a new entry. -- `findOfflineData` reads data entries. -- `updateOfflineData` updates data entries. -- `deleteOfflineData` deletes data entries. - -### `createOfflineData` - -Creates a new data entry in the storage. Entries will have a unique `uuid` (`String`) property to be used for future lookups. - -| Parameter | Description | -| ----------- | ------------------------------------- | -| `tableName` | The table the data will be stored in. | -| `data` | The data object to create. | - -**Returns:** A `Promise` that resolves of the `uuid` of the created entry. - -### `findOfflineData` - -Finds data in the storage based on the given criteria, returns all data if not criteria parameter is passed. - -| Parameter | Description | -| ----------- | -------------------------------------------------------------- | -| `tableName` | The table to be searched. | -| `criteria` | The criteria object to use for finding data, eg `{uuid: 123}`. | - -**Returns:** A `Promise` that resolves to an array of objects: - -### `updateOfflineData` - -Updates data in the storage with the matching `criteria`. - -| Parameter | Description | -| ----------- | -------------------------------------------------------------- | -| `tableName` | The table to be searched. | -| `criteria` | The criteria object to use for finding data, eg `{uuid: 123}`. | - -**Returns:** A `Promise` that resolves to an array of `uuid` of the updated entries. - -### `deleteOfflineData` - -Deletes data in the storage. - -| Parameter | Description | -| ----------- | -------------------------------------------------------------- | -| `tableName` | The table to be searched. | -| `criteria` | The criteria object to use for finding data, eg `{uuid: 123}`. | - -**Returns:** A `Promise` that resolves to a boolean value of whether the delete operation succeeded without errors. - -## Usage - -Example usage when using IndexedDB: - -**App.jsx** -```jsx -import React, { useEffect, useState } from "react"; -import { Table } from "@nmfs-radfish/react-radfish"; -import { useOfflineStorage, OfflineStorageWrapper } from "@nmfs-radfish/react-radfish"; - -const offlineStorageConfig = { - type: "indexedDB", - name: import.meta.env.VITE_INDEXED_DB_NAME, - version: import.meta.env.VITE_INDEXED_DB_VERSION, - stores: { - catches: "++id, numberOfFish" - }, -}; - -const Catches = () => { - const { createOfflineData, findOfflineData } = useOfflineStorage(); - - let [allCatches, setCatches] = useState([]); - - const fetchCatches = async () => { - const catches = await findOfflineData("catches"); - setCatches(catches); - }; - - const createNewCatch = async () => { - await createOfflineData("catches", { - numberOfFish: Math.floor(Math.random() * 10) + 1, - }); - await fetchCatches(); - }; - - useEffect(() => { - fetchCatches(); - }, []); - - return ( -
- -
- - ); -}; - -const App = () => { - return ( - - - - ); -}; - -export default App; -``` - -## Interfacing with backend services - -You are free to use any network library of your choice to handle HTTP requests (GET, POST, PUT, DELETE). For your convenience, we’ve provided examples using the native fetch API. You can adapt these examples to the library that best fits your needs. - -Refer to the [Integrating with Backend Services](https://nmfs-radfish.github.io/radfish/developer-documentation/building-your-application/patterns/apiservice) documentation for examples. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/routing.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/routing.md deleted file mode 100644 index c564695..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/routing.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -sidebar_position: 9 -description: Manage app routes with React Router ---- - -# Routing - -The **Routing** in RADFish applications is handled using `react-router-dom`. This section will guide you through the basic setup and usage of routing in your project. - -## React Router Overview - -React Router provides a declarative, component-based approach to defining routes and managing navigation in React applications. It supports nested routes, dynamic route matching, and lazy loading of components. - -To learn about React Router, refer to the official [React Router documentation](https://reactrouter.com/). - -### Features - -- **Declarative Routing.** Define routes in a declarative manner using components like `Routes`, `Route`, and `Link`. -- **Dynamic Routing.** Easily create routes that can change based on the application's state or URL parameters. -- **Nested Routing.** Support for nested routes, allowing more complex routing configurations. -- **Programmatic Navigation.** Use React Router hooks like `useNavigate` to navigate programmatically. - -### Usage - -In this project, routing is set up in the `App.jsx` file. This section provides a breakdown of the main components used for routing. - -**Basic Setup** - -First, import the necessary components from `react-router-dom`: - -```jsx -import { BrowserRouter, Routes, Route, Link } from "react-router-dom"; -``` - -**Defining Routes** - -Use the BrowserRouter to wrap your application and define routes with the Routes and Route components: - -```jsx - - - } /> - - -``` - -This setup ensures that when users navigate to the root URL (/), the HomePage component is rendered. - -**Navigation Links** - -To navigate between different routes, use the Link component: - -```jsx -Home -``` - -This setup provides a navigation link to the home page. - -### Example Code - -You can view the full example of the routing setup in the `App.jsx` file in the GitHub repository: [github/boilerplate/templates/react-javascript/src/App.jsx](https://github.com/NMFS-RADFish/boilerplate/blob/main/templates/react-javascript/src/App.jsx) - -```jsx -import { BrowserRouter, Routes, Route, Link } from "react-router-dom"; -import HomePage from "./pages/Home"; - -function App() { - return ( - - - - } /> - - - ); -} - -export default App; -``` diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/state-management.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/state-management.md deleted file mode 100644 index 2b0c2c4..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/state-management.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -sidebar_position: 2 -description: An overview of managing application state effectively ---- - -# State Management - -## What is State Management? - -NOAA web apps frequently deal with a variety of data. Data can range from user-generated form data to environmental statistics such as fish populations or weather changes. State management is our tool for keeping track of all these changes efficiently. Think of it as a digital notepad that records every update and change within the app. This ensures we always have the most current information at our fingertips. - -## Why Use State Management in NOAA Apps? - -Our applications are not just repositories of static data. They are dynamic platforms where data constantly evolves. State management is essential for several reasons: - -- **Stay Updated.** Display the most up-to-date information to our users. This ensures accuracy and reliability. -- **Work Offline.** Our apps can function even without an internet connection. We do this by storing data locally and syncing it back to our servers once a connection is re-established. -- **Fast and Responsive.** Our apps to react swiftly to user interactions and data changes, providing a smooth and efficient user experience. - -### A Simple Way to Manage State: Using React Context - -We use a feature called **React Context** to share and manage states across different parts of our applications. This creates a communal space where any component of our app can easily access or update shared information. This feature eliminates the complexity of passing data through multiple layers. - -## How We Implement State Management - -### FormState - -Our approach to managing form state is simple yet effective. Each form should maintain it's own state within the component itself. This is the recommended approach for managing a form's state, rather that reaching for a centralized state machine like React Context or Redux. This approach is more straightforward to implement and removes excess layers of abstraction. - -One downside of this approach is that each form has it's own state management. This can lead to less DRY code. This is an acceptable tradeoff in most cases, however. If you notice that certain patterns should be shared among different components, you will either need to pass these state values as props to child components, or wrap the related components in a `ContextProvider` and expose them via the `useContext` hook. See more about how to use React Context [here](https://react.dev/reference/react/useContext). - -For an example on best practices for implementing this type of form state management, you can run an example implementation with the RADFish CLI: - -`npx @nmfs-radfish/create-radfish-app my-app --example computed-form-fields` - -Here is a simplified code snippet on how to set this form state management up in a React component: - -```jsx -const SimplifiedForm = () => { - const [formData, setFormData] = useState({}); - - const handleSubmit = (event) => { - event.preventDefault(); - dispatchToast({ status: "success", message: "Successful form submission" }); - }; - - return ( - - - { - const { value } = event.target; - setFormData({ - ...formData, - ["fullName"]: value, - }); - }} - /> - - - ); -}; -``` - -### Flexibility and Debugging - -This method allows developers to implement form state within the scope of a single file. This makes it simpler to build out forms for different use cases. If certain repeatable patterns arise, they can be broken out into a separate context provider if needed. Alternatively, they can get passed in as props to child components. - -This approach provides better encapsulation and modularity. It also allows for more straightforward debugging and maintenance of form-related logic. - - -## Offline / Online State Management - -Any NOAA web application must be fully functional offline without a network connection. Fishermen are often on ships far away from network connection. They need to reliably store data that will be uploaded to NOAA services when the app comes back online. Therefore, designing apps to be “offline first” is of vital importance to NOAA web appdevelopment. - -Progressive Web Applications (PWAs) offer a robust solution for offline use at sea. They combine the benefits of an app-like experience, offline access, and efficient data management. These features make PWAs well-suited for maritime environments, where connectivity is often limited or intermittent. - -PWAs leverage service workers, which are scripts that run independently in the background. Service workers enable offline functionality by caching important static resources, such as HTML, CSS, and JavaScript files. This allows the PWA to continue functioning even when there’s no network connectivity. - -Read more about service workers [here](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API). - -Service workers are integrated into the RADFish application by default. After scaffolding the application you will notice the following files: - -`service-worker.js` - -`serviceWorkerRegistration.js` - -And the service workers is integrated into the React app in the app’s `index.js` entrypoint: - -```jsx -// If you want your app to work offline and load faster, you can change -// unregister() to register() below. Note this comes with some pitfalls. -// Learn more about service workers: https://cra.link/PWA -serviceWorkerRegistration.register(); -``` - -This will register the React application as a PWA, which can be downloaded from the browser. For more information on how to download the PWA onto your device, see [this blog article](https://aureatelabs.com/blog/install-pwa-to-device/). - -Additionally, you can query for whether or not the RADFish application is online or offline by leveraging the [navigator API](https://developer.mozilla.org/en-US/docs/Web/API/Navigator). - -> Note: This service worker is preconfigured when using the boilerplate `react-javascript` template. - -It is up to the developer on how or where this API needs to be used. It's a good idea to use it early on in your application, so that the rest of the application can listen for changes in offline state. The `@nmfs-radfish/react-radfish` package exposes a `useOfflineStatus` hook that gives you a simple way to tap into whether or not your application is online: - -```jsx -import { Application, useOfflineStatus } from "@nmfs-radfish/react-radfish"; - -function App() { - const { isOffline } = useOfflineStatus(); - - return ( - -

- Network Status: {isOffline ? "Offline ❌" : "Online ✅"} -

-
- ); -} -``` - -This underlying code listens for changes surfaced from the `navigator` API. It notifies the application in the form of a Toast message of the application's online/offline state. - -> 🚨 **Warning:** There is a known issue where if the user's device is in an offline state, and the RADFish application is booted up for the first time, the Navigator API will actually resolve to "offline". On future refreshes, this will appropriately resolve to the "offline" status. This is an issue with the underlying Navigator API and will be addressed in a future release. - -## Caching Strategy - -It is important to fetch and cache required data needed to basic app functionality while the application is online. This can be done by fetching the required data from an API, and storing that data into IndexedDB. To see a basic example of how this can be done, you can run the `server-sync` example from the CLI: - -`npx @nmfs-radfish/create-radfish-app my-app --example server-sync` - -This example fetches several JSON arrays from our Mock API, then stores and caches it in IndexedDB. The application then can reference the data in IndexedDB without a network connection. Keep in mind that it is up to the developer to decide when and how to invalidate this IndexedDB cache based on their application's needs. - -## **Offline Storage** - -To use offline data storage, use the `useOfflineStorage` hook. This React hook provides methods for managing offline form data. There are two storage methods available: `LocalStorageMethod` and `IndexedDBStorageMethod`. - -### Configuration - -Step-by-step instructions to configure offline storage: - -1. **Set the environment variables in the `.env` files. Based on which offline storage method you select, the following `env` variables are required:** - 1. Local Storage - 1. `VITE_LOCAL_STORAGE_KEY` - 2. Indexed DB: - 1. `VITE_INDEXED_DB_NAME` - 2. `VITE_INDEXED_DB_VERSION` - 3. `VITE_INDEXED_DB_TABLE_NAME` - 4. `VITE_INDEXED_DB_SCHEMA` -2. **In the `src/hooks/useOfflineStorage.js` file, initialize one of the these Storage Method instances, and pass the appropriate environment variables using `import.meta.env.REPLACE_WITH_KEY_NAME` as parameters:** - - 1. `LocalStorageMethod` — Requires one parameter, the key name for localStorage. - - ```jsx - const storageMethod = new LocalStorageMethod( - import.meta.env.VITE_LOCAL_STORAGE_KEY - ); - ``` - - 2. `IndexedDBStorageMethod` — Requires four parameters, the db name, db version, db table name, db schema. - - ```jsx - const storageMethod = new IndexedDBStorageMethod( - import.meta.env.VITE_INDEXED_DB_NAME, - import.meta.env.VITE_INDEXED_DB_VERSION, - import.meta.env.VITE_INDEXED_DB_TABLE_NAME, - import.meta.env.VITE_INDEXED_DB_SCHEMA - ); - ``` - -3. **In the `src/hooks/useOfflineStorage.js` file, create the `StorageModelFactory`:** - - ```jsx - // 1. Choose one of the following storage methods: - const storageMethod = new IndexedDBStorageMethod( - import.meta.env.VITE_INDEXED_DB_NAME, - import.meta.env.VITE_INDEXED_DB_VERSION, - import.meta.env.VITE_INDEXED_DB_TABLE_NAME, - import.meta.env.VITE_INDEXED_DB_SCHEMA - ); - const storageMethod = new LocalStorageMethod( - import.meta.env.VITE_LOCAL_STORAGE_KEY - ); - // 2. Create Storage Method - const storageModel = StorageModelFactory.createModel(storageMethod); - ``` - -### `useOfflineStorage` Hooks API - -The `useOfflineStorage` hook returns an object with the following methods: - -- **`createOfflineDataEntry(data)`** creates a new data entry in the storage. - - `data`: The data object to create. - - Returns a promise that resolves when the data is created. -- **`findOfflineData(criteria)`** finds data in the storage based on the given criteria. It returns all data if not criteria parameter is passed. - - `criteria`: The criteria object to use for finding data, eg `{uuid: 123}`. - - Returns a promise that resolves to an array of tuples: - - `[ [ uuid, { key: value } ], [ uuid2, { key: value } ] ]` -- **`updateOfflineDataEntry(criteria, data)`** updates data in the storage. - - `criteria`: The criteria to use for updating data. This should be an object. - - `data`: The updated data object. - - Returns a promise that resolves to the updated data as an object: - - `{ numberOfFish: 10, species: salmon }` - -### Usage - -```jsx -import useOfflineStorage from "./useOfflineStorage"; - -function MyComponent() { - const { createOfflineDataEntry, findOfflineData, updateOfflineDataEntry } = - useOfflineStorage(); - const data = { species: "Grouper", numberOfFish: 100 }; - - // Create new offline data entry - createOfflineDataEntry(data); - // Find all offline data - findOfflineData(); - // Find a specific offline data entry by uuid - findOfflineData({ uuid: "1234" }); - // Update an offline data entry by uuid - updateOfflineDataEntry({ uuid: "1234" }, data); - - // rest of code.... -} - -export default MyComponent; -``` - ---- - -## OfflineStorageWrapper Usage Guide - -`OfflineStorageWrapper` is a context wrapper component that provides offline storage functionality to its child components through a React context. It supports both IndexedDB and LocalStorage methods. - -### How to Use - -**1. Wrap your component with `OfflineStorageWrapper`:** - -```jsx -import { OfflineStorageWrapper } from "@nmfs-radfish/react-radfish"; - - - -; -``` - -The config prop is an object that specifies the storage type and configuration. It should include the `type` set to `indexedDB` or `localStorage`, database name (`string`), database version number (`number`), and stores (`object`). - -The `stores` object should contain a key that is mapped as the table name. The value should be a comma separated string that outlines the schema. For more information on setting up the stores, see the official `Dexie.js` docs: [https://dexie.org/docs/Tutorial/React#3-create-a-file-dbjs-or-dbts](https://dexie.org/docs/Tutorial/React#3-create-a-file-dbjs-or-dbts). - -For IndexedDB, the configuration should look like this: - -```js -const config = { - type: "indexedDB", - name: "your_db_name", - version: 1, - stores: { - table_name_1: "uuid, name", - // Add more stores as needed - }, -}; -``` - -For LocalStorage, the configuration should look like this: - -```js -const config = { - type: "localStorage", - name: "your_storage_name", -}; -``` - -**2. Use the useOfflineStorage hook in child components:** - -```jsx -import { useOfflineStorage } from "@nmfs-radfish/react-radfish"; - -function YourComponent() { - const { - createOfflineData, - findOfflineData, - updateOfflineData, - deleteOfflineData, - } = useOfflineStorage(); - - // Use these functions to interact with offline storage -} -``` - -The `useOfflineStorage` hook provides four functions: - -- `createOfflineData(tableName, data):` Creates a new record in the specified table. -- `findOfflineData(tableName, criteria):` Finds records in the specified table that match the criteria. -- `updateOfflineData(tableName, data):` Updates a record in the specified table. -- `deleteOfflineData(tableName, uuid):` Deletes a record with the specified UUID from the specified table. - -## Error Handling - -If you try to use the `useOfflineStorage` hook outside of an `OfflineStorageWrapper`, it will throw an error. Always make sure to use `useOfflineStorage` within a component that's wrapped with `OfflineStorageWrapper`. - -## Testing during development - -As a developer, you'll often run into an issue where an "offline-first" feature needs to be tested before pushed and merged into the `main` branch. For instance, you may be developing a `Toast` message that notifies the user whenever they go offline. If you are simply running the local vite server, and you go offline to test your feature, you'll notice that the page breaks on page refresh. This is because the `serviceWorker` is not being used until the production build is created. In order to do this, you need to bundle the application and serve it locally to simulate a production environment: - -`npm run build && npm run serve` - -This will bundle the application and serve it. When you turn your browser offline, the cached static assets will remain, and your application will not break when the page is refreshed. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/patterns/testing.md b/docs/developer-documentation/developer-documentation/building-your-application/patterns/testing.md deleted file mode 100644 index e47d416..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/patterns/testing.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -sidebar_position: 7 -description: Ensure code quality with Vitest and React Testing Library ---- - -# Testing - -Testing is a critical part of the software development process. Testing ensures the reliability and maintainability of your React application. This section provides an overview of several topics: -- Writing tests using [Vitest](https://vitest.dev/api/) -- Snapshot, unit, and browser testing with frameworks like [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) -- Debugging techniques for broken or failed tests -- Best practices for effective test writing - -Effective testing in React using Vitest and related frameworks builds robust applications. Remember, the goal of testing is not just to find bugs, but to build confidence in your codebase. - -## Running Tests - -Run tests with the following command: `npm test` - -## Writing Unit Tests - -Unit tests focus on testing individual components or functions in isolation. - -1. **Basic Unit Test** - - ```jsx - import { - fullNameValidators, - emailValidators, - phoneNumberValidators, - cityValidators, - stateValidators, - zipcodeValidators, - } from "../../utilities"; - - test("should validate a correct email format", () => { - expect(emailValidators[0].test("example@test.com")).toBe(true); - }); - ``` - -2. **Testing User Interactions** - -Use **`user-event`** or **`fireEvent`** from React Testing Library to simulate user actions. - - ```jsx - import { userEvent } from "@vitest/browser/context"; - import { screen } from "@testing-library/dom"; - - test("triggers a double click on an element", async () => { - const logo = screen.getByRole("img", { name: /logo/ }); - - await userEvent.dblClick(logo); - }); - ``` - -## Writing Browser Tests - -Browser testing involves testing the application in a web browser environment. Tools like [Puppeteer](https://pptr.dev/) can be used alongside Vitest. Please note Puppeteer does not come included by default in the RADFish framework. - -1. **Basic Browser Test** - - ```jsx - const puppeteer = require("puppeteer"); - - it("should display the homepage", async () => { - const browser = await puppeteer.launch(); - const page = await browser.newPage(); - await page.goto("http://localhost:3000"); - await expect(page.title()).resolves.toMatch("Home Page"); - await browser.close(); - }); - ``` - -## Additional Vitest Configuration - -Vitest and React Testing Library are included in the RADFish framework by default. The Vitest test configuration can be modified in the `vite.config.js` file. Refer to the official Vitest docs for the latest configuration options: [https://vitest.dev/config/](https://vitest.dev/config/). - -## Debugging Broken or Failed Tests - -1. **Review Test Output.** Vitest provides detailed error messages. Analyze them to understand the failure. -2. **Use `console.log`.** Temporarily add **`console.log`** statements within your test to inspect values. -3. **Check for Async Issues.** Ensure promises are resolved and state updates are completed. - -## Best Practices - -By following these best practices, you can ensure your code works as expected. Testing also ensures your code will be maintainable over time. - -- **Descriptive Test Names.** Clearly describe what each test is checking. -- **Small and Focused Tests.** Write tests that cover single functionalities. -- **Avoid Over-Mocking.** Use mocks sparingly to ensure tests remain close to real-world scenarios. -- **Test User Interactions.** Simulate how users interact with your application. -- **Continuous Integration**. Integrate testing into your CI/CD pipeline for regular feedback. - -## 508 Compliance -There are special steps to test whether your application meets 508 Compliance guidelines. Section 508 of the Rehabilitation Act mandates that federal agencies' electronic and information technology is accessible to people with disabilities, aligning with the Web Content Accessibility Guidelines (WCAG). - -### 1. Set Up Your React Project - - Make sure your React application is operational locally, typically accessed at `http://localhost:3000`. - -### 2. Automated Testing with Lighthouse - - 1. **Open Google Chrome.** Ensure Google Chrome is installed and open your project by navigating to `http://localhost:3000`. - 2. **Access Chrome DevTools.** Right-click on the page and select "Inspect", or use `Ctrl+Shift+I` (Windows/Linux) or `Cmd+Option+I` (Mac) to open DevTools. - 3. **Run Lighthouse Audit.** - - Click on the "Lighthouse" tab in the DevTools panel. - - Check the "Accessibility" box to focus the audit on accessibility compliance. - - Click "Analyze page load" to start the audit. Review the report that Lighthouse provides, detailing accessibility issues and suggestions for improvements. - -### 3. Implement Recommendations - - Address each listed accessibility issue based on Lighthouse’s suggestions. For example, you might add alt text to images, use proper semantic HTML, or correct ARIA labels. - -### 4. Rerun the Audit - - After making changes, run Lighthouse again. This will verify improvements and ensure no new issues have arisen. diff --git a/docs/developer-documentation/developer-documentation/building-your-application/service-worker-removal.md b/docs/developer-documentation/developer-documentation/building-your-application/service-worker-removal.md deleted file mode 100644 index c6ef252..0000000 --- a/docs/developer-documentation/developer-documentation/building-your-application/service-worker-removal.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_position: 7 -title: Service Worker Removal ---- - -### Removing the Preconfigured Service Worker - -**Disclaimer:** The service worker in this template is designed to provide offline functionality and improve app performance. Removing it is generally not recommended. However, if needed, follow these steps: - -1. **Uninstall the Service Worker Plugin** - Run the following command to uninstall `vite-plugin-pwa`: - ```bash - npm uninstall vite-plugin-pwa - ``` -2. **Remove Configuration from Vite** - Open `vite.config.js` and remove `vite-plugin-pwa`. - -3. **Remove Service Worker Setup** - In your `src/index.js` file, remove the service worker configurations. - -After these steps, the service worker will be removed from the application. diff --git a/docs/developer-documentation/developer-documentation/concepts/concepts.md b/docs/developer-documentation/developer-documentation/concepts/concepts.md deleted file mode 100644 index 96b5b0d..0000000 --- a/docs/developer-documentation/developer-documentation/concepts/concepts.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Concepts - -RADFish developers build applications that serve users in a variety of settings. Many of our users are commercial fishermen who harvest and process fish. Their work takes them to busy ports and the open sea, where internet connectivity can be unreliable or even non-existent. - -Imagine being a commercial fisherman on a vessel in a remote area. You must sort through catch and record weights and species. You need your data to sync with offices back on land. You may have limited storage space on your devices. - -Modern users expect apps to be responsive and reliable, even with limited internet connectivity. This is especially true for professionals such as commercial fishers. These users often operate in remote areas with unstable network access. To meet these expectations, developers can implement on-device storage to enable offline functionality. This increases user satisfaction and also ensures that critical tasks can be performed without interruption. - -Designing apps for these users present unique challenges. To meet these challenges, RADFish developers should be familiar with several concepts: - -* [Offline-First](https://nmfs-radfish.github.io/radfish/developer-documentation/concepts/offline-first) design prioritizes functionalatity even without internet connectivity. -* [On-Device Storage](https://nmfs-radfish.github.io/radfish/developer-documentation/concepts/on-device-storage) is storing data directly on a user's device, without relying on internet connectivity. \ No newline at end of file diff --git a/docs/developer-documentation/developer-documentation/concepts/offline-first.md b/docs/developer-documentation/developer-documentation/concepts/offline-first.md deleted file mode 100644 index 85b4783..0000000 --- a/docs/developer-documentation/developer-documentation/concepts/offline-first.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Offline-First - -Offline-first design prioritizes web app functionality even without internet connectivity. This means building the app so users can interact with it uninterrupted, even without a stable network. - -With offline-first, your application: - -- **Stores data locally.** When the user interacts with the app, data is cached on the device. -- **Synchronizes data automatically.** When internet connectivity returns, the app synchronizes any pending changes with remote servers. -- **Provides a seamless experience.** Whether they're online or offline, users enjoy an uninterrupted experience. - -## Service Workers: The Key to Offline-First - -To achieve offline-first functionality, developers use Service Workers. Service Workers are scripts that run in the background of web applications. They allow network requests and data caching without requiring user interaction. Service Workers help build web applications that function even with internet connectivity issues. \ No newline at end of file diff --git a/docs/developer-documentation/developer-documentation/concepts/on-device-storage.md b/docs/developer-documentation/developer-documentation/concepts/on-device-storage.md deleted file mode 100644 index 23a6522..0000000 --- a/docs/developer-documentation/developer-documentation/concepts/on-device-storage.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -sidebar_position: 3 ---- - -# On-Device Storage -On-device storage is the practice of storing data directly on a user's device, allowing web applications to function independently of network connectivity. This approach is critical for several reasons: - -- **Uninterrupted User Experience.** Users can use the application without disruption, regardless of their connectivity status. -- **Data Availability.** Essential data remains accessible. Users can perform tasks and access information when they need it most. -- **Improved Performance.** Faster data retrieval and smoother performance by reducing network requests. - -## Implementing On-Device Storage in your application - -When integrating on-device storage into your application, consider these best practices: - -- **Determine Data Requirements.** Assess the types and volumes of data your application needs to store. Choose the storage mechanism that best fits these requirements. -- **Plan for Synchronization.** Make sure your application can synchronize data with remote servers when connectivity is restored. This includes handling potential conflicts and ensuring data consistency. -- **Optimize for Performance.** Use asynchronous operations where possible to avoid blocking the main thread and degrading the user experience. -- **Ensure Data Security.** Implement appropriate security measures to protect stored data, including encryption and secure access controls. - -## Types of On-Device Storage - -There are various on-device storage mechanisms available in modern web development. Each is best for different types of data and use cases. Two prominent options are **LocalStorage** and **IndexedDB**. - -### LocalStorage - -LocalStorage is a simple and synchronous storage system built into web browsers. It stores key-value pairs and is designed to persist data even after the browser is closed. LocalStorage is good for storing small amounts of data, such as user preferences, session information, or basic application state. - -#### Benefits of LocalStorage: - -- **Simplicity.** The API is easy to use, for quick implementation. -- **Persistence.** Data remains available across sessions, ensuring continuity. -- **Wide Browser Support.** LocalStorage is supported by all major browsers, ensuring broad compatibility. - -#### Limitations of LocalStorage: - -- **Storage Capacity.** Typically limited to around 5MB, which may not be sufficient for all applications. -- **String-Only Storage.** Only string data types can be stored. More complex data structures need serialization. -- **Synchronous Nature.** Operations are blocking, which can impact performance for larger datasets. - -### IndexedDB - -For more complex and large-scale storage needs, IndexedDB is a powerful alternative. IndexedDB is an asynchronous, low-level API designed to store significant amounts of structured data, including files and blobs. It supports transactions, allowing for reliable data handling and advanced querying capabilities. - -### Benefits of IndexedDB: - -- **Large Storage Capacity.** Capable of storing much larger datasets compared to LocalStorage. -- **Complex Data Structures.** Supports a variety of data types, including objects and arrays, without requiring serialization. -- **Asynchronous Operations.** Non-blocking operations enhance performance, especially with large volumes of data. -- **Advanced Querying.** Provides robust indexing and querying capabilities for efficient data retrieval. diff --git a/docs/developer-documentation/developer-documentation/examples-and-templates/examples-and-templates.md b/docs/developer-documentation/developer-documentation/examples-and-templates/examples-and-templates.md deleted file mode 100644 index baa24b1..0000000 --- a/docs/developer-documentation/developer-documentation/examples-and-templates/examples-and-templates.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Examples and Templates - -Examples are small projects designed to demonstrate RADFish ecosystem. Templates are meant to be a clean starting point for a new RADFish project. - -## Examples - -Each exammple is scoped to teach developers how to implement core pieces of functionality. Examples include a detailed `README.md` file that explains its purpose, design pattern, and best practices. - -These examples are meant to be a reference for any RADFish project. These examples can serve as a starting point to build out a new RADFish application. However, we recommend starting with a fresh `react-javascript` template. - -The source code for each example is in the open source repo for RADFish [boilerplate](https://github.com/NMFS-RADFish/boilerplate/tree/main/examples). Each example can be cloned and run separately as you are working with each from the RADFish CLI. To learn how to run these scripts, refer to the [running examples](./building-your-application/available-scripts/running-example) section. - -### List of Examples -Here's a list of pre-built examples that you can use as a starting point for your application. These examples are scoped to one core feature. - -1. [Computed Form Fields](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/computed-form-fields/README.md) -1. [Conditional Form Fields](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/conditional-form-fields/README.md) -1. [Field Validators](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/field-validators/README.md) -1. [Form Structure](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/form-structure/README.md) -1. [Mock API](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/mock-api/README.md) -1. [Multistep Form](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/multistep-form/README.md) -1. [Network Status](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/network-status/README.md) -1. [On Device Storage](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/on-device-storage/README.md) -1. [Persisted Form](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/persisted-form/README.md) -1. [Server Sync](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/server-sync/README.md) -1. [Simple Table](https://github.com/NMFS-RADFish/boilerplate/blob/main/examples/simple-table/README.md) - -## Templates - -These templates are framework-specific. At the time of this writing, only the `react-javascript` template is supported. New templates for other frameworks and other languages are planned for the future! - -Templates come pre-configured with everything to start coding your new project right away. This includes RADFish core modules, service-worker configuration, application routing, and offline storage. - -Creating a new project based on a template is similar to running an example. If you want to create a new project from the `react-javascript` library, execute this RADFish CLI command: - - `npx @nmfs-radfish/create-radfish-app my-app --template react-javascript` - -This will create a new RADFish project named `my-app` in your current working directory. Happy hacking! - -**Note:** The `react-javascript` template is the default. Running `npx @nmfs-radfish/create-radfish-app my-app` will create the same project without needing to specify the template. - -### Template Directory Structure - -Once you scaffold a new template radfish app, you'll be given the following file structure: - -```bash -my-app -├── babel.config.js -├── index.html -├── mocks -│ ├── browser.js -│ └── handlers.js -├── node_modules/ -├── package-lock.json -├── package.json -├── public -│ ├── icons -│ ├── manifest.json -│ ├── mockServiceWorker.js -│ ├── noaafavicon.png -│ └── robots.txt -├── src -│ ├── App.jsx -│ ├── index.css -│ ├── index.jsx -│ ├── pages -│ └── Home.jsx -│ ├── service-worker.js -│ └── styles -│ └── theme.css -└── vite.config.js -``` - -#### Root Level - -- **`babel.config.js`** Configuration file for Babel, a JavaScript compiler. It specifies how Babel should transpile your code. This enables modern JavaScript features while maintaining compatibility with older browsers. - -- **`index.html`** The main HTML file that serves as the entry point of your application. It includes references to your compiled JavaScript and CSS files generated by the build process. - -- **`node_modules/`** This directory contains all the project's dependencies installed via npm. It's automatically generated when you run `npm install`. You should not manually modify this folder, as it's managed by npm. - -- **`package-lock.json`** Automatically generated file that records the exact version of each installed package. It locks dependencies to specific versions. This ensures consistent installs across different environments. - -- **`package.json`** A manifest file for your Node.js project. It includes metadata about the project, such as the name, version, scripts, dependencies, and more. This file is essential for managing project configurations and dependencies. - -- **`vite.config.js`** Configuration file for Vite, a fast build tool and development server. It customizes the behavior of the Vite server and build process, including plugins, aliases, and other settings. - -#### mocks/ - -This folder contains files related to mocking API requests for development and testing purposes. - -- **`mocks/browser.js`** Sets up and configures the mock service worker for the browser environment. It intercepts network requests during development to simulate API responses without needing a real backend. - -- **`mocks/handlers.js`** Defines request handlers for the mock service worker. Each handler specifies how to respond to certain API requests, allowing you to test different scenarios and data flows. - -#### public/ - -This folder ontains static assets that will be served directly to the browser. These files are not processed by Webpack. - -- **`public/icons`**: Directory containing icon images of various sizes. Typically used for favicons and Progressive Web App (PWA) requirements. -- **`manifest.json`**: Provides metadata about the web application. Useful for PWAs. -- **`mockServiceWorker.js`**: The automatically generated script for the mock service worker. It's used by the msw library to intercept network requests in the browser. -- **`noaafavicon.png`**: The favicon image for your application. This appears in the browser tab and bookmarks. -- **`robots.txt`**: A file that provides directives to web crawlers and bots about which pages or sections of your site should not be processed or scanned. - -#### src/ - -This folder contains source code for your React application. This is where you will spend most of your development time. - -- **`App.js`**: The root React component of your application. It serves as the main container for your app's components and routes. -- **`index.jsx`**: The entry point for your React application. It renders the App component into the DOM and may include global providers like routers or state management tools. -- **`index.css`**: Provides general styling rules that apply to the entire app. It includes resets, normalizations, and default HTML element styling. -- **`pages/`**: Directory containing React components that represent different pages or routes in your application. Each file typically corresponds to a route managed by your router. -- **`pages/Home.jsx`**: The main landing page of your application. It defines the content and layout for the homepage. It often contains key UI components such as headers, footers, navigation, and other elements relevant to the first impression of your app. -- **`service-worker.js`**: Custom service worker script for handling offline support, caching, and other background tasks. It enables your app to function as a PWA with offline capabilities. -- **`styles/`**: Directory for organizing additional CSS or styling files, such as variables, mixins, or component-specific stylesheets. -- **`styles/theme.css`**: Contains global theme variables and styles for consistency in design like colors, fonts, and spacing. diff --git a/docs/developer-documentation/developer-documentation/examples-and-templates/examples/index.mdx b/docs/developer-documentation/developer-documentation/examples-and-templates/examples/index.mdx deleted file mode 100644 index 6cd46a5..0000000 --- a/docs/developer-documentation/developer-documentation/examples-and-templates/examples/index.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Examples - -Examples are small projects designed to demonstrate RADFish ecosystem. Templates are meant to be a clean starting point for a new RADFish project. - -The source code for each example is in the open source repo for RADFish [boilerplate](https://github.com/NMFS-RADFish/boilerplate/tree/main/examples). Each example can be cloned and run separately as you are working with each from the RADFish CLI. To learn how to run these scripts, refer to the [running examples section](https://nmfs-radfish.github.io/radfish/developer-documentation/building-your-application/available-scripts/running-example). - - -```mdx-code-block -import DocCardList from '@theme/DocCardList'; - - -``` - -{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/getting-started.md b/docs/developer-documentation/developer-documentation/getting-started.md deleted file mode 100644 index 7c36cde..0000000 --- a/docs/developer-documentation/developer-documentation/getting-started.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Getting Started - -Create RADFish App is the officially supported tool for creating single-page React applications. It offers a modern build setup with no configuration. - -## Prerequisites - -Before you start, make sure you have the following installed: - -- [x] Node.js (v20.17.0 or later) -- [x] npm (v10.8.2 or later) -- [x] git (v2.0 or later) - -## Quick Start - -### Option 1: Scaffold a new app from a template - -Start your app with a barebones and pre-configured [template](./examples-and-templates#templates). - -```bash -npx @nmfs-radfish/create-radfish-app my-app -cd my-app -npm start -``` - -Once the development server starts, visit http://localhost:3000/ in your browser to see your app. - -### Option 2: Scaffold a new app from an example - -Select an [example](/radfish/developer-documentation/examples-and-templates) and run [the command](./building-your-application/available-scripts/running-example.md) using the `--example` tag. - -```bash -npx @nmfs-radfish/create-radfish-app my-app --example multistep-form -cd my-app -npm start -``` - -### Option 3: Clone the boilerplate repository to access all examples - -To get all the examples, clone the [boilerplate repository](https://github.com/NMFS-RADFish/boilerplate): - -```bash -git clone https://github.com/NMFS-RADFish/boilerplate.git -``` - -Then navigate to the example you want to run and start the app: - -```bash -cd boilerplate/examples/[example you want to run] -npm install -npm start -``` - -Once the development server starts, visit http://localhost:3000/ in your browser to see your app. - -### Using the help flag - -The `--help` flag is a common option that displays helpful information about a command or script, including available options and usage instructions. - -```bash -npx @nmfs-radfish/create-radfish-app --help -``` - -### Upgrading package versions in your app - -1. In the root of your project run: - ```bash - npm update - ``` - -2. Check for Changes: - ```bash - npm test - ``` -Please visit [upgrading](./upgrading.md) for more information. - -## Scripts - -**`npm start`** - -This script starts the Vite development server. It runs the app locally with hot module reloading, allowing for fast development and instant updates as you make changes. Open [http://localhost:3000](http://localhost:3000/) to view it in the browser. - -See [Available Scripts](./building-your-application/available-scripts) for full list of commands. - -## Next steps -Now that you are up and running, see the [Components & Usage](./building-your-application/patterns/components.md) section to start building out your first pages! diff --git a/docs/developer-documentation/developer-documentation/libraries/index.mdx b/docs/developer-documentation/developer-documentation/libraries/index.mdx deleted file mode 100644 index f237af0..0000000 --- a/docs/developer-documentation/developer-documentation/libraries/index.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Libraries - -You can learn about the libraries and packages used in RADFish here. - -```mdx-code-block -import DocCardList from '@theme/DocCardList'; - - -``` - -{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/libraries/radfish.md b/docs/developer-documentation/developer-documentation/libraries/radfish.md deleted file mode 100644 index b40b511..0000000 --- a/docs/developer-documentation/developer-documentation/libraries/radfish.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -sidebar_position: 1 -description: Core modules to build a RADFish app ---- - -# `radfish` - -The `radfish` NPM package contains the core JavaScript modules for any RADFish project. These modules are framework-agnostic. They should be fully functional whether you are building an application in React, Svelte, or even Vanilla JavaScript. - -This library is open source and can be found here: [https://www.npmjs.com/package/@nmfs-radfish/radfish](https://www.npmjs.com/package/@nmfs-radfish/radfish) diff --git a/docs/developer-documentation/developer-documentation/libraries/react-radfish.md b/docs/developer-documentation/developer-documentation/libraries/react-radfish.md deleted file mode 100644 index c702f46..0000000 --- a/docs/developer-documentation/developer-documentation/libraries/react-radfish.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -sidebar_position: 2 -description: Modules to build a RADFish app in React ---- - -# `react-radfish` - -The `react-radfish` NPM package contains the React component library for any RADFish project. It's designed for projects built with React or React-flavored frameworks (like Remix or Next.js). These modules expose components that can be used consistently across different React projects. - -Note that this library is not meant to replace the `@trussworks` library. It's meant to work alongside it. Where possible, you should leverage the `@trussworks` library. However, if there's a component not in `@trussworks`, or there's shortcomings with the `@trussworks` implementation, you can rely on the components in the `@nmfs-radfish/react-radfish` package. - -This library is open source and can be found here: [https://www.npmjs.com/package/@nmfs-radfish/react-radfish](https://www.npmjs.com/package/@nmfs-radfish/react-radfish) diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/dexie.md b/docs/developer-documentation/developer-documentation/technical-decision-log/dexie.md deleted file mode 100644 index bdf08c8..0000000 --- a/docs/developer-documentation/developer-documentation/technical-decision-log/dexie.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -sidebar_position: 9 -description: Simplifies working with IndexedDB ---- - -# Dexie for Offline Data -[Dexie](https://dexie.org/) simplifies working with IndexedDB. - -## Why we chose this -Dexie makes IndexedDB development less complex. IndexedDB is crucial for RADFish applications that require offline capabilities. RADFish apps need reliable data storage and retrieval with intermittent internet connectivity. - -## Trade-offs -Using a wrapper around IndexedDB like Dexie abstracts some low-level control. However, it significantly eases development complexity, making it a worthwhile trade-off. - -## Alternatives -[LocalForage](https://github.com/localForage/localForage) and [PouchDB](https://github.com/pouchdb/pouchdb) are alternatives that offer similar abstraction over IndexedDB. They offer additional features like automatic synchronization with remote databases. However, Dexie's simpler API and focus on IndexedDB make it more suitable for RADFish's client-side DB needs. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/index.mdx b/docs/developer-documentation/developer-documentation/technical-decision-log/index.mdx deleted file mode 100644 index 9c531ce..0000000 --- a/docs/developer-documentation/developer-documentation/technical-decision-log/index.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_position: 6 ---- - -# RADFish Technical Decision Log - -This section provides justification for the technologies and frameworks we chose for RADFish. Most pages include "Why we chose this", "Trade-offs", and "Alternatives" sections. These demonstrate pros, cons, and other options that were considered, respectively. - -For more information about this section, read the [statement of purpose](https://nmfs-radfish.github.io/radfish/developer-documentation/technical-decision-log/purpose). - -```mdx-code-block -import DocCardList from '@theme/DocCardList'; - - -``` - -{/* Write bottom text here */} diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/jsdocs.md b/docs/developer-documentation/developer-documentation/technical-decision-log/jsdocs.md deleted file mode 100644 index 78fd333..0000000 --- a/docs/developer-documentation/developer-documentation/technical-decision-log/jsdocs.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_position: 8 -description: Accessible and easy to adopt ---- - -# JavaScript with JSDoc - -[JSDoc](https://jsdoc.app/about-getting-started) is an automatic API documentation generator. - -## Why we chose this -JavaScript offers broad accessibility and ease of adoption for government contractors. Combined with JS Docs, this helps standardize frontend development. JavaScript’s flexibility allows for broader adoption among government contractors. It also adapts to RADFish's diverse and evolving project requirements. JS Docs also doesn't impose the stricter typing system of TypeScript. - -## Trade-offs -TypeScript provides static typing, offering compile-time type checking, which reduces runtime errors. The absence of TypeScript’s compile-time type checking may increase reliance on runtime testing. However, adopting TypeScript involves a steeper learning curve and potentially longer development times. RADFish leverages most developers' familiarity with JavaScript. JS Docs offers a balanced approach, providing some benefits of TypeScript without its overhead. - -## Alternatives -[TypeScript](https://www.typescriptlang.org/) can still be adopted by teams that wish to use it. Migrating from JS Docs to TypeScript is relatively straightforward. There are tools available to automate this process. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/mock-service-worker.md b/docs/developer-documentation/developer-documentation/technical-decision-log/mock-service-worker.md deleted file mode 100644 index 07586e0..0000000 --- a/docs/developer-documentation/developer-documentation/technical-decision-log/mock-service-worker.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -sidebar_position: 6 -description: Required for offline functionality ---- - -# Mock Service Worker -[Mock Service Worker (MSW)](https://mswjs.io/) simulates API responses during development and testing. - -## Why we chose this -NOAA applications must work offline. MSW lets developers build and test applications without dependency on real backend services. This helps develop applications with offline functionality without a backend to test against. - -## Trade-offs -Relying on MSW for development might mask integration issues with actual backend services. For example, an error in MWS setup could result in a real endpoint being overridden by the mock endpoint. However, the benefits of offline development and testing are crucial for RADFish's goals. - -## Alternatives -[JSON Server](https://www.npmjs.com/package/json-server) or [Mirage JS](https://miragejs.com/) provide similar mocking capabilities. They emphasize full-fledged backend simulation. They emphasize full-fledged backend simulation and ease of setup for simpler backends. However, MSW's integrates with service workers and can intercept network requests at the browser level. These features offer more realistic testing scenarios for RADFish's offline functionality. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/prettier.md b/docs/developer-documentation/developer-documentation/technical-decision-log/prettier.md deleted file mode 100644 index 4132dc5..0000000 --- a/docs/developer-documentation/developer-documentation/technical-decision-log/prettier.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_position: 7 -description: Ensures consistent code quality and style ---- - -# Prettier and ESLint - -[Prettier](https://prettier.io/) is an automatic code formatter. [ESLint](https://eslint.org/) analyzes code to find problems and errors in a process known as _linting_. - -## Why we chose this -Consistency in code quality and style is crucial for collaborative projects like RADFish. Prettier and ESLint automate formatting and linting. This ensures all code adheres to best practices and is accessible to all developers working on NOAA projects. - -## Trade-offs -Enforcing a specific coding style may require initial adjustments for developers. However, the long-term benefits of maintainable and error-free code outweigh this adjustment period. Also, these standards can be enforced automatically via code editor configuration setups. For example, developers can use the the “on-save” linting of VSCode. - -## Alternatives -[TSLint](https://palantir.github.io/tslint/) (deprecated in favor of ESLint in 2019) and [Stylelint](https://stylelint.io/) are alternatives to ESLint. They focus on on TypeScript and CSS, respectively. While they offer specialized linting capabilities, the combination of Prettier and ESLint covers a broader range of RADFish's code quality needs. Prettier and ESLint provide JavaScript styling and linting with a unified setup, making them more suitable than using separate tools for different languages. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/purpose.md b/docs/developer-documentation/developer-documentation/technical-decision-log/purpose.md deleted file mode 100644 index 7f3387f..0000000 --- a/docs/developer-documentation/developer-documentation/technical-decision-log/purpose.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -sidebar_position: 1 -description: Provides clarity around technical decisions ---- - -# Purpose - -This section provides justification for the technologies and frameworks we chose for RADFish. This provides transparency and clarity around the technical decisions we have made. - -NOAA's frontend applications have unique requirements, such as: - -- **Offline functionality.** Our users do not always have reliable internet access. Our applications must work offline. -- **Cross-platform performance.** Our applications must work on both mobile and desktop devices. They must work on a variety of operating systems and browsers. -- **Regulation compliance.** Federal web applications must meet regulation standards, such as 508 Compliance. - -Our choices must balance ease of use for our developers while meeting these challenges. We selected technologies and frameworks to create a cohesive, efficient, and compliant environment. The chosen stack optimizes developer productivity, application performance, and user experience. - ---- diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/tanstack.md b/docs/developer-documentation/developer-documentation/technical-decision-log/tanstack.md deleted file mode 100644 index 36ef3ea..0000000 --- a/docs/developer-documentation/developer-documentation/technical-decision-log/tanstack.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -sidebar_position: 11 -description: Offers flexible state management ---- - -# TanStack for State Management -[TanStack](https://tanstack.com/) provides utilities for state management, tables, and querying. - -## Why we chose this -TanStack helps manage server state and table state in RADFish applications. NOAA applications have complex data structures and multi-entry forms. TanStack creates an improved user experience with less boilerplate code. - -## Trade-offs -Using Tanstack requires familiarity with its API and concepts, which may present a learning curve. However, it handles NOAA’s data-centric applications and provides an enhanced user experience. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/trussworks.md b/docs/developer-documentation/developer-documentation/technical-decision-log/trussworks.md deleted file mode 100644 index 20624db..0000000 --- a/docs/developer-documentation/developer-documentation/technical-decision-log/trussworks.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_position: 5 -description: Adherence to US Web Design Standards ---- - -# Trussworks Component Library - -The [Trussworks component library](https://github.com/trussworks/react-uswds) is a set of standard components from React libraries and the [U.S. Web Design System (USWDS)](https://designsystem.digital.gov/). - -## Why we chose this -Trussworks component library adheres to USWDS standards. This ensures RADFish applications meet federal standards for accessibility and design. It also aligns with NOAA’s branding guidelines and 508 compliance requirements. - -## Trade-offs -Using a specific component library might restrict design flexibility. However, using a single component library provides consistency. Trussworks also meets compliance standards, which is invaluable for government projects. - -## Alternatives -[Material-UI](https://mui.com/material-ui/) and [Ant Design](https://ant.design/) offer extensive component libraries with customizable themes. These provides broader design options. However, Trussworks' specific focus on USWDS compliance and its integration with React makes it a better fit for RADFish. diff --git a/docs/developer-documentation/developer-documentation/technical-decision-log/workbox.md b/docs/developer-documentation/developer-documentation/technical-decision-log/workbox.md deleted file mode 100644 index 1ced0db..0000000 --- a/docs/developer-documentation/developer-documentation/technical-decision-log/workbox.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -sidebar_position: 10 -description: Service worker management for improved caching ---- - -# Workbox -[Workbox](https://developer.chrome.com/docs/workbox) is a collection of service worker libraries and tooling. - -## Why we chose this -Workbox streamlines service worker management and offline capabilities essential for RADFish. It simplifies caching strategies and offline data handling. This is critical for NOAA PWAs used offline. - -## Trade-offs -Workbox’s abstraction layer may obscure some of the finer details of service worker implementation. However, the ease of integrating robust offline functionalities justifies its use within RADFish. The ease of implementation makes it more approachable for NOAA developers. Developers can easily modify the RADFish-provided setup as well. diff --git a/docs/developer-documentation/developer-documentation/upgrading.md b/docs/developer-documentation/developer-documentation/upgrading.md deleted file mode 100644 index 5f2eac7..0000000 --- a/docs/developer-documentation/developer-documentation/upgrading.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -sidebar_position: 7 ---- - -# Upgrading - -## How to keep your RADFish project up to date - -Updating your RADFish version ensures stability, security, and the latest features. It also keeps your project free of warnings and errors. This section provides a step-by-step guide on how to update your RADFish packages. - -### 1. Upgrade Packages - - 1. **Run command:** In the root of your project, run: - ```bash - npm update - ``` - - This will update both `@nmfs-radfish/radfish` and `@nmfs-radfish/react-radfish` along with their dependencies to the latest compatible versions. - - 2. **Check for Changes:** After running the update, you should verify that everything is working as expected. It's a good practice to run your test suite to catch any potential issues: - ```bash - npm test - ``` - -### 2. Handling Warnings During Updates - - While updating your packages, you might encounter warnings. These warnings may not necessarily be RADFish-specific. These warnings often occur when certain packages in your project are outdated or incompatible. To get rid of these warnings: - - 1. **Check for outdated packages:** Run the command below to list all outdated packages, including those not related to RADFish. - ```bash - npm outdated - ``` - - 2. **Update dependencies:** You can selectively update non-react-radfish packages by running: - ```bash - npm update - ``` - - 3. **Resolve peer dependency warnings:** Some warnings may be related to peer dependencies. To resolve these, you might need to install or update the required dependencies manually. - ```bash - npm install - ``` - - 4. **Remove deprecated packages:** If the warning is about deprecated packages, it’s a good idea to check if these packages are still necessary and remove them if they’re not. - ```bash - npm uninstall - ``` - -### 3. Overview of Packages Managed in `radfish` and `react-radfish` - -In your RADFish project, these packages are managed and should be kept up to date: -- `@nmfs-radfish/radfish` -- `@nmfs-radfish/react-radfish` - -#### `@nmfs-radfish/radfish` -This package handles the core logic and utilities for RADFish. It manages several dependencies that are essential for the functionality of the RADFish system: - - - **Dependencies:** - - `dexie`: A minimalistic IndexedDB wrapper for managing databases. - - `msw`: A library for mocking API requests in development and testing environments. - - `react`: The core React library required for building user interfaces in RADFish projects. - -#### `@nmfs-radfish/react-radfish` - - This package provides UI components for React applications using RADFish. It manages several dependencies that enhance the user interface and functionality: - - - **Dependencies:** - - `@tanstack/react-table`: A headless table library for building powerful data tables in React. - - `@trussworks/react-uswds`: A component library that implements the U.S. Web Design System (USWDS) for React. - - - **DevDependencies**: - - `@testing-library/dom`: Utility for testing DOM nodes. - - `@testing-library/jest-dom`: Custom Jest matchers for asserting on DOM nodes. - - `@testing-library/react`: Testing utilities for React components. - - `@vitejs/plugin-react`: A Vite plugin that provides React support. - - `jsdom`: JavaScript implementation of the DOM for testing. - - `vite-plugin-css-injected-by-js`: A Vite plugin for injecting CSS in JavaScript. - - `vitest`: A Vite-native unit testing framework. From e9ae54fa459bf658488fc55d1bf14c65f0fb5b6e Mon Sep 17 00:00:00 2001 From: oanelson Date: Tue, 28 Jan 2025 13:37:31 -0800 Subject: [PATCH 4/5] Fix bold issue --- docs/about/disclaimer-and-open-source-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/about/disclaimer-and-open-source-policy.md b/docs/about/disclaimer-and-open-source-policy.md index c771734..e51888b 100644 --- a/docs/about/disclaimer-and-open-source-policy.md +++ b/docs/about/disclaimer-and-open-source-policy.md @@ -11,7 +11,7 @@ This section covers our accessibility and open source policies. It also covers c At RADFish, we're committed to ensuring that all users can fully engage with our project. We adhere to Section 508 of the Rehabilitation Act and the Web Content Accessibility Guidelines (WCAG 2.1) from the World Wide Web Consortium (W3C). Key accessibility features include: - **Alternative text for images.** Make sure all images have descriptive text. -- **Strong color contrast: Maintain high contrast between foreground and background colors for readability. +- **Strong color contrast**: Maintain high contrast between foreground and background colors for readability. - **Text resizing.** Allow users to adjust text sizes based on personal preferences. - **Proper use of headings.** Structure pages to ensure clear navigation for screen readers. - **Descriptive links.** Avoid ambiguous text like "Click here" or "More..." and instead using meaningful link descriptions. From 5c0e1073f352f6566eeaad270ae4c69238edf99c Mon Sep 17 00:00:00 2001 From: oanelson Date: Tue, 28 Jan 2025 13:46:21 -0800 Subject: [PATCH 5/5] Fixes typo. --- docs/developer-documentation/concepts/concepts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-documentation/concepts/concepts.md b/docs/developer-documentation/concepts/concepts.md index 96b5b0d..b0009da 100644 --- a/docs/developer-documentation/concepts/concepts.md +++ b/docs/developer-documentation/concepts/concepts.md @@ -12,5 +12,5 @@ Modern users expect apps to be responsive and reliable, even with limited intern Designing apps for these users present unique challenges. To meet these challenges, RADFish developers should be familiar with several concepts: -* [Offline-First](https://nmfs-radfish.github.io/radfish/developer-documentation/concepts/offline-first) design prioritizes functionalatity even without internet connectivity. +* [Offline-First](https://nmfs-radfish.github.io/radfish/developer-documentation/concepts/offline-first) design prioritizes functionality even without internet connectivity. * [On-Device Storage](https://nmfs-radfish.github.io/radfish/developer-documentation/concepts/on-device-storage) is storing data directly on a user's device, without relying on internet connectivity. \ No newline at end of file