diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 066a7b053..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,92 +0,0 @@ -version: 2.1 - -orbs: - cypress: cypress-io/cypress@2.2.0 - -executors: - default: - docker: - - image: cypress/browsers:22.15.0 - -parameters: - workspace_root: - type: string - default: '~/' - primary_cache_key: - type: string - default: 'oc-ci-2-{{ .Branch }}-{{ checksum "yarn.lock" }}' - backup_cache_key: - type: string - default: 'oc-ci-2-{{ .Branch }}-' - org_level_cache_key: - type: string - default: 'oc-ci-2-' - -aliases: - - &attach_workspace - attach_workspace: - at: << pipeline.parameters.workspace_root >> - - &restore_cache - restore_cache: - keys: - - << pipeline.parameters.primary_cache_key >> - # Fallback in case checksum fails. - - << pipeline.parameters.backup_cache_key >> - - << pipeline.parameters.org_level_cache_key >> - - &yarn_install - run: - name: 'Installing dependencies...' - command: yarn install --non-interactive --frozen-lockfile --cache_folder << pipeline.parameters.workspace_root >>.cache/yarn - -jobs: - install_dependencies: - executor: default - steps: - - checkout - - *attach_workspace - - *restore_cache - - *yarn_install - - save_cache: - key: << pipeline.parameters.primary_cache_key >> - paths: - - node_modules - - << pipeline.parameters.workspace_root >>.cache/yarn - - << pipeline.parameters.workspace_root >>.cache/Cypress - - run: node --version - - run: yarn --version - - unit_tests: - executor: default - steps: - - checkout - - *attach_workspace - - *restore_cache - - *yarn_install - - run: - name: Run tests - command: yarn test:ci - - lint: - executor: default - steps: - - checkout - - *attach_workspace - - *restore_cache - - *yarn_install - - run: - name: Lint - command: | - yarn lint:ci - -workflows: - default: - jobs: - - install_dependencies - - - unit_tests: - requires: - - install_dependencies - - - lint: - requires: - - install_dependencies diff --git a/.eslintignore b/.eslintignore index 754e83b29..61967d553 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,6 @@ node_modules package.json -yarn.lock +pnpm-lock.yaml .next .github bin diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 3a7435e17..b48ca2111 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -1,7 +1,7 @@ # .github/workflows/chromatic.yml # Workflow name -name: ci +name: Chromatic # Event for the workflow on: push @@ -17,32 +17,20 @@ jobs: with: fetch-depth: 0 + - name: Install pnpm + uses: pnpm/action-setup@v4 + - name: Read .nvmrc - run: echo ::set-output name=NVMRC::$(cat .nvmrc) - id: nvm + run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_ENV - name: Use Node - uses: actions/setup-node@v1 - with: - always-auth: true - registry-url: https://registry.npmjs.org - node-version: '${{ steps.nvm.outputs.NVMRC }}' - - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - - name: Use cached node_modules - uses: actions/cache@v4 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + uses: actions/setup-node@v5 with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' - name: Install dependencies - run: yarn install --frozen-lockfile --non-interactive + run: pnpm install --frozen-lockfile - name: Publish to Chromatic uses: chromaui/action@v1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..ebc9c8259 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,46 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + ci: + runs-on: ubuntu-latest + strategy: + matrix: + task: [lint, test] + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + run_install: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "pnpm" + + - name: Install dependencies + run: pnpm install + + - name: Run lint + if: matrix.task == 'lint' + run: pnpm lint:ci + + - name: Run tests + if: matrix.task == 'test' + run: pnpm test:ci + + - name: Upload coverage artifact + if: matrix.task == 'test' && github.event_name == 'pull_request' + uses: actions/upload-artifact@v4 + with: + name: vitest-coverage + path: vitest-coverage diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 6ab900b81..80b1e3084 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -13,18 +13,20 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v5 + - name: Install pnpm + uses: pnpm/action-setup@v4 - uses: actions/setup-node@v5 with: node-version-file: ".nvmrc" - cache: "yarn" + cache: "pnpm" - name: Install dependencies - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Install Playwright Browsers - run: yarn playwright install --with-deps + run: pnpm playwright install --with-deps - name: Run Playwright tests env: AIRTABLE_PAT: ${{ secrets.AIRTABLE_PAT }} - run: yarn test:e2e:headless + run: pnpm test:e2e:headless - uses: actions/upload-artifact@v4 if: failure() id: artifact-upload diff --git a/.github/workflows/report_coverage.yml b/.github/workflows/report_coverage.yml index 0c8adf775..6cd4ae237 100644 --- a/.github/workflows/report_coverage.yml +++ b/.github/workflows/report_coverage.yml @@ -1,8 +1,8 @@ -name: Report Coverage +name: Report Coverage on: workflow_run: - workflows: [Upload Coverage] + workflows: ["CI"] types: [completed] jobs: @@ -18,6 +18,7 @@ jobs: - name: Download Coverage Artifact uses: actions/download-artifact@v4 with: + name: vitest-coverage github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} diff --git a/.github/workflows/upload_coverage.yml b/.github/workflows/upload_coverage.yml deleted file mode 100644 index 43f778b46..000000000 --- a/.github/workflows/upload_coverage.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Upload Coverage - -on: - pull_request: - branches: [main] - -jobs: - coverage: - runs-on: ubuntu-latest - - permissions: - contents: read - - steps: - - uses: actions/checkout@v4 - - - name: Read .nvmrc - run: echo ::set-output name=NVMRC::$(cat .nvmrc) - id: nvm - - - name: Use Node - uses: actions/setup-node@v4 - with: - always-auth: true - registry-url: https://registry.npmjs.org - node-version: '${{ steps.nvm.outputs.NVMRC }}' - - - name: Enable Yarn - run: corepack enable - - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - - name: Use cached node_modules - uses: actions/cache@v4 - id: yarn-cache - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - name: Install dependencies - run: yarn install --frozen-lockfile --non-interactive - - - name: 'Test' - run: npx vitest --coverage.enabled true - - - name: "Upload Coverage" - uses: actions/upload-artifact@v4 - with: - name: vitest-coverage - path: vitest-coverage diff --git a/.gitignore b/.gitignore index 054e0fead..18787626d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ logs npm-debug.log* yarn-debug.log* yarn-error.log* +pnpm-debug.log* # Runtime data pids diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 000000000..cb2c84d5c --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +pnpm lint-staged diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100644 index 000000000..7e59f71a0 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1 @@ +pnpm test:changes diff --git a/.huskyrc b/.huskyrc deleted file mode 100644 index 9358b181a..000000000 --- a/.huskyrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "hooks": { - "pre-commit": "yarn lint-staged", - "pre-push": "yarn test:changes" - } -} diff --git a/.mergify.yml b/.mergify.yml index 19dc8b0be..de9e089b1 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -5,17 +5,17 @@ queue_rules: - '#changes-requested-reviews-by=0' - 'status-success=Vercel – operation-code' - 'status-success=Vercel – storybook' - - 'status-success=ci/circleci: lint' - - 'status-success=ci/circleci: unit_tests' - - 'status-success=cypress: all tests' + - 'status-success=CI / lint' + - 'status-success=CI / unit_tests' + - 'status-success=Playwright Tests / test' - status-success=codeclimate/diff-coverage - status-success=codeclimate/total-coverage merge_conditions: - 'status-success=Vercel – operation-code' - 'status-success=Vercel – storybook' - - 'status-success=ci/circleci: lint' - - 'status-success=ci/circleci: unit_tests' - - 'status-success=cypress: all tests' + - 'status-success=CI / lint' + - 'status-success=CI / unit_tests' + - 'status-success=Playwright Tests / test' - status-success=codeclimate/diff-coverage - status-success=codeclimate/total-coverage merge_method: rebase diff --git a/.prettierignore b/.prettierignore index e731bc4f6..85840f81b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,6 @@ node_modules package.json -yarn.lock +pnpm-lock.yaml .babelrc **/.babelrc .next diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6e82a2fd4..f53be6d6c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -104,7 +104,7 @@ Here is an alphabetically-sorted list of technologies this project leverages: - [React.js](https://facebook.github.io/react/) - Facebook's popular JavaScript front-end framework. - [Storybook](https://storybook.js.org) - Storybook acts as a "component workbench" and source for component documentation. You can learn more about Storybook on your own [here](https://www.learnstorybook.com/). You can see our Storybook here: [![Storybook](https://github.com/storybookjs/brand/blob/8d28584c89959d7075c237e9345955c895048977/badge/badge-storybook.svg)](http://storybook.operationcode.org) - [Webpack](https://webpack.js.org/) - The premier module bundler for JavaScript. Read [this article](https://survivejs.com/webpack/what-is-webpack/) for more information. -- [Yarn](https://yarnpkg.com/) - Facebook's open source JavaScript package manager. It has very subtle differences from npm, but essentially does the same thing. +- [pnpm](https://pnpm.io/) - Fast, disk space efficient package manager that uses a content-addressable storage system. ### PostCSS @@ -190,20 +190,19 @@ Which will output the following when deployed: ### Installing Dependencies -VERY IMPORTANT: Required versions of tools used within the repo are described [here](https://github.com/OperationCode/front-end#quick-start). We do not use `npm`. +VERY IMPORTANT: Required versions of tools used within the repo are described [here](https://github.com/OperationCode/front-end#quick-start). We use `pnpm` as our package manager. _You can check to see your versions like so:_ - Run `node -v`. You can download the latest LTS release of node at [nodejs.org](https://nodejs.org) or you can use [nvm](https://github.com/creationix/nvm) to be able to switch between node versions easily for many projects. If you use Windows, you will need to use [nvm-windows](https://github.com/coreybutler/nvm-windows) instead. -- Run `npm -v`. If you need to install or upgrade npm, run `npm install -g npm` -- Run `yarn --version`. If you need to install yarn, run `npm install --global yarn`. -- Once you have all the required tooling, you should be able to run `yarn` at the root level of your forked repo. You should see a bunch of emojis and progress bars - that is how you will know it is working! +- Run `pnpm --version`. If you need to install pnpm, run `npm install -g pnpm` or `corepack enable` (Node.js 16.13+). +- Once you have all the required tooling, you should be able to run `pnpm install` at the root level of your forked repo. You should see progress indicators showing installation progress! ### Run The Development Server -Now that you've installed your dependencies and your new branch in your fork, you can launch the "dev server" with `yarn dev`. +Now that you've installed your dependencies and your new branch in your fork, you can launch the "dev server" with `pnpm dev`. -**Note:** The dev server should be running on http://localhost:3000/ shortly after you run `yarn dev` +**Note:** The dev server should be running on http://localhost:3000/ shortly after you run `pnpm dev`
⚠️ Warning ⚠️
@@ -213,8 +212,8 @@ Now that you've installed your dependencies and your new branch in your fork, yo Some issues take awhile to code a solution for. It is very normal to take a large amount of time to turn in well-written work that resolves an issue! In the meantime, there could be many other people contributing to the code base. Since we use Git, you'll want to keep you project up-to-date with the `main` branch so there are no [merge conflicts](https://help.github.com/articles/about-merge-conflicts/) to resolve when you make your pull request. 1. [Keep your fork in sync with Operation Code's main branch.](https://help.github.com/articles/syncing-a-fork/) -2. Run `yarn` to install any updated dependencies -3. Run `yarn dev` to restart local development environment +2. Run `pnpm install` to install any updated dependencies +3. Run `pnpm dev` to restart local development environment ### Knowing The Tools At Your Disposal @@ -270,59 +269,59 @@ You can see interactive documentation on all of our components via [![Storybook] * - Root-level files are configuration and documentation. ``` -### npm Scripts With Explanations +### pnpm Scripts With Explanations ```sh # Install dependencies defined in `package.json` -yarn +pnpm install # Run local development server accessible in the browser via http://localhost:3000 -yarn dev +pnpm dev # Run Storybook development server. Used as a workbench when developing new common components. Accessible in the browser via http://localhost:9001 -yarn storybook +pnpm storybook # Create a static bundle of our Storybook instance that can be easily deployed. -yarn storybook:build +pnpm storybook:build # Create a bundle of our main application that can be easily deployed by a server or as a static export. -yarn build +pnpm build # Run build, but expose local instances of bundle visualizations to see what code we ship to users' browsers. -yarn build:analyze +pnpm build:analyze # Fix/reveal linting errors. Used in the precommit hook and on every build to ensure that code meets our linting standards. -yarn lint +pnpm lint # Start the main application server or to serve up a production build locally. -yarn start +pnpm start # Run all available unit and integration tests. -yarn test +pnpm test # Update all snapshot tests -yarn test -u OR yarn test:update-snaps +pnpm test -u OR pnpm test:update-snaps # Only run tests for files changed from main branch -yarn test:changes +pnpm test:changes # Start a test runner for files changed from main branch -yarn test:changes:watch +pnpm test:changes:watch # Start a test runner for all tests -yarn test:watch +pnpm test:watch # You can use the name of the file at the end of any non-e2e test command to run it against a single file -yarn test $fileName +pnpm test $fileName # Opens up a Cypress browser with which you can check e2e tests locally. Be sure the local dev server is running before this command! -yarn test:e2e +pnpm test:e2e #Create all the necessary files/folders for a new, reusable component. Please make `ComponentName` TitleCase. -yarn create-component $ComponentName +pnpm create-component $ComponentName #Create a new page in the pages directory. -yarn create-page $pageName +pnpm create-page $pageName ``` ## Mocking Back-end Server API @@ -437,13 +436,13 @@ Install the LTS version [Node.js](https://nodejs.org/en/download/). Follow the steps found in the [Quick Start Guide](https://github.com/OperationCode/operationcode_frontend/blob/main/CONTRIBUTING.md#quick-start-guide) -If you have any errors, make sure Node, npm, and Yarn is in your environment path by typing `PATH` in CMDER. +If you have any errors, make sure Node, npm, and pnpm is in your environment path by typing `PATH` in CMDER. Look for any path like the ones listed below. `{USER}` is your username you used to login into the computer. - `C:\Program Files\nodejs\` -- `C:\Program Files (x86)\Yarn\bin` +- `C:\Program Files (x86)\pnpm\bin` - `C:\Users\{USER}\AppData\Roaming\npm` -- `C:\Users\{USER}\AppData\Local\Yarn\bin` +- `C:\Users\{USER}\AppData\Local\pnpm\bin` - `C:\Program Files\Git\usr\bin` To add them in your path, you can go to your Control Panel by clicking on the `Start` > type in: `Control Panel` > click on `System and Security` > click on `System` > on the left hand side, click on `Advanced System Settings` > near the bottom of the window, click on the `Environment Variables` and then under the `User variables for {USER}` click on the `Path` table and click on `Edit..`. diff --git a/README.md b/README.md index 850273848..b9a06ddbc 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,6 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Twitter Follow](https://img.shields.io/twitter/follow/operation_code.svg?style=social&label=Follow&style=social)](https://twitter.com/operation_code) -[![CircleCI](https://circleci.com/gh/OperationCode/front-end/tree/main.svg?style=svg)](https://circleci.com/gh/OperationCode/front-end/tree/main) -[![Maintainability](https://api.codeclimate.com/v1/badges/5010b82ce5d8e319a597/maintainability)](https://codeclimate.com/github/OperationCode/front-end/maintainability) -[![Cypress.io tests](https://img.shields.io/badge/cypress.io-tests-green.svg?style=flat-square)](https://cypress.io) - [See unblocked, unassigned issues](https://github.com/OperationCode/front-end/issues?q=is%3Aopen+is%3Aissue+-label%3A%22Status%3A+Blocked%22+no%3Aassignee). We love our labels - feel free to filter issues to find what you want to work on. # Welcome! @@ -29,30 +25,30 @@ Our entire UI library is documented via [![Storybook](https://github.com/storybo Required versions of tools used within the repo: - Node: See [.nvmrc](https://github.com/OperationCode/front-end/blob/main/.nvmrc) -- `yarn@1` +- `pnpm@10` - `git@2.17.1` or greater ```sh # Install dependencies -yarn +pnpm install # Run local development -yarn dev +pnpm dev # Use Storybook as a workbench when developing new components -yarn storybook +pnpm storybook # Run all unit tests -yarn test +pnpm test # Run all Cypress tests (make sure your dev server is running) -yarn test:e2e +pnpm test:e2e # Create all the necessary files/folders for a new, reusable component -yarn create-component $ComponentName +pnpm create-component $ComponentName # Create the necessary file with a small boilerplate for a new page -yarn create-page $PageName +pnpm create-page $PageName ``` ## Open Source Gratitude diff --git a/common/utils/api-utils.ts b/common/utils/api-utils.ts index 672fb92f4..7b68dcc53 100644 --- a/common/utils/api-utils.ts +++ b/common/utils/api-utils.ts @@ -1,10 +1,8 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import type { AxiosError, AxiosInstance } from 'axios'; +import type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios'; import axios from 'axios'; import { networkErrorMessages } from 'common/constants/messages'; import { apiUrl, resourcesAPIURL } from 'common/config/environment'; import { setAuthorizationHeader } from 'common/utils/cookie-utils'; -import qs from 'qs'; const baseAxiosConfig = { baseURL: apiUrl, @@ -39,7 +37,10 @@ const getRequestAbortionPieces = () => { export const get = async ( path: string, - { token, parameters }: { token?: string; parameters?: Record } = {}, + { + token, + parameters, + }: { token?: string; parameters?: Record } = {}, axiosClient = OperationCodeAPI, ) => { const { abort, connectionTimeout } = getRequestAbortionPieces(); @@ -49,12 +50,6 @@ export const get = async ( headers: setAuthorizationHeader(token), cancelToken: abort.token, params: parameters, - /** - * @description paramsSerializer takes an array of query params that is usually - * serialized like this '/api/?id[]=1&id[]=2' and converts it into '/api/?id=1&id=2' - * to better work with the API - * */ - paramsSerializer: parameters_ => qs.stringify(parameters_, { arrayFormat: 'repeat' }), }) .then(response => { clearTimeout(connectionTimeout); @@ -68,7 +63,7 @@ export const get = async ( export const post = async ( path: string, - body: Record | any[], + body: object, { token }: { token?: string } = {}, axiosClient: AxiosInstance = axios, ) => { @@ -91,7 +86,7 @@ export const post = async ( export const patch = async ( path: string, - body: Record | any[], + body: object, { token }: { token?: string } = {}, axiosClient: AxiosInstance = axios, ) => { @@ -114,7 +109,7 @@ export const patch = async ( export const put = async ( path: string, - body: Record | any[], + body: object, { token }: { token?: string } = {}, axiosClient: AxiosInstance = axios, ) => { @@ -140,6 +135,7 @@ export const put = async ( * If object is unexpected, assume the server is down and return a relavant error message. */ export const getServerErrorMessage = (errorObject: AxiosError | Error | unknown) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const abstractError = errorObject as any; return abstractError?.response?.data?.error ?? networkErrorMessages.serverDown; diff --git a/components/Form/Select/__tests__/__snapshots__/SelectMulti.test.tsx.snap b/components/Form/Select/__tests__/__snapshots__/SelectMulti.test.tsx.snap index 562c942f1..44318b996 100644 --- a/components/Form/Select/__tests__/__snapshots__/SelectMulti.test.tsx.snap +++ b/components/Form/Select/__tests__/__snapshots__/SelectMulti.test.tsx.snap @@ -15,7 +15,7 @@ exports[`Select > should render with required props 1`] = ` className="lg:relative" >
should render with required props 1`] = ` className="css-1f43avz-a11yText-A11yText" />
Select...
should render with required props 1`] = `