From 0f5137ea2476ccc985ee1a335eb14bafba341267 Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Tue, 29 Mar 2022 17:09:23 +0100 Subject: [PATCH] Add storybook to nym-wallet --- .github/workflows/nym-wallet-storybook.yml | 55 ++++++++++++++++++ .../notifications/send_message.js | 2 +- .../support-files/nym-wallet/index.js | 29 ++++++++++ .../nym-wallet/templates/failure | 11 ++++ .../nym-wallet/templates/success | 15 +++++ nym-wallet/.storybook/main.js | 57 +++++++++++++++++++ nym-wallet/.storybook/mocks/tauri/index.js | 13 +++++ nym-wallet/.storybook/mocks/tauri/window.js | 10 ++++ nym-wallet/.storybook/preview.js | 19 +++++++ nym-wallet/package.json | 12 +++- .../src/stories/Introduction.stories.mdx | 7 +++ nym-wallet/src/theme/NymWalletTheme.tsx | 15 +++++ package.json | 3 +- 13 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/nym-wallet-storybook.yml create mode 100644 .github/workflows/support-files/nym-wallet/index.js create mode 100644 .github/workflows/support-files/nym-wallet/templates/failure create mode 100644 .github/workflows/support-files/nym-wallet/templates/success create mode 100644 nym-wallet/.storybook/main.js create mode 100644 nym-wallet/.storybook/mocks/tauri/index.js create mode 100644 nym-wallet/.storybook/mocks/tauri/window.js create mode 100644 nym-wallet/.storybook/preview.js create mode 100644 nym-wallet/src/stories/Introduction.stories.mdx create mode 100644 nym-wallet/src/theme/NymWalletTheme.tsx diff --git a/.github/workflows/nym-wallet-storybook.yml b/.github/workflows/nym-wallet-storybook.yml new file mode 100644 index 0000000000..b7930ed200 --- /dev/null +++ b/.github/workflows/nym-wallet-storybook.yml @@ -0,0 +1,55 @@ +name: Nym Wallet Storybook + +on: + push: + paths: + - 'nym-wallet/**' + +jobs: + build: + runs-on: custom-runner-linux + steps: + - uses: actions/checkout@v2 + - name: Install rsync + run: sudo apt-get install rsync + - uses: rlespinasse/github-slug-action@v3.x + - uses: actions/setup-node@v2 + with: + node-version: '16' + - name: Setup yarn + run: npm install -g yarn + - name: Build dependencies + run: yarn && yarn build + - name: Build storybook + run: yarn storybook:build + working-directory: ./nym-wallet + - name: Deploy branch to CI www (storybook) + continue-on-error: true + uses: easingthemes/ssh-deploy@main + env: + SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }} + ARGS: "-rltgoDzvO --delete" + SOURCE: "nym-wallet/storybook-static/" + REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }} + REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }} + TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/wallet-${{ env.GITHUB_REF_SLUG }} + EXCLUDE: "/dist/, /node_modules/" + - name: Keybase - Node Install + run: npm install + working-directory: .github/workflows/support-files + - name: Keybase - Send Notification + env: + NYM_NOTIFICATION_KIND: nym-wallet + NYM_PROJECT_NAME: "nym-wallet" + NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}" + NYM_CI_WWW_LOCATION: "wallet-${{ env.GITHUB_REF_SLUG }}" + GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}" + GIT_BRANCH: "${GITHUB_REF##*/}" + KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}" + KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}" + KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}" + KEYBASE_NYM_CHANNEL: "ci-nym-wallet" + IS_SUCCESS: "${{ job.status == 'success' }}" + uses: docker://keybaseio/client:stable-node + with: + args: .github/workflows/support-files/notifications/entry_point.sh diff --git a/.github/workflows/support-files/notifications/send_message.js b/.github/workflows/support-files/notifications/send_message.js index fa95444192..eacd5af1ed 100644 --- a/.github/workflows/support-files/notifications/send_message.js +++ b/.github/workflows/support-files/notifications/send_message.js @@ -3,7 +3,7 @@ require('dotenv').config(); const Bot = require('keybase-bot'); let context = { - kinds: ['ts-packages', 'network-explorer', 'nightly'], + kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly'], }; /** diff --git a/.github/workflows/support-files/nym-wallet/index.js b/.github/workflows/support-files/nym-wallet/index.js new file mode 100644 index 0000000000..be74285c12 --- /dev/null +++ b/.github/workflows/support-files/nym-wallet/index.js @@ -0,0 +1,29 @@ +const Handlebars = require('handlebars'); +const fs = require('fs'); +const path = require('path'); + +async function addToContextAndValidate(context) { + if (!context.env.NYM_CI_WWW_LOCATION) { + throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set'); + } + if (!context.env.NYM_CI_WWW_BASE) { + throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set'); + } +} + +async function getMessageBody(context) { + const source = fs + .readFileSync( + context.env.IS_SUCCESS === 'true' + ? path.resolve(__dirname, 'templates', 'success') + : path.resolve(__dirname, 'templates', 'failure'), + ) + .toString(); + const template = Handlebars.compile(source); + return template(context); +} + +module.exports = { + addToContextAndValidate, + getMessageBody, +}; diff --git a/.github/workflows/support-files/nym-wallet/templates/failure b/.github/workflows/support-files/nym-wallet/templates/failure new file mode 100644 index 0000000000..adc2896ace --- /dev/null +++ b/.github/workflows/support-files/nym-wallet/templates/failure @@ -0,0 +1,11 @@ +🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥 +> :rocket: {{ env.NYM_PROJECT_NAME }} +> 🔴 **FAILURE** :cry: +> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }} +> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }} +> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }} + +Commit message: +``` +{{ env.GIT_COMMIT_MESSAGE }} +``` diff --git a/.github/workflows/support-files/nym-wallet/templates/success b/.github/workflows/support-files/nym-wallet/templates/success new file mode 100644 index 0000000000..826f75e977 --- /dev/null +++ b/.github/workflows/support-files/nym-wallet/templates/success @@ -0,0 +1,15 @@ +🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 +> :rocket: {{ env.NYM_PROJECT_NAME }} +> ✅ **SUCCESS** + +> ➡️➡️➡️➡️➡️ **View output:** +> `storybook`: https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }} + +> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }} +> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }} +> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }} + +Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}: +``` +{{ env.GIT_COMMIT_MESSAGE }} +``` diff --git a/nym-wallet/.storybook/main.js b/nym-wallet/.storybook/main.js new file mode 100644 index 0000000000..db6de0998f --- /dev/null +++ b/nym-wallet/.storybook/main.js @@ -0,0 +1,57 @@ +/* eslint-disable no-param-reassign */ +const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], + addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-interactions'], + framework: '@storybook/react', + core: { + builder: 'webpack5', + }, + // webpackFinal: async (config, { configType }) => { + // // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION' + // // You can change the configuration based on that. + // // 'PRODUCTION' is used when building the static version of storybook. + webpackFinal: async (config) => { + config.module.rules.forEach((rule) => { + // look for SVG import rule and replace + // NOTE: the rule before modification is /\.(svg|ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/ + if (rule.test?.toString().includes('svg')) { + rule.test = /\.(ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/; + } + }); + + // handle asset loading with this + config.module.rules.unshift({ + test: /\.svg(\?.*)?$/i, + issuer: /\.[jt]sx?$/, + use: ['@svgr/webpack'], + }); + + config.resolve.extensions = ['.tsx', '.ts', '.js']; + config.resolve.plugins = [new TsconfigPathsPlugin()]; + + config.plugins.push(new ForkTsCheckerWebpackPlugin({ + typescript: { + mode: 'write-references', + diagnosticOptions: { + semantic: true, + syntactic: true, + }, + }, + })); + + if (!config.resolve.alias) { + config.resolve.alias = {}; + } + + config.resolve.alias['@tauri-apps/api'] = `${__dirname}/mocks/tauri`; + + // Return the altered config + return config; + }, + features: { + emotionAlias: false, + }, +}; diff --git a/nym-wallet/.storybook/mocks/tauri/index.js b/nym-wallet/.storybook/mocks/tauri/index.js new file mode 100644 index 0000000000..1288b5215f --- /dev/null +++ b/nym-wallet/.storybook/mocks/tauri/index.js @@ -0,0 +1,13 @@ +/** + * This is a mock for Tauri's API package (@tauri-apps/api), to prevent stories from being excluded, because they either use + * or import dependencies that use Tauri. + */ + +module.exports = { + invoke: (operation) => { + console.error(`Tauri cannot be used in Storybook. The operation requested was "${operation}". You can add mock responses to "nym_wallet/.storybook/mocks/tauri.js" if you need. The default response is "void".`); + return new Promise((resolve, reject) => { + reject(new Error(`Tauri operation ${operation} not available in storybook.`)); + }); + }, +} \ No newline at end of file diff --git a/nym-wallet/.storybook/mocks/tauri/window.js b/nym-wallet/.storybook/mocks/tauri/window.js new file mode 100644 index 0000000000..9f0afeeebd --- /dev/null +++ b/nym-wallet/.storybook/mocks/tauri/window.js @@ -0,0 +1,10 @@ +/** + * This is a mock for Tauri's API package (@tauri-apps/api/window), to prevent stories from being excluded, because they either use + * or import dependencies that use Tauri. + */ + +module.exports = { + appWindow: { + maximize: () => undefined, + } +} diff --git a/nym-wallet/.storybook/preview.js b/nym-wallet/.storybook/preview.js new file mode 100644 index 0000000000..73ab87b2dd --- /dev/null +++ b/nym-wallet/.storybook/preview.js @@ -0,0 +1,19 @@ +import { NymWalletThemeWithMode } from '../src/theme/NymWalletTheme'; + +export const parameters = { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, +} + +const withThemeProvider = (Story, context) => ( + + + +); + +export const decorators = [withThemeProvider]; diff --git a/nym-wallet/package.json b/nym-wallet/package.json index 1e83032807..299b34b39f 100644 --- a/nym-wallet/package.json +++ b/nym-wallet/package.json @@ -10,11 +10,15 @@ "tauri:dev": "yarn tauri dev", "tauri:build": "yarn tauri build", "tsc": "tsc --noEmit true", + "tsc:watch": "tsc --noEmit true --watch", "dev": "yarn run webpack:dev & yarn run tauri:dev", "prebuild": "yarn --cwd .. build", "build": "run-s webpack:prod tauri:build", "lint": "eslint src", - "lint:fix": "eslint src --fix" + "lint:fix": "eslint src --fix", + "prestorybook": "yarn --cwd .. build", + "storybook": "start-storybook -p 6006", + "storybook:build": "build-storybook" }, "dependencies": { "@babel/preset-typescript": "^7.15.0", @@ -47,6 +51,12 @@ "@babel/preset-react": "^7.14.5", "@nymproject/eslint-config-react-typescript": "^1.0.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", + "@storybook/addon-actions": "^6.4.19", + "@storybook/addon-essentials": "^6.4.19", + "@storybook/addon-interactions": "^6.4.19", + "@storybook/addon-links": "^6.4.19", + "@storybook/react": "^6.4.19", + "@storybook/testing-library": "^0.0.9", "@svgr/webpack": "^6.1.1", "@tauri-apps/cli": "^1.0.0-rc.5", "@testing-library/jest-dom": "^5.14.1", diff --git a/nym-wallet/src/stories/Introduction.stories.mdx b/nym-wallet/src/stories/Introduction.stories.mdx new file mode 100644 index 0000000000..c22001164e --- /dev/null +++ b/nym-wallet/src/stories/Introduction.stories.mdx @@ -0,0 +1,7 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Nym Wallet Storybook + +This is the Storybook for the Nym Wallet. diff --git a/nym-wallet/src/theme/NymWalletTheme.tsx b/nym-wallet/src/theme/NymWalletTheme.tsx new file mode 100644 index 0000000000..0b7ee87f90 --- /dev/null +++ b/nym-wallet/src/theme/NymWalletTheme.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { CssBaseline, PaletteMode } from '@mui/material'; +import { createTheme, ThemeProvider } from '@mui/material/styles'; +import { getDesignTokens } from './theme'; +import '@assets/fonts/fonts.css'; + +export const NymWalletThemeWithMode: React.FC<{ mode: PaletteMode }> = ({ mode, children }) => { + const theme = React.useMemo(() => createTheme(getDesignTokens(mode)), [mode]); + return ( + + + {children} + + ); +}; diff --git a/package.json b/package.json index 27039fe423..da52f34d1e 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "explorer" ], "scripts": { - "build": "lerna run --scope @nymproject/mui-theme --scope @nymproject/react build --stream", + "build": "run-s build:packages", + "build:packages": "lerna run --scope @nymproject/mui-theme --scope @nymproject/react --stream build", "build:react-example": "lerna run --scope @nymproject/react-webpack-with-theme-example build --stream", "build:playground": "lerna run --scope @nymproject/react storybook:build --stream", "build:ci": "yarn build && run-p build:react-example build:playground && yarn build:ci:collect-artifacts",