[FEATURE] Move the Schedule Payment to the main tab.
This commit is contained in:
parent
577ab52a4e
commit
eb19dd9f0b
|
@ -1,24 +1,32 @@
|
||||||
import { GenerateTransactionFactory } from './GenerateTransactionFactory';
|
import { GenerateTransactionFactory } from './GenerateTransactionFactory';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import { SigningStatus } from 'components';
|
import { ScheduleTransactionFactory } from './ScheduleTransactionFactory';
|
||||||
import './GenerateTransaction.scss';
|
|
||||||
|
|
||||||
export const GenerateTransaction: React.SFC<{}> = () => (
|
interface Props {
|
||||||
<React.Fragment>
|
scheduling?: boolean;
|
||||||
<GenerateTransactionFactory
|
}
|
||||||
|
|
||||||
|
export const GenerateTransaction: React.SFC<Props> = props => {
|
||||||
|
if (props.scheduling) {
|
||||||
|
return (
|
||||||
|
<ScheduleTransactionFactory
|
||||||
withProps={({ disabled, isWeb3Wallet, onClick }) => (
|
withProps={({ disabled, isWeb3Wallet, onClick }) => (
|
||||||
<React.Fragment>
|
<button disabled={disabled} className="btn btn-info btn-block" onClick={onClick}>
|
||||||
<button
|
{isWeb3Wallet ? translate('SCHEDULE_schedule') : translate('DEP_signtx')}
|
||||||
disabled={disabled}
|
|
||||||
className="btn btn-info btn-block GenerateTransaction"
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
{isWeb3Wallet ? translate('SEND_GENERATE') : translate('DEP_SIGNTX')}
|
|
||||||
</button>
|
</button>
|
||||||
</React.Fragment>
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<SigningStatus />
|
);
|
||||||
</React.Fragment>
|
}
|
||||||
);
|
|
||||||
|
return (
|
||||||
|
<GenerateTransactionFactory
|
||||||
|
withProps={({ disabled, isWeb3Wallet, onClick }) => (
|
||||||
|
<button disabled={disabled} className="btn btn-info btn-block" onClick={onClick}>
|
||||||
|
{isWeb3Wallet ? translate('SEND_generate') : translate('DEP_signtx')}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -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>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
|
@ -57,8 +57,8 @@ class AdvancedGas extends React.Component<Props, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const { autoGasLimitEnabled, gasPrice, validGasPrice, scheduling } = this.props;
|
const { autoGasLimitEnabled, gasPrice, validGasPrice } = this.props;
|
||||||
const { gasPriceField, gasLimitField, nonceField, dataField, feeSummary } = this.state.options;
|
const { gasPriceField, gasLimitField, nonceField, dataField } = this.state.options;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="AdvancedGas row form-group">
|
<div className="AdvancedGas row form-group">
|
||||||
|
@ -111,22 +111,21 @@ class AdvancedGas extends React.Component<Props, State> {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!scheduling &&
|
{this.renderFee()}
|
||||||
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>
|
</div>
|
||||||
)}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
{scheduling &&
|
private renderFee() {
|
||||||
feeSummary && (
|
const { gasPrice, scheduling } = this.props;
|
||||||
|
const { feeSummary } = this.state.options;
|
||||||
|
|
||||||
|
if (!feeSummary) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scheduling) {
|
||||||
|
return (
|
||||||
<div className="AdvancedGas-fee-summary">
|
<div className="AdvancedGas-fee-summary">
|
||||||
<SchedulingFeeSummary
|
<SchedulingFeeSummary
|
||||||
gasPrice={gasPrice}
|
gasPrice={gasPrice}
|
||||||
|
@ -143,7 +142,19 @@ class AdvancedGas extends React.Component<Props, State> {
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { gasPriceDefaults } from 'config';
|
||||||
import { InlineSpinner } from 'components/ui/InlineSpinner';
|
import { InlineSpinner } from 'components/ui/InlineSpinner';
|
||||||
import { TInputGasPrice } from 'actions/transaction';
|
import { TInputGasPrice } from 'actions/transaction';
|
||||||
import SchedulingFeeSummary from './SchedulingFeeSummary';
|
import SchedulingFeeSummary from './SchedulingFeeSummary';
|
||||||
|
import FeeSummary from './FeeSummary';
|
||||||
const SliderWithTooltip = createSliderWithTooltip(Slider);
|
const SliderWithTooltip = createSliderWithTooltip(Slider);
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
|
@ -114,6 +115,17 @@ class SimpleGas extends React.Component<Props> {
|
||||||
<span>{translate('TX_FEE_SCALE_RIGHT')}</span>
|
<span>{translate('TX_FEE_SCALE_RIGHT')}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{this.renderFee()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderFee() {
|
||||||
|
const { gasPrice, scheduling } = this.props;
|
||||||
|
|
||||||
|
if (scheduling) {
|
||||||
|
return (
|
||||||
<SchedulingFeeSummary
|
<SchedulingFeeSummary
|
||||||
gasPrice={gasPrice}
|
gasPrice={gasPrice}
|
||||||
render={({ fee, usd }) => (
|
render={({ fee, usd }) => (
|
||||||
|
@ -122,8 +134,18 @@ class SimpleGas extends React.Component<Props> {
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
);
|
||||||
</div>
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FeeSummary
|
||||||
|
gasPrice={gasPrice}
|
||||||
|
render={({ fee, usd }) => (
|
||||||
|
<span>
|
||||||
|
{fee} {usd && <span>/ ${usd}</span>}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ export * from './GenerateTransaction';
|
||||||
export * from './SendButton';
|
export * from './SendButton';
|
||||||
export * from './SigningStatus';
|
export * from './SigningStatus';
|
||||||
export * from './WindowStartField';
|
export * from './WindowStartField';
|
||||||
export * from './ScheduleTransaction';
|
|
||||||
export { default as NonceField } from './NonceField';
|
export { default as NonceField } from './NonceField';
|
||||||
export { default as Header } from './Header';
|
export { default as Header } from './Header';
|
||||||
export { default as Footer } from './Footer';
|
export { default as Footer } from './Footer';
|
||||||
|
|
|
@ -7,14 +7,17 @@ import {
|
||||||
TXMetaDataPanel,
|
TXMetaDataPanel,
|
||||||
CurrentCustomMessage,
|
CurrentCustomMessage,
|
||||||
GenerateTransaction,
|
GenerateTransaction,
|
||||||
SendButton
|
SendButton,
|
||||||
|
SigningStatus,
|
||||||
|
WindowStartField
|
||||||
} from 'components';
|
} from 'components';
|
||||||
import { OnlyUnlocked, WhenQueryExists } from 'components/renderCbs';
|
import { OnlyUnlocked, WhenQueryExists } from 'components/renderCbs';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
|
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { NonStandardTransaction } from './components';
|
import { NonStandardTransaction } from './components';
|
||||||
import { getOffline } from 'selectors/config';
|
import { getCurrentWindowStart, ICurrentWindowStart } from 'selectors/transaction';
|
||||||
|
import { getNetworkConfig } from 'selectors/config';
|
||||||
|
|
||||||
const QueryWarning: React.SFC<{}> = () => (
|
const QueryWarning: React.SFC<{}> = () => (
|
||||||
<WhenQueryExists
|
<WhenQueryExists
|
||||||
|
@ -27,13 +30,57 @@ const QueryWarning: React.SFC<{}> = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
|
schedulingDisabled: boolean;
|
||||||
shouldDisplay: boolean;
|
shouldDisplay: boolean;
|
||||||
offline: boolean;
|
offline: boolean;
|
||||||
|
windowStart: ICurrentWindowStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
class FieldsClass extends Component<StateProps> {
|
class FieldsClass extends Component<StateProps> {
|
||||||
public render() {
|
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 (
|
return (
|
||||||
<OnlyUnlocked
|
<OnlyUnlocked
|
||||||
whenUnlocked={
|
whenUnlocked={
|
||||||
|
@ -69,5 +116,7 @@ class FieldsClass extends Component<StateProps> {
|
||||||
|
|
||||||
export const Fields = connect((state: AppState) => ({
|
export const Fields = connect((state: AppState) => ({
|
||||||
shouldDisplay: !isAnyOfflineWithWeb3(state),
|
shouldDisplay: !isAnyOfflineWithWeb3(state),
|
||||||
offline: getOffline(state)
|
offline: getOffline(state),
|
||||||
|
windowStart: getCurrentWindowStart(state),
|
||||||
|
schedulingDisabled: getNetworkConfig(state).name !== 'Kovan'
|
||||||
}))(FieldsClass);
|
}))(FieldsClass);
|
||||||
|
|
|
@ -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);
|
|
|
@ -1,2 +1 @@
|
||||||
export * from './Fields';
|
export * from './Fields';
|
||||||
export * from './SchedulingFields';
|
|
||||||
|
|
|
@ -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>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -3,4 +3,4 @@ export * from './UnavailableWallets';
|
||||||
export * from './SideBar';
|
export * from './SideBar';
|
||||||
export { default as WalletInfo } from './WalletInfo';
|
export { default as WalletInfo } from './WalletInfo';
|
||||||
export { default as RequestPayment } from './RequestPayment';
|
export { default as RequestPayment } from './RequestPayment';
|
||||||
export { default as SchedulePayment } from './SchedulePayment';
|
export { default as RecentTransactions } from './RecentTransactions';
|
||||||
|
|
|
@ -12,13 +12,11 @@ import {
|
||||||
RequestPayment,
|
RequestPayment,
|
||||||
RecentTransactions,
|
RecentTransactions,
|
||||||
Fields,
|
Fields,
|
||||||
UnavailableWallets,
|
UnavailableWallets
|
||||||
SchedulePayment
|
|
||||||
} from 'containers/Tabs/SendTransaction/components';
|
} from 'containers/Tabs/SendTransaction/components';
|
||||||
import SubTabs, { Tab } from 'components/SubTabs';
|
import SubTabs, { Tab } from 'components/SubTabs';
|
||||||
import { RouteNotFound } from 'components/RouteNotFound';
|
import { RouteNotFound } from 'components/RouteNotFound';
|
||||||
import { isNetworkUnit } from 'selectors/config/wallet';
|
import { isNetworkUnit } from 'selectors/config/wallet';
|
||||||
import { getNetworkConfig } from 'selectors/config/networks';
|
|
||||||
|
|
||||||
const Send = () => (
|
const Send = () => (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
@ -30,7 +28,6 @@ const Send = () => (
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
wallet: AppState['wallet']['inst'];
|
wallet: AppState['wallet']['inst'];
|
||||||
requestDisabled: boolean;
|
requestDisabled: boolean;
|
||||||
scheduleDisabled: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = StateProps & RouteComponentProps<{}>;
|
type Props = StateProps & RouteComponentProps<{}>;
|
||||||
|
@ -45,11 +42,6 @@ class SendTransaction extends React.Component<Props> {
|
||||||
name: translate('NAV_SENDETHER'),
|
name: translate('NAV_SENDETHER'),
|
||||||
disabled: !!wallet && !!wallet.isReadOnly
|
disabled: !!wallet && !!wallet.isReadOnly
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'schedule',
|
|
||||||
name: translate('NAV_SchedulePayment'),
|
|
||||||
disabled: (!!wallet && !!wallet.isReadOnly) || this.props.scheduleDisabled
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'request',
|
path: 'request',
|
||||||
name: translate('Request Payment'),
|
name: translate('Request Payment'),
|
||||||
|
@ -104,15 +96,9 @@ class SendTransaction extends React.Component<Props> {
|
||||||
render={() => <RequestPayment wallet={wallet} />}
|
render={() => <RequestPayment wallet={wallet} />}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={`${currentPath}/schedule`}
|
path={`${currentPath}/recent-txs`}
|
||||||
exact={true}
|
exact={true}
|
||||||
render={() => {
|
render={() => <RecentTransactions wallet={wallet} />}
|
||||||
return wallet.isReadOnly || this.props.scheduleDisabled ? (
|
|
||||||
<Redirect to={`${currentPath}/info`} />
|
|
||||||
) : (
|
|
||||||
<SchedulePayment />
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<RouteNotFound />
|
<RouteNotFound />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
@ -128,6 +114,5 @@ class SendTransaction extends React.Component<Props> {
|
||||||
|
|
||||||
export default connect((state: AppState) => ({
|
export default connect((state: AppState) => ({
|
||||||
wallet: getWalletInst(state),
|
wallet: getWalletInst(state),
|
||||||
requestDisabled: !isNetworkUnit(state, 'ETH'),
|
requestDisabled: !isNetworkUnit(state, 'ETH')
|
||||||
scheduleDisabled: getNetworkConfig(state).name !== 'Kovan'
|
|
||||||
}))(SendTransaction);
|
}))(SendTransaction);
|
||||||
|
|
|
@ -42,6 +42,5 @@ exports[`render snapshot 1`] = `
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
requestDisabled={false}
|
requestDisabled={false}
|
||||||
scheduleDisabled={true}
|
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
|
|
Loading…
Reference in New Issue