From 71a9510fc19f02e95eb79fdc2a2df53d08f38707 Mon Sep 17 00:00:00 2001 From: schmanu Date: Thu, 24 Nov 2022 16:05:29 +0100 Subject: [PATCH 1/2] feat: redesign (external) links --- .../address-book/ExportDialog/index.tsx | 10 +++---- .../address-book/ImportDialog/index.tsx | 10 +++---- src/components/common/CookieBanner/index.tsx | 12 ++++---- src/components/common/ErrorBoundary/index.tsx | 5 ++-- src/components/common/ExternalLink/index.tsx | 23 +++++++++++++++ src/components/common/Footer/index.tsx | 29 +++++++++---------- .../PairingDetails/PairingDescription.tsx | 9 +++--- .../load-safe/steps/SetAddressStep.tsx | 21 ++++---------- .../safe-apps/AddCustomAppModal/index.tsx | 17 ++++------- .../AppFrame/ThirdPartyCookiesWarning.tsx | 9 +++--- .../SafeAppsLoadError.tsx | 8 ++--- .../SafeAppsInfoModal/LegalDisclaimer.tsx | 12 +++----- .../ContractVersion/UpdateSafeDialog.tsx | 11 +++---- .../settings/ContractVersion/index.tsx | 16 ++++------ src/components/settings/SafeModules/index.tsx | 7 ++--- .../settings/TransactionGuards/index.tsx | 11 +++---- .../sidebar/SidebarFooter/index.tsx | 2 +- .../transactions/GroupedTxListItems/index.tsx | 13 ++++----- .../TxDetails/TxData/Rejection/index.tsx | 11 ++++--- src/components/transactions/Warning/index.tsx | 9 +++--- .../tx/AdvancedParams/AdvancedParamsForm.tsx | 11 +++---- .../tx/TxSimulation/SimulationResult.tsx | 13 +++------ src/config/constants.ts | 2 +- src/pages/settings/appearance.tsx | 9 +++--- src/styles/theme.ts | 2 +- 25 files changed, 127 insertions(+), 155 deletions(-) create mode 100644 src/components/common/ExternalLink/index.tsx diff --git a/src/components/address-book/ExportDialog/index.tsx b/src/components/address-book/ExportDialog/index.tsx index c7849a921b..7d0f590911 100644 --- a/src/components/address-book/ExportDialog/index.tsx +++ b/src/components/address-book/ExportDialog/index.tsx @@ -1,7 +1,6 @@ import DialogContent from '@mui/material/DialogContent' import DialogActions from '@mui/material/DialogActions' import Button from '@mui/material/Button' -import Link from '@mui/material/Link' import Typography from '@mui/material/Typography' import { useCSVDownloader } from 'react-papaparse' import type { SyntheticEvent } from 'react' @@ -11,6 +10,7 @@ import ModalDialog from '@/components/common/ModalDialog' import { type AddressBookState, selectAllAddressBooks } from '@/store/addressBookSlice' import { useAppSelector } from '@/store' import { trackEvent, ADDRESS_BOOK_EVENTS } from '@/services/analytics' +import ExternalLink from '@/components/common/ExternalLink' const COL_1 = 'address' const COL_2 = 'name' @@ -65,14 +65,12 @@ const ExportDialog = ({ handleClose }: { handleClose: () => void }): ReactElemen - Learn about the address book import and export - + diff --git a/src/components/address-book/ImportDialog/index.tsx b/src/components/address-book/ImportDialog/index.tsx index 87ad7a8274..6a80a7c993 100644 --- a/src/components/address-book/ImportDialog/index.tsx +++ b/src/components/address-book/ImportDialog/index.tsx @@ -1,7 +1,6 @@ import DialogContent from '@mui/material/DialogContent' import DialogActions from '@mui/material/DialogActions' import Button from '@mui/material/Button' -import Link from '@mui/material/Link' import Typography from '@mui/material/Typography' import { useCSVReader, formatFileSize } from 'react-papaparse' import type { ParseResult } from 'papaparse' @@ -17,6 +16,7 @@ import { abCsvReaderValidator, abOnUploadValidator } from './validation' import ErrorMessage from '@/components/tx/ErrorMessage' import { Errors, logError } from '@/services/exceptions' import FileUpload, { FileTypes, type FileInfo } from '@/components/common/FileUpload' +import ExternalLink from '@/components/common/ExternalLink' type AddressBookCSVRow = ['address', 'name', 'chainId'] @@ -153,14 +153,12 @@ const ImportDialog = ({ handleClose }: { handleClose: () => void }): ReactElemen Only CSV files exported from a Safe can be imported.
- Learn about the address book import and export - +
diff --git a/src/components/common/CookieBanner/index.tsx b/src/components/common/CookieBanner/index.tsx index 1ef798d0d1..8bafe69d80 100644 --- a/src/components/common/CookieBanner/index.tsx +++ b/src/components/common/CookieBanner/index.tsx @@ -1,6 +1,6 @@ import type { ReactElement } from 'react' import { useEffect } from 'react' -import { Button, Checkbox, FormControlLabel, Link, Typography, Paper, SvgIcon } from '@mui/material' +import { Button, Checkbox, FormControlLabel, Typography, Paper, SvgIcon } from '@mui/material' import WarningIcon from '@/public/images/notifications/warning.svg' import { useForm } from 'react-hook-form' @@ -9,6 +9,7 @@ import { selectCookies, CookieType, saveCookieConsent } from '@/store/cookiesSli import { selectCookieBanner, openCookieBanner, closeCookieBanner } from '@/store/popupSlice' import css from './styles.module.css' +import ExternalLink from '../ExternalLink' const COOKIE_WARNING: Record = { [CookieType.NECESSARY]: '', @@ -53,12 +54,9 @@ const CookieBannerPopup = ({ warningKey }: { warningKey?: CookieType }): ReactEl We use cookies to provide you with the best experience and to help improve our website and application. Please - read our{' '} - - Cookie Policy - {' '} - for more information. By clicking "Accept all", you agree to the storing of cookies on your device to - enhance site navigation, analyze site usage and provide customer support. + read our Cookie Policy for more information. By + clicking "Accept all", you agree to the storing of cookies on your device to enhance site navigation, + analyze site usage and provide customer support.
diff --git a/src/components/common/ErrorBoundary/index.tsx b/src/components/common/ErrorBoundary/index.tsx index cee9118e0d..e56022a431 100644 --- a/src/components/common/ErrorBoundary/index.tsx +++ b/src/components/common/ErrorBoundary/index.tsx @@ -8,6 +8,7 @@ import WarningIcon from '@/public/images/notifications/warning.svg' import css from '@/components/common/ErrorBoundary/styles.module.css' import CircularIcon from '../icons/CircularIcon' +import ExternalLink from '../ExternalLink' const ErrorBoundary: FallbackRender = ({ error, componentStack }) => { return ( @@ -24,8 +25,8 @@ const ErrorBoundary: FallbackRender = ({ error, componentStack }) => { {IS_PRODUCTION ? ( In case the problem persists, please reach out to us via our{' '} - - Help Center + + Help Center ) : ( diff --git a/src/components/common/ExternalLink/index.tsx b/src/components/common/ExternalLink/index.tsx new file mode 100644 index 0000000000..f8530b8caf --- /dev/null +++ b/src/components/common/ExternalLink/index.tsx @@ -0,0 +1,23 @@ +import { OpenInNewRounded } from '@mui/icons-material' +import { Box, Link, type LinkProps } from '@mui/material' + +/** + * Renders an external Link which always sets the noopener and noreferrer rel attribute and the target to _blank. + * It also always adds the external link icon as end adornment. + */ +const ExternalLink = ({ + suppressIcon = false, + children, + ...props +}: Omit & { suppressIcon?: boolean }) => { + return ( + + + {children} + {!suppressIcon && } + + + ) +} + +export default ExternalLink diff --git a/src/components/common/Footer/index.tsx b/src/components/common/Footer/index.tsx index ea59f9fa0d..5ecc87e9c5 100644 --- a/src/components/common/Footer/index.tsx +++ b/src/components/common/Footer/index.tsx @@ -7,6 +7,7 @@ import { openCookieBanner } from '@/store/popupSlice' import { AppRoutes } from '@/config/routes' import packageJson from '../../../../package.json' import AppstoreButton from '../AppStoreButton' +import ExternalLink from '../ExternalLink' const footerPages = [AppRoutes.welcome, AppRoutes.settings.index] @@ -30,42 +31,38 @@ const Footer = (): ReactElement | null => { ©2022 Safe Ecosystem Foundation
  • - + Terms - +
  • - + Privacy - +
  • - + Licenses - +
  • - + Imprint - +
  • - + Cookie Policy - +  —  Preferences
  • - + v{packageJson.version} - +
  • diff --git a/src/components/common/PairingDetails/PairingDescription.tsx b/src/components/common/PairingDetails/PairingDescription.tsx index f90811d6dc..85df5ca1aa 100644 --- a/src/components/common/PairingDetails/PairingDescription.tsx +++ b/src/components/common/PairingDetails/PairingDescription.tsx @@ -1,9 +1,10 @@ -import { Typography, Link } from '@mui/material' +import { Typography } from '@mui/material' import type { ReactElement } from 'react' import AppStoreButton from '@/components/common/AppStoreButton' +import ExternalLink from '../ExternalLink' -const HELP_ARTICLE = 'https://help.gnosis-safe.io/en/articles/5584901-desktop-pairing' +const HELP_ARTICLE = 'https://help.safe.global/en/articles/5584901-desktop-pairing' const PairingDescription = (): ReactElement => { return ( @@ -11,9 +12,9 @@ const PairingDescription = (): ReactElement => { Scan this code in the Safe mobile app to sign transactions with your mobile device.
    - + Learn more about this feature. - +
    diff --git a/src/components/load-safe/steps/SetAddressStep.tsx b/src/components/load-safe/steps/SetAddressStep.tsx index f9b4a5dcac..aea1981a5b 100644 --- a/src/components/load-safe/steps/SetAddressStep.tsx +++ b/src/components/load-safe/steps/SetAddressStep.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { Box, Button, CircularProgress, Divider, Grid, InputAdornment, Link, Paper, Typography } from '@mui/material' +import { Box, Button, CircularProgress, Divider, Grid, InputAdornment, Paper, Typography } from '@mui/material' import { useForm, FormProvider } from 'react-hook-form' import type { StepRenderProps } from '@/components/tx/TxStepper/useTxStepper' import ChainIndicator from '@/components/common/ChainIndicator' @@ -13,6 +13,7 @@ import { useAddressResolver } from '@/hooks/useAddressResolver' import { useMnemonicSafeName } from '@/hooks/useMnemonicName' import type { SafeFormData } from '@/components/create-safe/types' import { trackEvent, LOAD_SAFE_EVENTS } from '@/services/analytics' +import ExternalLink from '@/components/common/ExternalLink' type Props = { params: SafeFormData @@ -90,13 +91,9 @@ const SetAddressStep = ({ params, onSubmit, onBack }: Props) => { Don't have the address of the Safe you created?{' '} - + This article explains how to find it. - + @@ -121,14 +118,8 @@ const SetAddressStep = ({ params, onSubmit, onBack }: Props) => { By continuing you consent to the{' '} - - terms of use - {' '} - and{' '} - - privacy policy - - . + terms of use and{' '} + privacy policy. diff --git a/src/components/safe-apps/AddCustomAppModal/index.tsx b/src/components/safe-apps/AddCustomAppModal/index.tsx index c3926a2abd..086e87bc0b 100644 --- a/src/components/safe-apps/AddCustomAppModal/index.tsx +++ b/src/components/safe-apps/AddCustomAppModal/index.tsx @@ -9,7 +9,6 @@ import { TextField, FormControlLabel, Checkbox, - Link, Box, FormHelperText, } from '@mui/material' @@ -29,6 +28,7 @@ import CustomAppPlaceholder from './CustomAppPlaceholder' import CustomApp from './CustomApp' import css from './styles.module.css' +import ExternalLink from '@/components/common/ExternalLink' type Props = { open: boolean @@ -44,7 +44,7 @@ type CustomAppFormData = { safeApp: SafeAppData } -const HELP_LINK = 'https://docs.gnosis-safe.io/build/sdks/safe-apps' +const HELP_LINK = 'https://docs.safe.global/build/sdks/safe-apps' const APP_ALREADY_IN_THE_LIST_ERROR = 'This app is already in the list' const MANIFEST_ERROR = "The app doesn't support Safe App functionality" const INVALID_URL_ERROR = 'The url is invalid' @@ -152,15 +152,10 @@ export const AddCustomAppModal = ({ open, onClose, onSave, safeAppsList }: Props
    Learn more about building - - Safe Apps. - + + Safe Apps + + .
    diff --git a/src/components/safe-apps/AppFrame/ThirdPartyCookiesWarning.tsx b/src/components/safe-apps/AppFrame/ThirdPartyCookiesWarning.tsx index 8498b996b3..d7fad84130 100644 --- a/src/components/safe-apps/AppFrame/ThirdPartyCookiesWarning.tsx +++ b/src/components/safe-apps/AppFrame/ThirdPartyCookiesWarning.tsx @@ -1,12 +1,13 @@ import React from 'react' -import { Alert, Link, AlertTitle } from '@mui/material' +import { Alert, AlertTitle } from '@mui/material' +import ExternalLink from '@/components/common/ExternalLink' type ThirdPartyCookiesWarningProps = { onClose: () => void } const HELP_LINK = - 'https://help.gnosis-safe.io/en/articles/5955031-why-do-i-need-to-enable-third-party-cookies-for-safe-apps' + 'https://help.safe.global/en/articles/5955031-why-do-i-need-to-enable-third-party-cookies-for-safe-apps' export const ThirdPartyCookiesWarning = ({ onClose }: ThirdPartyCookiesWarningProps): React.ReactElement => { return ( @@ -23,9 +24,9 @@ export const ThirdPartyCookiesWarning = ({ onClose }: ThirdPartyCookiesWarningPr Third party cookies are disabled. Safe Apps may therefore not work properly. You can find out more information about this{' '} - + here - + ) diff --git a/src/components/safe-apps/SafeAppsErrorBoundary/SafeAppsLoadError.tsx b/src/components/safe-apps/SafeAppsErrorBoundary/SafeAppsLoadError.tsx index d70cbf6938..6fdb58f249 100644 --- a/src/components/safe-apps/SafeAppsErrorBoundary/SafeAppsLoadError.tsx +++ b/src/components/safe-apps/SafeAppsErrorBoundary/SafeAppsLoadError.tsx @@ -1,12 +1,11 @@ import Typography from '@mui/material/Typography' -import Link from '@mui/material/Link' import Button from '@mui/material/Button' import SvgIcon from '@mui/material/SvgIcon' -import OpenInNew from '@mui/icons-material/OpenInNew' import { SAFE_APPS_SUPPORT_CHAT_URL } from '@/config/constants' import NetworkError from '@/public/images/apps/network-error.svg' import css from './styles.module.css' +import ExternalLink from '@/components/common/ExternalLink' type SafeAppsLoadErrorProps = { onBackToApps: () => void @@ -22,10 +21,9 @@ const SafeAppsLoadError = ({ onBackToApps }: SafeAppsLoadErrorProps): React.Reac
    In case the problem persists, please reach out to us via - + Discord - - +