[FEATURE] Move the Schedule Payment to the main tab.

This commit is contained in:
Daniel Kmak 2018-03-20 14:11:04 +01:00 committed by Bagaric
parent 577ab52a4e
commit eb19dd9f0b
13 changed files with 156 additions and 211 deletions

View File

@ -1,24 +1,32 @@
import { GenerateTransactionFactory } from './GenerateTransactionFactory';
import React from 'react';
import translate from 'translations';
import { SigningStatus } from 'components';
import './GenerateTransaction.scss';
import { ScheduleTransactionFactory } from './ScheduleTransactionFactory';
export const GenerateTransaction: React.SFC<{}> = () => (
<React.Fragment>
interface Props {
scheduling?: boolean;
}
export const GenerateTransaction: React.SFC<Props> = props => {
if (props.scheduling) {
return (
<ScheduleTransactionFactory
withProps={({ disabled, isWeb3Wallet, onClick }) => (
<button disabled={disabled} className="btn btn-info btn-block" onClick={onClick}>
{isWeb3Wallet ? translate('SCHEDULE_schedule') : translate('DEP_signtx')}
</button>
)}
/>
);
}
return (
<GenerateTransactionFactory
withProps={({ disabled, isWeb3Wallet, onClick }) => (
<React.Fragment>
<button
disabled={disabled}
className="btn btn-info btn-block GenerateTransaction"
onClick={onClick}
>
{isWeb3Wallet ? translate('SEND_GENERATE') : translate('DEP_SIGNTX')}
</button>
</React.Fragment>
<button disabled={disabled} className="btn btn-info btn-block" onClick={onClick}>
{isWeb3Wallet ? translate('SEND_generate') : translate('DEP_signtx')}
</button>
)}
/>
<SigningStatus />
</React.Fragment>
);
);
};

View File

@ -1,13 +0,0 @@
import { ScheduleTransactionFactory } from './ScheduleTransactionFactory';
import React from 'react';
import translate from 'translations';
export const ScheduleTransaction: React.SFC<{}> = () => (
<ScheduleTransactionFactory
withProps={({ disabled, isWeb3Wallet, onClick }) => (
<button disabled={disabled} className="btn btn-info btn-block" onClick={onClick}>
{isWeb3Wallet ? translate('SCHEDULE_schedule') : translate('DEP_signtx')}
</button>
)}
/>
);

View File

@ -57,8 +57,8 @@ class AdvancedGas extends React.Component<Props, State> {
};
public render() {
const { autoGasLimitEnabled, gasPrice, validGasPrice, scheduling } = this.props;
const { gasPriceField, gasLimitField, nonceField, dataField, feeSummary } = this.state.options;
const { autoGasLimitEnabled, gasPrice, validGasPrice } = this.props;
const { gasPriceField, gasLimitField, nonceField, dataField } = this.state.options;
return (
<div className="AdvancedGas row form-group">
@ -111,39 +111,50 @@ class AdvancedGas extends React.Component<Props, State> {
</div>
)}
{!scheduling &&
feeSummary && (
<div className="AdvancedGas-fee-summary">
<FeeSummary
gasPrice={gasPrice}
render={({ gasPriceWei, gasLimit, fee, usd }) => (
<span>
{gasPriceWei} * {gasLimit} = {fee} {usd && <span>~= ${usd} USD</span>}
</span>
)}
/>
</div>
)}
{this.renderFee()}
</div>
);
}
{scheduling &&
feeSummary && (
<div className="AdvancedGas-fee-summary">
<SchedulingFeeSummary
gasPrice={gasPrice}
render={({ gasPriceWei, gasLimit, fee, usd }) => (
<div>
<span>
{EAC_SCHEDULING_CONFIG.PAYMENT} + {gasPriceWei} * ({
EAC_SCHEDULING_CONFIG.SCHEDULING_GAS_LIMIT
}{' '}
+ {EAC_SCHEDULING_CONFIG.FUTURE_EXECUTION_COST} + {gasLimit}) = {fee}{' '}
{usd && <span>~= ${usd} USD</span>}
</span>
</div>
)}
/>
</div>
private renderFee() {
const { gasPrice, scheduling } = this.props;
const { feeSummary } = this.state.options;
if (!feeSummary) {
return;
}
if (scheduling) {
return (
<div className="AdvancedGas-fee-summary">
<SchedulingFeeSummary
gasPrice={gasPrice}
render={({ gasPriceWei, gasLimit, fee, usd }) => (
<div>
<span>
{EAC_SCHEDULING_CONFIG.PAYMENT} + {gasPriceWei} * ({
EAC_SCHEDULING_CONFIG.SCHEDULING_GAS_LIMIT
}{' '}
+ {EAC_SCHEDULING_CONFIG.FUTURE_EXECUTION_COST} + {gasLimit}) = {fee}{' '}
{usd && <span>~= ${usd} USD</span>}
</span>
</div>
)}
/>
</div>
);
}
return (
<div className="AdvancedGas-fee-summary">
<FeeSummary
gasPrice={gasPrice}
render={({ gasPriceWei, gasLimit, fee, usd }) => (
<span>
{gasPriceWei} * {gasLimit} = {fee} {usd && <span>~= ${usd} USD</span>}
</span>
)}
/>
</div>
);
}

View File

@ -17,6 +17,7 @@ import { gasPriceDefaults } from 'config';
import { InlineSpinner } from 'components/ui/InlineSpinner';
import { TInputGasPrice } from 'actions/transaction';
import SchedulingFeeSummary from './SchedulingFeeSummary';
import FeeSummary from './FeeSummary';
const SliderWithTooltip = createSliderWithTooltip(Slider);
interface OwnProps {
@ -114,19 +115,40 @@ class SimpleGas extends React.Component<Props> {
<span>{translate('TX_FEE_SCALE_RIGHT')}</span>
</div>
</div>
<SchedulingFeeSummary
gasPrice={gasPrice}
render={({ fee, usd }) => (
<span>
{fee} {usd && <span>/ ${usd}</span>}
</span>
)}
/>
{this.renderFee()}
</div>
</div>
);
}
private renderFee() {
const { gasPrice, scheduling } = this.props;
if (scheduling) {
return (
<SchedulingFeeSummary
gasPrice={gasPrice}
render={({ fee, usd }) => (
<span>
{fee} {usd && <span>/ ${usd}</span>}
</span>
)}
/>
);
}
return (
<FeeSummary
gasPrice={gasPrice}
render={({ fee, usd }) => (
<span>
{fee} {usd && <span>/ ${usd}</span>}
</span>
)}
/>
);
}
private handleSlider = (gasGwei: number) => {
this.props.inputGasPrice(gasGwei.toString());
};

View File

@ -9,7 +9,6 @@ export * from './GenerateTransaction';
export * from './SendButton';
export * from './SigningStatus';
export * from './WindowStartField';
export * from './ScheduleTransaction';
export { default as NonceField } from './NonceField';
export { default as Header } from './Header';
export { default as Footer } from './Footer';

View File

@ -7,14 +7,17 @@ import {
TXMetaDataPanel,
CurrentCustomMessage,
GenerateTransaction,
SendButton
SendButton,
SigningStatus,
WindowStartField
} from 'components';
import { OnlyUnlocked, WhenQueryExists } from 'components/renderCbs';
import translate from 'translations';
import { AppState } from 'reducers';
import { NonStandardTransaction } from './components';
import { getOffline } from 'selectors/config';
import { getCurrentWindowStart, ICurrentWindowStart } from 'selectors/transaction';
import { getNetworkConfig } from 'selectors/config';
const QueryWarning: React.SFC<{}> = () => (
<WhenQueryExists
@ -27,13 +30,57 @@ const QueryWarning: React.SFC<{}> = () => (
);
interface StateProps {
schedulingDisabled: boolean;
shouldDisplay: boolean;
offline: boolean;
windowStart: ICurrentWindowStart;
}
class FieldsClass extends Component<StateProps> {
public render() {
const { shouldDisplay, offline } = this.props;
const { schedulingDisabled, shouldDisplay, windowStart } = this.props;
const scheduling = Boolean(windowStart.value);
const content = (
<div className="Tab-content-pane">
<AddressField />
<div className="row form-group">
<div className="col-xs-12">
<AmountField hasUnitDropdown={true} />
<SendEverything />
</div>
</div>
{!schedulingDisabled && (
<div className="row form-group">
<div className="col-xs-12">
<WindowStartField />
</div>
</div>
)}
<div className="row form-group">
<div className="col-xs-12">
<TXMetaDataPanel scheduling={scheduling} />
</div>
</div>
<CurrentCustomMessage />
<NonStandardTransaction />
<div className="row form-group">
<div className="col-xs-12 clearfix">
<GenerateTransaction scheduling={scheduling} />
</div>
</div>
<SigningStatus />
<div className="row form-group">
<SendButton />
</div>
</div>
);
return (
<OnlyUnlocked
whenUnlocked={
@ -69,5 +116,7 @@ class FieldsClass extends Component<StateProps> {
export const Fields = connect((state: AppState) => ({
shouldDisplay: !isAnyOfflineWithWeb3(state),
offline: getOffline(state)
offline: getOffline(state),
windowStart: getCurrentWindowStart(state),
schedulingDisabled: getNetworkConfig(state).name !== 'Kovan'
}))(FieldsClass);

View File

@ -1,103 +0,0 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { isAnyOfflineWithWeb3 } from 'selectors/derived';
import {
AddressField,
AmountField,
TXMetaDataPanel,
SendEverything,
CurrentCustomMessage,
ScheduleTransaction,
SendButton,
SigningStatus,
WindowStartField
} from 'components';
import { OnlyUnlocked, WhenQueryExists } from 'components/renderCbs';
import translate from 'translations';
import { AppState } from 'reducers';
import { NonStandardTransaction } from './components';
import { NewTabLink } from 'components/ui';
const EACLink = () => (
<NewTabLink href="https://chronologic.network" content="Ethereum Alarm Clock" />
);
const content = (
<div className="Tab-content-pane">
<div className="row form-group">
<div className="col-xs-12">
<h3>ChronoLogic Scheduler</h3>
Powered by the <EACLink />, ChronoLogic Scheduler is a decentralized scheduling protocol
based on the Ethereum blockchain.
</div>
</div>
<div className="row form-group" />
<AddressField />
<div className="row form-group">
<div className="col-xs-12">
<AmountField hasUnitDropdown={true} />
<SendEverything />
</div>
</div>
<div className="row form-group">
<div className="col-xs-12">
<WindowStartField />
</div>
</div>
<div className="row form-group">
<div className="col-xs-12">
<TXMetaDataPanel scheduling={true} />
</div>
</div>
<CurrentCustomMessage />
<NonStandardTransaction />
<div className="row form-group">
<div className="col-xs-12 clearfix">
<ScheduleTransaction />
</div>
</div>
<SigningStatus />
<div className="row form-group">
<SendButton />
</div>
</div>
);
const QueryWarning: React.SFC<{}> = () => (
<WhenQueryExists
whenQueryExists={
<div className="alert alert-info">
<p>{translate('WARN_Send_Link')}</p>
</div>
}
/>
);
interface StateProps {
shouldDisplay: boolean;
}
class SchedulingFieldsClass extends Component<StateProps> {
public render() {
const { shouldDisplay } = this.props;
return (
<OnlyUnlocked
whenUnlocked={
<React.Fragment>
<QueryWarning />
{shouldDisplay ? content : null}
</React.Fragment>
}
/>
);
}
}
export const SchedulingFields = connect((state: AppState) => ({
shouldDisplay: !isAnyOfflineWithWeb3(state)
}))(SchedulingFieldsClass);

View File

@ -1,2 +1 @@
export * from './Fields';
export * from './SchedulingFields';

View File

@ -1,11 +0,0 @@
import React from 'react';
import { SchedulingFields, UnavailableWallets } from 'containers/Tabs/SendTransaction/components';
export default function() {
return (
<React.Fragment>
<SchedulingFields />
<UnavailableWallets />
</React.Fragment>
);
}

View File

@ -3,4 +3,4 @@ export * from './UnavailableWallets';
export * from './SideBar';
export { default as WalletInfo } from './WalletInfo';
export { default as RequestPayment } from './RequestPayment';
export { default as SchedulePayment } from './SchedulePayment';
export { default as RecentTransactions } from './RecentTransactions';

View File

@ -12,13 +12,11 @@ import {
RequestPayment,
RecentTransactions,
Fields,
UnavailableWallets,
SchedulePayment
UnavailableWallets
} from 'containers/Tabs/SendTransaction/components';
import SubTabs, { Tab } from 'components/SubTabs';
import { RouteNotFound } from 'components/RouteNotFound';
import { isNetworkUnit } from 'selectors/config/wallet';
import { getNetworkConfig } from 'selectors/config/networks';
const Send = () => (
<React.Fragment>
@ -30,7 +28,6 @@ const Send = () => (
interface StateProps {
wallet: AppState['wallet']['inst'];
requestDisabled: boolean;
scheduleDisabled: boolean;
}
type Props = StateProps & RouteComponentProps<{}>;
@ -45,11 +42,6 @@ class SendTransaction extends React.Component<Props> {
name: translate('NAV_SENDETHER'),
disabled: !!wallet && !!wallet.isReadOnly
},
{
path: 'schedule',
name: translate('NAV_SchedulePayment'),
disabled: (!!wallet && !!wallet.isReadOnly) || this.props.scheduleDisabled
},
{
path: 'request',
name: translate('Request Payment'),
@ -104,15 +96,9 @@ class SendTransaction extends React.Component<Props> {
render={() => <RequestPayment wallet={wallet} />}
/>
<Route
path={`${currentPath}/schedule`}
path={`${currentPath}/recent-txs`}
exact={true}
render={() => {
return wallet.isReadOnly || this.props.scheduleDisabled ? (
<Redirect to={`${currentPath}/info`} />
) : (
<SchedulePayment />
);
}}
render={() => <RecentTransactions wallet={wallet} />}
/>
<RouteNotFound />
</Switch>
@ -128,6 +114,5 @@ class SendTransaction extends React.Component<Props> {
export default connect((state: AppState) => ({
wallet: getWalletInst(state),
requestDisabled: !isNetworkUnit(state, 'ETH'),
scheduleDisabled: getNetworkConfig(state).name !== 'Kovan'
requestDisabled: !isNetworkUnit(state, 'ETH')
}))(SendTransaction);

View File

@ -42,6 +42,5 @@ exports[`render snapshot 1`] = `
}
}
requestDisabled={false}
scheduleDisabled={true}
/>
`;