From f3391e1250767eb9ef7a74f78eded38fa3c94586 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 12 Oct 2018 11:00:36 -0700 Subject: feat: make redux actions type-sage --- .../instant/src/components/instant_heading.tsx | 2 -- packages/instant/src/components/order_details.tsx | 3 -- .../instant/src/components/zero_ex_instant.tsx | 1 + .../src/components/zero_ex_instant_container.tsx | 2 -- .../src/containers/selected_asset_amount_input.ts | 12 +++++--- .../src/containers/selected_asset_buy_button.ts | 16 ++++------ packages/instant/src/redux/actions.ts | 36 ++++++++++++++++++++++ packages/instant/src/redux/async_data.ts | 5 ++- packages/instant/src/redux/reducer.ts | 4 ++- packages/instant/src/types.ts | 16 +++------- 10 files changed, 60 insertions(+), 37 deletions(-) create mode 100644 packages/instant/src/redux/actions.ts diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 951858695..377bb20bf 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -1,9 +1,7 @@ import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import * as React from 'react'; -import { ethDecimals } from '../constants'; import { SelectedAssetAmountInput } from '../containers/selected_asset_amount_input'; import { ColorOption } from '../style/theme'; import { format } from '../util/format'; diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 78359898f..66e7e2406 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -1,11 +1,8 @@ import { BuyQuoteInfo } from '@0xproject/asset-buyer'; import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import * as React from 'react'; -import { BIG_NUMBER_ZERO, ethDecimals } from '../constants'; - import { ColorOption } from '../style/theme'; import { format } from '../util/format'; diff --git a/packages/instant/src/components/zero_ex_instant.tsx b/packages/instant/src/components/zero_ex_instant.tsx index 17ef737c9..f6472e811 100644 --- a/packages/instant/src/components/zero_ex_instant.tsx +++ b/packages/instant/src/components/zero_ex_instant.tsx @@ -9,6 +9,7 @@ import { theme, ThemeProvider } from '../style/theme'; import { ZeroExInstantContainer } from './zero_ex_instant_container'; fonts.include(); +// tslint:disable-next-line:no-floating-promises asyncData.fetchAndDispatchToStore(); export interface ZeroExInstantProps {} diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 44f702aa2..b624d712f 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -6,8 +6,6 @@ import { SelectedAssetInstantHeading } from '../containers/selected_asset_instan import { ColorOption } from '../style/theme'; -import { BuyButton } from './buy_button'; -import { InstantHeading } from './instant_heading'; import { Container, Flex } from './ui'; export interface ZeroExInstantContainerProps {} diff --git a/packages/instant/src/containers/selected_asset_amount_input.ts b/packages/instant/src/containers/selected_asset_amount_input.ts index fa675b385..9e3063ecc 100644 --- a/packages/instant/src/containers/selected_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_asset_amount_input.ts @@ -6,9 +6,10 @@ import { connect } from 'react-redux'; import { Dispatch } from 'redux'; import { zrxContractAddress, zrxDecimals } from '../constants'; +import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { ColorOption } from '../style/theme'; -import { Action, ActionTypes, AsyncProcessState } from '../types'; +import { AsyncProcessState } from '../types'; import { assetBuyer } from '../util/asset_buyer'; import { AmountInput } from '../components/amount_input'; @@ -38,7 +39,7 @@ const updateBuyQuote = async (dispatch: Dispatch, assetAmount?: BigNumbe const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, zrxDecimals); const newBuyQuote = await assetBuyer.getBuyQuoteForERC20TokenAddressAsync(zrxContractAddress, baseUnitValue); // invalidate the last buy quote. - dispatch({ type: ActionTypes.UPDATE_LATEST_BUY_QUOTE, data: newBuyQuote }); + dispatch(actions.updateLatestBuyQuote(newBuyQuote)); }; const debouncedUpdateBuyQuote = _.debounce(updateBuyQuote, 200, { trailing: true }); @@ -46,11 +47,12 @@ const debouncedUpdateBuyQuote = _.debounce(updateBuyQuote, 200, { trailing: true const mapDispatchToProps = (dispatch: Dispatch): ConnectedDispatch => ({ onChange: async value => { // Update the input - dispatch({ type: ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, data: value }); + dispatch(actions.updateSelectedAssetAmount(value)); // invalidate the last buy quote. - dispatch({ type: ActionTypes.UPDATE_LATEST_BUY_QUOTE, data: undefined }); + dispatch(actions.updateLatestBuyQuote(undefined)); // reset our buy state - dispatch({ type: ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, data: AsyncProcessState.NONE }); + dispatch(actions.updateSelectedAssetBuyState(AsyncProcessState.NONE)); + // tslint:disable-next-line:no-floating-promises debouncedUpdateBuyQuote(dispatch, value); }, }); diff --git a/packages/instant/src/containers/selected_asset_buy_button.ts b/packages/instant/src/containers/selected_asset_buy_button.ts index 678c7e445..4cbaf5537 100644 --- a/packages/instant/src/containers/selected_asset_buy_button.ts +++ b/packages/instant/src/containers/selected_asset_buy_button.ts @@ -4,12 +4,11 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; +import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; -import { Action, ActionTypes, AsyncProcessState } from '../types'; -import { assetBuyer } from '../util/asset_buyer'; -import { web3Wrapper } from '../util/web3_wrapper'; +import { AsyncProcessState } from '../types'; -import { BuyButton, BuyButtonProps } from '../components/buy_button'; +import { BuyButton } from '../components/buy_button'; export interface SelectedAssetBuyButtonProps {} @@ -45,12 +44,9 @@ const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyButtonProps): }); const mapDispatchToProps = (dispatch: Dispatch, ownProps: SelectedAssetBuyButtonProps): ConnectedDispatch => ({ - onClick: buyQuote => - dispatch({ type: ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, data: AsyncProcessState.PENDING }), - onBuySuccess: buyQuote => - dispatch({ type: ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, data: AsyncProcessState.SUCCESS }), - onBuyFailure: buyQuote => - dispatch({ type: ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, data: AsyncProcessState.FAILURE }), + onClick: buyQuote => dispatch(actions.updateSelectedAssetBuyState(AsyncProcessState.PENDING)), + onBuySuccess: buyQuote => dispatch(actions.updateSelectedAssetBuyState(AsyncProcessState.SUCCESS)), + onBuyFailure: buyQuote => dispatch(actions.updateSelectedAssetBuyState(AsyncProcessState.FAILURE)), }); export const SelectedAssetBuyButton: React.ComponentClass = connect( diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts new file mode 100644 index 000000000..7d07b4950 --- /dev/null +++ b/packages/instant/src/redux/actions.ts @@ -0,0 +1,36 @@ +import { BuyQuote } from '@0xproject/asset-buyer'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; + +import { ActionsUnion, AsyncProcessState } from '../types'; + +export interface PlainAction { + type: T; +} + +export interface ActionWithPayload extends PlainAction { + data: P; +} + +export type Action = ActionsUnion; + +function createAction(type: T): PlainAction; +function createAction(type: T, data: P): ActionWithPayload; +function createAction(type: T, data?: P): PlainAction | ActionWithPayload { + return _.isUndefined(data) ? { type } : { type, data }; +} + +export enum ActionTypes { + UPDATE_ETH_USD_PRICE = 'UPDATE_ETH_USD_PRICE', + UPDATE_SELECTED_ASSET_AMOUNT = 'UPDATE_SELECTED_ASSET_AMOUNT', + UPDATE_SELECTED_ASSET_BUY_STATE = 'UPDATE_SELECTED_ASSET_BUY_STATE', + UPDATE_LATEST_BUY_QUOTE = 'UPDATE_LATEST_BUY_QUOTE', +} + +export const actions = { + updateEthUsdPrice: (price?: BigNumber) => createAction(ActionTypes.UPDATE_ETH_USD_PRICE, price), + updateSelectedAssetAmount: (amount?: BigNumber) => createAction(ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, amount), + updateSelectedAssetBuyState: (buyState: AsyncProcessState) => + createAction(ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, buyState), + updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UPDATE_LATEST_BUY_QUOTE, buyQuote), +}; diff --git a/packages/instant/src/redux/async_data.ts b/packages/instant/src/redux/async_data.ts index b368491f0..348838307 100644 --- a/packages/instant/src/redux/async_data.ts +++ b/packages/instant/src/redux/async_data.ts @@ -1,9 +1,8 @@ -import { BigNumber } from '@0xproject/utils'; - import { BIG_NUMBER_ZERO } from '../constants'; -import { ActionTypes } from '../types'; import { coinbaseApi } from '../util/coinbase_api'; +import { ActionTypes } from './actions'; + import { store } from './store'; export const asyncData = { diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index c0c4b06ad..56a4ee236 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -2,7 +2,9 @@ import { BuyQuote } from '@0xproject/asset-buyer'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; -import { Action, ActionTypes, AsyncProcessState } from '../types'; +import { AsyncProcessState } from '../types'; + +import { Action, ActionTypes } from './actions'; export interface State { selectedAssetAmount?: BigNumber; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index bbf31cbf4..ffa5d679e 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -1,3 +1,5 @@ +import { ObjectMap } from '@0xproject/types'; + // Reusable export enum AsyncProcessState { NONE, @@ -6,14 +8,6 @@ export enum AsyncProcessState { FAILURE, } -export enum ActionTypes { - UPDATE_ETH_USD_PRICE, - UPDATE_SELECTED_ASSET_AMOUNT, - UPDATE_SELECTED_ASSET_BUY_STATE, - UPDATE_LATEST_BUY_QUOTE, -} - -export interface Action { - type: ActionTypes; - data?: any; -} +export type FunctionType = (...args: any[]) => any; +export type ActionCreatorsMapObject = ObjectMap; +export type ActionsUnion = ReturnType; -- cgit v1.2.3