[FEATURE] Time/block selector

This commit is contained in:
Joseph Bagaric 2018-03-29 12:16:40 +02:00 committed by Bagaric
parent 49fa54ba0b
commit 09b1062db1
19 changed files with 175 additions and 10 deletions

View File

@ -13,7 +13,8 @@ import {
SetGasPriceFieldAction,
SetTimeBountyFieldAction,
SetWindowStartFieldAction,
SetScheduleTimestampFieldAction
SetScheduleTimestampFieldAction,
SetScheduleTypeAction
} from '../actionTypes';
import { TypeKeys } from 'actions/transaction/constants';
@ -107,6 +108,12 @@ const setScheduleTimestampField = (
payload
});
type TSetScheduleType = typeof setScheduleType;
const setScheduleType = (payload: SetScheduleTypeAction['payload']): SetScheduleTypeAction => ({
type: TypeKeys.SCHEDULE_TYPE_SET,
payload
});
type TReset = typeof reset;
const reset = (payload: ResetAction['payload'] = { include: {}, exclude: {} }): ResetAction => ({
type: TypeKeys.RESET,
@ -128,6 +135,7 @@ export {
TSetWindowStartField,
TSetTimeBountyField,
TSetScheduleTimestampField,
TSetScheduleType,
TReset,
inputGasLimit,
inputGasPrice,
@ -143,5 +151,6 @@ export {
setGasPriceField,
setWindowStartField,
setScheduleTimestampField,
setScheduleType,
reset
};

View File

@ -7,4 +7,5 @@ export * from './current';
export * from './timeBounty';
export * from './windowStart';
export * from './scheduleTimestamp';
export * from './scheduleType';
export * from './sendEverything';

View File

@ -0,0 +1,10 @@
import { SetCurrentScheduleTypeAction } from '../actionTypes/scheduleType';
import { TypeKeys } from '../';
export type TSetCurrentScheduleType = typeof setCurrentScheduleType;
export const setCurrentScheduleType = (
payload: SetCurrentScheduleTypeAction['payload']
): SetCurrentScheduleTypeAction => ({
type: TypeKeys.CURRENT_SCHEDULE_TYPE,
payload
});

View File

@ -107,6 +107,14 @@ interface SetScheduleTimestampFieldAction {
};
}
interface SetScheduleTypeAction {
type: TypeKeys.SCHEDULE_TYPE_SET;
payload: {
raw: string;
value: string | null;
};
}
type InputFieldAction = InputNonceAction | InputGasLimitAction | InputDataAction;
type FieldAction =
@ -118,7 +126,8 @@ type FieldAction =
| SetGasPriceFieldAction
| SetTimeBountyFieldAction
| SetWindowStartFieldAction
| SetScheduleTimestampFieldAction;
| SetScheduleTimestampFieldAction
| SetScheduleTypeAction;
export {
InputGasLimitAction,
@ -138,5 +147,6 @@ export {
SetGasPriceFieldAction,
SetTimeBountyFieldAction,
SetWindowStartFieldAction,
SetScheduleTimestampFieldAction
SetScheduleTimestampFieldAction,
SetScheduleTypeAction
};

View File

@ -0,0 +1,12 @@
import { TypeKeys } from '../constants';
/* user input */
interface SetCurrentScheduleTypeAction {
type: TypeKeys.CURRENT_SCHEDULE_TYPE;
payload: string;
}
type CurrentAction = SetCurrentScheduleTypeAction;
export { SetCurrentScheduleTypeAction, CurrentAction };

View File

@ -28,6 +28,7 @@ export enum TypeKeys {
CURRENT_TIME_BOUNTY_SET = 'CURRENT_TIME_BOUNTY_SET',
CURRENT_WINDOW_START_SET = 'CURRENT_WINDOW_START_SET',
CURRENT_SCHEDULE_TIMESTAMP_SET = 'CURRENT_SCHEDULE_TIMESTAMP_SET',
CURRENT_SCHEDULE_TYPE = 'CURRENT_SCHEDULE_TYPE',
DATA_FIELD_INPUT = 'DATA_FIELD_INPUT',
GAS_LIMIT_INPUT = 'GAS_LIMIT_INPUT',
@ -47,6 +48,7 @@ export enum TypeKeys {
WINDOW_START_FIELD_SET = 'WINDOW_START_FIELD_SET',
SCHEDULE_TIMESTAMP_FIELD_SET = 'SCHEDULE_TIMESTAMP_FIELD_SET',
SCHEDULE_TIMEZONE_SET = 'SCHEDULE_TIMEZONE_SET',
SCHEDULE_TYPE_SET = 'SCHEDULE_TYPE_SET',
TOKEN_TO_META_SET = 'TOKEN_TO_META_SET',
UNIT_META_SET = 'UNIT_META_SET',

View File

@ -0,0 +1,71 @@
import React, { Component } from 'react';
import { setScheduleType, TSetScheduleType } from 'actions/transaction';
import { connect } from 'react-redux';
import translate from 'translations';
import { getCurrentScheduleType, ICurrentScheduleType } from 'selectors/transaction';
import { AppState } from 'reducers';
interface DispatchProps {
setScheduleType: TSetScheduleType;
}
interface StateProps {
currentScheduleType: ICurrentScheduleType;
}
type Props = DispatchProps & StateProps;
class ScheduleTypeClass extends Component<Props> {
public render() {
const { currentScheduleType } = this.props;
return (
<div className="input-group-wrapper">
<label className="input-group">
<div className="row">
<div className="col-xs-6">
<div className="radio">
<label>
<input
type="radio"
name="scheduleType"
value="time"
onChange={this.handleOnChange}
checked={currentScheduleType.value === 'time'}
/>
{translate('SCHEDULE_type_time')}
</label>
</div>
</div>
<div className="col-xs-6">
<div className="radio">
<label>
<input
type="radio"
name="scheduleType"
value="block"
onChange={this.handleOnChange}
checked={currentScheduleType.value === 'block'}
/>
{translate('SCHEDULE_type_block')}
</label>
</div>
</div>
</div>
</label>
</div>
);
}
private handleOnChange = (ev: React.ChangeEvent<HTMLInputElement>) => {
const value = ev.currentTarget.value;
this.props.setScheduleType({ raw: value, value });
};
}
export const ScheduleType = connect(
(state: AppState) => ({
currentScheduleType: getCurrentScheduleType(state)
}),
{ setScheduleType }
)(ScheduleTypeClass);

View File

@ -0,0 +1 @@
export * from './ScheduleType';

View File

@ -10,6 +10,7 @@ export * from './SendButton';
export * from './SigningStatus';
export * from './ScheduleTimestampField';
export * from './ScheduleTimezoneDropDown';
export * from './ScheduleType';
export * from '../containers/Tabs/ScheduleTransaction/components';
export { default as NonceField } from './NonceField';
export { default as Header } from './Header';

View File

@ -15,7 +15,8 @@ export const EAC_SCHEDULING_CONFIG = {
TIME_BOUNTY_DEFAULT: TIME_BOUNTY_MIN,
TIME_BOUNTY_MAX: toWei('900', Units.ether.length - 1), // 900 ETH
WINDOW_SIZE_IN_BLOCKS: 90,
SCHEDULE_TIMESTAMP_FORMAT: 'YYYY-MM-DD HH:mm:ss'
SCHEDULE_TIMESTAMP_FORMAT: 'YYYY-MM-DD HH:mm:ss',
DEFAULT_SCHEDULING_METHOD: 'time'
};
export const EAC_ADDRESSES = {

View File

@ -26,6 +26,10 @@ const INITIAL_STATE: State = {
timeBounty: {
raw: fromWei(EAC_SCHEDULING_CONFIG.TIME_BOUNTY_DEFAULT, 'ether'),
value: EAC_SCHEDULING_CONFIG.TIME_BOUNTY_DEFAULT
},
scheduleType: {
raw: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD,
value: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD
}
};
@ -82,6 +86,8 @@ export const fields = (
return updateField('windowStart')(state, action);
case TK.SCHEDULE_TIMESTAMP_FIELD_SET:
return updateField('scheduleTimestamp')(state, action);
case TK.SCHEDULE_TYPE_SET:
return updateField('scheduleType')(state, action);
case TK.TOKEN_TO_ETHER_SWAP:
return tokenToEther(state, action);
case TK.ETHER_TO_TOKEN_SWAP:

View File

@ -4,7 +4,8 @@ import {
SetNonceFieldAction,
SetGasLimitFieldAction,
SetWindowStartFieldAction,
SetScheduleTimestampFieldAction
SetScheduleTimestampFieldAction,
SetScheduleTypeAction
} from 'actions/transaction';
import { Wei } from 'libs/units';
@ -18,4 +19,5 @@ export interface State {
timeBounty: { raw: string; value: Wei };
windowStart: SetWindowStartFieldAction['payload'];
scheduleTimestamp: SetScheduleTimestampFieldAction['payload'];
scheduleType: SetScheduleTypeAction['payload'];
}

View File

@ -13,6 +13,7 @@ const getNonce = (state: AppState) => getFields(state).nonce;
const getTimeBounty = (state: AppState) => getFields(state).timeBounty;
const getWindowStart = (state: AppState) => getFields(state).windowStart;
const getScheduleTimestamp = (state: AppState) => getFields(state).scheduleTimestamp;
const getScheduleType = (state: AppState) => getFields(state).scheduleType;
const getDataExists = (state: AppState) => {
const { value } = getData(state);
@ -41,5 +42,6 @@ export {
getValidGasCost,
getTimeBounty,
getWindowStart,
getScheduleTimestamp
getScheduleTimestamp,
getScheduleType
};

View File

@ -7,4 +7,5 @@ export * from './current';
export * from './windowStart';
export * from './timeBounty';
export * from './scheduleTimestamp';
export * from './scheduleType';
export * from './network';

View File

@ -0,0 +1,11 @@
import { AppState } from 'reducers';
import { getScheduleType } from './fields';
interface ICurrentScheduleType {
raw: string;
value: string | null;
}
const getCurrentScheduleType = (state: AppState): ICurrentScheduleType => getScheduleType(state);
export { getCurrentScheduleType, ICurrentScheduleType };

View File

@ -1,6 +1,13 @@
import { AppState } from 'reducers';
import { getCurrentTo, getCurrentValue } from './current';
import { getFields, getData, getWindowStart, getNonce, getTimeBounty } from './fields';
import {
getFields,
getData,
getWindowStart,
getNonce,
getTimeBounty,
getScheduleType
} from './fields';
import { makeTransaction, IHexStrTransaction } from 'libs/transaction';
import EthTx from 'ethereumjs-tx';
import { getUnit } from 'selectors/transaction/meta';
@ -66,6 +73,7 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => {
const dataExists = getDataExists(state);
const callData = getData(state);
const validGasCost = getValidGasCost(state);
const scheduleType = getScheduleType(state);
const windowStart = getWindowStart(state);
const gasLimit = getGasLimit(state);
const nonce = getNonce(state);
@ -98,7 +106,11 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => {
);
const transactionOptions = {
to: Address(EAC_ADDRESSES.KOVAN.blockScheduler),
to: Address(
scheduleType.value === 'time'
? EAC_ADDRESSES.KOVAN.timestampScheduler
: EAC_ADDRESSES.KOVAN.blockScheduler
),
data: transactionData,
gasLimit: EAC_SCHEDULING_CONFIG.SCHEDULING_GAS_LIMIT,
gasPrice: gasPrice.value,

View File

@ -18,7 +18,11 @@ describe('fields reducer', () => {
value: EAC_SCHEDULING_CONFIG.TIME_BOUNTY_DEFAULT
},
windowStart: { raw: '', value: null },
scheduleTimestamp: { raw: '', value: null }
scheduleTimestamp: { raw: '', value: null },
scheduleType: {
raw: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD,
value: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD
}
};
const testPayload = { raw: 'test', value: null };

View File

@ -51,6 +51,10 @@ describe('fields selector', () => {
scheduleTimestamp: {
raw: '',
value: null
},
scheduleType: {
raw: 'time',
value: 'time'
}
};

View File

@ -55,6 +55,10 @@ describe('helpers selector', () => {
scheduleTimestamp: {
raw: '',
value: null
},
scheduleType: {
raw: 'time',
value: 'time'
}
}
};
@ -69,7 +73,8 @@ describe('helpers selector', () => {
value: Wei('1000000000'),
timeBounty: Wei('1500'),
windowStart: null,
scheduleTimestamp: null
scheduleTimestamp: null,
scheduleType: 'time'
};
expect(reduceToValues(state.transaction.fields)).toEqual(values);
});