diff --git a/.eslintrc b/.eslintrc index d4ad3bc0..362d66d6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,10 +1,10 @@ { "parser": "@typescript-eslint/parser", "extends": [ - "plugin:react/recommended", - "plugin:@typescript-eslint/recommended", - "prettier", - "plugin:prettier/recommended" + "plugin:react/recommended", // React recommended rules plugin + "plugin:@typescript-eslint/recommended", // Plugin to use typescript with eslint + "prettier", // Add prettier rules to eslint + "plugin:prettier/recommended" // Plugin to use prettier rules with eslint ], "plugins": ["react-hooks"], "parserOptions": { diff --git a/.github/workflows/deploy-storybook.yml b/.github/workflows/deploy-storybook.yml new file mode 100644 index 00000000..8f2bf412 --- /dev/null +++ b/.github/workflows/deploy-storybook.yml @@ -0,0 +1,86 @@ +name: Deploy storybook + +on: + # Pull request hook without any config. Launches for every pull request + pull_request: + # Launches build when release is published + release: + types: [published] + +env: + REPO_NAME_ALPHANUMERIC: safereactcomponents + +jobs: + deploy: + name: Deployment + runs-on: ubuntu-latest + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + + - uses: actions/checkout@v2 + + - name: Node.js setup + uses: actions/setup-node@v2 + with: + node-version: 14 + + - uses: actions/cache@v2 + with: + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Env dependencies setup + run: | + sudo apt-get update + sudo apt-get -y install python3-pip python3-dev + pip install awscli --upgrade --user + + - name: Yarn install + run: | + mkdir .yarncache + yarn install --cache-folder ./.yarncache --frozen-lockfile + rm -rf .yarncache + yarn cache clean + + - name: Build storybook + run: yarn build-storybook + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ secrets.AWS_DEFAULT_REGION }} + + # Script to deploy Pull Requests + - run: bash ./scripts/github/deploy_pull_request.sh + if: success() && github.event.number + env: + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + PR_NUMBER: ${{ github.event.number }} + REVIEW_BUCKET_NAME: ${{ secrets.AWS_REVIEW_BUCKET_NAME }} + + - name: 'PRaul: Comment PR with app URLs' + uses: mshick/add-pr-comment@v1 + with: + message: | + :books: [Storybook review](${{ env.REVIEW_FEATURE_URL }}) + repo-token: ${{ secrets.GITHUB_TOKEN }} + repo-token-user-login: 'github-actions[bot]' + if: success() && github.event.number + env: + REVIEW_FEATURE_URL: https://pr${{ github.event.number }}--safereactcomponents.review.gnosisdev.com + + + # Script to prepare production deployments + - run: bash ./scripts/github/prepare_production_deployment.sh + if: success() && startsWith(github.ref, 'refs/tags/v') + env: + PROD_DEPLOYMENT_HOOK_TOKEN: ${{ secrets.PROD_DEPLOYMENT_HOOK_TOKEN }} + PROD_DEPLOYMENT_HOOK_URL: ${{ secrets.PROD_DEPLOYMENT_HOOK_URL }} + VERSION_TAG: ${{ github.event.release.tag_name }} diff --git a/.prettierrc b/.prettierrc index 7f0a1dfc..ca7749f4 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,6 @@ { "bracketSpacing": true, - "jsxBracketSameLine": true, + "bracketSameLine": true, "printWidth": 80, "singleQuote": true, "trailingComma": "es5", diff --git a/.storybook/main.js b/.storybook/main.js index 26608b83..6a2dd296 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -4,5 +4,6 @@ module.exports = { "@storybook/addon-actions", "@storybook/addon-links", "@storybook/addon-docs", + "storybook-addon-react-docgen", ] }; diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js index ebcefdd1..226335e9 100644 --- a/.storybook/webpack.config.js +++ b/.storybook/webpack.config.js @@ -1,13 +1,18 @@ module.exports = ({ config }) => { config.module.rules.push({ - test: /\.(ts|tsx)$/, + test: /\.(ts|js)x?$/, + exclude: [/node_modules/], use: [ { - loader: require.resolve('awesome-typescript-loader') + loader: require.resolve('babel-loader'), + options: { + presets: [ + '@babel/preset-env', + '@babel/preset-react', + '@babel/preset-typescript', + ], + }, }, - { - loader: require.resolve('react-docgen-typescript-loader') - } ] }); diff --git a/README.md b/README.md index 1aa20878..96b2b231 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,10 @@ As Gnosis Safe allows to integrate third party applications ("Safe Apps"), these ## Integration -This library makes use of [material-ui - 4.X.X](https://material-ui.com/) and [styled-componentes - 5.X.X]() as `peer dependencies`, this means you must install it in your Safe App. Make sure to provide the same version as the one being used by the current version of this library. +This library makes use of [material-ui - 4.X.X](https://material-ui.com/) and [styled-components - 5.X.X](https://styled-components.com/) as `peer dependencies`, this means you must install it in your Safe App. Make sure to provide the same version as the one being used by the current version of this library. -Once everything is installed, you have to instantiate a [ThemeProvider](https://styled-components.com/docs/api#themeprovider) from [styled-components](http://styled-components.com/). +Once everything is installed, you have to instantiate a [ThemeProvider](https://styled-components.com/docs/api#themeprovider) from [styled-components](https://styled-components.com/). This example uses the theme exported by safe-react-components. Here, you can extend this theme to customize it to your needs. diff --git a/babel.config.js b/babel.config.js index 19646cbe..be7af752 100644 --- a/babel.config.js +++ b/babel.config.js @@ -4,4 +4,5 @@ module.exports = { '@babel/preset-typescript', '@babel/preset-react', ], + plugins: ['react-docgen'], }; diff --git a/package.json b/package.json index 7e1b2141..635f9088 100644 --- a/package.json +++ b/package.json @@ -28,10 +28,10 @@ "react-media": "^1.10.0" }, "devDependencies": { - "@babel/core": "^7.14.0", - "@babel/preset-env": "^7.14.0", - "@babel/preset-react": "^7.14.0", - "@babel/preset-typescript": "^7.14.0", + "@babel/core": "^7.16.0", + "@babel/preset-env": "^7.16.0", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", "@material-ui/core": "^4.12.3", "@storybook/addon-actions": "^6.3.12", "@storybook/addon-docs": "^6.3.12", @@ -43,32 +43,33 @@ "@testing-library/react": "^11.2.7", "@testing-library/user-event": "^12.2.0", "@types/jest": "^26.0.0", - "@types/material-ui": "^0.21.9", - "@types/node": "^16.6.1", + "@types/material-ui": "^0.21.12", + "@types/node": "^16.11.9", "@types/react": "^16.9.55", "@types/react-dom": "^16.9.0", - "@types/styled-components": "^5.1.12", - "@typescript-eslint/eslint-plugin": "^4.29.2", - "@typescript-eslint/parser": "^4.29.2", - "awesome-typescript-loader": "^5.2.1", + "@types/styled-components": "^5.1.15", + "@typescript-eslint/eslint-plugin": "^4.31.0", + "@typescript-eslint/parser": "^4.31.0", + "babel-loader": "^8.2.3", + "babel-plugin-react-docgen": "^4.2.1", "copy-webpack-plugin": "^6.3.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", - "eslint-plugin-prettier": "^3.4.0", - "eslint-plugin-react": "^7.24.0", - "eslint-plugin-react-hooks": "^4.2.0", + "eslint-plugin-prettier": "^4.0.0", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", "ethereum-blockies-base64": "^1.0.2", "file-loader": "^6.2.0", "identity-obj-proxy": "^3.0.0", "jest": "^26.6.3", - "jest-styled-components": "^7.0.5", - "prettier": "^2.3.2", + "jest-styled-components": "^7.0.6", + "prettier": "^2.4.1", "react": "^16.14.0", - "react-docgen-typescript-loader": "^3.7.2", "react-dom": "^16.14.0", "rimraf": "^3.0.2", - "styled-components": "^5.3.0", - "typescript": "^4.0.5", + "storybook-addon-react-docgen": "^1.2.42", + "styled-components": "^5.3.3", + "typescript": "^4.5.0", "url-loader": "^4.1.1", "webpack": "4.43.0", "webpack-cli": "^3.3.10", diff --git a/scripts/github/deploy_pull_request.sh b/scripts/github/deploy_pull_request.sh new file mode 100644 index 00000000..c25f8114 --- /dev/null +++ b/scripts/github/deploy_pull_request.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +BUILD_DIR='storybook-static' + +function deploy_pull_request { + REVIEW_ENVIRONMENT_DOMAIN='review.gnosisdev.com' + + # Pull request name with "pr" prefix + PULL_REQUEST_NAME="pr$PR_NUMBER" + + # Only alphanumeric characters. Example safe-react-components -> safereactcomponents + REVIEW_FEATURE_FOLDER="$REPO_NAME_ALPHANUMERIC/$PULL_REQUEST_NAME" + + aws s3 sync ${BUILD_DIR} s3://${REVIEW_BUCKET_NAME}/${REVIEW_FEATURE_FOLDER} --delete +} + +function publish_pull_request_urls_in_github { + REVIEW_FEATURE_URL="https://$PULL_REQUEST_NAME--$REPO_NAME_ALPHANUMERIC.$REVIEW_ENVIRONMENT_DOMAIN" + + # Using the Issues api instead of the PR api + # Done so because every PR is an issue, and the issues api allows to post general comments, + # while the PR api requires that comments are made to specific files and specific commits + GITHUB_PR_COMMENTS=https://api.github.com/repos/${TRAVIS_REPO_SLUG}/issues/${TRAVIS_PULL_REQUEST}/comments + curl -H "Authorization: token ${GITHUB_API_TOKEN}" --request POST ${GITHUB_PR_COMMENTS} --data '{"body":"Travis automatic deployment:\r\n '${REVIEW_FEATURE_URL}' \r\n"}' +} + +# Only: +# - Pull requests +# - Security env variables are available. PR from forks don't have them. +if [ -n "$AWS_ACCESS_KEY_ID" ] +then + deploy_pull_request + # publish_pull_request_urls_in_github +fi diff --git a/scripts/github/prepare_production_deployment.sh b/scripts/github/prepare_production_deployment.sh new file mode 100644 index 00000000..f4e1f516 --- /dev/null +++ b/scripts/github/prepare_production_deployment.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -ev + +# Only: +# - Tagged commits +# - Security env variables are available. +if [ -n "$VERSION_TAG" ] && [ -n "$PROD_DEPLOYMENT_HOOK_TOKEN" ] && [ -n "$PROD_DEPLOYMENT_HOOK_URL" ] +then + # Call Devops Releases Handler CI + curl --silent --output /dev/null --write-out "%{http_code}" -X POST \ + -F token="$PROD_DEPLOYMENT_HOOK_TOKEN" \ + -F ref=master \ + -F "variables[TRIGGER_RELEASE_COMMIT_TAG]=$VERSION_TAG" \ + $PROD_DEPLOYMENT_HOOK_URL +else + echo "[ERROR] Production deployment could not be prepared" +fi diff --git a/src/colors.stories.tsx b/src/colors.stories.tsx index e9ac1e34..282fbf0e 100644 --- a/src/colors.stories.tsx +++ b/src/colors.stories.tsx @@ -35,9 +35,9 @@ export const ColorsSample = (): React.ReactElement => { if (typeof (theme.colors as Record)[name] === 'string') { acc.push({ name, - code: ((theme.colors as Record)[ - name - ] as string).toUpperCase(), + code: ( + (theme.colors as Record)[name] as string + ).toUpperCase(), }); } return acc; diff --git a/src/dataDisplay/Amount/index.test.ts b/src/dataDisplay/Amount/index.test.ts index 6191ea2a..d2efa4d8 100644 --- a/src/dataDisplay/Amount/index.test.ts +++ b/src/dataDisplay/Amount/index.test.ts @@ -1,3 +1,4 @@ +/* eslint @typescript-eslint/no-loss-of-precision: 0 */ import { formatAmount } from '.'; describe('formatAmount', () => { diff --git a/tests/__snapshots__/colors.stories.storyshot b/tests/__snapshots__/colors.stories.storyshot index 0e0ae8db..78e55579 100644 --- a/tests/__snapshots__/colors.stories.storyshot +++ b/tests/__snapshots__/colors.stories.storyshot @@ -2,423 +2,423 @@ exports[`Storyshots Utils/Colors Colors Sample 1`] = `

secondary

#001428

text

#001428

primaryHover

#005546

errorHover

#C31717

secondaryHover

#5D6D74

placeHolder

#5D6D74

error

#DB3A3D

primary

#008C73

pending

#E8663D

rinkeby

#E8673C

secondaryLight

#B2B5B2

icon

#B2B5B2

primaryLight

#A1D2CA

warning

#FFC05F

tag

#D4D5D3

separator

#E8E7E6

pendingTagHover

#FBE5C5

errorTooltip

#FFE6EA

inputField

#F0EFEE

background

#F7F5F5

white

#FFFFFF diff --git a/tests/dataDisplay/Accordion/__snapshots__/accordion.stories.storyshot b/tests/dataDisplay/Accordion/__snapshots__/accordion.stories.storyshot index dfe42499..f543791e 100644 --- a/tests/dataDisplay/Accordion/__snapshots__/accordion.stories.storyshot +++ b/tests/dataDisplay/Accordion/__snapshots__/accordion.stories.storyshot @@ -13,12 +13,12 @@ exports[`Storyshots Data Display/Accordion Compact Accordion 1`] = ` } >

Transaction 1 @@ -131,7 +131,7 @@ exports[`Storyshots Data Display/Accordion Compact Accordion 1`] = ` className="MuiAccordionDetails-root" >

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget. @@ -143,12 +143,12 @@ exports[`Storyshots Data Display/Accordion Compact Accordion 1`] = `

Transaction 2 @@ -261,7 +261,7 @@ exports[`Storyshots Data Display/Accordion Compact Accordion 1`] = ` className="MuiAccordionDetails-root" >

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget. @@ -273,12 +273,12 @@ exports[`Storyshots Data Display/Accordion Compact Accordion 1`] = `

Transaction 3 @@ -391,7 +391,7 @@ exports[`Storyshots Data Display/Accordion Compact Accordion 1`] = ` className="MuiAccordionDetails-root" >

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget. @@ -407,15 +407,15 @@ exports[`Storyshots Data Display/Accordion Compact Accordion 1`] = ` exports[`Storyshots Data Display/Accordion Simple Accordion 1`] = `

Transaction 1 @@ -528,7 +528,7 @@ exports[`Storyshots Data Display/Accordion Simple Accordion 1`] = ` className="MuiAccordionDetails-root" >

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget. @@ -540,12 +540,12 @@ exports[`Storyshots Data Display/Accordion Simple Accordion 1`] = `

Transaction 2 @@ -658,7 +658,7 @@ exports[`Storyshots Data Display/Accordion Simple Accordion 1`] = ` className="MuiAccordionDetails-root" >

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget. @@ -670,12 +670,12 @@ exports[`Storyshots Data Display/Accordion Simple Accordion 1`] = `

Transaction 3 @@ -788,7 +788,7 @@ exports[`Storyshots Data Display/Accordion Simple Accordion 1`] = ` className="MuiAccordionDetails-root" >

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget. diff --git a/tests/dataDisplay/Card/__snapshots__/card.stories.storyshot b/tests/dataDisplay/Card/__snapshots__/card.stories.storyshot index 581da9b4..b34447c1 100644 --- a/tests/dataDisplay/Card/__snapshots__/card.stories.storyshot +++ b/tests/dataDisplay/Card/__snapshots__/card.stories.storyshot @@ -2,17 +2,17 @@ exports[`Storyshots Data Display/Card Card Disabled 1`] = `

@@ -20,12 +20,12 @@ exports[`Storyshots Data Display/Card Card Disabled 1`] = `

Some text
,
,
Some content2 @@ -29,7 +29,7 @@ exports[`Storyshots Data Display/Divider Vertical 1`] = ` Some content
Some content2 diff --git a/tests/dataDisplay/Dot/__snapshots__/dot.stories.storyshot b/tests/dataDisplay/Dot/__snapshots__/dot.stories.storyshot index 99794211..74c9a15a 100644 --- a/tests/dataDisplay/Dot/__snapshots__/dot.stories.storyshot +++ b/tests/dataDisplay/Dot/__snapshots__/dot.stories.storyshot @@ -2,11 +2,11 @@ exports[`Storyshots Data Display/Dot Dot With Icon 1`] = `

diff --git a/tests/dataDisplay/FixedDialog/__snapshots__/FixedDialog.stories.storyshot b/tests/dataDisplay/FixedDialog/__snapshots__/FixedDialog.stories.storyshot index ef501007..2224e9a9 100644 --- a/tests/dataDisplay/FixedDialog/__snapshots__/FixedDialog.stories.storyshot +++ b/tests/dataDisplay/FixedDialog/__snapshots__/FixedDialog.stories.storyshot @@ -2,35 +2,35 @@ exports[`Storyshots Data Display/FixedDialog Simple Fixed Dialog 1`] = `

Legal Disclaimer
Some Body
  • Owner 1

    @@ -677,16 +677,16 @@ exports[`Storyshots Ethereum/Eth hash Info With Name 1`] = ` exports[`Storyshots Ethereum/Eth hash Info With Short Address 1`] = `

    @@ -699,37 +699,37 @@ exports[`Storyshots Ethereum/Eth hash Info With Short Address 1`] = ` exports[`Storyshots Ethereum/Eth hash Info With Show And Copy Short Name 1`] = `

    Owner 1

    ,
    ,
    ,
    ,
    ,
    , diff --git a/tests/inputs/Button/__snapshots__/button.stories.storyshot b/tests/inputs/Button/__snapshots__/button.stories.storyshot index cb05aaf0..b5da44ff 100644 --- a/tests/inputs/Button/__snapshots__/button.stories.storyshot +++ b/tests/inputs/Button/__snapshots__/button.stories.storyshot @@ -2,10 +2,10 @@ exports[`Storyshots Inputs/Button Disabled Button 1`] = `
    ,