From 2fec7613c408a046c130f4c5817696ab3b5e3928 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 26 Nov 2018 13:20:16 -0800 Subject: Token Selector open, closed, chose --- packages/instant/src/components/zero_ex_instant_container.tsx | 3 +++ packages/instant/src/redux/analytics_middleware.ts | 9 +++++++++ packages/instant/src/util/analytics.ts | 7 +++++++ 3 files changed, 19 insertions(+) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 47c938472..f30bda6ed 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -12,6 +12,7 @@ import { SelectedAssetInstantHeading } from '../containers/selected_asset_instan import { ColorOption } from '../style/theme'; import { zIndex } from '../style/z_index'; import { OrderProcessState, SlideAnimationState } from '../types'; +import { analytics } from '../util/analytics'; import { CSSReset } from './css_reset'; import { SlidingPanel } from './sliding_panel'; @@ -82,11 +83,13 @@ export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantCon ); } private readonly _handleSymbolClick = (): void => { + analytics.trackTokenSelectorOpened(); this.setState({ tokenSelectionPanelAnimationState: 'slidIn', }); }; private readonly _handlePanelClose = (): void => { + analytics.trackTokenSelectorClosed(); this.setState({ tokenSelectionPanelAnimationState: 'slidOut', }); diff --git a/packages/instant/src/redux/analytics_middleware.ts b/packages/instant/src/redux/analytics_middleware.ts index 299c2560e..1a8aefb38 100644 --- a/packages/instant/src/redux/analytics_middleware.ts +++ b/packages/instant/src/redux/analytics_middleware.ts @@ -53,6 +53,15 @@ export const analyticsMiddleware: Middleware = store => next => middlewareAction ).toString(); analytics.addUserProperties({ ethBalanceInUnitAmount }); } + break; + case ActionTypes.UPDATE_SELECTED_ASSET: + if (curState.selectedAsset) { + analytics.trackTokenSelectorChose({ + assetName: curState.selectedAsset.metaData.name, + assetData: curState.selectedAsset.assetData, + }); + } + break; } return nextAction; diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index e389e1530..50bab174f 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -18,6 +18,9 @@ enum EventNames { ACCOUNT_UNLOCK_REQUESTED = 'Account - Unlock Requested', ACCOUNT_UNLOCK_DENIED = 'Account - Unlock Denied', ACCOUNT_ADDRESS_CHANGED = 'Account - Address Changed', + TOKEN_SELECTOR_OPENED = 'Token Selector - Opened', + TOKEN_SELECTOR_CLOSED = 'Token Selector - Closed', + TOKEN_SELECTOR_CHOSE = 'Token Selector - Chose', } const track = (eventName: EventNames, eventProperties: EventProperties = {}): void => { evaluateIfEnabled(() => { @@ -67,4 +70,8 @@ export const analytics = { trackAccountUnlockDenied: trackingEventFnWithoutPayload(EventNames.ACCOUNT_UNLOCK_DENIED), trackAccountAddressChanged: (address: string) => trackingEventFnWithPayload(EventNames.ACCOUNT_ADDRESS_CHANGED)({ address }), + trackTokenSelectorOpened: trackingEventFnWithoutPayload(EventNames.TOKEN_SELECTOR_OPENED), + trackTokenSelectorClosed: trackingEventFnWithoutPayload(EventNames.TOKEN_SELECTOR_CLOSED), + trackTokenSelectorChose: (payload: { assetName: string; assetData: string }) => + trackingEventFnWithPayload(EventNames.TOKEN_SELECTOR_CHOSE)(payload), }; -- cgit v1.2.3 From 9206f2d288f33367877d2d557d50f1d485d4b92e Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 26 Nov 2018 13:26:29 -0800 Subject: Token selector searched --- packages/instant/src/components/erc20_token_selector.tsx | 2 ++ packages/instant/src/util/analytics.ts | 3 +++ 2 files changed, 5 insertions(+) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/erc20_token_selector.tsx b/packages/instant/src/components/erc20_token_selector.tsx index 1b1921acb..0a3d4427a 100644 --- a/packages/instant/src/components/erc20_token_selector.tsx +++ b/packages/instant/src/components/erc20_token_selector.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import { ColorOption } from '../style/theme'; import { ERC20Asset } from '../types'; +import { analytics } from '../util/analytics'; import { assetUtils } from '../util/asset'; import { SearchInput } from './search_input'; @@ -57,6 +58,7 @@ export class ERC20TokenSelector extends React.Component this.setState({ searchQuery, }); + analytics.trackTokenSelectorSearched(searchQuery); }; private readonly _isTokenQueryMatch = (token: ERC20Asset): boolean => { const { searchQuery } = this.state; diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index 50bab174f..cd1074cba 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -21,6 +21,7 @@ enum EventNames { TOKEN_SELECTOR_OPENED = 'Token Selector - Opened', TOKEN_SELECTOR_CLOSED = 'Token Selector - Closed', TOKEN_SELECTOR_CHOSE = 'Token Selector - Chose', + TOKEN_SELECTOR_SEARCHED = 'Token Selector - Searched', } const track = (eventName: EventNames, eventProperties: EventProperties = {}): void => { evaluateIfEnabled(() => { @@ -74,4 +75,6 @@ export const analytics = { trackTokenSelectorClosed: trackingEventFnWithoutPayload(EventNames.TOKEN_SELECTOR_CLOSED), trackTokenSelectorChose: (payload: { assetName: string; assetData: string }) => trackingEventFnWithPayload(EventNames.TOKEN_SELECTOR_CHOSE)(payload), + trackTokenSelectorSearched: (searchText: string) => + trackingEventFnWithPayload(EventNames.TOKEN_SELECTOR_SEARCHED)({ searchText }), }; -- cgit v1.2.3 From ae570dba05cfc0d696c616d05804152791d29677 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 26 Nov 2018 15:04:02 -0800 Subject: feat(instant): Event tracking for token selector --- .../src/components/zero_ex_instant_container.tsx | 17 ++++++++++++----- packages/instant/src/util/analytics.ts | 7 ++++++- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index f30bda6ed..b72493ce6 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -12,7 +12,7 @@ import { SelectedAssetInstantHeading } from '../containers/selected_asset_instan import { ColorOption } from '../style/theme'; import { zIndex } from '../style/z_index'; import { OrderProcessState, SlideAnimationState } from '../types'; -import { analytics } from '../util/analytics'; +import { analytics, TokenSelectorClosedVia } from '../util/analytics'; import { CSSReset } from './css_reset'; import { SlidingPanel } from './sliding_panel'; @@ -30,6 +30,13 @@ export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantCon public state = { tokenSelectionPanelAnimationState: 'none' as SlideAnimationState, }; + private _handlePanelCloseClickedX: () => void; + private _handlePanelCloseAfterChose: () => void; + public constructor(props: {}) { + super(props); + this._handlePanelCloseClickedX = this._handlePanelClose.bind(this, TokenSelectorClosedVia.ClickedX); + this._handlePanelCloseAfterChose = this._handlePanelClose.bind(this, TokenSelectorClosedVia.TokenChose); + } public render(): React.ReactNode { return ( @@ -61,9 +68,9 @@ export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantCon - + @@ -88,8 +95,8 @@ export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantCon tokenSelectionPanelAnimationState: 'slidIn', }); }; - private readonly _handlePanelClose = (): void => { - analytics.trackTokenSelectorClosed(); + private readonly _handlePanelClose = (closedVia: TokenSelectorClosedVia): void => { + analytics.trackTokenSelectorClosed(closedVia); this.setState({ tokenSelectionPanelAnimationState: 'slidOut', }); diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index cd1074cba..8f8cec284 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -52,7 +52,10 @@ export interface AnalyticsEventOptions { gitSha?: string; npmVersion?: string; } - +export enum TokenSelectorClosedVia { + ClickedX = 'Clicked X', + TokenChose = 'Token Chose', +} export const analytics = { addUserProperties: (properties: AnalyticsUserOptions): void => { evaluateIfEnabled(() => { @@ -73,6 +76,8 @@ export const analytics = { trackingEventFnWithPayload(EventNames.ACCOUNT_ADDRESS_CHANGED)({ address }), trackTokenSelectorOpened: trackingEventFnWithoutPayload(EventNames.TOKEN_SELECTOR_OPENED), trackTokenSelectorClosed: trackingEventFnWithoutPayload(EventNames.TOKEN_SELECTOR_CLOSED), + trackTokenSelectorClosed: (closedVia: TokenSelectorClosedVia) => + trackingEventFnWithPayload(EventNames.TOKEN_SELECTOR_CLOSED)({ closedVia }), trackTokenSelectorChose: (payload: { assetName: string; assetData: string }) => trackingEventFnWithPayload(EventNames.TOKEN_SELECTOR_CHOSE)(payload), trackTokenSelectorSearched: (searchText: string) => -- cgit v1.2.3 From d5898a3a050a8c97e516dba62ba040140fd74c62 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 26 Nov 2018 15:12:51 -0800 Subject: Fix dupe merge issue --- packages/instant/src/util/analytics.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index 1dda649b3..51be63da2 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -102,7 +102,6 @@ export const analytics = { trackAccountAddressChanged: (address: string) => trackingEventFnWithPayload(EventNames.ACCOUNT_ADDRESS_CHANGED)({ address }), trackTokenSelectorOpened: trackingEventFnWithoutPayload(EventNames.TOKEN_SELECTOR_OPENED), - trackTokenSelectorClosed: trackingEventFnWithoutPayload(EventNames.TOKEN_SELECTOR_CLOSED), trackTokenSelectorClosed: (closedVia: TokenSelectorClosedVia) => trackingEventFnWithPayload(EventNames.TOKEN_SELECTOR_CLOSED)({ closedVia }), trackTokenSelectorChose: (payload: { assetName: string; assetData: string }) => -- cgit v1.2.3 From 7610130f7353ea6134fae441a8fe23e0fd0ddb2f Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 26 Nov 2018 15:51:40 -0800 Subject: Track numberAvailableAssets, selectedAssetName, selectedAssetData event properties --- .../src/components/zero_ex_instant_provider.tsx | 1 + packages/instant/src/redux/analytics_middleware.ts | 21 ++++++++++++++++++--- packages/instant/src/util/analytics.ts | 16 ++++++++++++++-- 3 files changed, 33 insertions(+), 5 deletions(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index fe34c4466..e006a5a5f 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -131,6 +131,7 @@ export class ZeroExInstantProvider extends React.Component next => middlewareAction } break; case ActionTypes.UPDATE_SELECTED_ASSET: - if (curState.selectedAsset) { + const selectedAsset = curState.selectedAsset; + if (selectedAsset) { + const assetName = selectedAsset.metaData.name; + const assetData = selectedAsset.assetData; analytics.trackTokenSelectorChose({ - assetName: curState.selectedAsset.metaData.name, - assetData: curState.selectedAsset.assetData, + assetName, + assetData, + }); + analytics.addEventProperties({ + selectedAssetName: assetName, + selectedAssetData: assetData, + }); + } + break; + case ActionTypes.SET_AVAILABLE_ASSETS: + const availableAssets = curState.availableAssets; + if (availableAssets) { + analytics.addEventProperties({ + numberAvailableAssets: availableAssets.length, }); } break; diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index 51be63da2..331cd86e8 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -1,4 +1,4 @@ -import { AffiliateInfo, Network, OrderSource, ProviderState } from '../types'; +import { AffiliateInfo, Asset, Network, OrderSource, ProviderState } from '../types'; import { EventProperties, heapUtil } from './heap'; @@ -25,6 +25,7 @@ enum EventNames { TOKEN_SELECTOR_CHOSE = 'Token Selector - Chose', TOKEN_SELECTOR_SEARCHED = 'Token Selector - Searched', } + const track = (eventName: EventNames, eventProperties: EventProperties = {}): void => { evaluateIfEnabled(() => { heapUtil.evaluateHeapCall(heap => heap.track(eventName, eventProperties)); @@ -56,6 +57,9 @@ export interface AnalyticsEventOptions { orderSource?: string; affiliateAddress?: string; affiliateFeePercent?: number; + numberAvailableAssets?: number; + selectedAssetName?: string; + selectedAssetData?: string; } export enum TokenSelectorClosedVia { ClickedX = 'Clicked X', @@ -77,12 +81,13 @@ export const analytics = { orderSource: OrderSource, providerState: ProviderState, window: Window, + selectedAsset?: Asset, affiliateInfo?: AffiliateInfo, ): AnalyticsEventOptions => { const affiliateAddress = affiliateInfo ? affiliateInfo.feeRecipient : 'none'; const affiliateFeePercent = affiliateInfo ? parseFloat(affiliateInfo.feePercentage.toFixed(4)) : 0; const orderSourceName = typeof orderSource === 'string' ? orderSource : 'provided'; - return { + const eventOptions: AnalyticsEventOptions = { embeddedHost: window.location.host, embeddedUrl: window.location.href, networkId: network, @@ -93,6 +98,13 @@ export const analytics = { affiliateAddress, affiliateFeePercent, }; + + if (selectedAsset) { + eventOptions.selectedAssetName = selectedAsset.metaData.name; + eventOptions.selectedAssetData = selectedAsset.assetData; + } + + return eventOptions; }, trackInstantOpened: trackingEventFnWithoutPayload(EventNames.INSTANT_OPENED), trackAccountLocked: trackingEventFnWithoutPayload(EventNames.ACCOUNT_LOCKED), -- cgit v1.2.3 From 0192127e5d20222698673d5c63c1025a10d5011f Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 26 Nov 2018 15:53:39 -0800 Subject: Set selected asset to none --- packages/instant/src/util/analytics.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index 331cd86e8..aa0f37194 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -97,13 +97,9 @@ export const analytics = { orderSource: orderSourceName, affiliateAddress, affiliateFeePercent, + selectedAssetName: selectedAsset ? selectedAsset.metaData.name : 'none', + selectedAssetData: selectedAsset ? selectedAsset.assetData : 'none', }; - - if (selectedAsset) { - eventOptions.selectedAssetName = selectedAsset.metaData.name; - eventOptions.selectedAssetData = selectedAsset.assetData; - } - return eventOptions; }, trackInstantOpened: trackingEventFnWithoutPayload(EventNames.INSTANT_OPENED), -- cgit v1.2.3 From 80a53aedf220948675a938dc4ae5227381fb96e5 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 26 Nov 2018 16:53:50 -0800 Subject: Fix props --- packages/instant/src/components/zero_ex_instant_container.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index b72493ce6..72a3cde2f 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -19,20 +19,18 @@ import { SlidingPanel } from './sliding_panel'; import { Container } from './ui/container'; import { Flex } from './ui/flex'; -export interface ZeroExInstantContainerProps { - orderProcessState: OrderProcessState; -} +export interface ZeroExInstantContainerProps {} export interface ZeroExInstantContainerState { tokenSelectionPanelAnimationState: SlideAnimationState; } -export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantContainerState> { +export class ZeroExInstantContainer extends React.Component { public state = { tokenSelectionPanelAnimationState: 'none' as SlideAnimationState, }; private _handlePanelCloseClickedX: () => void; private _handlePanelCloseAfterChose: () => void; - public constructor(props: {}) { + public constructor(props: ZeroExInstantContainerProps) { super(props); this._handlePanelCloseClickedX = this._handlePanelClose.bind(this, TokenSelectorClosedVia.ClickedX); this._handlePanelCloseAfterChose = this._handlePanelClose.bind(this, TokenSelectorClosedVia.TokenChose); -- cgit v1.2.3 From ee5b6ad77ffac9aca00035a6bc50cdbf25caf348 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 27 Nov 2018 09:16:26 -0800 Subject: Linting --- packages/instant/src/components/zero_ex_instant_container.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 72a3cde2f..1e74cf41c 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -11,7 +11,7 @@ import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_ import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; import { ColorOption } from '../style/theme'; import { zIndex } from '../style/z_index'; -import { OrderProcessState, SlideAnimationState } from '../types'; +import { SlideAnimationState } from '../types'; import { analytics, TokenSelectorClosedVia } from '../util/analytics'; import { CSSReset } from './css_reset'; @@ -28,8 +28,8 @@ export class ZeroExInstantContainer extends React.Component void; - private _handlePanelCloseAfterChose: () => void; + private readonly _handlePanelCloseClickedX: () => void; + private readonly _handlePanelCloseAfterChose: () => void; public constructor(props: ZeroExInstantContainerProps) { super(props); this._handlePanelCloseClickedX = this._handlePanelClose.bind(this, TokenSelectorClosedVia.ClickedX); -- cgit v1.2.3 From 9c27feeff61ab38771709b3f4ccd1fb1ff29e1d2 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 27 Nov 2018 10:00:21 -0800 Subject: Make explicit functions --- .../instant/src/components/zero_ex_instant_container.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 1e74cf41c..8a809ee31 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -28,13 +28,6 @@ export class ZeroExInstantContainer extends React.Component void; - private readonly _handlePanelCloseAfterChose: () => void; - public constructor(props: ZeroExInstantContainerProps) { - super(props); - this._handlePanelCloseClickedX = this._handlePanelClose.bind(this, TokenSelectorClosedVia.ClickedX); - this._handlePanelCloseAfterChose = this._handlePanelClose.bind(this, TokenSelectorClosedVia.TokenChose); - } public render(): React.ReactNode { return ( @@ -93,6 +86,12 @@ export class ZeroExInstantContainer extends React.Component { + this._handlePanelClose(TokenSelectorClosedVia.ClickedX); + }; + private readonly _handlePanelCloseAfterChose = (): void => { + this._handlePanelClose(TokenSelectorClosedVia.TokenChose); + }; private readonly _handlePanelClose = (closedVia: TokenSelectorClosedVia): void => { analytics.trackTokenSelectorClosed(closedVia); this.setState({ -- cgit v1.2.3