From c84740c4d434161270f4f4dcdf4cf76940635fbf Mon Sep 17 00:00:00 2001 From: HenryNguyen5 Date: Mon, 29 Jan 2018 16:38:28 -0500 Subject: [PATCH] Generic Confirmation Modal (#940) * Make generic modal * Allow generic modals to be injected into send button component --- common/components/ConfirmationModal/index.ts | 1 - common/components/ConfirmationModal/index.tsx | 14 +++++ .../ConfirmationModalTemplate.scss} | 0 .../ConfirmationModalTemplate.tsx} | 56 +++++++++++++------ .../ConfirmationModalTemplate/index.ts | 1 + common/components/SendButton.tsx | 9 ++- .../SendButtonFactory/OnlineSend.tsx | 6 +- .../SendButtonFactory/SendButtonFactory.tsx | 4 +- .../Tabs/Contracts/components/Deploy.tsx | 2 + 9 files changed, 71 insertions(+), 22 deletions(-) delete mode 100644 common/components/ConfirmationModal/index.ts create mode 100644 common/components/ConfirmationModal/index.tsx rename common/components/{ConfirmationModal/ConfirmationModal.scss => ConfirmationModalTemplate/ConfirmationModalTemplate.scss} (100%) rename common/components/{ConfirmationModal/ConfirmationModal.tsx => ConfirmationModalTemplate/ConfirmationModalTemplate.tsx} (73%) create mode 100644 common/components/ConfirmationModalTemplate/index.ts diff --git a/common/components/ConfirmationModal/index.ts b/common/components/ConfirmationModal/index.ts deleted file mode 100644 index 828239d5..00000000 --- a/common/components/ConfirmationModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './ConfirmationModal'; diff --git a/common/components/ConfirmationModal/index.tsx b/common/components/ConfirmationModal/index.tsx new file mode 100644 index 00000000..0b4f7062 --- /dev/null +++ b/common/components/ConfirmationModal/index.tsx @@ -0,0 +1,14 @@ +import { + ConfirmationModalTemplate, + OwnProps as ConfirmationModalTemplateProps +} from '../ConfirmationModalTemplate'; +import { Details, Summary } from './components'; +import React, { SFC } from 'react'; + +interface OwnProps { + onClose: ConfirmationModalTemplateProps['onClose']; +} + +export const ConfirmationModal: SFC = ({ onClose }) => ( + } details={
} onClose={onClose} /> +); diff --git a/common/components/ConfirmationModal/ConfirmationModal.scss b/common/components/ConfirmationModalTemplate/ConfirmationModalTemplate.scss similarity index 100% rename from common/components/ConfirmationModal/ConfirmationModal.scss rename to common/components/ConfirmationModalTemplate/ConfirmationModalTemplate.scss diff --git a/common/components/ConfirmationModal/ConfirmationModal.tsx b/common/components/ConfirmationModalTemplate/ConfirmationModalTemplate.tsx similarity index 73% rename from common/components/ConfirmationModal/ConfirmationModal.tsx rename to common/components/ConfirmationModalTemplate/ConfirmationModalTemplate.tsx index 9a3a6937..e06d8c42 100644 --- a/common/components/ConfirmationModal/ConfirmationModal.tsx +++ b/common/components/ConfirmationModalTemplate/ConfirmationModalTemplate.tsx @@ -1,6 +1,5 @@ import Modal, { IButton } from 'components/ui/Modal'; import Spinner from 'components/ui/Spinner'; -import { Details, Summary } from './components'; import React from 'react'; import { connect } from 'react-redux'; import { getWalletType, IWalletType } from 'selectors/wallet'; @@ -17,13 +16,14 @@ import { currentTransactionFailed } from 'selectors/transaction'; import translate, { translateRaw } from 'translations'; -import './ConfirmationModal.scss'; +import './ConfirmationModalTemplate.scss'; import { AppState } from 'reducers'; interface DispatchProps { broadcastLocalTransactionRequested: TBroadcastLocalTransactionRequested; broadcastWeb3TransactionRequested: TBroadcastWeb3TransactionRequested; } + interface StateProps { lang: string; walletTypes: IWalletType; @@ -31,7 +31,20 @@ interface StateProps { transactionBroadcasted: boolean; transactionFailed: boolean; } -interface OwnProps { + +export interface ConfirmButtonCBProps { + type: IButton['type']; + timeLocked: boolean; + timeLeft: number; + timePrefix: string; + defaultText: string; + onConfirm: ConfirmationModalTemplateClass['confirm']; +} + +export interface OwnProps { + summary: React.ReactElement | null; + details: React.ReactElement | null; + withConfirmButton?(props: ConfirmButtonCBProps): IButton; onClose(): void; } interface State { @@ -41,7 +54,7 @@ interface State { type Props = DispatchProps & StateProps & OwnProps; -class ConfirmationModalClass extends React.Component { +class ConfirmationModalTemplateClass extends React.Component { private readTimer = 0; public constructor(props: Props) { super(props); @@ -72,15 +85,27 @@ class ConfirmationModalClass extends React.Component { public render() { const { onClose, transactionBroadcasting } = this.props; const { timeToRead } = this.state; - const buttonPrefix = timeToRead > 0 ? `(${timeToRead}) ` : ''; + const defaultConfirmButton = { + text: buttonPrefix + translateRaw('SENDModal_Yes'), + type: 'primary' as IButton['type'], + disabled: timeToRead > 0, + onClick: this.confirm + }; + + const confirmButton: IButton = this.props.withConfirmButton + ? this.props.withConfirmButton({ + onConfirm: defaultConfirmButton.onClick, + timeLeft: timeToRead, + timePrefix: buttonPrefix, + timeLocked: defaultConfirmButton.disabled, + defaultText: translateRaw('SENDModal_Yes'), + type: defaultConfirmButton.type + }) + : defaultConfirmButton; + const buttons: IButton[] = [ - { - text: buttonPrefix + translateRaw('SENDModal_Yes'), - type: 'primary', - disabled: timeToRead > 0, - onClick: this.confirm - }, + confirmButton, { text: translateRaw('SENDModal_No'), type: 'default', @@ -104,9 +129,8 @@ class ConfirmationModalClass extends React.Component { ) : (
- -
- + {this.props.summary} + {this.props.details}
{translate('SENDModal_Content_3')}
)} @@ -130,7 +154,7 @@ class ConfirmationModalClass extends React.Component { }; } -export const ConfirmationModal = connect( +export const ConfirmationModalTemplate = connect( (state: AppState) => ({ transactionBroadcasting: currentTransactionBroadcasting(state), transactionBroadcasted: currentTransactionBroadcasted(state), @@ -139,4 +163,4 @@ export const ConfirmationModal = connect( walletTypes: getWalletType(state) }), { broadcastLocalTransactionRequested, broadcastWeb3TransactionRequested } -)(ConfirmationModalClass); +)(ConfirmationModalTemplateClass); diff --git a/common/components/ConfirmationModalTemplate/index.ts b/common/components/ConfirmationModalTemplate/index.ts new file mode 100644 index 00000000..9d0695e0 --- /dev/null +++ b/common/components/ConfirmationModalTemplate/index.ts @@ -0,0 +1 @@ +export * from './ConfirmationModalTemplate'; diff --git a/common/components/SendButton.tsx b/common/components/SendButton.tsx index 7840f24f..33501c91 100644 --- a/common/components/SendButton.tsx +++ b/common/components/SendButton.tsx @@ -1,12 +1,15 @@ import React from 'react'; import { SendButtonFactory } from './SendButtonFactory'; import translate from 'translations'; +import { ConfirmationModal } from 'components/ConfirmationModal'; -export const SendButton: React.SFC<{ onlyTransactionParameters?: boolean }> = ({ - onlyTransactionParameters -}) => ( +export const SendButton: React.SFC<{ + onlyTransactionParameters?: boolean; + customModal?: typeof ConfirmationModal; +}> = ({ onlyTransactionParameters, customModal }) => ( (
diff --git a/common/components/SendButtonFactory/OnlineSend.tsx b/common/components/SendButtonFactory/OnlineSend.tsx index 875d1f38..5fccd756 100644 --- a/common/components/SendButtonFactory/OnlineSend.tsx +++ b/common/components/SendButtonFactory/OnlineSend.tsx @@ -22,20 +22,24 @@ interface DispatchProps { showNotification: TShowNotification; reset: TReset; } + interface OwnProps { + Modal: typeof ConfirmationModal; withProps(props: CallbackProps): React.ReactElement | null; } + const INITIAL_STATE: State = { showModal: false }; type Props = OwnProps & StateProps & DispatchProps; + class OnlineSendClass extends Component { public state: State = INITIAL_STATE; public render() { const displayModal = this.state.showModal ? ( - + ) : null; return !this.props.offline ? ( diff --git a/common/components/SendButtonFactory/SendButtonFactory.tsx b/common/components/SendButtonFactory/SendButtonFactory.tsx index 39338d68..0b8d5128 100644 --- a/common/components/SendButtonFactory/SendButtonFactory.tsx +++ b/common/components/SendButtonFactory/SendButtonFactory.tsx @@ -8,6 +8,7 @@ import { getWalletType, IWalletType } from 'selectors/wallet'; import React, { Component } from 'react'; import { connect } from 'react-redux'; import { AppState } from 'reducers'; +import { ConfirmationModal } from 'components/ConfirmationModal'; export interface CallbackProps { onClick(): void; @@ -18,6 +19,7 @@ interface StateProps { } interface OwnProps { onlyTransactionParameters?: boolean; + Modal: typeof ConfirmationModal; withProps(props: CallbackProps): React.ReactElement | null; } @@ -62,7 +64,7 @@ class SendButtonFactoryClass extends Component {
)} - + )} /> diff --git a/common/containers/Tabs/Contracts/components/Deploy.tsx b/common/containers/Tabs/Contracts/components/Deploy.tsx index 291f3293..e773be30 100644 --- a/common/containers/Tabs/Contracts/components/Deploy.tsx +++ b/common/containers/Tabs/Contracts/components/Deploy.tsx @@ -12,6 +12,7 @@ import { connect } from 'react-redux'; import { FullWalletOnly } from 'components/renderCbs'; import { NonceField, TXMetaDataPanel } from 'components'; import './Deploy.scss'; +import { ConfirmationModal } from 'components/ConfirmationModal'; interface DispatchProps { setToField: TSetToField; @@ -73,6 +74,7 @@ class DeployClass extends Component { {translate('NAV_DeployContract')} )} + Modal={ConfirmationModal} /> );