Generic Confirmation Modal (#940)
* Make generic modal * Allow generic modals to be injected into send button component
This commit is contained in:
parent
9fd00a4f70
commit
c84740c4d4
|
@ -1 +0,0 @@
|
||||||
export * from './ConfirmationModal';
|
|
|
@ -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<OwnProps> = ({ onClose }) => (
|
||||||
|
<ConfirmationModalTemplate summary={<Summary />} details={<Details />} onClose={onClose} />
|
||||||
|
);
|
|
@ -1,6 +1,5 @@
|
||||||
import Modal, { IButton } from 'components/ui/Modal';
|
import Modal, { IButton } from 'components/ui/Modal';
|
||||||
import Spinner from 'components/ui/Spinner';
|
import Spinner from 'components/ui/Spinner';
|
||||||
import { Details, Summary } from './components';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { getWalletType, IWalletType } from 'selectors/wallet';
|
import { getWalletType, IWalletType } from 'selectors/wallet';
|
||||||
|
@ -17,13 +16,14 @@ import {
|
||||||
currentTransactionFailed
|
currentTransactionFailed
|
||||||
} from 'selectors/transaction';
|
} from 'selectors/transaction';
|
||||||
import translate, { translateRaw } from 'translations';
|
import translate, { translateRaw } from 'translations';
|
||||||
import './ConfirmationModal.scss';
|
import './ConfirmationModalTemplate.scss';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
|
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
broadcastLocalTransactionRequested: TBroadcastLocalTransactionRequested;
|
broadcastLocalTransactionRequested: TBroadcastLocalTransactionRequested;
|
||||||
broadcastWeb3TransactionRequested: TBroadcastWeb3TransactionRequested;
|
broadcastWeb3TransactionRequested: TBroadcastWeb3TransactionRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
lang: string;
|
lang: string;
|
||||||
walletTypes: IWalletType;
|
walletTypes: IWalletType;
|
||||||
|
@ -31,7 +31,20 @@ interface StateProps {
|
||||||
transactionBroadcasted: boolean;
|
transactionBroadcasted: boolean;
|
||||||
transactionFailed: 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<any> | null;
|
||||||
|
details: React.ReactElement<any> | null;
|
||||||
|
withConfirmButton?(props: ConfirmButtonCBProps): IButton;
|
||||||
onClose(): void;
|
onClose(): void;
|
||||||
}
|
}
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -41,7 +54,7 @@ interface State {
|
||||||
|
|
||||||
type Props = DispatchProps & StateProps & OwnProps;
|
type Props = DispatchProps & StateProps & OwnProps;
|
||||||
|
|
||||||
class ConfirmationModalClass extends React.Component<Props, State> {
|
class ConfirmationModalTemplateClass extends React.Component<Props, State> {
|
||||||
private readTimer = 0;
|
private readTimer = 0;
|
||||||
public constructor(props: Props) {
|
public constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -72,15 +85,27 @@ class ConfirmationModalClass extends React.Component<Props, State> {
|
||||||
public render() {
|
public render() {
|
||||||
const { onClose, transactionBroadcasting } = this.props;
|
const { onClose, transactionBroadcasting } = this.props;
|
||||||
const { timeToRead } = this.state;
|
const { timeToRead } = this.state;
|
||||||
|
|
||||||
const buttonPrefix = timeToRead > 0 ? `(${timeToRead}) ` : '';
|
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[] = [
|
const buttons: IButton[] = [
|
||||||
{
|
confirmButton,
|
||||||
text: buttonPrefix + translateRaw('SENDModal_Yes'),
|
|
||||||
type: 'primary',
|
|
||||||
disabled: timeToRead > 0,
|
|
||||||
onClick: this.confirm
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
text: translateRaw('SENDModal_No'),
|
text: translateRaw('SENDModal_No'),
|
||||||
type: 'default',
|
type: 'default',
|
||||||
|
@ -104,9 +129,8 @@ class ConfirmationModalClass extends React.Component<Props, State> {
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<Summary />
|
{this.props.summary}
|
||||||
<Details />
|
{this.props.details}
|
||||||
|
|
||||||
<div className="ConfModal-confirm">{translate('SENDModal_Content_3')}</div>
|
<div className="ConfModal-confirm">{translate('SENDModal_Content_3')}</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -130,7 +154,7 @@ class ConfirmationModalClass extends React.Component<Props, State> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConfirmationModal = connect(
|
export const ConfirmationModalTemplate = connect(
|
||||||
(state: AppState) => ({
|
(state: AppState) => ({
|
||||||
transactionBroadcasting: currentTransactionBroadcasting(state),
|
transactionBroadcasting: currentTransactionBroadcasting(state),
|
||||||
transactionBroadcasted: currentTransactionBroadcasted(state),
|
transactionBroadcasted: currentTransactionBroadcasted(state),
|
||||||
|
@ -139,4 +163,4 @@ export const ConfirmationModal = connect(
|
||||||
walletTypes: getWalletType(state)
|
walletTypes: getWalletType(state)
|
||||||
}),
|
}),
|
||||||
{ broadcastLocalTransactionRequested, broadcastWeb3TransactionRequested }
|
{ broadcastLocalTransactionRequested, broadcastWeb3TransactionRequested }
|
||||||
)(ConfirmationModalClass);
|
)(ConfirmationModalTemplateClass);
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './ConfirmationModalTemplate';
|
|
@ -1,12 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SendButtonFactory } from './SendButtonFactory';
|
import { SendButtonFactory } from './SendButtonFactory';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
|
import { ConfirmationModal } from 'components/ConfirmationModal';
|
||||||
|
|
||||||
export const SendButton: React.SFC<{ onlyTransactionParameters?: boolean }> = ({
|
export const SendButton: React.SFC<{
|
||||||
onlyTransactionParameters
|
onlyTransactionParameters?: boolean;
|
||||||
}) => (
|
customModal?: typeof ConfirmationModal;
|
||||||
|
}> = ({ onlyTransactionParameters, customModal }) => (
|
||||||
<SendButtonFactory
|
<SendButtonFactory
|
||||||
onlyTransactionParameters={!!onlyTransactionParameters}
|
onlyTransactionParameters={!!onlyTransactionParameters}
|
||||||
|
Modal={customModal ? customModal : ConfirmationModal}
|
||||||
withProps={({ onClick }) => (
|
withProps={({ onClick }) => (
|
||||||
<div className="row form-group">
|
<div className="row form-group">
|
||||||
<div className="col-xs-12">
|
<div className="col-xs-12">
|
||||||
|
|
|
@ -22,20 +22,24 @@ interface DispatchProps {
|
||||||
showNotification: TShowNotification;
|
showNotification: TShowNotification;
|
||||||
reset: TReset;
|
reset: TReset;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
|
Modal: typeof ConfirmationModal;
|
||||||
withProps(props: CallbackProps): React.ReactElement<any> | null;
|
withProps(props: CallbackProps): React.ReactElement<any> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const INITIAL_STATE: State = {
|
const INITIAL_STATE: State = {
|
||||||
showModal: false
|
showModal: false
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = OwnProps & StateProps & DispatchProps;
|
type Props = OwnProps & StateProps & DispatchProps;
|
||||||
|
|
||||||
class OnlineSendClass extends Component<Props, State> {
|
class OnlineSendClass extends Component<Props, State> {
|
||||||
public state: State = INITIAL_STATE;
|
public state: State = INITIAL_STATE;
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const displayModal = this.state.showModal ? (
|
const displayModal = this.state.showModal ? (
|
||||||
<ConfirmationModal onClose={this.toggleModal} />
|
<this.props.Modal onClose={this.toggleModal} />
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
return !this.props.offline ? (
|
return !this.props.offline ? (
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { getWalletType, IWalletType } from 'selectors/wallet';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
|
import { ConfirmationModal } from 'components/ConfirmationModal';
|
||||||
|
|
||||||
export interface CallbackProps {
|
export interface CallbackProps {
|
||||||
onClick(): void;
|
onClick(): void;
|
||||||
|
@ -18,6 +19,7 @@ interface StateProps {
|
||||||
}
|
}
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
onlyTransactionParameters?: boolean;
|
onlyTransactionParameters?: boolean;
|
||||||
|
Modal: typeof ConfirmationModal;
|
||||||
withProps(props: CallbackProps): React.ReactElement<any> | null;
|
withProps(props: CallbackProps): React.ReactElement<any> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +64,7 @@ class SendButtonFactoryClass extends Component<Props> {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<OfflineBroadcast />
|
<OfflineBroadcast />
|
||||||
<OnlineSend withProps={this.props.withProps} />
|
<OnlineSend withProps={this.props.withProps} Modal={this.props.Modal} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { connect } from 'react-redux';
|
||||||
import { FullWalletOnly } from 'components/renderCbs';
|
import { FullWalletOnly } from 'components/renderCbs';
|
||||||
import { NonceField, TXMetaDataPanel } from 'components';
|
import { NonceField, TXMetaDataPanel } from 'components';
|
||||||
import './Deploy.scss';
|
import './Deploy.scss';
|
||||||
|
import { ConfirmationModal } from 'components/ConfirmationModal';
|
||||||
|
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
setToField: TSetToField;
|
setToField: TSetToField;
|
||||||
|
@ -73,6 +74,7 @@ class DeployClass extends Component<DispatchProps> {
|
||||||
{translate('NAV_DeployContract')}
|
{translate('NAV_DeployContract')}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
Modal={ConfirmationModal}
|
||||||
/>
|
/>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue