Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

Commit

Permalink
feat: improve analytics (#3415)
Browse files Browse the repository at this point in the history
* feat: add Google Tag Manager

* fix: load GTM from cookie banner (#3417)

* fix: load GTM from cookie banner

* fix: GTM env init check

* fix: move gtm dev env to env var

* feat: create `Track` HoC (#3421)

* feat: create `Track` HoC

* fix: remove unnecessary `undefined` check

* fix: prop names/type tweak + conditional payload

* fix: short props, throw when Fragment + add tests

* fix: rename file extension

* fix: migrate anonymous page tracking to GTM (#3426)

* fix: migrate pageview tracking to GTM

* fix: cleanup event emission

* fix: add chain data to tracking (#3523)

* fix: add chain data to tracking + cross-env tests

* fix: separate chain data from payload

* fix: track `shortName` instead of `chainName`

* feat: track create/load Safe (#3553)

* feat: track create/load Safe steppers

* fix: payload tracking in Safe create/load

* fix: Track Safe creation events

* fix: rename event + remove unnecessary var

* fix: payload test

Co-authored-by: Usame Algan <usame.algan@gnosis.pm>

* [Analytics] Track overview layout (#3606)

* feat: track create/load Safe steppers

* fix: payload tracking in Safe create/load

* fix: Track Safe creation events

* fix: rename event + remove unnecessary var

* fix: payload test

* wrap overview buttons with <Track /> HOC

* fix: Adjust structure of dataLayer object for trackEvent call

* refactor: Extract track variables

* chore: Revert method name refactor

* refactor: Move safe overview tags to its own file

* feat: Add tracking to currency change, intercom and help center

* fix: Remove spreads where possible

* fix: failing test

Co-authored-by: iamacook <aaron.cook@gnosis.pm>
Co-authored-by: Usame Algan <usame.algan@gnosis.pm>

* fix: remove GA (#3613)

* fix: remove GA

* fix: remove GA from test

* chore: add GTM env vars to deploy script

* Merge branch 'dev' into improve-analytics

* fix: top-level tracking (#3659)

* fix: top level tracking + unload tracking

* fix: use shorthand

* fix: add dependency

* fix: tracking events

* fix: track via listener

* fix: `waitFor` event listener

* fix: lint

* fix: add GA `eventValue` + centralise events

* fix: cleanup

* fix: `currentStep` as value

* fix: remove `eventValue` + less verbose events

* fix: add dependency

* fix: use ref in variable

* fix: test

* fix: check that GTM is loaded + remove comment

* fix: return early

* fix: track all events (#3675)

* fix: add legacy events

* fix: incorrect events

* fix: remove unnecessary dependencies

* feat: add new tracking events

* fix: test

* fix: memoize tracking + always init GTM

* fix: spending limit tracking label

* fix: rm `navigation` category + rm `pageview` vars

* fix: remove memoization

* fix: track wallet, (un-)pin/named Safe Apps, App click

* fix: use campaign link for iPhone app

* fix: only log differeng tokens after fetch

* fix: tweak events + don't trigger GA on dev (#3715)

* fix: events + don't trigger GA on dev env

* fix: remove dev flag from events

* fix: only track changing `pathname`

* fix: don't cache anonymised path

Co-authored-by: Usame Algan <usame.algan@gnosis.pm>
Co-authored-by: Diogo Soares <32431609+DiogoSoaress@users.noreply.github.com>
Co-authored-by: katspaugh <381895+katspaugh@users.noreply.github.com>
  • Loading branch information
4 people authored Mar 24, 2022
1 parent 2365323 commit 5ec343f
Show file tree
Hide file tree
Showing 83 changed files with 1,655 additions and 666 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ env:
REPO_NAME_ALPHANUMERIC: safereact
STAGING_BUCKET_NAME: ${{ secrets.STAGING_BUCKET_NAME }}
REACT_APP_SENTRY_DSN: ${{ secrets.SENTRY_DSN_MAINNET }}
REACT_APP_GOOGLE_ANALYTICS: ${{ secrets.REACT_APP_GOOGLE_ANALYTICS_ID_MAINNET }}
REACT_APP_ETHERSCAN_API_KEY: ${{ secrets.REACT_APP_ETHERSCAN_API_KEY }}
REACT_APP_ETHGASSTATION_API_KEY: ${{ secrets.REACT_APP_ETHGASSTATION_API_KEY }}

Expand Down Expand Up @@ -93,6 +92,9 @@ jobs:
REACT_APP_INTERCOM_ID: ${{ secrets.REACT_APP_INTERCOM_ID }}
REACT_APP_BEAMER_ID: ${{ secrets.REACT_APP_BEAMER_ID }}
REACT_APP_IPFS_GATEWAY: ${{ secrets.REACT_APP_IPFS_GATEWAY }}
REACT_APP_GOOGLE_TAG_MANAGER_ID: ${{ secrets.REACT_APP_GOOGLE_TAG_MANAGER_ID }}
REACT_APP_GOOGLE_TAG_MANAGER_LIVE_AUTH: ${{ secrets.REACT_APP_GOOGLE_TAG_MANAGER_LIVE_AUTH }}
REACT_APP_GOOGLE_TAG_MANAGER_DEVELOPMENT_AUTH: ${{ secrets.REACT_APP_GOOGLE_TAG_MANAGER_DEVELOPMENT_AUTH }}

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"prettier": "prettier './src/**/*.{js,jsx,ts,tsx}'",
"start": "rescripts start",
"start:docker": "docker-compose build && docker-compose up",
"test": "REACT_APP_ENV=test rescripts test --env=jsdom",
"test": "cross-env REACT_APP_ENV=test rescripts test --env=jsdom",
"test:coverage": "REACT_APP_ENV=test yarn test --coverage --watchAll=false",
"test:ci": "REACT_APP_ENV=test yarn test --ci --coverage --json --watchAll=false --testLocationInResults --runInBand --outputFile=jest.results.json",
"update-mocks": "./scripts/update-mocks.sh",
Expand Down Expand Up @@ -124,7 +124,7 @@
"react-dom": "17.0.2",
"react-final-form": "^6.5.3",
"react-final-form-listeners": "^1.0.2",
"react-ga": "3.3.0",
"react-gtm-module": "^2.0.11",
"react-intersection-observer": "^8.32.0",
"react-papaparse": "^3.16.1",
"react-qr-reader": "^2.2.1",
Expand Down Expand Up @@ -160,6 +160,7 @@
"@types/node": "^16.9.1",
"@types/react": "^17.0.21",
"@types/react-dom": "^17.0.9",
"@types/react-gtm-module": "^2.0.1",
"@types/react-redux": "^7.1.18",
"@types/react-router-dom": "^5.1.9",
"@types/redux-actions": "^2.6.2",
Expand Down
5 changes: 4 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
<title>Gnosis Safe</title>

<meta property="og:title" content="Gnosis Safe" />
<meta property="og:description" content="Gnosis Safe is the most trusted platform to manage digital assets on Ethereum" />
<meta
property="og:description"
content="Gnosis Safe is the most trusted platform to manage digital assets on Ethereum"
/>
<meta property="og:image" content="%PUBLIC_URL%/resources/og-image.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="%PUBLIC_URL%/resources/og-image.png" />
Expand Down
10 changes: 7 additions & 3 deletions src/components/AppLayout/Header/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import WalletSwitch from 'src/components/WalletSwitch'
import Divider from 'src/components/layout/Divider'
import { shouldSwitchWalletChain } from 'src/logic/wallets/store/selectors'
import { useSelector } from 'react-redux'
import { OVERVIEW_EVENTS } from 'src/utils/events/overview'
import Track from 'src/components/Track'

const styles = () => ({
root: {
Expand Down Expand Up @@ -95,9 +97,11 @@ const Layout = ({ classes, providerDetails, providerInfo }) => {
return (
<Row className={classes.summary}>
<Col className={classes.logo} middle="xs" start="xs">
<Link to={WELCOME_ROUTE}>
<Img alt="Gnosis Safe" height={36} src={SafeLogo} testId="heading-gnosis-logo" id="safe-logo" />
</Link>
<Track {...OVERVIEW_EVENTS.HOME}>
<Link to={WELCOME_ROUTE}>
<Img alt="Gnosis Safe" height={36} src={SafeLogo} testId="heading-gnosis-logo" id="safe-logo" />
</Link>
</Track>
</Col>

<Spacer />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { useSelector } from 'react-redux'
import { currentChainId } from 'src/logic/config/store/selectors'
import { getChainById } from 'src/config'
import { ChainId } from 'src/config/chain.d'
import { trackEvent } from 'src/utils/googleTagManager'
import { OVERVIEW_EVENTS } from 'src/utils/events/overview'

const styles = {
root: {
Expand Down Expand Up @@ -90,6 +92,8 @@ const NetworkSelector = ({ open, toggle, clickAway }: NetworkSelectorProps): Rea
e.preventDefault()
clickAway()

trackEvent({ ...OVERVIEW_EVENTS.SWITCH_NETWORK, label: chainId })

const newRoute = getNetworkRootRoutes().find((network) => network.chainId === chainId)
if (newRoute) {
history.push(newRoute.route)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import Row from 'src/components/layout/Row'
import usePairing from 'src/logic/wallets/pairing/hooks/usePairing'
import { initPairing, isPairingModule } from 'src/logic/wallets/pairing/utils'
import { useGetPairingUri } from 'src/logic/wallets/pairing/hooks/useGetPairingUri'
import { OVERVIEW_EVENTS } from 'src/utils/events/overview'
import Track from 'src/components/Track'
import AppstoreButton from 'src/components/AppstoreButton'

const StyledDivider = styled(Divider)`
Expand Down Expand Up @@ -55,16 +57,22 @@ const PairingDetails = ({ classes }: { classes: Record<string, string> }): React
<Row>
<Paragraph className={classes.centerText} size="sm">
Scan this code in the{' '}
<Link href="https://apps.apple.com/us/app/gnosis-safe/id1515759131">Gnosis Safe app</Link> to sign
transactions with your mobile device.
<Track {...OVERVIEW_EVENTS.IPHONE_APP_BUTTON}>
<Link href="https://apps.apple.com/app/apple-store/id1515759131?pt=119497694&ct=Web%20App%20Connect&mt=8">
Gnosis Safe app
</Link>
</Track>{' '}
to sign transactions with your mobile device.
<br />
<Link href="https://help.gnosis-safe.io/en/articles/5584901-desktop-pairing">Learn more</Link> about this
feature.
</Paragraph>
</Row>

<Row className={classes.justifyCenter}>
<AppstoreButton placement="pairing" />
<Track {...OVERVIEW_EVENTS.IPHONE_APP_BUTTON}>
<AppstoreButton placement="pairing" />
</Track>
</Row>
</>
)
Expand Down
38 changes: 27 additions & 11 deletions src/components/AppLayout/Sidebar/SafeHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { ChainInfo } from '@gnosis.pm/safe-react-gateway-sdk'
import PrefixedEthHashInfo from 'src/components/PrefixedEthHashInfo'
import { copyShortNameSelector } from 'src/logic/appearance/selectors'
import { ADDRESSED_ROUTE, extractShortChainName } from 'src/routes/routes'
import Track from 'src/components/Track'
import { OVERVIEW_EVENTS } from 'src/utils/events/overview'
import Threshold from 'src/components/AppLayout/Sidebar/Threshold'

export const TOGGLE_SIDEBAR_BTN_TESTID = 'TOGGLE_SIDEBAR_BTN'
Expand Down Expand Up @@ -173,11 +175,17 @@ const SafeHeader = ({
</StyledTextSafeName>
<StyledPrefixedEthHashInfo hash={address} shortenHash={4} textSize="sm" />
<IconContainer>
<ButtonHelper onClick={onReceiveClick}>
<Icon size="sm" type="qrCode" tooltip="Show QR" />
</ButtonHelper>
<CopyToClipboardBtn textToCopy={copyChainPrefix ? `${shortName}:${address}` : `${address}`} />
<ExplorerButton explorerUrl={getExplorerInfo(address)} />
<Track {...OVERVIEW_EVENTS.SHOW_QR}>
<ButtonHelper onClick={onReceiveClick}>
<Icon size="sm" type="qrCode" tooltip="Show QR code" />
</ButtonHelper>
</Track>
<Track {...OVERVIEW_EVENTS.COPY_ADDRESS}>
<CopyToClipboardBtn textToCopy={copyChainPrefix ? `${shortName}:${address}` : `${address}`} />
</Track>
<Track {...OVERVIEW_EVENTS.OPEN_EXPLORER}>
<ExplorerButton explorerUrl={getExplorerInfo(address)} />
</Track>
</IconContainer>

{!granted && (
Expand All @@ -189,12 +197,20 @@ const SafeHeader = ({
)}

<StyledText size="xl">{balance}</StyledText>
<StyledButton size="md" disabled={!granted} color="primary" variant="contained" onClick={onNewTransactionClick}>
<FixedIcon type="arrowSentWhite" />
<Text size="xl" color="white">
New transaction
</Text>
</StyledButton>
<Track {...OVERVIEW_EVENTS.NEW_TRANSACTION}>
<StyledButton
size="md"
disabled={!granted}
color="primary"
variant="contained"
onClick={onNewTransactionClick}
>
<FixedIcon type="arrowSentWhite" />
<Text size="xl" color="white">
New transaction
</Text>
</StyledButton>
</Track>
</Container>
</>
)
Expand Down
22 changes: 14 additions & 8 deletions src/components/AppLayout/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import List, { ListItemType, StyledListItem, StyledListItemText } from 'src/comp
import SafeHeader from './SafeHeader'
import { IS_PRODUCTION, BEAMER_ID } from 'src/utils/constants'
import { wrapInSuspense } from 'src/utils/wrapInSuspense'
import Track from 'src/components/Track'
import { OVERVIEW_EVENTS } from 'src/utils/events/overview'
import ListIcon from 'src/components/List/ListIcon'
import { openCookieBanner } from 'src/logic/cookies/store/actions/openCookieBanner'
import { loadFromCookie } from 'src/logic/cookies/utils'
Expand Down Expand Up @@ -125,16 +127,20 @@ const Sidebar = ({

<HelpList>
{!isDesktop && BEAMER_ID && (
<StyledListItem id="whats-new-button" button onClick={handleClick}>
<ListIcon type="gift" />
<StyledListItemText>What&apos;s new</StyledListItemText>
</StyledListItem>
<Track {...OVERVIEW_EVENTS.WHATS_NEW}>
<StyledListItem id="whats-new-button" button onClick={handleClick}>
<ListIcon type="gift" />
<StyledListItemText>What&apos;s new</StyledListItemText>
</StyledListItem>
</Track>
)}

<HelpCenterLink href="https://help.gnosis-safe.io/en/" target="_blank" title="Help Center of Gnosis Safe">
<ListIcon type="question" />
<StyledListItemText>Help Center</StyledListItemText>
</HelpCenterLink>
<Track {...OVERVIEW_EVENTS.HELP_CENTER}>
<HelpCenterLink href="https://help.gnosis-safe.io/en/" target="_blank" title="Help Center of Gnosis Safe">
<ListIcon type="question" />
<StyledListItemText>Help Center</StyledListItemText>
</HelpCenterLink>
</Track>
</HelpList>
</HelpContainer>
</>
Expand Down
10 changes: 7 additions & 3 deletions src/components/ConnectButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { ReactElement } from 'react'

import Button from 'src/components/layout/Button'
import onboard, { checkWallet } from 'src/logic/wallets/onboard'
import { OVERVIEW_EVENTS } from 'src/utils/events/overview'
import Track from '../Track'

export const onConnectButtonClick = async (): Promise<void> => {
const walletSelected = await onboard().walletSelect()
Expand All @@ -13,9 +15,11 @@ export const onConnectButtonClick = async (): Promise<void> => {
}

const ConnectButton = (props: { 'data-testid': string }): ReactElement => (
<Button color="primary" minWidth={240} onClick={onConnectButtonClick} variant="contained" {...props}>
Connect
</Button>
<Track {...OVERVIEW_EVENTS.ONBOARD}>
<Button color="primary" minWidth={240} onClick={onConnectButtonClick} variant="contained" {...props}>
Connect
</Button>
</Track>
)

export default ConnectButton
6 changes: 3 additions & 3 deletions src/components/CookiesBanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import { closeCookieBanner, openCookieBanner } from 'src/logic/cookies/store/act
import { cookieBannerState } from 'src/logic/cookies/store/selectors'
import { loadFromCookie, saveCookie } from 'src/logic/cookies/utils'
import { mainFontFamily, md, primary, screenSm } from 'src/theme/variables'
import { loadGoogleAnalytics, unloadGoogleAnalytics } from 'src/utils/googleAnalytics'
import { closeIntercom, isIntercomLoaded, loadIntercom } from 'src/utils/intercom'
import AlertRedIcon from './assets/alert-red.svg'
import IntercomIcon from './assets/intercom.png'
import { useSafeAppUrl } from 'src/logic/hooks/useSafeAppUrl'
import { loadGoogleTagManager, unloadGoogleTagManager } from 'src/utils/googleTagManager'
import { loadBeamer, unloadBeamer } from 'src/utils/beamer'

const isDesktop = process.env.REACT_APP_BUILD_FOR_DESKTOP
Expand Down Expand Up @@ -270,9 +270,9 @@ const CookiesBanner = isDesktop
setLocalAnalytics(acceptedAnalytics)
}, [setLocalNecessary, setLocalSupportAndUpdates, setLocalAnalytics, openBanner])

// Load or unload analytics depending on user choice
// Load or unload GTM depending on user choice
useEffect(() => {
localAnalytics ? loadGoogleAnalytics() : unloadGoogleAnalytics()
localAnalytics ? loadGoogleTagManager() : unloadGoogleTagManager()
}, [localAnalytics])

// Toggle Intercom
Expand Down
7 changes: 5 additions & 2 deletions src/components/ExecuteCheckbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { sm } from 'src/theme/variables'
import Row from 'src/components/layout/Row'
import Img from 'src/components/layout/Img'
import InfoIcon from 'src/assets/icons/info.svg'
import { trackEvent } from 'src/utils/googleTagManager'
import { MODALS_EVENTS } from 'src/utils/events/modals'

const StyledRow = styled(Row)`
align-items: center;
Expand All @@ -28,8 +30,9 @@ interface ExecuteCheckboxProps {
}

const ExecuteCheckbox = ({ checked, onChange }: ExecuteCheckboxProps): ReactElement => {
const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
onChange(e.target.checked)
const handleChange = (_: React.ChangeEvent<HTMLInputElement>, checked: boolean): void => {
trackEvent({ ...MODALS_EVENTS.EXECUTE_TX, label: checked })
onChange(checked)
}
return (
<StyledRow>
Expand Down
16 changes: 14 additions & 2 deletions src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ButtonProps as ButtonPropsMUI, Modal as ModalMUI } from '@material-ui/c
import cn from 'classnames'
import { ReactElement, ReactNode } from 'react'
import { ModalHeader } from 'src/routes/safe/components/Balances/SendModal/screens/ModalHeader'
import { getModalEvent } from 'src/utils/events/modals'
import { trackEvent } from 'src/utils/googleTagManager'
import styled from 'styled-components'

type Theme = typeof theme
Expand Down Expand Up @@ -191,13 +193,15 @@ const Buttons = ({ cancelButtonProps = {}, confirmButtonProps = {} }: ButtonsPro
status: cancelStatus = ButtonStatus.READY,
text: cancelText = ButtonStatus.LOADING === cancelStatus ? 'Cancelling' : 'Cancel',
testId: cancelTestId = '',
onClick: cancelOnClick,
...cancelProps
} = cancelButtonProps
const {
disabled: confirmDisabled,
status: confirmStatus = ButtonStatus.READY,
text: confirmText = ButtonStatus.LOADING === confirmStatus ? 'Submitting' : 'Submit',
testId: confirmTestId = '',
onClick: confirmOnClick,
...confirmProps
} = confirmButtonProps

Expand All @@ -207,9 +211,13 @@ const Buttons = ({ cancelButtonProps = {}, confirmButtonProps = {} }: ButtonsPro
size="md"
color="primary"
variant="outlined"
type={cancelProps?.onClick ? 'button' : 'submit'}
type={cancelOnClick ? 'button' : 'submit'}
disabled={cancelDisabled || [ButtonStatus.DISABLED, ButtonStatus.LOADING].includes(cancelStatus)}
data-testid={cancelTestId}
onClick={(e) => {
trackEvent(getModalEvent(cancelText))
cancelOnClick?.(e)
}}
{...cancelProps}
>
{ButtonStatus.LOADING === cancelStatus ? (
Expand All @@ -223,9 +231,13 @@ const Buttons = ({ cancelButtonProps = {}, confirmButtonProps = {} }: ButtonsPro
</Button>
<Button
size="md"
type={confirmProps?.onClick ? 'button' : 'submit'}
type={confirmOnClick ? 'button' : 'submit'}
disabled={confirmDisabled || [ButtonStatus.DISABLED, ButtonStatus.LOADING].includes(confirmStatus)}
data-testid={confirmTestId}
onClick={(e) => {
trackEvent(getModalEvent(confirmText))
confirmOnClick?.(e)
}}
{...confirmProps}
>
{ButtonStatus.LOADING === confirmStatus ? (
Expand Down
20 changes: 12 additions & 8 deletions src/components/SafeListSidebar/AddSafeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import Fab from '@material-ui/core/Fab'
import AddIcon from '@material-ui/icons/Add'
import { Text } from '@gnosis.pm/safe-react-components'
import { WELCOME_ROUTE } from 'src/routes/routes'
import { OVERVIEW_EVENTS } from 'src/utils/events/overview'
import Track from '../Track'

interface Props {
onAdd: () => unknown
Expand Down Expand Up @@ -34,15 +36,17 @@ const StyledLink = styled(Link)`

const AddSafeButton = ({ onAdd }: Props): ReactElement => {
return (
<StyledLink onClick={onAdd} to={WELCOME_ROUTE}>
<Fab color="secondary" size="small" aria-label="Add Safe">
<AddIcon />
<Track {...OVERVIEW_EVENTS.ADD_SAFE}>
<StyledLink onClick={onAdd} to={WELCOME_ROUTE}>
<Fab color="secondary" size="small" aria-label="Add Safe">
<AddIcon />

<Text color="primary" size="xl" strong>
Add Safe
</Text>
</Fab>
</StyledLink>
<Text color="primary" size="xl" strong>
Add Safe
</Text>
</Fab>
</StyledLink>
</Track>
)
}

Expand Down
Loading

0 comments on commit 5ec343f

Please sign in to comment.